From 25df88d0ab9d7444ed1d162b9efa1259ac2f6f66 Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期一, 27 四月 2026 10:13:53 +0800
Subject: [PATCH] 小程序对接finish

---
 backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java |   42 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java b/backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java
index 1b1bba9..e2c629f 100644
--- a/backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java
@@ -267,6 +267,26 @@
         }
     }
 
+    @Transactional(rollbackFor = Exception.class)
+    public void cancelInstance(ApprovalInstance inst, String reason) {
+        inst.setStatus(ApprovalInstanceStatus.CANCELLED);
+        inst.setFinishedAt(LocalDateTime.now());
+        approvalInstanceMapper.updateById(inst);
+        List<ApprovalTask> pending =
+                approvalTaskMapper.selectList(
+                        new LambdaQueryWrapper<ApprovalTask>()
+                                .eq(ApprovalTask::getInstanceId, inst.getId())
+                                .in(
+                                        ApprovalTask::getTaskStatus,
+                                        ApprovalTaskStatus.PENDING,
+                                        ApprovalTaskStatus.WAITING));
+        for (ApprovalTask t : pending) {
+            t.setTaskStatus(ApprovalTaskStatus.CANCELLED);
+            t.setComment(reason);
+            approvalTaskMapper.updateById(t);
+        }
+    }
+
     private String resolveFirstNodeWithAssignees(List<String> chain, AppointmentOrder order) {
         for (String nodeCode : chain) {
             List<Long> assignees = resolveAssignees(nodeCode, order);
@@ -457,7 +477,9 @@
         List<Long> assignees = resolveAssignees(nodeCode, order);
         int created = createTasksWithGroupKey(inst.getId(), nodeCode, nodeCode, assignees, initialStatus);
         if (created <= 0) {
-            throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "节点无审批人: " + nodeCode);
+            throw new BizException(
+                    BizErrorCode.CONFIG_NOT_FOUND,
+                    "节点无审批人: " + resolveNodeName(nodeCode));
         }
         return created;
     }
@@ -468,7 +490,7 @@
         if (!Boolean.TRUE.equals(order.getInvolveOtherLocalUnit()) || localUnitIds.isEmpty()) {
             throw new BizException(
                     BizErrorCode.CONFIG_NOT_FOUND,
-                    "节点无审批人: " + ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER);
+                    "节点无审批人: " + resolveNodeName(ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER));
         }
 
         List<MpPassLocalUnit> units =
@@ -592,11 +614,25 @@
         if (total <= 0) {
             throw new BizException(
                     BizErrorCode.CONFIG_NOT_FOUND,
-                    "节点无审批人: " + ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER);
+                    "节点无审批人: " + resolveNodeName(ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER));
         }
         return total;
     }
 
+    private String resolveNodeName(String nodeCode) {
+        if (!StringUtils.hasText(nodeCode)) {
+            return "未知节点";
+        }
+        return switch (nodeCode) {
+            case ApprovalNodeCode.LEVEL1_HANDLER -> "经办人(一级)";
+            case ApprovalNodeCode.LEVEL2_DEPT_LEADER -> "部门负责人(二级)";
+            case ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER -> "属地管理部门领导(三级)";
+            case ApprovalNodeCode.LEVEL4_VISIT_DEPT -> "访客主管部门(四级)";
+            case ApprovalNodeCode.LEVEL5_VISIT_DEPT_LEADER -> "访客主管部门领导(五级)";
+            default -> nodeCode;
+        };
+    }
+
     private int createTasksWithGroupKey(
             Long instanceId, String nodeCode, String groupKey, List<Long> assignees, String initialStatus) {
         Set<Long> unique = new LinkedHashSet<>(assignees == null ? List.of() : assignees);

--
Gitblit v1.7.1