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

<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>