You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

775 lines
27 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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 () => {
// 从query参数获取businessId
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 () => {
// 从query参数获取businessId和taskId
const businessId = routeParams.value.id;
const taskId = routeParams.value.taskId;
// 通过taskId或businessId获取当前任务
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;
}
// 准备工作流变量 - 确保变量结构符合SubmitVerify和Warm-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) {
// 直接在taskVariables根级别设置approveStatus - 这是SubmitVerify期望的格式
taskVariables.value.approveStatus = form.approveStatus;
console.log('设置审批状态变量:', form.approveStatus);
}
// 如果是确认阶段,设置确认结果变量
if (routeParams.value.type === 'confirm' && form.repairConfirm) {
// 确认通过传0确认不通过传1
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>