yinq 3 weeks ago
commit 874a3605e9

@ -4,8 +4,7 @@
<div class="componentMenu">
<el-popover
trigger="click"
placement="bottom-start"
>
placement="bottom-start">
<template #reference>
<div style="margin-left: 20px;display: inline-block">
<svg viewBox="0 0 1024 1024" width="20" height="20" style="margin-top: 15px;">
@ -70,13 +69,35 @@
</div>
<div class="optionsMenu"></div>
</div>
<div class="left"></div>
<div class="left">
<div class="title">
图层
</div>
<div class="level" v-for="i in 10">
<div class="isShow">
<el-icon style="cursor: pointer" color="#fff" :size="16">
<View />
</el-icon>
</div>
<div class="icon">
<svg viewBox="0 0 1024 1024" width="16" height="16"
style="margin-left: 10px;">
<path
d="M629.333333 160v768h-213.333333v-768h213.333333z m-277.333333 192v576h-213.333333v-576h213.333333z m554.666667 213.333333v362.666667h-213.333334v-362.666667h213.333334z m-341.333334-341.333333h-85.333333v640h85.333333v-640z m-277.333333 192h-85.333333v448h85.333333v-448z m554.666667 213.333333h-85.333334v234.666667h85.333334v-234.666667z"
fill="#ddd" p-id="10516"></path>
</svg>
</div>
<div class="boardName">
<span style=" display: inline-block;">图表名称</span>
</div>
</div>
</div>
<div class="center"></div>
<div class="right"></div>
</div>
</template>
<script setup>
import { ArrowDown } from '@element-plus/icons-vue';
import { ArrowDown, View } from '@element-plus/icons-vue';
</script>
<style scoped lang="less">
.boardGenerate {
@ -99,6 +120,43 @@ import { ArrowDown } from '@element-plus/icons-vue';
overflow: auto;
background-color: #1F2224;
border-right: 1px solid #000;
.title {
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
color: #FFF;
border-bottom: 1px solid #000;
}
.level {
display: flex;
align-items: center; /* 核心对齐逻辑 */
height: 50px;
padding-left: 20px;
border-bottom: 1px solid #000;
.isShow, .icon, .boardName {
display: flex;
align-items: center;
}
.isShow {
width: 30px;
height: 50px;
border-right: 1px solid #000;
}
.icon {
width: 40px;
}
.boardName {
font-size: 14px;
color: #fff;
}
}
}
.center {

@ -0,0 +1,280 @@
<template>
<div class="container">
<el-dialog v-model="visible" draggable title="审批记录" :width="props.width" :height="props.height" :close-on-click-modal="false">
<el-tabs v-model="tabActiveName" class="demo-tabs">
<el-tab-pane v-loading="loading" label="流程图" name="image" style="height: 68vh">
<div
ref="imageWrapperRef"
class="image-wrapper"
@wheel="handleMouseWheel"
@mousedown="handleMouseDown"
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
@mouseleave="handleMouseLeave"
@dblclick="resetTransform"
:style="transformStyle"
>
<el-card class="box-card">
<el-image :src="imgUrl" class="scalable-image" />
</el-card>
</div>
</el-tab-pane>
<el-tab-pane v-loading="loading" label="审批信息" name="info">
<div>
<el-table :data="historyList" style="width: 100%" border fit>
<el-table-column type="index" label="序号" align="center" width="60"></el-table-column>
<el-table-column prop="nodeName" label="任务名称" sortable align="center"></el-table-column>
<el-table-column prop="approveName" :show-overflow-tooltip="true" label="办理人" sortable align="center">
<template #default="scope">
<template v-if="scope.row.approveName">
<el-tag v-for="(item, index) in scope.row.approveName.split(',')" :key="index" type="success">{{ item }}</el-tag>
</template>
<template v-else> <el-tag type="success"></el-tag></template>
</template>
</el-table-column>
<el-table-column prop="flowStatus" label="状态" width="80" sortable align="center">
<template #default="scope">
<dict-tag :options="wf_task_status" :value="scope.row.flowStatus"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="message" label="审批意见" :show-overflow-tooltip="true" sortable align="center"></el-table-column>
<el-table-column prop="createTime" label="开始时间" width="160" :show-overflow-tooltip="true" sortable align="center"></el-table-column>
<el-table-column prop="updateTime" label="结束时间" width="160" :show-overflow-tooltip="true" sortable align="center"></el-table-column>
<el-table-column
prop="runDuration"
label="运行时长"
width="140"
:show-overflow-tooltip="true"
sortable
align="center"
></el-table-column>
<el-table-column prop="attachmentList" width="120" label="附件" align="center">
<template #default="scope">
<el-popover v-if="scope.row.attachmentList && scope.row.attachmentList.length > 0" placement="right" :width="310" trigger="click">
<template #reference>
<el-button type="primary" style="margin-right: 16px">附件</el-button>
</template>
<el-table border :data="scope.row.attachmentList">
<el-table-column prop="originalName" width="202" :show-overflow-tooltip="true" label="附件名称"></el-table-column>
<el-table-column prop="name" width="80" align="center" :show-overflow-tooltip="true" label="操作">
<template #default="tool">
<el-button type="text" @click="handleDownload(tool.row.ossId)"></el-button>
</template>
</el-table-column>
</el-table>
</el-popover>
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
</el-tabs>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { flowImage } from '@/api/workflow/instance';
import { propTypes } from '@/utils/propTypes';
import { listByIds } from '@/api/system/oss';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { wf_task_status } = toRefs<any>(proxy?.useDict('wf_task_status'));
const props = defineProps({
width: propTypes.string.def('80%'),
height: propTypes.string.def('100%')
});
const loading = ref(false);
const visible = ref(false);
const historyList = ref<Array<any>>([]);
const tabActiveName = ref('image');
const imgUrl = ref('');
//
const init = async (businessId: string | number) => {
visible.value = true;
loading.value = true;
tabActiveName.value = 'image';
historyList.value = [];
flowImage(businessId).then((resp) => {
if (resp.data) {
historyList.value = resp.data.list;
imgUrl.value = 'data:image/gif;base64,' + resp.data.image;
if (historyList.value.length > 0) {
historyList.value.forEach((item) => {
if (item.ext) {
getIds(item.ext).then((res) => {
item.attachmentList = res.data;
});
} else {
item.attachmentList = [];
}
});
}
loading.value = false;
}
});
};
const getIds = async (ids: string | number) => {
const res = await listByIds(ids);
return res;
};
/** 下载按钮操作 */
const handleDownload = (ossId: string) => {
proxy?.$download.oss(ossId);
};
const imageWrapperRef = ref<HTMLElement | null>(null);
const scale = ref(1); //
const maxScale = 3; //
const minScale = 0.5; //
let isDragging = false;
let startX = 0;
let startY = 0;
let currentTranslateX = 0;
let currentTranslateY = 0;
const handleMouseWheel = (event: WheelEvent) => {
event.preventDefault();
let newScale = scale.value - event.deltaY / 1000;
newScale = Math.max(minScale, Math.min(newScale, maxScale));
if (newScale !== scale.value) {
scale.value = newScale;
resetDragPosition(); // 使
}
};
const handleMouseDown = (event: MouseEvent) => {
if (scale.value > 1) {
event.preventDefault(); //
isDragging = true;
startX = event.clientX;
startY = event.clientY;
}
};
const handleMouseMove = (event: MouseEvent) => {
if (!isDragging || !imageWrapperRef.value) return;
const deltaX = event.clientX - startX;
const deltaY = event.clientY - startY;
startX = event.clientX;
startY = event.clientY;
currentTranslateX += deltaX;
currentTranslateY += deltaY;
//
const bounds = getBounds();
if (currentTranslateX > bounds.maxTranslateX) {
currentTranslateX = bounds.maxTranslateX;
} else if (currentTranslateX < bounds.minTranslateX) {
currentTranslateX = bounds.minTranslateX;
}
if (currentTranslateY > bounds.maxTranslateY) {
currentTranslateY = bounds.maxTranslateY;
} else if (currentTranslateY < bounds.minTranslateY) {
currentTranslateY = bounds.minTranslateY;
}
applyTransform();
};
const handleMouseUp = () => {
isDragging = false;
};
const handleMouseLeave = () => {
isDragging = false;
};
const resetTransform = () => {
scale.value = 1;
currentTranslateX = 0;
currentTranslateY = 0;
applyTransform();
};
const resetDragPosition = () => {
currentTranslateX = 0;
currentTranslateY = 0;
applyTransform();
};
const applyTransform = () => {
if (imageWrapperRef.value) {
imageWrapperRef.value.style.transform = `translate(${currentTranslateX}px, ${currentTranslateY}px) scale(${scale.value})`;
}
};
const getBounds = () => {
if (!imageWrapperRef.value) return { minTranslateX: 0, maxTranslateX: 0, minTranslateY: 0, maxTranslateY: 0 };
const imgRect = imageWrapperRef.value.getBoundingClientRect();
const containerRect = imageWrapperRef.value.parentElement?.getBoundingClientRect() ?? imgRect;
const minTranslateX = (containerRect.width - imgRect.width * scale.value) / 2;
const maxTranslateX = -(containerRect.width - imgRect.width * scale.value) / 2;
const minTranslateY = (containerRect.height - imgRect.height * scale.value) / 2;
const maxTranslateY = -(containerRect.height - imgRect.height * scale.value) / 2;
return { minTranslateX, maxTranslateX, minTranslateY, maxTranslateY };
};
const transformStyle = computed(() => ({
transition: isDragging ? 'none' : 'transform 0.2s ease'
}));
/**
* 对外暴露子组件方法
*/
defineExpose({
init
});
</script>
<style lang="scss" scoped>
.triangle {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
border-radius: 6px;
}
.triangle::after {
content: ' ';
position: absolute;
top: 8em;
right: 215px;
border: 15px solid;
border-color: transparent #fff transparent transparent;
}
.container {
:deep(.el-dialog .el-dialog__body) {
max-height: calc(100vh - 170px) !important;
min-height: calc(100vh - 170px) !important;
}
}
.image-wrapper {
width: 100%;
overflow: hidden;
position: relative;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
user-select: none; /* 禁用文本选择 */
cursor: grab; /* 设置初始鼠标指针为可拖动 */
}
.image-wrapper:active {
cursor: grabbing; /* 当正在拖动时改变鼠标指针 */
}
.scalable-image {
object-fit: contain;
width: 100%;
padding: 15px;
}
</style>

@ -0,0 +1,775 @@
<template>
<div class="p-2">
<!-- 操作按钮区域 -->
<el-card shadow="never">
<div style="display: flex; justify-content: space-between">
<div>
<el-button
v-if="submitButtonShow"
:loading="buttonLoading"
type="info"
@click="submitForm('draft')">
暂存
</el-button>
<el-button
v-if="submitButtonShow"
:loading="buttonLoading"
type="primary"
@click="submitForm('submit')">
提交
</el-button>
<el-button
v-if="approvalButtonShow"
:loading="buttonLoading"
type="primary"
@click="approvalVerifyOpen">
{{ currentStepName }}
</el-button>
<el-button
v-if="confirmButtonShow"
:loading="buttonLoading"
type="success"
@click="handleConfirm">
主管确认
</el-button>
<el-button
v-if="workOrder?.wfDefinitionId"
type="primary"
@click="handleApprovalRecord">
流程进度
</el-button>
</div>
<div>
<el-button @click="goBack()"></el-button>
</div>
</div>
</el-card>
<!-- 工单基本信息区域 -->
<el-card shadow="never" class="mb-[10px]">
<h4 class="form-header">工单基本信息</h4>
<el-form label-width="120px">
<el-row>
<el-col :span="8">
<el-form-item label="工单编号">
<el-input v-model="workOrder.billsFaultCode" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="工单状态">
<el-input v-model="workOrderStatusText" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请人">
<el-input v-model="workOrder.applyUser" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="设备编号">
<el-input v-model="workOrder.machineCode" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备名称">
<el-input v-model="workOrder.machineName" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请时间">
<el-input v-model="workOrder.applyTime" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 当前步骤处理区域 -->
<el-card shadow="never">
<h4 class="form-header">{{ currentStepTitle }}</h4>
<el-form
ref="processFormRef"
v-loading="loading"
:disabled="routeParams.type === 'view'"
:model="form"
:rules="rules"
label-width="120px">
<el-row>
<!-- 第一步故障报修信息 -->
<template v-if="currentStepOrder === 1">
<el-col :span="8">
<el-form-item label="故障类型" prop="faultType">
<el-select v-model="form.faultType" placeholder="请选择故障类型">
<el-option
v-for="dict in activity_fault_type"
:key="dict.value"
:label="dict.label"
:value="dict.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修类型" prop="repairType">
<el-select
v-model="form.repairType"
placeholder="请选择维修类型"
@change="updateOutsourcingValidation">
<el-option
v-for="dict in fault_repair_type"
:key="dict.value"
:label="dict.label"
:value="dict.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="外协单位" prop="outsourcingId">
<el-input v-model="form.outsourcingId" placeholder="请输入外协单位" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="故障描述" prop="faultDescription">
<el-input
v-model="form.faultDescription"
type="textarea"
:rows="3"
placeholder="请输入故障描述" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="涉及操作" prop="designOperations">
<el-input
v-model="form.designOperations"
type="textarea"
:rows="2"
placeholder="请输入涉及操作" />
</el-form-item>
</el-col>
</template>
<!-- 第二步维修处理 -->
<template v-if="currentStepOrder === 2">
<el-col :span="8">
<el-form-item label="故障类型">
<el-input v-model="form.faultType" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修类型">
<el-input v-model="form.repairType" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修人" prop="repairer">
<el-input v-model="form.repairer" placeholder="请输入维修人" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="检查后的故障判断" prop="checkedFault">
<el-input
v-model="form.checkedFault"
type="textarea"
:rows="3"
placeholder="请输入检查后的故障判断" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修措施" prop="protectedMethod">
<el-input
v-model="form.protectedMethod"
type="textarea"
:rows="3"
placeholder="请输入维修措施" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修内容" prop="repairContent">
<el-input
v-model="form.repairContent"
type="textarea"
:rows="4"
placeholder="请输入维修内容" />
</el-form-item>
</el-col>
</template>
<!-- 第三步维修确认 -->
<template v-if="currentStepOrder === 3">
<el-col :span="8">
<el-form-item label="维修人">
<el-input v-model="form.repairer" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修结果" prop="repairConfirm">
<el-select v-model="form.repairConfirm" placeholder="请选择维修结果">
<el-option
v-for="dict in fault_repair_confirm"
:key="dict.value"
:label="dict.label"
:value="dict.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="关联更换零部件" prop="componentsPartsId">
<el-input v-model="form.componentsPartsId" placeholder="请输入关联更换零部件内容" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修内容">
<el-input v-model="form.repairContent" type="textarea" :rows="3" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修措施">
<el-input v-model="form.protectedMethod" type="textarea" :rows="3" disabled />
</el-form-item>
</el-col>
</template>
<!-- 审批状态选择仅在审批阶段显示 -->
<el-col :span="8" v-if="isApprovalStage">
<el-form-item label="审批状态" prop="approveStatus">
<el-select v-model="form.approveStatus" placeholder="请选择审批状态">
<el-option
v-for="dict in dms_approve_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
:disabled="dict.value === '1'">
</el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 处理意见除第一步外都需要 -->
<el-col :span="24" v-if="needProcessResolution">
<el-form-item label="处理意见" prop="processHandleResolution">
<el-input
v-model="form.processHandleResolution"
type="textarea"
:rows="3"
placeholder="请输入处理意见" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 审批组件 -->
<submitVerify
ref="submitVerifyRef"
:task-variables="taskVariables"
@submit-callback="submitCallback" />
<!-- 审批记录组件 -->
<approvalRecord ref="approvalRecordRef" />
</div>
</template>
<script setup name="FaultWorkOrderProcess" lang="ts">
//
import { ref, reactive, computed, onMounted, getCurrentInstance, toRefs, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { getDmsBillsFaultInstance, approveWorkOrder, confirmRepairResult } from '@/api/dms/dmsBillsFaultInstance';
import { addDmsFaultInstanceActivity } from '@/api/dms/dmsFaultInstanceActivity';
import { pageByTaskWait } from '@/api/workflow/task';
import { getCurrentDateTime } from '@/utils/dateUtils';
import { getDmsBaseOutsourcingInfoList } from '@/api/dms/dmsBaseOutsourcingInfo';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { fault_repair_type, activity_fault_type, fault_repair_confirm, dms_approve_status } = toRefs<any>(proxy?.useDict('fault_repair_type', 'activity_fault_type', 'fault_repair_confirm', 'dms_approve_status'));
const route = useRoute();
const router = useRouter();
//
const loading = ref(true);
const buttonLoading = ref(false);
const routeParams = ref<Record<string, any>>({});
const workOrder = ref<any>({});
const workOrderStatusText = ref('');
const outsourceList = ref<any[]>([]);
//
const processFormRef = ref<ElFormInstance>();
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
//
const currentTask = ref<any>(null);
const currentStepOrder = ref(1);
const taskVariables = ref<any>({});
//
const initFormData = {
repairInstanceId: undefined,
faultType: undefined,
faultDescription: undefined,
designOperations: undefined,
repairType: undefined,
outsourcingId: undefined,
checkedFault: undefined,
repairContent: undefined,
protectedMethod: undefined,
repairer: undefined,
repairConfirm: undefined,
componentsPartsId: undefined,
processHandleResolution: undefined,
processStepOrder: undefined,
approveStatus: undefined
};
const form = reactive({ ...initFormData });
//
const rules = reactive({
faultType: [{ required: true, message: '故障类型不能为空', trigger: 'change' }],
faultDescription: [{ required: true, message: '故障描述不能为空', trigger: 'blur' }],
repairType: [{ required: true, message: '维修类型不能为空', trigger: 'change' }],
outsourcingId: [{ required: false, message: '外协单位不能为空', trigger: 'change' }],
repairer: [{ required: false, message: '维修人不能为空', trigger: 'blur' }],
checkedFault: [{ required: false, message: '检查后的故障判断不能为空', trigger: 'blur' }],
protectedMethod: [{ required: false, message: '维修措施不能为空', trigger: 'blur' }],
repairContent: [{ required: false, message: '维修内容不能为空', trigger: 'blur' }],
repairConfirm: [{ required: false, message: '维修结果不能为空', trigger: 'change' }],
processHandleResolution: [{ required: false, message: '处理意见不能为空', trigger: 'blur' }],
approveStatus: [{ required: false, message: '审批状态不能为空', trigger: 'change' }]
});
//
const needProcessResolution = computed(() => currentStepOrder.value > 1);
const currentStepName = computed(() => {
const stepNames = {
1: '故障报修',
2: '维修处理',
3: '维修确认'
};
return stepNames[currentStepOrder.value] || '处理工单';
});
const currentStepTitle = computed(() => {
const stepTitles = {
1: '步骤1故障报修要求参数',
2: '步骤2维修处理实际参数',
3: '步骤3维修确认'
};
return stepTitles[currentStepOrder.value] || '工单处理';
});
const approvalButtonShow = computed(() => {
return routeParams.value.type === 'approval' && currentTask.value;
});
const confirmButtonShow = computed(() => {
//
// 1. confirm
// 2. (2)(0)
// 3. (2) -
return routeParams.value.type === 'confirm' ||
(workOrder.value.billsStatus === '2' &&
workOrder.value.repairConfirm === '0' &&
workOrder.value.approveStatus === '2');
});
//
const isApprovalStage = computed(() => {
return routeParams.value.type === 'approval' && workOrder.value.approveStatus === '1';
});
//
const submitButtonShow = computed(() => {
return (
routeParams.value.type === 'add' ||
(routeParams.value.type === 'update' &&
workOrder.value.billsStatus &&
(workOrder.value.billsStatus === 'draft' || workOrder.value.billsStatus === 'cancel' || workOrder.value.billsStatus === 'back'))
);
});
//
onMounted(async () => {
routeParams.value = route.query;
loading.value = true;
try {
//
await loadWorkOrderInfo();
//
await getOutsourceList();
//
if (routeParams.value.type === 'approval') {
await loadCurrentTask();
}
//
initializeFormData();
//
if (routeParams.value.type === 'approval' && workOrder.value.approveStatus === '1') {
rules.approveStatus = [{ required: true, message: '审批状态不能为空', trigger: 'change' }];
}
//
updateOutsourcingValidation();
} catch (error) {
console.error('初始化失败:', error);
proxy?.$modal.msgError('加载数据失败');
} finally {
loading.value = false;
}
});
//
watch(() => form.repairType, (newValue) => {
updateOutsourcingValidation();
//
if (newValue !== '2') {
form.outsourcingId = undefined;
}
});
//
const loadWorkOrderInfo = async () => {
// querybusinessId
const businessId = routeParams.value.id;
if (!businessId) {
proxy?.$modal.msgError('缺少工单ID参数');
return;
}
const res = await getDmsBillsFaultInstance(businessId);
workOrder.value = res.data;
//
workOrderStatusText.value = getStatusText(workOrder.value.billsStatus);
};
//
const loadCurrentTask = async () => {
// querybusinessIdtaskId
const businessId = routeParams.value.id;
const taskId = routeParams.value.taskId;
// taskIdbusinessId
const taskRes = await pageByTaskWait({
pageNum: 1,
pageSize: 10,
flowCode: 'Fault01' //
});
const tasks = taskRes.rows.filter(task =>
task.businessId === businessId || task.id === taskId
);
if (tasks.length > 0) {
currentTask.value = tasks[0];
//
const nodeName = currentTask.value.nodeName;
if (nodeName === '故障报修') {
currentStepOrder.value = 1;
} else if (nodeName === '维修处理') {
currentStepOrder.value = 2;
} else if (nodeName === '维修确认') {
currentStepOrder.value = 3;
}
//
if (needProcessResolution.value) {
rules.processHandleResolution = [
{ required: true, message: '处理意见不能为空', trigger: 'blur' }
];
}
}
};
//
const initializeFormData = () => {
//
form.repairInstanceId = workOrder.value.repairInstanceId;
form.processStepOrder = currentStepOrder.value;
if (currentStepOrder.value === 1) {
//
form.faultType = workOrder.value.faultType;
form.faultDescription = workOrder.value.faultDescription;
form.designOperations = workOrder.value.designOperations;
form.repairType = workOrder.value.repairType;
form.outsourcingId = workOrder.value.outsourcingId;
} else {
//
form.faultType = workOrder.value.faultType;
form.faultDescription = workOrder.value.faultDescription;
form.designOperations = workOrder.value.designOperations;
form.repairType = workOrder.value.repairType;
form.outsourcingId = workOrder.value.outsourcingId;
form.checkedFault = workOrder.value.checkedFault;
form.repairContent = workOrder.value.repairContent;
form.protectedMethod = workOrder.value.protectedMethod;
form.repairer = workOrder.value.repairer;
form.repairConfirm = workOrder.value.repairConfirm;
form.componentsPartsId = workOrder.value.componentsPartsId;
}
};
//
const submitForm = async (status: string) => {
if (!processFormRef.value) return;
try {
const valid = await processFormRef.value.validate();
if (valid) {
buttonLoading.value = true;
if (status === 'draft') {
//
await addDmsFaultInstanceActivity({
repairInstanceId: form.repairInstanceId,
faultType: form.faultType,
faultDescription: form.faultDescription,
designOperations: form.designOperations,
repairType: form.repairType,
outsourcingId: form.outsourcingId,
checkedFault: form.checkedFault || '',
repairContent: form.repairContent || '',
protectedMethod: form.protectedMethod || '',
repairer: form.repairer || '',
repairConfirm: form.repairConfirm,
componentsPartsId: form.componentsPartsId,
processHandleResolution: form.processHandleResolution || '',
processStepOrder: form.processStepOrder,
handleTime: getCurrentDateTime()
});
proxy?.$modal.msgSuccess('暂存成功');
goBack();
} else {
//
//
taskVariables.value = {
entity: {
repairInstanceId: form.repairInstanceId,
faultType: form.faultType,
faultDescription: form.faultDescription,
designOperations: form.designOperations,
repairType: form.repairType,
outsourcingId: form.outsourcingId,
checkedFault: form.checkedFault || '',
repairContent: form.repairContent || '',
protectedMethod: form.protectedMethod || '',
repairer: form.repairer || '',
repairConfirm: form.repairConfirm,
componentsPartsId: form.componentsPartsId,
processHandleResolution: form.processHandleResolution || '',
processStepOrder: form.processStepOrder
}
};
//
if (routeParams.value.taskId) {
submitVerifyRef.value?.openDialog(routeParams.value.taskId);
} else {
//
proxy?.$modal.msgSuccess('提交成功');
goBack();
}
}
}
} catch (error) {
console.error('提交失败:', error);
proxy?.$modal.msgError('提交失败');
} finally {
buttonLoading.value = false;
}
};
//
const approvalVerifyOpen = async () => {
if (!processFormRef.value) return;
try {
const valid = await processFormRef.value.validate();
if (valid) {
//
if (routeParams.value.type === 'approval' && !form.approveStatus) {
proxy?.$modal.msgError('请选择审批状态');
return;
}
// - SubmitVerifyWarm-Flow
taskVariables.value = {
//
entity: {
repairInstanceId: form.repairInstanceId,
faultType: form.faultType,
faultDescription: form.faultDescription,
designOperations: form.designOperations,
repairType: form.repairType,
outsourcingId: form.outsourcingId,
checkedFault: form.checkedFault || '',
repairContent: form.repairContent || '',
protectedMethod: form.protectedMethod || '',
repairer: form.repairer || '',
repairConfirm: form.repairConfirm,
componentsPartsId: form.componentsPartsId,
processHandleResolution: form.processHandleResolution || '',
processStepOrder: form.processStepOrder
}
};
//
if (routeParams.value.type === 'approval' && form.approveStatus) {
// taskVariablesapproveStatus - SubmitVerify
taskVariables.value.approveStatus = form.approveStatus;
console.log('设置审批状态变量:', form.approveStatus);
}
//
if (routeParams.value.type === 'confirm' && form.repairConfirm) {
// 01
const repairConfirmValue = form.repairConfirm === '1' ? '0' : '1';
taskVariables.value.repairConfirm = repairConfirmValue;
console.log('设置确认结果变量:', repairConfirmValue);
}
console.log('完整的工作流变量:', taskVariables.value);
// 使taskId
submitVerifyRef.value?.openDialog(routeParams.value.taskId);
}
} catch (error) {
proxy?.$modal.msgError('表单验证失败,请检查输入项');
}
};
//
const submitCallback = async (approvalResult?: any) => {
try {
//
if (routeParams.value.type === 'approval') {
// 使
const approveStatus = form.approveStatus; // 使
const message = approvalResult?.message || form.processHandleResolution || '';
await approveWorkOrder(form.repairInstanceId, approveStatus, message);
const statusText = approveStatus === '2' ? '通过' : '拒绝';
proxy?.$modal.msgSuccess(`审批${statusText}成功`);
} else if (routeParams.value.type === 'confirm') {
//
const confirmResult = form.repairConfirm || '1'; //
await confirmRepairResult(form.repairInstanceId, confirmResult);
proxy?.$modal.msgSuccess('确认完成');
} else {
//
await addDmsFaultInstanceActivity({
repairInstanceId: form.repairInstanceId,
faultType: form.faultType,
faultDescription: form.faultDescription,
designOperations: form.designOperations,
repairType: form.repairType,
outsourcingId: form.outsourcingId,
checkedFault: form.checkedFault || '',
repairContent: form.repairContent || '',
protectedMethod: form.protectedMethod || '',
repairer: form.repairer || '',
repairConfirm: form.repairConfirm,
componentsPartsId: form.componentsPartsId,
processHandleResolution: form.processHandleResolution || '',
processStepOrder: form.processStepOrder,
handleTime: getCurrentDateTime()
});
proxy?.$modal.msgSuccess(`${currentStepName.value}完成`);
}
//
goBack();
} catch (error: any) {
console.error('操作失败:', error);
proxy?.$modal.msgError('操作失败:' + (error.message || '未知错误'));
}
};
//
const handleConfirm = async () => {
try {
//
form.repairConfirm = '1'; // 1
//
await approvalVerifyOpen();
} catch (error: any) {
if (error !== 'cancel' && error !== 'close') {
console.error('确认失败:', error);
proxy?.$modal.msgError('确认失败:' + (error.message || '未知错误'));
}
}
};
//
const handleApprovalRecord = () => {
approvalRecordRef.value?.init(routeParams.value.id);
};
//
const goBack = () => {
proxy?.$tab.closePage(proxy?.$route);
router.go(-1);
};
//
const getOutsourceList = async () => {
try {
const res = await getDmsBaseOutsourcingInfoList(null);
outsourceList.value = res.data;
} catch (error) {
console.error('获取外协单位列表失败:', error);
}
};
//
const updateOutsourcingValidation = () => {
if (form.repairType === '2') {
//
rules.outsourcingId = [{ required: true, message: '外协单位不能为空', trigger: 'change' }];
} else {
//
rules.outsourcingId = [{ required: false, message: '外协单位不能为空', trigger: 'change' }];
}
};
//
const getStatusText = (status: string) => {
const statusMap = {
'0': '待维修',
'1': '维修中',
'2': '维修完成',
'draft': '草稿',
'cancel': '已取消'
};
return statusMap[status] || '未知状态';
};
</script>
<style scoped>
.form-header {
margin-bottom: 16px;
color: #303133;
font-weight: 600;
}
</style>

@ -4,37 +4,37 @@
<el-card shadow="never">
<div style="display: flex; justify-content: space-between">
<div>
<el-button
v-if="submitButtonShow"
:loading="buttonLoading"
type="info"
<el-button
v-if="submitButtonShow"
:loading="buttonLoading"
type="info"
@click="submitForm('draft')">
暂存
</el-button>
<el-button
v-if="submitButtonShow"
:loading="buttonLoading"
type="primary"
<el-button
v-if="submitButtonShow"
:loading="buttonLoading"
type="primary"
@click="submitForm('submit')">
提交
</el-button>
<el-button
v-if="approvalButtonShow"
:loading="buttonLoading"
type="primary"
<el-button
v-if="approvalButtonShow"
:loading="buttonLoading"
type="primary"
@click="approvalVerifyOpen">
{{ currentStepName }}
</el-button>
<el-button
v-if="confirmButtonShow"
:loading="buttonLoading"
type="success"
<el-button
v-if="confirmButtonShow"
:loading="buttonLoading"
type="success"
@click="handleConfirm">
主管确认
</el-button>
<el-button
v-if="workOrder?.wfDefinitionId"
type="primary"
<el-button
v-if="workOrder?.wfDefinitionId"
type="primary"
@click="handleApprovalRecord">
流程进度
</el-button>
@ -52,7 +52,7 @@
<el-row>
<el-col :span="8">
<el-form-item label="工单编号">
<el-input v-model="workOrder.billsFaultCode" disabled />
<el-input :value="workOrder?.billsFaultCode || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
@ -62,24 +62,24 @@
</el-col>
<el-col :span="8">
<el-form-item label="申请人">
<el-input v-model="workOrder.applyUser" disabled />
<el-input :value="workOrder?.applyUser || ''" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="设备编号">
<el-input v-model="workOrder.machineCode" disabled />
<el-input :value="workOrder?.machineCode || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备名称">
<el-input v-model="workOrder.machineName" disabled />
<el-input :value="workOrder?.machineName || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请时间">
<el-input v-model="workOrder.applyTime" disabled />
<el-input :value="workOrder?.applyTime || ''" disabled />
</el-form-item>
</el-col>
</el-row>
@ -89,66 +89,66 @@
<!-- 当前步骤处理区域 -->
<el-card shadow="never">
<h4 class="form-header">{{ currentStepTitle }}</h4>
<el-form
ref="processFormRef"
v-loading="loading"
:disabled="routeParams.type === 'view'"
:model="form"
:rules="rules"
<el-form
ref="processFormRef"
v-loading="loading"
:disabled="routeParams.type === 'view'"
:model="form"
:rules="rules"
label-width="120px">
<el-row>
<!-- 第一步故障报修信息 -->
<template v-if="currentStepOrder === 1">
<el-col :span="8">
<el-form-item label="故障类型" prop="faultType">
<el-select v-model="form.faultType" placeholder="请选择故障类型">
<el-option
v-for="dict in activity_fault_type"
:key="dict.value"
:label="dict.label"
<el-form-item label="故障类型" prop="faultType">
<el-select v-model="form.faultType" placeholder="请选择故障类型">
<el-option
v-for="dict in activity_fault_type"
:key="dict.value"
:label="dict.label"
:value="dict.value">
</el-option>
</el-select>
</el-form-item>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修类型" prop="repairType">
<el-select
v-model="form.repairType"
placeholder="请选择维修类型"
@change="updateOutsourcingValidation">
<el-option
v-for="dict in fault_repair_type"
:key="dict.value"
:label="dict.label"
<el-form-item label="维修类型" prop="repairType">
<el-select
v-model="form.repairType"
placeholder="请选择维修类型"
@change="updateOutsourcingValidation">
<el-option
v-for="dict in fault_repair_type"
:key="dict.value"
:label="dict.label"
:value="dict.value">
</el-option>
</el-select>
</el-form-item>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="外协单位" prop="outsourcingId">
<el-input v-model="form.outsourcingId" placeholder="请输入外协单位" />
</el-form-item>
<el-form-item label="外协单位" prop="outsourcingId">
<el-input v-model="form.outsourcingId" placeholder="请输入外协单位" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="故障描述" prop="faultDescription">
<el-input
v-model="form.faultDescription"
type="textarea"
:rows="3"
<el-input
v-model="form.faultDescription"
type="textarea"
:rows="3"
placeholder="请输入故障描述" />
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="涉及操作" prop="designOperations">
<el-input
v-model="form.designOperations"
type="textarea"
:rows="2"
<el-input
v-model="form.designOperations"
type="textarea"
:rows="2"
placeholder="请输入涉及操作" />
</el-form-item>
</el-form-item>
</el-col>
</template>
@ -157,42 +157,42 @@
<el-col :span="8">
<el-form-item label="故障类型">
<el-input v-model="form.faultType" disabled />
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修类型">
<el-input v-model="form.repairType" disabled />
</el-form-item>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修人" prop="repairer">
<el-input v-model="form.repairer" placeholder="请输入维修人" />
</el-form-item>
<el-form-item label="维修人" prop="repairer">
<el-input v-model="form.repairer" placeholder="请输入维修人" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="检查后的故障判断" prop="checkedFault">
<el-input
v-model="form.checkedFault"
type="textarea"
:rows="3"
<el-input
v-model="form.checkedFault"
type="textarea"
:rows="3"
placeholder="请输入检查后的故障判断" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修措施" prop="protectedMethod">
<el-input
v-model="form.protectedMethod"
type="textarea"
:rows="3"
<el-input
v-model="form.protectedMethod"
type="textarea"
:rows="3"
placeholder="请输入维修措施" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修内容" prop="repairContent">
<el-input
v-model="form.repairContent"
type="textarea"
:rows="4"
<el-input
v-model="form.repairContent"
type="textarea"
:rows="4"
placeholder="请输入维修内容" />
</el-form-item>
</el-col>
@ -206,21 +206,21 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="维修结果" prop="repairConfirm">
<el-select v-model="form.repairConfirm" placeholder="请选择维修结果">
<el-option
v-for="dict in fault_repair_confirm"
:key="dict.value"
:label="dict.label"
<el-form-item label="维修结果" prop="repairConfirm">
<el-select v-model="form.repairConfirm" placeholder="请选择维修结果">
<el-option
v-for="dict in fault_repair_confirm"
:key="dict.value"
:label="dict.label"
:value="dict.value">
</el-option>
</el-select>
</el-form-item>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="关联更换零部件" prop="componentsPartsId">
<el-input v-model="form.componentsPartsId" placeholder="请输入关联更换零部件内容" />
</el-form-item>
<el-input v-model="form.componentsPartsId" placeholder="请输入关联更换零部件内容" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="维修内容">
@ -233,8 +233,8 @@
</el-form-item>
</el-col>
</template>
<!-- 审批状态选择仅在审批阶段显示 -->
<!-- 审批状态选择仅在审批阶段显示 -->
<el-col :span="8" v-if="isApprovalStage">
<el-form-item label="审批状态" prop="approveStatus">
<el-select v-model="form.approveStatus" placeholder="请选择审批状态">
@ -264,11 +264,11 @@
</el-card>
<!-- 审批组件 -->
<submitVerify
ref="submitVerifyRef"
:task-variables="taskVariables"
<submitVerify
ref="submitVerifyRef"
:task-variables="taskVariables"
@submit-callback="submitCallback" />
<!-- 审批记录组件 -->
<approvalRecord ref="approvalRecordRef" />
@ -284,7 +284,7 @@ import { addDmsFaultInstanceActivity } from '@/api/dms/dmsFaultInstanceActivity'
import { pageByTaskWait } from '@/api/workflow/task';
import { getCurrentDateTime } from '@/utils/dateUtils';
import { getDmsBaseOutsourcingInfoList } from '@/api/dms/dmsBaseOutsourcingInfo';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import SubmitVerify from '@/views/dms/dmsFaultInstanceActivity/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -333,9 +333,9 @@ const form = reactive({ ...initFormData });
//
const rules = reactive({
faultType: [{ required: true, message: '故障类型不能为空', trigger: 'change' }],
faultDescription: [{ required: true, message: '故障描述不能为空', trigger: 'blur' }],
repairType: [{ required: true, message: '维修类型不能为空', trigger: 'change' }],
faultType: [{ required: false, message: '故障类型不能为空', trigger: 'change' }],
faultDescription: [{ required: false, message: '故障描述不能为空', trigger: 'blur' }],
repairType: [{ required: false, message: '维修类型不能为空', trigger: 'change' }],
outsourcingId: [{ required: false, message: '外协单位不能为空', trigger: 'change' }],
repairer: [{ required: false, message: '维修人不能为空', trigger: 'blur' }],
checkedFault: [{ required: false, message: '检查后的故障判断不能为空', trigger: 'blur' }],
@ -352,7 +352,7 @@ const needProcessResolution = computed(() => currentStepOrder.value > 1);
const currentStepName = computed(() => {
const stepNames = {
1: '故障报修',
2: '维修处理',
2: '维修处理',
3: '维修确认'
};
return stepNames[currentStepOrder.value] || '处理工单';
@ -377,14 +377,14 @@ const confirmButtonShow = computed(() => {
// 2. (2)(0)
// 3. (2) -
return routeParams.value.type === 'confirm' ||
(workOrder.value.billsStatus === '2' &&
workOrder.value.repairConfirm === '0' &&
workOrder.value.approveStatus === '2');
(workOrder.value?.billsStatus === '2' &&
workOrder.value?.repairConfirm === '0' &&
workOrder.value?.approveStatus === '2');
});
//
const isApprovalStage = computed(() => {
return routeParams.value.type === 'approval' && workOrder.value.approveStatus === '1';
return routeParams.value.type === 'approval' && workOrder.value?.approveStatus === '1';
});
//
@ -392,7 +392,7 @@ const submitButtonShow = computed(() => {
return (
routeParams.value.type === 'add' ||
(routeParams.value.type === 'update' &&
workOrder.value.billsStatus &&
workOrder.value?.billsStatus &&
(workOrder.value.billsStatus === 'draft' || workOrder.value.billsStatus === 'cancel' || workOrder.value.billsStatus === 'back'))
);
});
@ -414,16 +414,11 @@ onMounted(async () => {
await loadCurrentTask();
}
//
initializeFormData();
//
initializeFormData();
//
if (routeParams.value.type === 'approval' && workOrder.value.approveStatus === '1') {
rules.approveStatus = [{ required: true, message: '审批状态不能为空', trigger: 'change' }];
}
//
updateOutsourcingValidation();
//
setDynamicValidationRules();
} catch (error) {
console.error('初始化失败:', error);
@ -446,17 +441,17 @@ watch(() => form.repairType, (newValue) => {
const loadWorkOrderInfo = async () => {
// querybusinessId
const businessId = routeParams.value.id;
if (!businessId) {
proxy?.$modal.msgError('缺少工单ID参数');
return;
}
const res = await getDmsBillsFaultInstance(businessId);
workOrder.value = res.data;
//
workOrderStatusText.value = getStatusText(workOrder.value.billsStatus);
workOrder.value = res.data || {}; // null
// -
workOrderStatusText.value = getStatusText(workOrder.value.billsStatus || '');
};
//
@ -464,21 +459,21 @@ const loadCurrentTask = async () => {
// querybusinessIdtaskId
const businessId = routeParams.value.id;
const taskId = routeParams.value.taskId;
// taskIdbusinessId
const taskRes = await pageByTaskWait({
pageNum: 1,
pageSize: 10,
flowCode: 'Fault01' //
});
const tasks = taskRes.rows.filter(task =>
const tasks = taskRes.rows.filter(task =>
task.businessId === businessId || task.id === taskId
);
if (tasks.length > 0) {
currentTask.value = tasks[0];
//
const nodeName = currentTask.value.nodeName;
if (nodeName === '故障报修') {
@ -488,7 +483,7 @@ const loadCurrentTask = async () => {
} else if (nodeName === '维修确认') {
currentStepOrder.value = 3;
}
//
if (needProcessResolution.value) {
rules.processHandleResolution = [
@ -501,41 +496,37 @@ const loadCurrentTask = async () => {
//
const initializeFormData = () => {
//
form.repairInstanceId = workOrder.value.repairInstanceId;
form.repairInstanceId = workOrder.value?.repairInstanceId;
form.processStepOrder = currentStepOrder.value;
// undefined
form.faultType = workOrder.value?.faultType || '';
form.faultDescription = workOrder.value?.faultDescription || '';
form.designOperations = workOrder.value?.designOperations || '';
form.repairType = workOrder.value?.repairType || '';
form.outsourcingId = workOrder.value?.outsourcingId || '';
form.checkedFault = workOrder.value?.checkedFault || '';
form.repairContent = workOrder.value?.repairContent || '';
form.protectedMethod = workOrder.value?.protectedMethod || '';
form.repairer = workOrder.value?.repairer || '';
form.repairConfirm = workOrder.value?.repairConfirm || '';
form.componentsPartsId = workOrder.value?.componentsPartsId || '';
if (currentStepOrder.value === 1) {
//
form.faultType = workOrder.value.faultType;
form.faultDescription = workOrder.value.faultDescription;
form.designOperations = workOrder.value.designOperations;
form.repairType = workOrder.value.repairType;
form.outsourcingId = workOrder.value.outsourcingId;
} else {
//
form.faultType = workOrder.value.faultType;
form.faultDescription = workOrder.value.faultDescription;
form.designOperations = workOrder.value.designOperations;
form.repairType = workOrder.value.repairType;
form.outsourcingId = workOrder.value.outsourcingId;
form.checkedFault = workOrder.value.checkedFault;
form.repairContent = workOrder.value.repairContent;
form.protectedMethod = workOrder.value.protectedMethod;
form.repairer = workOrder.value.repairer;
form.repairConfirm = workOrder.value.repairConfirm;
form.componentsPartsId = workOrder.value.componentsPartsId;
//
if (routeParams.value.type === 'approval' && !form.approveStatus) {
form.approveStatus = undefined; //
}
};
//
const submitForm = async (status: string) => {
if (!processFormRef.value) return;
try {
const valid = await processFormRef.value.validate();
if (valid) {
buttonLoading.value = true;
if (status === 'draft') {
//
await addDmsFaultInstanceActivity({
@ -555,7 +546,7 @@ const submitForm = async (status: string) => {
processStepOrder: form.processStepOrder,
handleTime: getCurrentDateTime()
});
proxy?.$modal.msgSuccess('暂存成功');
goBack();
} else {
@ -579,7 +570,7 @@ const submitForm = async (status: string) => {
processStepOrder: form.processStepOrder
}
};
//
if (routeParams.value.taskId) {
submitVerifyRef.value?.openDialog(routeParams.value.taskId);
@ -601,108 +592,73 @@ const submitForm = async (status: string) => {
//
const approvalVerifyOpen = async () => {
if (!processFormRef.value) return;
try {
const valid = await processFormRef.value.validate();
if (valid) {
//
if (routeParams.value.type === 'approval' && !form.approveStatus) {
proxy?.$modal.msgError('请选择审批状态');
return;
}
await proxy?.$modal.confirm('是否确认提交审批?');
// - SubmitVerifyWarm-Flow
taskVariables.value = {
//
entity: {
repairInstanceId: form.repairInstanceId,
faultType: form.faultType,
faultDescription: form.faultDescription,
designOperations: form.designOperations,
repairType: form.repairType,
outsourcingId: form.outsourcingId,
checkedFault: form.checkedFault || '',
repairContent: form.repairContent || '',
protectedMethod: form.protectedMethod || '',
repairer: form.repairer || '',
repairConfirm: form.repairConfirm,
componentsPartsId: form.componentsPartsId,
processHandleResolution: form.processHandleResolution || '',
processStepOrder: form.processStepOrder
}
};
buttonLoading.value = true;
//
if (routeParams.value.type === 'approval' && form.approveStatus) {
// taskVariablesapproveStatus - SubmitVerify
taskVariables.value.approveStatus = form.approveStatus;
console.log('设置审批状态变量:', form.approveStatus);
}
//
const approveStatus = form.approveStatus;
const message = form.processHandleResolution || '';
await approveWorkOrder(form.repairInstanceId, approveStatus, message);
//
if (routeParams.value.type === 'confirm' && form.repairConfirm) {
// 01
const repairConfirmValue = form.repairConfirm === '1' ? '0' : '1';
taskVariables.value.repairConfirm = repairConfirmValue;
console.log('设置确认结果变量:', repairConfirmValue);
}
const statusText = approveStatus === '2' ? '通过' : '拒绝';
proxy?.$modal.msgSuccess(`审批${statusText}成功`);
console.log('完整的工作流变量:', taskVariables.value);
// 使taskId
submitVerifyRef.value?.openDialog(routeParams.value.taskId);
//
goBack();
}
} catch (error) {
proxy?.$modal.msgError('表单验证失败,请检查输入项');
} catch (error: any) {
if (error !== 'cancel' && error !== 'close') {
console.error('审批失败:', error);
proxy?.$modal.msgError('审批失败:' + (error.message || '未知错误'));
}
} finally {
buttonLoading.value = false;
}
};
//
const submitCallback = async (approvalResult?: any) => {
try {
//
if (routeParams.value.type === 'approval') {
// 使
const approveStatus = form.approveStatus; // 使
const message = approvalResult?.message || form.processHandleResolution || '';
await approveWorkOrder(form.repairInstanceId, approveStatus, message);
const statusText = approveStatus === '2' ? '通过' : '拒绝';
proxy?.$modal.msgSuccess(`审批${statusText}成功`);
} else if (routeParams.value.type === 'confirm') {
if (routeParams.value.type === 'confirm') {
//
const confirmResult = form.repairConfirm || '1'; //
await confirmRepairResult(form.repairInstanceId, confirmResult);
proxy?.$modal.msgSuccess('确认完成');
} else {
//
await addDmsFaultInstanceActivity({
repairInstanceId: form.repairInstanceId,
faultType: form.faultType,
faultDescription: form.faultDescription,
designOperations: form.designOperations,
repairType: form.repairType,
outsourcingId: form.outsourcingId,
checkedFault: form.checkedFault || '',
repairContent: form.repairContent || '',
protectedMethod: form.protectedMethod || '',
repairer: form.repairer || '',
repairConfirm: form.repairConfirm,
componentsPartsId: form.componentsPartsId,
processHandleResolution: form.processHandleResolution || '',
processStepOrder: form.processStepOrder,
handleTime: getCurrentDateTime()
});
proxy?.$modal.msgSuccess(`${currentStepName.value}完成`);
//
await addDmsFaultInstanceActivity({
repairInstanceId: form.repairInstanceId,
faultType: form.faultType,
faultDescription: form.faultDescription,
designOperations: form.designOperations,
repairType: form.repairType,
outsourcingId: form.outsourcingId,
checkedFault: form.checkedFault || '',
repairContent: form.repairContent || '',
protectedMethod: form.protectedMethod || '',
repairer: form.repairer || '',
repairConfirm: form.repairConfirm,
componentsPartsId: form.componentsPartsId,
processHandleResolution: form.processHandleResolution || '',
processStepOrder: form.processStepOrder,
handleTime: getCurrentDateTime()
});
proxy?.$modal.msgSuccess(`${currentStepName.value}完成`);
}
//
goBack();
} catch (error: any) {
console.error('操作失败:', error);
proxy?.$modal.msgError('操作失败:' + (error.message || '未知错误'));
}
} catch (error: any) {
console.error('操作失败:', error);
proxy?.$modal.msgError('操作失败:' + (error.message || '未知错误'));
}
};
//
@ -710,7 +666,7 @@ const handleConfirm = async () => {
try {
//
form.repairConfirm = '1'; // 1
//
await approvalVerifyOpen();
} catch (error: any) {
@ -744,15 +700,61 @@ const getOutsourceList = async () => {
//
const updateOutsourcingValidation = () => {
if (form.repairType === '2') {
//
//
if (routeParams.value.type !== 'approval' && form.repairType === '2') {
rules.outsourcingId = [{ required: true, message: '外协单位不能为空', trigger: 'change' }];
} else {
//
rules.outsourcingId = [{ required: false, message: '外协单位不能为空', trigger: 'change' }];
}
};
//
const setDynamicValidationRules = () => {
//
Object.keys(rules).forEach(key => {
rules[key] = [{ required: false, message: rules[key][0].message, trigger: rules[key][0].trigger }];
});
//
if (routeParams.value.type === 'approval') {
//
rules.approveStatus = [{ required: true, message: '审批状态不能为空', trigger: 'change' }];
if (needProcessResolution.value) {
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
}
} else if (routeParams.value.type === 'confirm') {
//
rules.repairConfirm = [{ required: true, message: '维修结果不能为空', trigger: 'change' }];
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
} else {
//
if (currentStepOrder.value === 1) {
//
rules.faultType = [{ required: true, message: '故障类型不能为空', trigger: 'change' }];
rules.faultDescription = [{ required: true, message: '故障描述不能为空', trigger: 'blur' }];
rules.repairType = [{ required: true, message: '维修类型不能为空', trigger: 'change' }];
} else if (currentStepOrder.value === 2) {
//
rules.repairer = [{ required: true, message: '维修人不能为空', trigger: 'blur' }];
rules.checkedFault = [{ required: true, message: '检查后的故障判断不能为空', trigger: 'blur' }];
rules.protectedMethod = [{ required: true, message: '维修措施不能为空', trigger: 'blur' }];
rules.repairContent = [{ required: true, message: '维修内容不能为空', trigger: 'blur' }];
if (needProcessResolution.value) {
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
}
} else if (currentStepOrder.value === 3) {
//
rules.repairConfirm = [{ required: true, message: '维修结果不能为空', trigger: 'change' }];
if (needProcessResolution.value) {
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
}
}
}
//
updateOutsourcingValidation();
};
//
const getStatusText = (status: string) => {
const statusMap = {
@ -772,4 +774,4 @@ const getStatusText = (status: string) => {
color: #303133;
font-weight: 600;
}
</style>
</style>

@ -0,0 +1,557 @@
<template>
<el-dialog v-model="dialog.visible" :title="dialog.title" width="50%" draggable :before-close="cancel" center :close-on-click-modal="false">
<el-form v-loading="loading" :model="form" label-width="120px">
<el-form-item label="消息提醒">
<el-checkbox-group v-model="form.messageType">
<el-checkbox value="1" name="type" disabled>站内信</el-checkbox>
<el-checkbox value="2" name="type">邮件</el-checkbox>
<el-checkbox value="3" name="type">短信</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item v-if="task.flowStatus === 'waiting'" label="附件">
<fileUpload v-model="form.fileId" :file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']" :file-size="20" />
</el-form-item>
<el-form-item label="抄送" v-if="task.flowStatus === 'waiting' && buttonObj.copy">
<el-button type="primary" icon="Plus" circle @click="openUserSelectCopy" />
<el-tag v-for="user in selectCopyUserList" :key="user.userId" closable style="margin: 2px" @close="handleCopyCloseTag(user)">
{{ user.nickName }}
</el-tag>
</el-form-item>
<el-form-item v-if="buttonObj.pop && nestNodeList && nestNodeList.length > 0" label="下一步审批人" prop="assigneeMap">
<div v-for="(item, index) in nestNodeList" :key="index" style="margin-bottom: 5px; width: 500px">
<span>{{ item.nodeName }}</span>
<el-input v-if="false" v-model="form.assigneeMap[item.nodeCode]" />
<el-input placeholder="请选择审批人" readonly v-model="nickName[item.nodeCode]">
<template v-slot:append>
<el-button @click="choosePeople(item)" icon="search">选择</el-button>
</template>
</el-input>
</div>
</el-form-item>
<el-form-item v-if="task.flowStatus === 'waiting'" label="审批意见">
<el-input v-model="form.message" type="textarea" resize="none" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button :disabled="buttonDisabled" type="primary" @click="handleCompleteTask"> </el-button>
<el-button v-if="task.flowStatus === 'waiting' && buttonObj.trust" :disabled="buttonDisabled" type="primary" @click="openDelegateTask">
委托
</el-button>
<el-button v-if="task.flowStatus === 'waiting' && buttonObj.transfer" :disabled="buttonDisabled" type="primary" @click="openTransferTask">
转办
</el-button>
<el-button
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0 && buttonObj.addSign"
:disabled="buttonDisabled"
type="primary"
@click="openMultiInstanceUser"
>
加签
</el-button>
<el-button
v-if="task.flowStatus === 'waiting' && Number(task.nodeRatio) > 0 && buttonObj.subSign"
:disabled="buttonDisabled"
type="primary"
@click="handleTaskUser"
>
减签
</el-button>
<el-button
v-if="task.flowStatus === 'waiting' && buttonObj.termination"
:disabled="buttonDisabled"
type="danger"
@click="handleTerminationTask"
>
终止
</el-button>
<el-button v-if="task.flowStatus === 'waiting' && buttonObj.back" :disabled="buttonDisabled" type="danger" @click="handleBackProcessOpen">
退回
</el-button>
<el-button :disabled="buttonDisabled" @click="cancel"></el-button>
</span>
</template>
<!-- 抄送 -->
<UserSelect ref="userSelectCopyRef" :multiple="true" :data="selectCopyUserIds" @confirm-call-back="userSelectCopyCallBack"></UserSelect>
<!-- 转办 -->
<UserSelect ref="transferTaskRef" :multiple="false" @confirm-call-back="handleTransferTask"></UserSelect>
<!-- 委托 -->
<UserSelect ref="delegateTaskRef" :multiple="false" @confirm-call-back="handleDelegateTask"></UserSelect>
<!-- 加签组件 -->
<UserSelect ref="multiInstanceUserRef" :multiple="true" @confirm-call-back="addMultiInstanceUser"></UserSelect>
<!-- 弹窗选人 -->
<UserSelect ref="porUserRef" :multiple="true" :userIds="popUserIds" @confirm-call-back="handlePopUser"></UserSelect>
<!-- 驳回开始 -->
<el-dialog v-model="backVisible" draggable title="驳回" width="40%" :close-on-click-modal="false">
<el-form v-if="task.flowStatus === 'waiting'" v-loading="backLoading" :model="backForm" label-width="120px">
<el-form-item label="驳回节点">
<el-select v-model="backForm.nodeCode" clearable placeholder="请选择" style="width: 300px">
<el-option v-for="item in taskNodeList" :key="item.nodeCode" :label="item.nodeName" :value="item.nodeCode" />
</el-select>
</el-form-item>
<el-form-item label="消息提醒">
<el-checkbox-group v-model="backForm.messageType">
<el-checkbox label="1" name="type" disabled>站内信</el-checkbox>
<el-checkbox label="2" name="type">邮件</el-checkbox>
<el-checkbox label="3" name="type">短信</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item v-if="task.flowStatus === 'waiting'" label="附件">
<fileUpload
v-model="backForm.fileId"
:file-type="['png', 'jpg', 'jpeg', 'doc', 'docx', 'xlsx', 'xls', 'ppt', 'txt', 'pdf']"
:file-size="20"
/>
</el-form-item>
<el-form-item label="审批意见">
<el-input v-model="backForm.message" type="textarea" resize="none" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer" style="float: right; padding-bottom: 20px">
<el-button :disabled="backButtonDisabled" type="primary" @click="handleBackProcess"></el-button>
<el-button :disabled="backButtonDisabled" @click="backVisible = false">取消</el-button>
</div>
</template>
</el-dialog>
<!-- 驳回结束 -->
<el-dialog v-model="deleteSignatureVisible" draggable title="减签人员" width="700px" height="400px" append-to-body :close-on-click-modal="false">
<div>
<el-table :data="deleteUserList" border>
<el-table-column prop="nodeName" label="任务名称" />
<el-table-column prop="nickName" label="办理人" />
<el-table-column label="操作" align="center" width="160">
<template #default="scope">
<el-button type="danger" size="small" icon="Delete" @click="deleteMultiInstanceUser(scope.row)"> </el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-dialog>
</el-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { ComponentInternalInstance } from 'vue';
import { ElForm } from 'element-plus';
import {
completeTask,
backProcess,
getTask,
taskOperation,
terminationTask,
getBackTaskNode,
currentTaskAllUser,
getNextNodeList
} from '@/api/workflow/task';
import UserSelect from '@/components/UserSelect/index.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
import { UserVO } from '@/api/system/user/types';
import { FlowTaskVO, TaskOperationBo } from '@/api/workflow/task/types';
const userSelectCopyRef = ref<InstanceType<typeof UserSelect>>();
const transferTaskRef = ref<InstanceType<typeof UserSelect>>();
const delegateTaskRef = ref<InstanceType<typeof UserSelect>>();
const multiInstanceUserRef = ref<InstanceType<typeof UserSelect>>();
const porUserRef = ref<InstanceType<typeof UserSelect>>();
const props = defineProps({
taskVariables: {
type: Object as () => Record<string, any>,
default: () => {}
}
});
//
const loading = ref(true);
//
const buttonDisabled = ref(true);
//id
const taskId = ref<string>('');
//
const selectCopyUserList = ref<UserVO[]>([]);
//id
const selectCopyUserIds = ref<string>(undefined);
//
const deleteUserList = ref<any>([]);
//id
const popUserIds = ref<any>([]);
//
const backVisible = ref(false);
const backLoading = ref(true);
const backButtonDisabled = ref(true);
//
const taskNodeList = ref([]);
const nickName = ref({});
//
const nodeCode = ref<string>('');
const buttonObj = ref<any>({
pop: false,
trust: false,
transfer: false,
addSign: false,
subSign: false,
termination: false,
back: false
});
//
const nestNodeList = ref([]);
//
const task = ref<FlowTaskVO>({
id: undefined,
createTime: undefined,
updateTime: undefined,
tenantId: undefined,
definitionId: undefined,
instanceId: undefined,
flowName: undefined,
businessId: undefined,
nodeCode: undefined,
nodeName: undefined,
flowCode: undefined,
flowStatus: undefined,
formCustom: undefined,
formPath: undefined,
nodeType: undefined,
nodeRatio: undefined,
applyNode: false,
buttonList: []
});
const dialog = reactive<DialogOption>({
visible: false,
title: '提示'
});
//
const deleteSignatureVisible = ref(false);
const form = ref<Record<string, any>>({
taskId: undefined,
message: undefined,
assigneeMap: {},
variables: {},
messageType: ['1'],
flowCopyList: []
});
const backForm = ref<Record<string, any>>({
taskId: undefined,
nodeCode: undefined,
message: undefined,
variables: {},
messageType: ['1']
});
//
const openDialog = async (id?: string) => {
selectCopyUserIds.value = undefined;
selectCopyUserList.value = [];
form.value.fileId = undefined;
taskId.value = id;
form.value.message = undefined;
dialog.visible = true;
loading.value = true;
buttonDisabled.value = true;
const response = await getTask(taskId.value);
task.value = response.data;
buttonObj.value = {};
task.value.buttonList.forEach((e) => {
buttonObj.value[e.code] = e.show;
});
buttonDisabled.value = false;
const data = {
taskId: taskId.value,
variables: props.taskVariables
};
const nextData = await getNextNodeList(data);
nestNodeList.value = nextData.data;
loading.value = false;
};
onMounted(() => {});
const emits = defineEmits(['submitCallback', 'cancelCallback']);
/** 办理流程 */
const handleCompleteTask = async () => {
form.value.taskId = taskId.value;
form.value.taskVariables = props.taskVariables;
let verify = false;
if (buttonObj.value.pop && nestNodeList.value && nestNodeList.value.length > 0) {
nestNodeList.value.forEach((e) => {
if (
Object.keys(form.value.assigneeMap).length === 0 ||
form.value.assigneeMap[e.nodeCode] === '' ||
form.value.assigneeMap[e.nodeCode] === null ||
form.value.assigneeMap[e.nodeCode] === undefined
) {
verify = true;
}
});
if (verify) {
proxy?.$modal.msgWarning('请选择审批人!');
return false;
}
} else {
form.value.assigneeMap = {};
}
if (selectCopyUserList.value && selectCopyUserList.value.length > 0) {
const flowCopyList = [];
selectCopyUserList.value.forEach((e) => {
const copyUser = {
userId: e.userId,
userName: e.nickName
};
flowCopyList.push(copyUser);
});
form.value.flowCopyList = flowCopyList;
}
//
if (props.taskVariables && typeof props.taskVariables === 'object') {
const taskVars = props.taskVariables as any;
// 1.
if (taskVars.entity) {
form.value.entity = taskVars.entity;
}
// 2. -
if (taskVars.variables) {
form.value.variables = taskVars.variables;
console.log('设置工作流变量:', form.value.variables);
}
// 3.
if (taskVars.approveStatus) {
form.value.approveStatus = taskVars.approveStatus;
}
// 4.
if (taskVars.repairConfirm !== undefined) {
form.value.repairConfirm = taskVars.repairConfirm;
}
}
await proxy?.$modal.confirm('是否确认提交?');
loading.value = true;
buttonDisabled.value = true;
try {
await completeTask(form.value);
dialog.visible = false;
emits('submitCallback');
proxy?.$modal.msgSuccess('操作成功');
} finally {
loading.value = false;
buttonDisabled.value = false;
}
};
/** 驳回弹窗打开 */
const handleBackProcessOpen = async () => {
backForm.value = {};
backForm.value.messageType = ['1'];
backVisible.value = true;
backLoading.value = true;
backButtonDisabled.value = true;
const data = await getBackTaskNode(task.value.definitionId, task.value.nodeCode);
taskNodeList.value = data.data;
backLoading.value = false;
backButtonDisabled.value = false;
backForm.value.nodeCode = taskNodeList.value[0].nodeCode;
};
/** 驳回流程 */
const handleBackProcess = async () => {
backForm.value.taskId = taskId.value;
await proxy?.$modal.confirm('是否确认驳回到申请人?');
loading.value = true;
backLoading.value = true;
backButtonDisabled.value = true;
await backProcess(backForm.value).finally(() => {
loading.value = false;
buttonDisabled.value = false;
});
dialog.visible = false;
backLoading.value = false;
backButtonDisabled.value = false;
emits('submitCallback');
proxy?.$modal.msgSuccess('操作成功');
};
//
const cancel = async () => {
dialog.visible = false;
buttonDisabled.value = false;
nickName.value = {};
form.value.assigneeMap = {};
emits('cancelCallback');
};
//
const openUserSelectCopy = () => {
userSelectCopyRef.value.open();
};
//
const userSelectCopyCallBack = (data: UserVO[]) => {
if (data && data.length > 0) {
selectCopyUserList.value = data;
selectCopyUserIds.value = selectCopyUserList.value.map((item) => item.userId).join(',');
}
};
//
const handleCopyCloseTag = (user: UserVO) => {
const userId = user.userId;
// 使split
const index = selectCopyUserList.value.findIndex((item) => item.userId === userId);
selectCopyUserList.value.splice(index, 1);
selectCopyUserIds.value = selectCopyUserList.value.map((item) => item.userId).join(',');
};
//
const openMultiInstanceUser = async () => {
multiInstanceUserRef.value.open();
};
//
const addMultiInstanceUser = async (data) => {
if (data && data.length > 0) {
const taskOperationBo = reactive<TaskOperationBo>({
userIds: data.map((e) => e.userId),
taskId: taskId.value,
message: form.value.message
});
await proxy?.$modal.confirm('是否确认提交?');
loading.value = true;
buttonDisabled.value = true;
await taskOperation(taskOperationBo, 'addSignature').finally(() => {
loading.value = false;
buttonDisabled.value = false;
});
dialog.visible = false;
emits('submitCallback');
proxy?.$modal.msgSuccess('操作成功');
} else {
proxy?.$modal.msgWarning('请选择用户!');
}
};
//
const deleteMultiInstanceUser = async (row) => {
await proxy?.$modal.confirm('是否确认提交?');
loading.value = true;
buttonDisabled.value = true;
const taskOperationBo = reactive<TaskOperationBo>({
userIds: [row.userId],
taskId: taskId.value,
message: form.value.message
});
await taskOperation(taskOperationBo, 'reductionSignature').finally(() => {
loading.value = false;
buttonDisabled.value = false;
});
dialog.visible = false;
emits('submitCallback');
proxy?.$modal.msgSuccess('操作成功');
};
//
const openTransferTask = () => {
transferTaskRef.value.open();
};
//
const handleTransferTask = async (data) => {
if (data && data.length > 0) {
const taskOperationBo = reactive<TaskOperationBo>({
userId: data[0].userId,
taskId: taskId.value,
message: form.value.message
});
await proxy?.$modal.confirm('是否确认提交?');
loading.value = true;
buttonDisabled.value = true;
await taskOperation(taskOperationBo, 'transferTask').finally(() => {
loading.value = false;
buttonDisabled.value = false;
});
dialog.visible = false;
emits('submitCallback');
proxy?.$modal.msgSuccess('操作成功');
} else {
proxy?.$modal.msgWarning('请选择用户!');
}
};
//
const openDelegateTask = () => {
delegateTaskRef.value.open();
};
//
const handleDelegateTask = async (data) => {
if (data && data.length > 0) {
const taskOperationBo = reactive<TaskOperationBo>({
userId: data[0].userId,
taskId: taskId.value,
message: form.value.message
});
await proxy?.$modal.confirm('是否确认提交?');
loading.value = true;
buttonDisabled.value = true;
await taskOperation(taskOperationBo, 'delegateTask').finally(() => {
loading.value = false;
buttonDisabled.value = false;
});
dialog.visible = false;
emits('submitCallback');
proxy?.$modal.msgSuccess('操作成功');
} else {
proxy?.$modal.msgWarning('请选择用户!');
}
};
//
const handleTerminationTask = async () => {
const params = {
taskId: taskId.value,
comment: form.value.message
};
await proxy?.$modal.confirm('是否确认终止?');
loading.value = true;
buttonDisabled.value = true;
await terminationTask(params).finally(() => {
loading.value = false;
buttonDisabled.value = false;
});
dialog.visible = false;
emits('submitCallback');
proxy?.$modal.msgSuccess('操作成功');
};
const handleTaskUser = async () => {
const data = await currentTaskAllUser(taskId.value);
deleteUserList.value = data.data;
if (deleteUserList.value && deleteUserList.value.length > 0) {
deleteUserList.value.forEach((e) => {
e.nodeName = task.value.nodeName;
});
}
deleteSignatureVisible.value = true;
};
//
const choosePeople = async (data) => {
if (!data.permissionFlag) {
proxy?.$modal.msgError('没有可选择的人员,请联系管理员!');
}
popUserIds.value = data.permissionFlag;
nodeCode.value = data.nodeCode;
porUserRef.value.open();
};
//
const handlePopUser = async (userList) => {
const userIds = userList.map((item) => {
return item.userId;
});
const nickNames = userList.map((item) => {
return item.nickName;
});
form.value.assigneeMap[nodeCode.value] = userIds.join(',');
nickName.value[nodeCode.value] = nickNames.join(',');
};
/**
* 对外暴露子组件方法
*/
defineExpose({
openDialog
});
</script>
Loading…
Cancel
Save