From 51456dba5c5a01571d4edb4bc2c39640c25085f2 Mon Sep 17 00:00:00 2001 From: zch Date: Wed, 24 Jun 2026 17:38:06 +0800 Subject: [PATCH] =?UTF-8?q?refactor(oa/erp/tempTask):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E6=B5=81=E7=A8=8B=E9=80=BB=E8=BE=91=E5=B9=B6?= =?UTF-8?q?=E8=A1=A5=E5=85=85=E8=A1=A8=E5=8D=95=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 移除页面上冗余的提交完成和评分关闭按钮,统一由审批按钮拦截处理 2. 补充任务标题、实际需求人、计划起止时间、需求部门的表单校验规则 3. 重构approvalVerifyOpen审批回调逻辑,按工作流节点做差异化处理 4. 新增领导审批节点指定主执行人校验,execute/leader_final节点强制走专属业务入口 --- src/views/oa/erp/tempTask/edit.vue | 51 +++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/views/oa/erp/tempTask/edit.vue b/src/views/oa/erp/tempTask/edit.vue index 370f6d8..e1455d6 100644 --- a/src/views/oa/erp/tempTask/edit.vue +++ b/src/views/oa/erp/tempTask/edit.vue @@ -11,12 +11,13 @@ :pageType="pageType" :mode="false" > - + + @@ -232,7 +233,8 @@ @@ -464,8 +466,13 @@ const initFormData: TempTaskForm = { const form = ref({ ...initFormData }); const rules: ElFormRules = { + taskTitle: [{ required: true, message: '任务标题不能为空', trigger: 'blur' }], taskDesc: [{ required: true, message: '任务描述不能为空', trigger: 'blur' }], taskType: [{ required: true, message: '任务类型不能为空', trigger: 'change' }], + realRequesterName: [{ required: true, message: '实际需求人不能为空', trigger: 'change' }], + planStartTime: [{ required: true, message: '计划开始时间不能为空', trigger: 'change' }], + planEndTime: [{ required: true, message: '计划完成时间不能为空', trigger: 'change' }], + realRequestDeptId: [{ required: true, message: '实际需求部门不能为空', trigger: 'change' }], projectCode: [ { validator: (_rule, value, callback) => { @@ -1026,11 +1033,11 @@ const handleScoreAndClose = async () => { }; /** - * 审批按钮回调,根据当前工作流节点做三路分发。 + * 审批按钮回调,根据当前工作流节点做分发。 * * 分支逻辑: * 1. leader_review(领导审批节点): - * - 先校验主表单 + * - 先校验主表单 + 主执行人必填 * - 调用 leaderReviewAndCompleteTempTask 原子完成落库+流转 * - 直接关闭页面返回列表(无需弹出 submitVerify,因为后端已完成 completeTask) * @@ -1039,13 +1046,19 @@ const handleScoreAndClose = async () => { * - 重新 buildVariables() 装配最新的流程变量 * - 弹出 submitVerify 对话框,由用户确认后调用 workflow completeTask 流转 * - * 3. 其他节点(新增/修改提交、驳回重提等): + * 3. execute(主执行人执行节点): + * - 重定向到 handleSubmitFinish,走"提交完成"业务入口 + * - 后端原子完成工时校验(totalHours>0)、lockFlag 锁定、taskStatus→4、completeTask + * - 标准审批按钮不能绕过这些业务逻辑 + * + * 4. leader_final(软件部领导评分节点): + * - 重定向到 openScoreDialog,走"评分关闭"业务入口 + * - 领导必须对每位参与人评分(A++/A+/A/B/C)后才能关闭 + * - 标准审批按钮不能绕过评分校验 + * + * 5. 其他节点(新增/修改提交、驳回重提等): * - 直接 buildVariables() 装配流程变量 * - 弹出 submitVerify 对话框,走标准提交流程 - * - * 为什么 leader_review 不弹出 submitVerify: - * leaderReviewAndCompleteTempTask 已经在后端原子完成了 completeTask, - * 如果前端再调 completeTask 会导致重复流转。 */ const approvalVerifyOpen = async () => { const taskId = route.query.taskId as string; @@ -1060,6 +1073,12 @@ const approvalVerifyOpen = async () => { if (!valid) { return; } + // Why:领导审批通过后流程会进入 execute 或 assignee_review,两者的 permissionFlag 均依赖 ${assigneeId}, + // 因此领导在 leader_review 节点提交审批时必须已指定主执行人(可由领导在此节点选择填入)。 + if (!form.value.assigneeId) { + proxy?.$modal.msgWarning('请先指定主执行人再提交审批'); + return; + } // 领导审批:后端原子完成审核落库+流转,前端不再调 completeTask await leaderReviewAndCompleteTempTask({ ...form.value, taskId }); proxy?.$modal.msgSuccess('领导审批成功'); @@ -1070,6 +1089,16 @@ const approvalVerifyOpen = async () => { // 主执行人审阅:先回写可改字段,再重新装配变量后弹出审阅确认 await assigneeReviewTempTask(form.value); buildVariables(); + } else if (currentNodeCode.value === 'execute') { + // Why:execute 节点必须走 handleSubmitFinish 业务入口——后端原子完成工时校验、lockFlag 锁定、 + // totalHours 汇总、taskStatus→4 和 completeTask 流转。标准审批按钮不能绕过这些业务逻辑。 + await handleSubmitFinish(); + return; + } else if (currentNodeCode.value === 'leader_final') { + // Why:leader_final 节点必须走 openScoreDialog 业务入口——领导必须对每位参与人评分后才能关闭。 + // 标准审批按钮不能绕过评分校验,否则评分等级必填(A++/A+/A/B/C) 的约束形同虚设。 + openScoreDialog(); + return; } else { // 标准路径:装配变量后弹出提交流程确认 buildVariables();