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.

797 lines
35 KiB
Vue

<template>
<div class="p-2">
<!-- 工单信息区域 -->
<h4 class="form-header h4">工单信息</h4>
<el-card shadow="never" class="mb-[10px]">
<el-form label-width="120px">
<el-row>
<el-col :span="8" :offset="2">
<el-form-item label="工单编号">
<el-input v-model="billsInfo.billsLubeCode" disabled />
</el-form-item>
</el-col>
<el-col :span="8" :offset="2">
<el-form-item label="工单状态">
<el-input v-model="billsStatusCheck" disabled />
</el-form-item>
</el-col>
<el-col :span="8" :offset="2">
<el-form-item label="申请人">
<el-input v-model="billsInfo.createBy" disabled />
</el-form-item>
</el-col>
<el-col :span="8" :offset="2">
<el-form-item label="申请时间">
<el-input v-model="billsInfo.createTime" disabled />
</el-form-item>
</el-col>
<el-col :span="16" :offset="2">
<el-form-item label="备注">
<el-input v-model="billsInfo.remark" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 流程步骤展示区域 -->
<el-card shadow="never" class="mb-[10px]">
<el-form ref="stepFormRef" :model="form" label-width="100px">
<!-- 第一步 -->
<h4 class="form-header h4" v-if="dmsBillsLubeInstanceActivityList.length > 0">1</h4>
<el-row v-if="dmsBillsLubeInstanceActivityList.length > 0">
<el-col :span="8">
<el-form-item label="润滑级别" prop="lubeLevel">
<el-select v-model="form.lubeLevel" placeholder="润滑级别" disabled>
<el-option v-for="dict in lube_level" :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="lubeGroup">
<el-input v-model="form.lubeGroup" placeholder="请输入润滑组别" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="润滑负责人" prop="lubeSupervisor">
<el-input v-model="form.lubeSupervisor" placeholder="请输入润滑负责人" disabled />
</el-form-item>
</el-col>
</el-row>
<!-- 中间步骤 (已处理的后续节点) -->
<template v-for="activity in dmsBillsLubeInstanceActivityList" :key="activity.instanceActivityId">
<div v-if="activity.processStepOrder && activity.processStepOrder > 1">
<h4 class="form-header h4">{{ `已处理节点:步骤${activity.processStepOrder}${activity.processStepOrder === 2 ? '实际参数' : '工单完成'}` }}</h4>
<el-row>
<el-col :span="8">
<el-form-item label="润滑级别">
<el-select v-model="activity.lubeLevel" placeholder="润滑级别" disabled>
<el-option v-for="dict in lube_level" :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="润滑组别">
<el-input v-model="activity.lubeGroup" disabled placeholder="润滑组别"> </el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="润滑负责人">
<el-input v-model="activity.lubeSupervisor" disabled placeholder="润滑负责人"> </el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="处理意见">
<el-input v-model="activity.processHandleResolution" disabled placeholder="处理意见"> </el-input>
</el-form-item>
</el-col>
</el-row>
</div>
</template>
<!-- 当前步骤表单 (用于提交新节点) -->
<div v-if="isUpdate">
<h4 class="form-header h4">
{{
isCreatingWorkflow && dmsBillsLubeInstanceActivityList.length === 0
? `创建工单步骤1要求参数`
: `当前处理节点:步骤${nextStepOrder}${nextStepOrder === 2 ? '(实际参数)' : nextStepOrder === 3 ? '(工单完成)' : ''}`
}}
</h4>
<el-form ref="nextStepFormRef" :model="nextStepForm" :rules="nextStepFormRules" label-width="100px">
<el-row>
<el-col :span="8">
<el-form-item label="润滑级别" prop="lubeLevel">
<el-select v-model="nextStepForm.lubeLevel" placeholder="润滑级别" :disabled="nextStepOrder === 3">
<el-option v-for="dict in lube_level" :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="lubeGroup">
<el-input v-model="nextStepForm.lubeGroup" placeholder="润滑组别" :disabled="nextStepOrder === 3"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="润滑负责人" prop="lubeSupervisor">
<el-input v-model="nextStepForm.lubeSupervisor" placeholder="润滑负责人" :disabled="nextStepOrder === 3"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" v-if="!(isCreatingWorkflow && dmsBillsLubeInstanceActivityList.length === 0)">
<el-form-item label="处理意见" prop="processHandleResolution">
<el-input v-model="nextStepForm.processHandleResolution" placeholder="处理意见"></el-input>
</el-form-item>
</el-col>
<el-col :span="24" class="text-center mt-4">
<el-button
type="primary"
@click="submitForm"
:loading="buttonLoading"
:disabled="buttonLoading || (!currentTaskId && !isCreatingWorkflow)"
>
{{ buttonText }}
</el-button>
<el-button
v-if="billsInfo && billsInfo.lubeInstanceId !== null && billsInfo.status !== 'draft'"
type="primary"
@click="handleApprovalRecord"
>
流程进度
</el-button>
</el-col>
</el-row>
</el-form>
</div>
</el-form>
</el-card>
<!-- 润滑计划详情区域 -->
<el-card shadow="never">
<h4 class="form-header h4 text-center">润滑计划详细信息</h4>
<el-table v-loading="loading" :data="planLubeDetail">
<el-table-column label="设备名称" align="center" prop="machineName" />
<el-table-column label="润滑部位" align="center" prop="lubeStationName" />
<el-table-column label="润滑标准" align="center" prop="lubeStandardCode" />
<el-table-column label="操作描述" align="center" prop="operationDescription" />
</el-table>
</el-card>
<!-- 提交组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables as any" @submit-callback="submitCallback" @cancel-callback="cancelCallback" />
<!-- 审批记录 -->
<approvalRecord ref="approvalRecordRef" />
</div>
</template>
<script setup name="DmsBillsLubeInstanceActivity" lang="ts">
import { ref, reactive, toRefs, getCurrentInstance, onMounted, computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import type { FormInstance, FormRules } from 'element-plus'; // 引入 FormInstance 和 FormRules 类型
import {
listDmsBillsLubeInstanceActivity,
addDmsBillsLubeInstanceActivity,
updateDmsBillsLubeInstanceActivity
} from '@/api/dms/dmsBillsLubeInstanceActivity';
import {
DmsBillsLubeInstanceActivityVO,
DmsBillsLubeInstanceActivityForm
} from '@/api/dms/dmsBillsLubeInstanceActivity/types';
import { getDmsBillsLubeInstance } from '@/api/dms/dmsBillsLubeInstance';
import { getDmsPlanLubeDetailList} from '@/api/dms/dmsPlanLubeDetail';
import {DmsPlanLubeDetailVO} from "@/api/dms/dmsPlanLubeDetail/types";
// 引入工作流相关组件和API
import { startWorkFlow, pageByTaskWait } from '@/api/workflow/task';
import { pageByCurrent } from '@/api/workflow/instance';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
import { FlowInstanceQuery, FlowInstanceVO } from '@/api/workflow/instance/types';
import { TaskQuery, FlowTaskVO } from '@/api/workflow/task/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { lube_level, process_handle_status } = toRefs<any>(proxy?.useDict('lube_level', 'process_handle_status'));
const route = useRoute();
// 表单实例
const stepFormRef = ref<FormInstance>(); // 主表单 ref
const nextStepFormRef = ref<FormInstance>(); // 下一步表单 ref
// 工作流相关
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
const taskVariables = ref<any>({});
const submitFormData = ref<StartProcessBo>({
businessId: '',
flowCode: 'Lube01',
variables: {}
});
// 基础数据定义
const loading = ref(true);
const dmsBillsLubeInstanceActivityList = ref<DmsBillsLubeInstanceActivityVO[]>([]);
const billsInfo = ref<any>({}); // 工单主体信息
const planLubeDetail = ref<DmsPlanLubeDetailVO[]>([]);
const billsStatusCheck = ref(''); // 工单状态显示文本
const isUpdate = ref(true); // 控制是否显示提交表单区域
const planLubeId = ref(''); // 润滑计划ID从工单信息中获取
const lubeInstanceId = route.params.lubeInstanceId as string; // 类型断言
const buttonLoading = ref(false);
// 新增状态
const currentTaskId = ref<string | number | null>(null);
const isCreatingWorkflow = ref(false); // true 表示在走创建流程的第一步startWorkFlow
const buttonText = ref('创建工单并提交');
// 暂存业务数据,等待工作流提交成功后再保存
const pendingActivityData = ref<DmsBillsLubeInstanceActivityForm | null>(null);
// 计算下一步序号
const nextStepOrder = computed(() => {
return dmsBillsLubeInstanceActivityList.value.length + 1;
});
// 表单数据 (用于展示第一个已处理节点的信息)
const form = reactive<Partial<DmsBillsLubeInstanceActivityForm>>({
lubeGroup: undefined,
lubeSupervisor: undefined,
lubeLevel: undefined,
remark: undefined,
});
// 下一步表单 (用于提交新的节点)
const nextStepForm = reactive<DmsBillsLubeInstanceActivityForm>({
instanceActivityId: undefined,
lubeInstanceId: lubeInstanceId,
lubeGroup: undefined,
lubeSupervisor: undefined,
lubeLevel: undefined,
processHandleResolution: undefined,
processHandleStatus: undefined,
processStepOrder: undefined,
startTime: undefined,
endTime: undefined,
handleUserId: undefined,
handleBy: undefined,
handleTime: undefined,
transferUserId: undefined,
attr1: undefined,
remark: undefined,
});
// 下一步表单校验规则
const nextStepFormRules = reactive<FormRules>({
lubeLevel: [{ required: true, message: "润滑级别不能为空", trigger: "change" }],
lubeGroup: [{ required: true, message: "润滑组别不能为空", trigger: "blur" }],
lubeSupervisor: [{ required: true, message: "润滑负责人不能为空", trigger: "blur" }],
// 处理意见的校验会由 updateButtonAndFormState 动态设置
processHandleResolution: [{ required: false, message: "处理意见不能为空", trigger: "blur" }],
});
// 查询参数
const queryParams = reactive({
pageNum: 1,
pageSize: 150,
lubeInstanceId: lubeInstanceId,
});
// 初始化数据
onMounted(async () => {
// 判断当前页面是查看还是编辑
if(route.name === 'childDmsBillsLubeInstanceActivity') {
isUpdate.value = true;
} else if(route.name === 'selectChildDmsBillsLubeInstanceActivity') {
isUpdate.value = false;
}
if (isUpdate.value) { // 仅在编辑模式下加载数据和设置状态
await loadData();
} else {
// 查看模式也需要加载工单信息和已处理节点
await dmsBillsLubeInstance();
await getList();
loading.value = false;
}
});
async function loadData() {
loading.value = true;
try {
// 先清除表单验证状态,避免在数据加载过程中触发不必要的表单验证错误
if (nextStepFormRef.value) {
nextStepFormRef.value.clearValidate();
}
await dmsBillsLubeInstance();
await getList(); // 获取已处理节点会影响 nextStepOrder 和 nextStepForm 的初始化
if (dmsBillsLubeInstanceActivityList.value.length === 0) {
currentTaskId.value = null;
isCreatingWorkflow.value = true;
} else {
isCreatingWorkflow.value = false;
currentTaskId.value = null; // 重置当前任务ID准备从流程引擎获取
const completedSteps = dmsBillsLubeInstanceActivityList.value.length;
// 如果流程业务步骤少于3步工单创建、工单处理、工单完成则尝试获取当前活动任务
if (completedSteps < 3) {
proxy?.$modal.loading("正在获取最新流程任务...");
let expectedNodeName = '';
if (completedSteps === 1) expectedNodeName = '工单处理';
else if (completedSteps === 2) expectedNodeName = '工单完成';
console.log(`[loadData] Attempting to find current task. Completed steps: ${completedSteps}, Expected next node: '${expectedNodeName}' for businessId: ${lubeInstanceId}`);
try {
let tasks: FlowTaskVO[] = [];
// 尝试使用期望的节点名称进行精确查找
if (expectedNodeName) {
const taskRes = await pageByTaskWait({
pageNum: 1,
pageSize: 10, // 通常特定业务ID和节点名称的任务不会很多
flowCode: 'Lube01', // 从 submitFormData 获取或确认此编码正确
nodeName: expectedNodeName
});
if (taskRes.rows) {
tasks = taskRes.rows.filter(task => task.businessId === lubeInstanceId);
if (tasks.length > 0) {
console.log(`[loadData] Found ${tasks.length} task(s) using specific nodeName '${expectedNodeName}' and businessId '${lubeInstanceId}'.`);
} else {
console.log(`[loadData] No tasks found using specific nodeName '${expectedNodeName}' for businessId '${lubeInstanceId}'. Will try broader search.`);
}
}
}
let foundTask: FlowTaskVO | undefined = tasks.length > 0 ? tasks[0] : undefined; // 如果有多个,暂时取第一个
if (tasks.length > 1) {
console.warn(`[loadData] Multiple tasks (${tasks.length}) found with specific nodeName '${expectedNodeName}' and businessId '${lubeInstanceId}'. Using the first one found: ${foundTask?.id}.`);
}
// 如果未通过特定节点名称找到则尝试仅通过flowCode查找然后匹配businessId
if (!foundTask) {
console.log(`[loadData] Task not found with specific nodeName. Fetching all waiting tasks for flowCode 'Lube01' to filter by businessId '${lubeInstanceId}'.`);
const taskResAll = await pageByTaskWait({
pageNum: 1,
pageSize: 50, // 获取更多任务以便筛选
flowCode: 'Lube01'
});
if (taskResAll.rows && taskResAll.rows.length > 0) {
const businessTasks = taskResAll.rows.filter(task => task.businessId === lubeInstanceId);
if (businessTasks.length === 1) {
foundTask = businessTasks[0];
console.log(`[loadData] Found single task by businessId from all waiting tasks: ${foundTask.id}, Node: ${foundTask.nodeName}`);
} else if (businessTasks.length > 1) {
console.warn(`[loadData] Multiple tasks (${businessTasks.length}) found for businessId '${lubeInstanceId}' from all waiting tasks. Attempting to match with expectedNodeName '${expectedNodeName}'.`);
if (expectedNodeName) {
foundTask = businessTasks.find(task => task.nodeName === expectedNodeName);
}
if (foundTask) {
console.log(`[loadData] Matched task by expectedNodeName from multiple: ${foundTask.id}`);
} else {
// Fallback: 如果仍有多个或无法通过expectedNodeName匹配则取第一个或记录更严重的警告
foundTask = businessTasks[0];
console.warn(`[loadData] Could not specifically match by nodeName among multiple tasks for businessId '${lubeInstanceId}'. Using the first one found: ${foundTask?.id}, Node: ${foundTask?.nodeName}. Review workflow design if this is not correct.`);
}
} else {
console.log(`[loadData] No tasks found for businessId '${lubeInstanceId}' even after broader search by flowCode 'Lube01'.`);
}
}
}
if (foundTask) {
currentTaskId.value = foundTask.id;
console.log(`[loadData] Successfully set currentTaskId via pageByTaskWait to: ${currentTaskId.value} (Node: ${foundTask.nodeName}, BusinessID: ${foundTask.businessId})`);
} else {
console.warn(`[loadData] No suitable waiting task found for businessId ${lubeInstanceId} with flowCode Lube01. Button may show '暂无操作'.`);
}
} catch (error) {
console.error("[loadData] Error fetching current task via pageByTaskWait:", error);
proxy?.$modal.msgError("获取最新流程任务失败");
} finally {
proxy?.$modal.closeLoading();
}
} else {
console.log("[loadData] All expected business steps completed (>=3) or initial creation. No active task to fetch from workflow via pageByTaskWait for middle steps.");
}
}
updateButtonAndFormState();
// 数据加载后再次清除表单验证状态确保UI渲染正确
setTimeout(() => {
if (nextStepFormRef.value) {
nextStepFormRef.value.clearValidate();
}
}, 100);
} catch (error) {
console.error("Failed to load initial data", error);
proxy?.$modal.msgError("加载数据失败");
// 出错时,尝试恢复到一个相对安全的状态
currentTaskId.value = null;
isCreatingWorkflow.value = dmsBillsLubeInstanceActivityList.value.length === 0;
updateButtonAndFormState();
} finally {
loading.value = false;
}
}
function updateButtonAndFormState() {
const activitiesCount = dmsBillsLubeInstanceActivityList.value.length;
// 第一步:创建工单(工单创建)
if (activitiesCount === 0 && isCreatingWorkflow.value) {
buttonText.value = '创建工单并提交';
nextStepFormRules.processHandleResolution = [{ required: false, message: "处理意见不能为空", trigger: "blur" }];
// 清理 nextStepForm
Object.assign(nextStepForm, {
instanceActivityId: undefined, // 重置ID
lubeInstanceId: lubeInstanceId, // 确保lubeInstanceId正确
lubeGroup: undefined,
lubeSupervisor: undefined,
lubeLevel: undefined,
processHandleResolution: undefined,
processHandleStatus: undefined,
processStepOrder: undefined,
startTime: undefined,
endTime: undefined,
handleUserId: undefined,
handleBy: undefined,
handleTime: undefined,
transferUserId: undefined,
attr1: undefined,
remark: undefined,
});
}
// 有待办任务ID且非创建模式
else if (currentTaskId.value && !isCreatingWorkflow.value) {
const currentStepBasedOnActivities = activitiesCount + 1; // 下一步是第几步
if (currentStepBasedOnActivities === 2) {
// 第二步:工单处理
buttonText.value = '工单处理';
nextStepFormRules.processHandleResolution = [{ required: true, message: "处理意见不能为空", trigger: "blur" }];
} else if (currentStepBasedOnActivities === 3) {
// 第三步:工单完成
buttonText.value = '工单完成';
nextStepFormRules.processHandleResolution = [{ required: true, message: "处理意见不能为空", trigger: "blur" }];
} else {
buttonText.value = '提交处理';
nextStepFormRules.processHandleResolution = [{ required: true, message: "处理意见不能为空", trigger: "blur" }];
}
if (activitiesCount > 0) {
if (currentStepBasedOnActivities === 3) {
// 第三步应复制第一步的数据
const firstActivity = dmsBillsLubeInstanceActivityList.value[0];
Object.assign(nextStepForm, {
instanceActivityId: undefined, // 新节点ID为空
lubeInstanceId: lubeInstanceId,
lubeGroup: firstActivity.lubeGroup, // 复制第一步的数据
lubeSupervisor: firstActivity.lubeSupervisor, // 复制第一步的数据
lubeLevel: firstActivity.lubeLevel, // 复制第一步的数据
processHandleResolution: '', // 清空处理意见
remark: '', // 清空备注
processHandleStatus: undefined,
processStepOrder: undefined,
});
} else {
// 其他步骤使用最后一个节点的数据
const lastActivity = dmsBillsLubeInstanceActivityList.value[activitiesCount - 1];
Object.assign(nextStepForm, {
instanceActivityId: undefined, // 新节点ID为空
lubeInstanceId: lubeInstanceId,
lubeGroup: lastActivity.lubeGroup,
lubeSupervisor: lastActivity.lubeSupervisor,
lubeLevel: lastActivity.lubeLevel,
processHandleResolution: '', // 清空处理意见
remark: '', // 清空备注
processHandleStatus: undefined,
processStepOrder: undefined,
});
}
} else { // 有 currentTaskId 但没有历史活动,这通常不应该发生,但为了健壮性处理
Object.assign(nextStepForm, {
instanceActivityId: undefined,
lubeInstanceId: lubeInstanceId,
processHandleResolution: '',
remark: '',
});
}
} else { // 没有待办任务(可能已结束、非处理人打开、或查看模式)或状态不明确
buttonText.value = '暂无操作';
if (isUpdate.value) { // 如果是编辑模式但无操作,则禁用提交相关的校验
nextStepFormRules.processHandleResolution = [{ required: false }];
}
}
}
// 获取工单实例数据
const dmsBillsLubeInstance = async () => {
const _lubeInstanceId = lubeInstanceId;
const res = await getDmsBillsLubeInstance(_lubeInstanceId);
billsInfo.value = res.data;
// 确保 planLubeId 是字符串类型
const lubeIdFromServer = res.data.planLubeId;
planLubeId.value = typeof lubeIdFromServer === 'number' ? String(lubeIdFromServer) : lubeIdFromServer;
// 设置工单状态显示文本
if (lube_level.value && billsInfo.value.lubeStatus !== undefined) {
const statusItem = lube_level.value.find((item: any) => String(item.value) === String(billsInfo.value.lubeStatus));
billsStatusCheck.value = statusItem ? statusItem.label : '未知状态';
} else {
billsStatusCheck.value = '未知状态';
}
// 获取润滑计划详情
if (planLubeId.value) {
getPlanLubeDetailData();
}
};
// 获取润滑计划详情
const getPlanLubeDetailData = async () => {
if (!planLubeId.value) return;
loading.value = true;
const res = await getDmsPlanLubeDetailList({planLubeId: planLubeId.value});
planLubeDetail.value = res.data;
};
// 获取工单实例节点数据
const getList = async () => {
loading.value = true;
try {
const res = await listDmsBillsLubeInstanceActivity(queryParams);
dmsBillsLubeInstanceActivityList.value = res.rows;
// 填充第一步数据 (用于表单展示)
if (res.rows && res.rows.length > 0) {
Object.assign(form, {
lubeGroup: res.rows[0].lubeGroup,
lubeSupervisor: res.rows[0].lubeSupervisor,
lubeLevel: res.rows[0].lubeLevel,
remark: res.rows[0].remark
});
// 根据步骤数初始化下一步表单数据
if (nextStepOrder.value === 2) {
// 第二步,复制第一步的润滑组别和润滑负责人
Object.assign(nextStepForm, {
lubeGroup: res.rows[0].lubeGroup,
lubeSupervisor: res.rows[0].lubeSupervisor,
lubeLevel: res.rows[0].lubeLevel,
processHandleResolution: null, // 第二步需要填写处理意见
remark: ''
});
} else if (nextStepOrder.value === 3) {
// 第三步,复制第一步的润滑组别和润滑负责人
const firstActivity = res.rows[0];
Object.assign(nextStepForm, {
lubeGroup: firstActivity.lubeGroup, // 复制第一步数据
lubeSupervisor: firstActivity.lubeSupervisor, // 复制第一步数据
lubeLevel: firstActivity.lubeLevel, // 复制第一步数据
processHandleResolution: null, // 清空处理意见
remark: ''
});
} else if (nextStepOrder.value > 3) {
// 第四步及以后,使用最后一个节点的数据(正常不会有这种情况)
const lastActivity = res.rows[res.rows.length - 1];
Object.assign(nextStepForm, {
lubeGroup: lastActivity.lubeGroup,
lubeSupervisor: lastActivity.lubeSupervisor,
lubeLevel: lastActivity.lubeLevel,
processHandleResolution: null, // 清空处理意见
remark: ''
});
}
} else {
// 如果没有已处理节点,则 nextStepForm 全新初始化
Object.assign(nextStepForm, {
lubeGroup: undefined,
lubeSupervisor: undefined,
lubeLevel: undefined,
processHandleResolution: null,
remark: ''
});
}
// 更新表单校验规则
nextStepFormRules.processHandleResolution = [{
required: nextStepOrder.value > 1,
message: "处理意见不能为空",
trigger: "blur"
}];
} catch (error) {
console.error('获取工单实例节点数据失败', error);
proxy?.$modal.msgError("获取工单实例节点数据失败");
} finally {
loading.value = false;
}
};
// 提交表单
const submitForm = async () => {
if (!nextStepFormRef.value) return;
try {
// 清空之前的错误状态
buttonLoading.value = false;
pendingActivityData.value = null;
// 触发一次校验更新确保最新的rules生效
nextStepFormRef.value.clearValidate();
const valid = await nextStepFormRef.value.validate().catch(errors => {
console.error("表单验证错误:", errors);
return false;
});
if (valid) {
buttonLoading.value = true;
try {
nextStepForm.processStepOrder = dmsBillsLubeInstanceActivityList.value.length + 1;
nextStepForm.lubeInstanceId = lubeInstanceId;
// 确保处理意见有值避免数据库NOT NULL约束异常
if (nextStepForm.processHandleResolution === undefined || nextStepForm.processHandleResolution === null) {
nextStepForm.processHandleResolution = '';
}
// 复制一份表单数据用于后续保存
pendingActivityData.value = JSON.parse(JSON.stringify(nextStepForm));
// 将当前表单的数据放入流程变量 - 仅传递简单必要字段而不是整个对象
taskVariables.value = {
entity: {
lubeInstanceId: pendingActivityData.value.lubeInstanceId,
lubeGroup: pendingActivityData.value.lubeGroup,
lubeSupervisor: pendingActivityData.value.lubeSupervisor,
lubeLevel: pendingActivityData.value.lubeLevel,
processHandleResolution: pendingActivityData.value.processHandleResolution,
processStepOrder: pendingActivityData.value.processStepOrder
}
};
if (isCreatingWorkflow.value && dmsBillsLubeInstanceActivityList.value.length === 0) {
// 步骤一: 创建工单,启动工作流
submitFormData.value.businessId = lubeInstanceId;
submitFormData.value.variables = taskVariables.value;
console.log("[submitForm] 开始启动工作流, businessId:", lubeInstanceId);
const workflowRes = await startWorkFlow(submitFormData.value);
if (!workflowRes || !workflowRes.data || !workflowRes.data.taskId) {
buttonLoading.value = false;
throw new Error("工作流启动失败未能获取有效的任务ID");
}
console.log("[submitForm] 工作流启动成功, taskId:", workflowRes.data.taskId);
if (submitVerifyRef.value) {
buttonLoading.value = false; // openDialog 前重置loading
submitVerifyRef.value.openDialog(String(workflowRes.data.taskId));
} else {
buttonLoading.value = false;
throw new Error("提交流程组件不可用");
}
} else if (currentTaskId.value && !isCreatingWorkflow.value) {
// 第二步或第三步:处理工作流节点
console.log("[submitForm] 处理工作流节点, taskId:", currentTaskId.value);
if (submitVerifyRef.value) {
buttonLoading.value = false;
submitVerifyRef.value.openDialog(String(currentTaskId.value));
} else {
buttonLoading.value = false;
throw new Error("提交流程组件不可用");
}
} else {
buttonLoading.value = false;
throw new Error("未知的提交流程状态或没有待办任务ID");
}
} catch (error: any) {
buttonLoading.value = false;
pendingActivityData.value = null; // 出错时清空待处理数据
console.error('[submitForm] 提交失败:', error);
proxy?.$modal.msgError(error.message || "提交失败,请检查数据或联系管理员");
}
} else {
buttonLoading.value = false;
proxy?.$modal.msgError("表单校验失败,请检查输入项");
}
} catch (error) {
buttonLoading.value = false;
console.error('[submitForm] 意外错误:', error);
proxy?.$modal.msgError("表单提交过程中发生错误");
}
};
// 审批记录
const handleApprovalRecord = () => {
approvalRecordRef.value.init(lubeInstanceId);
};
// 提交回调
const submitCallback = async (/* success?: boolean, nextTaskId?: string | number | null */) => {
// success 和 nextTaskId 参数在此被注释掉或忽略,
// 因为 submitVerify.vue 组件的 submitCallback 事件没有传递这些参数,
// 导致它们在父组件中始终是 undefined。
console.log('[submitCallback] Invoked.');
try {
if (pendingActivityData.value) {
// 当 submitCallback 被调用,我们假定 submitVerify.vue 中的工作流步骤已被尝试。
// 现在,我们尝试保存业务数据。
const activityRes = await addDmsBillsLubeInstanceActivity(pendingActivityData.value);
console.log("[submitCallback] Business data saved successfully:", activityRes.data);
// 根据已暂存的待处理活动数据的步骤顺序来判断当前完成的是哪个步骤
const stepOrderOfSavedData = pendingActivityData.value.processStepOrder;
if (stepOrderOfSavedData === 1) {
proxy?.$modal.msgSuccess("工单创建数据已保存,流程已流转。");
} else if (stepOrderOfSavedData === 2) {
proxy?.$modal.msgSuccess("工单处理数据已保存,流程已流转。");
} else if (stepOrderOfSavedData === 3) {
proxy?.$modal.msgSuccess("工单完成数据已保存,工作流已结束。");
// 流程结束后currentTaskId 应该在 loadData 后变为 null
} else {
// 这是一个通用回退理论上不应发生因为步骤是明确的1, 2, 或 3
proxy?.$modal.msgSuccess("业务数据已保存,操作已继续。");
}
// 注意实际的下一个任务ID (currentTaskId) 将由后续的 loadData() 调用来确定和更新。
} else {
// 如果 pendingActivityData.value 为 null
// 这可能意味着 submitForm 未能正确设置它,或者是一个取消操作。
// submitVerify.vue 的内部 "操作成功" 消息可能已经显示。
// 此处我们不应再显示一个全局的错误,除非我们能确定这是一个未预期的状态。
console.warn("[submitCallback] pendingActivityData was null upon callback. This might be normal if a cancel operation occurred or submitForm failed before calling workflow.");
}
} catch (error) {
console.error('[submitCallback] Error saving business data:', error);
// 这是一个严重问题:工作流可能已推进,但业务数据未能保存。
proxy?.$modal.msgError("关键错误:业务数据保存失败!工作流可能已推进,请紧急核查数据一致性。");
} finally {
// 重置加载和工作流创建状态
buttonLoading.value = false;
// 一旦提交尝试发生(无论成功与否),就不再是"正在创建工作流"的初始状态了。
// isCreatingWorkflow 的状态将在 loadData 完成后,根据实际的活动列表长度被重新评估。
// isCreatingWorkflow.value = false; // 暂时注释掉让loadData来决定
pendingActivityData.value = null; // 清空暂存的业务数据
// 重新加载数据以反映工作流的最新状态和更新UI
if (isUpdate.value) {
try {
console.log("[submitCallback] Reloading data to reflect current workflow state...");
await loadData(); // loadData 会更新 currentTaskId, dmsBillsLubeInstanceActivityList, 和按钮状态等。
console.log("[submitCallback] Data reloaded. Current Task ID is now:", currentTaskId.value);
} catch (loadError) {
console.error('[submitCallback] Failed to reload data post-submission attempt:', loadError);
proxy?.$modal.msgError("数据刷新失败,请手动刷新页面以查看最新状态。");
}
}
}
};
// 取消回调
const cancelCallback = () => {
console.log('[cancelCallback] 用户取消了操作');
pendingActivityData.value = null; // 清空待保存数据
buttonLoading.value = false;
};
</script>
<style scoped>
.form-header {
font-size: 15px;
color: #409eff;
border-bottom: 1px solid #ddd;
margin: 8px 0 15px;
padding-bottom: 10px;
}
</style>