|
|
|
|
@ -11,12 +11,13 @@
|
|
|
|
|
:pageType="pageType"
|
|
|
|
|
:mode="false"
|
|
|
|
|
>
|
|
|
|
|
<el-button v-if="canSubmitFinish" type="success" icon="CircleCheck" @click="handleSubmitFinish" v-hasPermi="['oa/erp:tempTask:submitFinish']">
|
|
|
|
|
<!-- 提交完成/评分关闭按钮已移除,统一由审批按钮触发 approvalVerifyOpen 拦截 execute/leader_final 节点 -->
|
|
|
|
|
<!-- <el-button v-if="canSubmitFinish" type="success" icon="CircleCheck" @click="handleSubmitFinish" v-hasPermi="['oa/erp:tempTask:submitFinish']">
|
|
|
|
|
提交完成
|
|
|
|
|
</el-button>
|
|
|
|
|
<el-button v-if="canScoreClose" type="warning" icon="Star" @click="openScoreDialog" v-hasPermi="['oa/erp:tempTask:edit']">
|
|
|
|
|
评分关闭
|
|
|
|
|
</el-button>
|
|
|
|
|
</el-button>-->
|
|
|
|
|
</approvalButton>
|
|
|
|
|
|
|
|
|
|
<el-card shadow="never" class="mb-3">
|
|
|
|
|
@ -232,7 +233,8 @@
|
|
|
|
|
<template #header>
|
|
|
|
|
<div class="flex justify-between items-center">
|
|
|
|
|
<span>评分结果</span>
|
|
|
|
|
<el-button
|
|
|
|
|
<!-- 评分关闭按钮已移除,统一由审批按钮触发 approvalVerifyOpen → openScoreDialog -->
|
|
|
|
|
<!-- <el-button
|
|
|
|
|
v-if="canScoreClose"
|
|
|
|
|
type="warning"
|
|
|
|
|
plain
|
|
|
|
|
@ -242,7 +244,7 @@
|
|
|
|
|
v-hasPermi="['oa/erp:tempTask:edit']"
|
|
|
|
|
>
|
|
|
|
|
评分关闭
|
|
|
|
|
</el-button>
|
|
|
|
|
</el-button>-->
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<el-table :data="scoreList" border>
|
|
|
|
|
@ -464,8 +466,13 @@ const initFormData: TempTaskForm = {
|
|
|
|
|
const form = ref<TempTaskForm>({ ...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();
|
|
|
|
|
|