fix(leave): 修复请假流程 waiting 与业务 draft 不同步导致无审批按钮

申请人提交后业务表可能仍停在 draft,办理页不显示审批按钮;在请假模块内补齐任务创建时状态对齐,禁止 waiting 被回写为 draft,并仅在暂存时写 draft。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
“wuzhen”andCursor committed 2026-09-20 10:27:28 +08:00
1 parent 65abe022c7
commit a6a5b88f47
3 files changed
+50 -17

No files matched your search

@@ -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<String, Object> 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*)
* <p>
* 补齐缺口:申请人办理后流程已是 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());
}
}
/**
@@ -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) {
+4 -2
View File
@@ -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 {