diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentLeaveServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentLeaveServiceImpl.java index b38d24c7..16f4f414 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentLeaveServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentLeaveServiceImpl.java @@ -414,6 +414,16 @@ public class XgStudentLeaveServiceImpl implements IXgStudentLeaveService { public Boolean updateByBo(XgStudentLeaveBo bo) { XgStudentLeave update = MapstructUtils.convert(bo, XgStudentLeave.class); validEntityBeforeSave(update); + // 流程已在待审核时,禁止被前端再次保存成 draft(否则办理页审批按钮会消失) + if (update.getId() != null && StringUtils.isNotBlank(update.getApprovalStatus())) { + XgStudentLeave existing = baseMapper.selectById(update.getId()); + if (ObjectUtil.isNotNull(existing) + && BusinessStatusEnum.WAITING.getStatus().equals(existing.getApprovalStatus()) + && BusinessStatusEnum.DRAFT.getStatus().equals(update.getApprovalStatus())) { + log.warn("忽略将请假审批状态从 waiting 回写为 draft, leaveId={}", update.getId()); + update.setApprovalStatus(null); + } + } return baseMapper.updateById(update) > 0; } @@ -441,16 +451,25 @@ public class XgStudentLeaveServiceImpl implements IXgStudentLeaveService { /** * 总体流程监听(例如: 草稿,撤销,退回,作废,终止,已完成,单任务完成等) - * 正常使用只需#processEvent.flowCode=='leave1' - * 示例为了方便则使用startsWith匹配了全部示例key + * 仅处理请假流程 hzdyjs-qj* * * @param processEvent 参数 */ + @Transactional(rollbackFor = Exception.class) @EventListener(condition = "#processEvent.flowCode.startsWith('hzdyjs-qj')") public void processHandler(ProcessEvent processEvent) { log.info("当前任务执行了{}", processEvent.toString()); XgStudentLeave xgStudentLeave = baseMapper.selectById(Long.valueOf(processEvent.getBusinessId())); - xgStudentLeave.setApprovalStatus(processEvent.getStatus()); + if (ObjectUtil.isNull(xgStudentLeave)) { + log.error("请假流程事件未找到业务数据, businessId={}", processEvent.getBusinessId()); + return; + } + // 申请人提交:强制对齐为 waiting;其它事件按流程状态同步(空 status 不覆盖) + if (processEvent.getSubmit()) { + xgStudentLeave.setApprovalStatus(BusinessStatusEnum.WAITING.getStatus()); + } else if (StringUtils.isNotBlank(processEvent.getStatus())) { + xgStudentLeave.setApprovalStatus(processEvent.getStatus()); + } // 用于例如审批附件 审批意见等 存储到业务表内 自行根据业务实现存储流程 Map params = processEvent.getParams(); if (MapUtil.isNotEmpty(params)) { @@ -461,9 +480,6 @@ public class XgStudentLeaveServiceImpl implements IXgStudentLeaveService { // 办理意见 String message = Convert.toStr(params.get("message")); } - if (processEvent.getSubmit()) { - xgStudentLeave.setApprovalStatus(BusinessStatusEnum.WAITING.getStatus()); - } baseMapper.updateById(xgStudentLeave); } @@ -505,19 +521,32 @@ public class XgStudentLeaveServiceImpl implements IXgStudentLeaveService { } /** - * 执行任务创建监听 - * 示例:也可通过 @EventListener(condition = - * "#processTaskEvent.flowCode=='leave1'")进行判断 - * 在方法中判断流程节点key - * if ("xxx".equals(processTaskEvent.getNodeCode())) { - * //执行业务逻辑 - * } + * 执行任务创建监听(仅 hzdyjs-qj*) + *

+ * 补齐缺口:申请人办理后流程已是 waiting,但业务表仍停在 draft 时(submit 标记丢失等), + * 在审批任务创建时把 approval_status 对齐为 waiting,避免办理页无「审批」按钮。 * * @param processTaskEvent 参数 */ + @Transactional(rollbackFor = Exception.class) @EventListener(condition = "#processTaskEvent.flowCode.startsWith('hzdyjs-qj')") public void processTaskHandler(ProcessTaskEvent processTaskEvent) { log.info("当前任务创建了{}", processTaskEvent.toString()); + if (StringUtils.isBlank(processTaskEvent.getBusinessId())) { + return; + } + XgStudentLeave leave = baseMapper.selectById(Long.valueOf(processTaskEvent.getBusinessId())); + if (ObjectUtil.isNull(leave)) { + log.error("请假任务创建事件未找到业务数据, businessId={}", processTaskEvent.getBusinessId()); + return; + } + if (BusinessStatusEnum.DRAFT.getStatus().equals(leave.getApprovalStatus()) + && BusinessStatusEnum.WAITING.getStatus().equals(processTaskEvent.getStatus())) { + leave.setApprovalStatus(BusinessStatusEnum.WAITING.getStatus()); + baseMapper.updateById(leave); + log.info("请假业务状态已从 draft 对齐为 waiting, businessId={}, taskId={}, nodeName={}", + processTaskEvent.getBusinessId(), processTaskEvent.getTaskId(), processTaskEvent.getNodeName()); + } } /** diff --git a/mobile/src/pages/xg/xsjcxx/xsqj/leaveEdit/index.vue b/mobile/src/pages/xg/xsjcxx/xsqj/leaveEdit/index.vue index 98181b72..1b296139 100644 --- a/mobile/src/pages/xg/xsjcxx/xsqj/leaveEdit/index.vue +++ b/mobile/src/pages/xg/xsjcxx/xsqj/leaveEdit/index.vue @@ -2999,10 +2999,12 @@ export default { this.form.attachmentOssIds = attachmentOssIds; console.log('提交的附件ossIds:', attachmentOssIds); - // 保存数据 + // 保存数据:仅暂存时写入草稿;提交时不强制 draft,避免覆盖流程已同步的 waiting const saveData = { ...this.form }; saveData.status = status; - saveData.approvalStatus = 'draft'; + if (status === 'draft') { + saveData.approvalStatus = 'draft'; + } let response; if (saveData.id) { diff --git a/web/src/views/xg/xsjcxx/xsqj/dialog.vue b/web/src/views/xg/xsjcxx/xsqj/dialog.vue index 435d54c7..cbbb9f01 100644 --- a/web/src/views/xg/xsjcxx/xsqj/dialog.vue +++ b/web/src/views/xg/xsjcxx/xsqj/dialog.vue @@ -1046,8 +1046,10 @@ const submitForm = (status: string) => { // 将附件ID添加到表单数据中,处理成逗号分隔的字符串 form.attachmentOssIds = attachmentOssIds.join(','); - // 设置审批状态为草稿 - form.approvalStatus = 'draft'; + // 仅暂存时写入草稿;提交时不强制 draft,避免覆盖流程已同步的 waiting + if (status === 'draft') { + form.approvalStatus = 'draft'; + } // 保存业务数据 try {