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.

549 lines
18 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>
<!-- 移除提交按钮Web端不再创建工单 -->
<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 :value="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 :value="workOrder?.applyUser || ''" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="设备编号">
<el-input :value="workOrder?.machineCode || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="设备名称">
<el-input :value="workOrder?.machineName || ''" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="申请时间">
<el-input :value="workOrder?.applyTime || ''" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- PDA端创建的工单详情只读显示 -->
<el-card shadow="never">
<h4 class="form-header">PDA端创建的工单详情只读</h4>
<el-form
ref="processFormRef"
v-loading="loading"
:model="form"
:rules="rules"
label-width="120px">
<el-row>
<!-- 故障报修信息(只读显示) -->
<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="外协单位">
<el-input v-model="outsourcingName" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="故障描述">
<el-input
v-model="form.faultDescription"
type="textarea"
:rows="3"
disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="涉及操作">
<el-input
v-model="form.designOperations"
type="textarea"
:rows="2"
disabled />
</el-form-item>
</el-col>
<!-- 维修处理信息(只读显示) -->
<template v-if="form.repairer">
<el-col :span="8">
<el-form-item label="维修人">
<el-input v-model="form.repairer" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="检查后的故障判断">
<el-input
v-model="form.checkedFault"
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>
<el-col :span="24">
<el-form-item label="维修内容">
<el-input
v-model="form.repairContent"
type="textarea"
:rows="4"
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 } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessageBox, type FormInstance } from 'element-plus';
import type { ComponentInternalInstance } from 'vue';
import { getDmsBillsFaultInstance, approveWorkOrder, confirmRepairResult } from '@/api/dms/dmsBillsFaultInstance';
import { getDmsBaseOutsourcingInfoList } from '@/api/dms/dmsBaseOutsourcingInfo';
import SubmitVerify from '@/views/dms/dmsFaultInstanceActivity/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 outsourcingName = ref('');
// 表单相关
const processFormRef = ref<FormInstance>();
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
// 任务变量
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,
approveStatus: undefined
};
const form = reactive({ ...initFormData });
// 表单验证规则
const rules = reactive({
approveStatus: [{ required: false, message: '审批状态不能为空', trigger: 'change' }],
processHandleResolution: [{ required: false, message: '处理意见不能为空', trigger: 'blur' }]
});
// 计算属性
const needProcessResolution = computed(() => {
return isApprovalStage.value || confirmButtonShow.value;
});
const currentStepName = computed(() => {
if (workOrder.value?.approveStatus === '1') {
return '审批工单';
}
return '处理工单';
});
const approvalButtonShow = computed(() => {
// 显示审批按钮的条件:工单审批状态为待审批(1)
return workOrder.value?.approveStatus === '1';
});
const confirmButtonShow = computed(() => {
// 【调试信息】输出实际的字段值,帮助排查问题
console.log('主管确认按钮显示条件检查:', {
billsStatus: workOrder.value?.billsStatus,
billsStatusType: typeof workOrder.value?.billsStatus,
approveStatus: workOrder.value?.approveStatus,
approveStatusType: typeof workOrder.value?.approveStatus,
repairConfirm: workOrder.value?.repairConfirm,
repairConfirmType: typeof workOrder.value?.repairConfirm
});
// 显示主管确认按钮的条件:
// 工单状态为维修完成(2) && 审批状态为审批成功(2) && 确认状态为待确认(0)
// 【修复】使用字符串比较,并处理可能的数据类型问题
const billsStatusMatches = String(workOrder.value?.billsStatus) === '2';
const approveStatusMatches = String(workOrder.value?.approveStatus) === '2';
const repairConfirmMatches = String(workOrder.value?.repairConfirm) === '0';
const shouldShow = billsStatusMatches && approveStatusMatches && repairConfirmMatches;
console.log('主管确认按钮显示结果:', {
billsStatusMatches,
approveStatusMatches,
repairConfirmMatches,
shouldShow
});
return shouldShow;
});
// 是否为审批阶段
const isApprovalStage = computed(() => {
return workOrder.value?.approveStatus === '1';
});
// 初始化
onMounted(async () => {
routeParams.value = route.query;
loading.value = true;
try {
// 获取工单信息
await loadWorkOrderInfo();
// 获取外协单位列表
await getOutsourceList();
// 初始化表单数据
initializeFormData();
// 动态设置表单验证规则
setDynamicValidationRules();
} catch (error) {
console.error('初始化失败:', error);
(proxy as any)?.$modal.msgError('加载数据失败');
} finally {
loading.value = false;
}
});
// 加载工单信息
const loadWorkOrderInfo = async () => {
// 从query参数获取businessId
const businessId = routeParams.value.id;
if (!businessId) {
(proxy as any)?.$modal.msgError('缺少工单ID参数');
return;
}
const res = await getDmsBillsFaultInstance(businessId);
workOrder.value = res.data || {}; // 确保不为null
// 设置状态显示文本 - 添加安全检查
workOrderStatusText.value = getStatusText(workOrder.value.billsStatus || '');
};
// 初始化表单数据
const initializeFormData = () => {
// 基础信息从工单获取
form.repairInstanceId = workOrder.value?.repairInstanceId;
// 处理所有字段确保没有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 (form.outsourcingId && outsourceList.value.length > 0) {
const outsourcing = outsourceList.value.find(item => item.outsourcingId === form.outsourcingId);
outsourcingName.value = outsourcing?.outsourcingName || '';
}
// 如果是审批阶段,设置默认审批状态
if (routeParams.value.type === 'approval' && !form.approveStatus) {
form.approveStatus = undefined; // 保持未选择状态,让用户必须选择
}
};
// 审批处理
const approvalVerifyOpen = async () => {
if (!processFormRef.value) return;
try {
const valid = await processFormRef.value.validate();
if (valid) {
await (proxy as any)?.$modal.confirm('是否确认提交审批?');
buttonLoading.value = true;
// 直接调用后端审批接口,后端会在同一事务中处理业务状态更新和工作流推进
const approveStatus = form.approveStatus;
const message = form.processHandleResolution || '';
await approveWorkOrder(form.repairInstanceId, approveStatus, message);
const statusText = approveStatus === '2' ? '通过' : '拒绝';
(proxy as any)?.$modal.msgSuccess(`审批${statusText}成功`);
// 关闭页面返回
goBack();
}
} catch (error: any) {
if (error !== 'cancel' && error !== 'close') {
console.error('审批失败:', error);
(proxy as any)?.$modal.msgError('审批失败:' + (error.message || '未知错误'));
}
} finally {
buttonLoading.value = false;
}
};
// 提交回调
const submitCallback = async (approvalResult?: any) => {
try {
if (routeParams.value.type === 'confirm') {
// 主管确认逻辑
const confirmResult = form.repairConfirm || '1'; // 默认确认通过
await confirmRepairResult(form.repairInstanceId, confirmResult);
(proxy as any)?.$modal.msgSuccess('确认完成');
}
// 关闭页面返回
goBack();
} catch (error: any) {
console.error('操作失败:', error);
(proxy as any)?.$modal.msgError('操作失败:' + (error.message || '未知错误'));
}
};
// 主管确认处理
const handleConfirm = async () => {
try {
// 使用自定义按钮的确认对话框
const result = await ElMessageBox.confirm(
'请选择维修结果确认方式:\n• 通过:维修通过,工单完成\n• 退回:维修不通过,返回维修环节重新维修',
'主管确认',
{
confirmButtonText: '通过',
cancelButtonText: '退回',
type: 'warning',
distinguishCancelAndClose: true
}
);
buttonLoading.value = true;
// 用户点击通过,设置为确认通过
form.repairConfirm = '1'; // 1表示确认通过
// 调用主管确认接口
await confirmRepairResult(form.repairInstanceId, form.repairConfirm);
(proxy as any)?.$modal.msgSuccess('确认通过完成');
goBack();
} catch (action: any) {
if (action === 'cancel') {
// 用户点击退回,设置为确认不通过
try {
buttonLoading.value = true;
form.repairConfirm = '2'; // 2表示确认不通过
await confirmRepairResult(form.repairInstanceId, form.repairConfirm);
(proxy as any)?.$modal.msgSuccess('退回维修环节完成');
goBack();
} catch (confirmError: any) {
console.error('退回操作失败:', confirmError);
(proxy as any)?.$modal.msgError('退回操作失败:' + (confirmError.message || '未知错误'));
} finally {
buttonLoading.value = false;
}
} else if (action === 'close') {
// 用户点击关闭按钮或按ESC键不执行任何操作
console.log('用户取消了确认操作');
} else {
console.error('确认失败:', action);
(proxy as any)?.$modal.msgError('确认失败:' + (action.message || '未知错误'));
}
} finally {
if (form.repairConfirm === '1') {
buttonLoading.value = false;
}
}
};
// 审批记录
const handleApprovalRecord = () => {
approvalRecordRef.value?.init(routeParams.value.id);
};
// 返回
const goBack = () => {
(proxy as any)?.$tab.closePage((proxy as any)?.$route);
router.go(-1);
};
// 获取外协单位列表
const getOutsourceList = async () => {
try {
const res = await getDmsBaseOutsourcingInfoList(null);
outsourceList.value = res.data;
} catch (error) {
console.error('获取外协单位列表失败:', error);
}
};
// 动态设置表单验证规则
const setDynamicValidationRules = () => {
// 重置所有规则为非必填
Object.keys(rules).forEach(key => {
rules[key] = [{ required: false, message: rules[key][0].message, trigger: rules[key][0].trigger }];
});
// 根据工单状态设置验证规则
if (workOrder.value?.approveStatus === '1') {
// 审批阶段:需要审批状态和处理意见
rules.approveStatus = [{ required: true, message: '审批状态不能为空', trigger: 'change' }];
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
} else if (workOrder.value?.billsStatus === '2' &&
workOrder.value?.approveStatus === '2' &&
workOrder.value?.repairConfirm === '0') {
// 主管确认阶段:需要处理意见
rules.processHandleResolution = [{ required: true, message: '处理意见不能为空', trigger: 'blur' }];
}
};
// 工具函数
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>