From 5882ba8863d77fdcc168b176c3ffb30e8a20556a Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期一, 13 七月 2026 17:54:25 +0800
Subject: [PATCH] 缩短二维码原始参数

---
 backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java |  417 ++++++++++++++++++++++++++++------------------------------
 1 files changed, 202 insertions(+), 215 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 e2c629f..47ab6cc 100644
--- a/backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/ApprovalEngineService.java
@@ -17,6 +17,7 @@
 import com.sinata.appointment.entity.MpPassLocalUnitMember;
 import com.sinata.appointment.entity.MpStaffGroupMember;
 import com.sinata.appointment.entity.MpUser;
+import com.sinata.appointment.entity.SysDept;
 import com.sinata.appointment.exception.BizException;
 import com.sinata.appointment.mapper.ApprovalInstanceMapper;
 import com.sinata.appointment.mapper.ApprovalTaskMapper;
@@ -25,6 +26,7 @@
 import com.sinata.appointment.mapper.MpPassLocalUnitMemberMapper;
 import com.sinata.appointment.mapper.MpStaffGroupMemberMapper;
 import com.sinata.appointment.mapper.MpUserMapper;
+import com.sinata.appointment.mapper.SysDeptMapper;
 import com.sinata.appointment.constants.BizErrorCode;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
@@ -48,11 +50,13 @@
 
     private static final TypeReference<List<Long>> LONG_LIST_TYPE = new TypeReference<>() {};
     private static final String AUTO_APPROVE_COMMENT = "前序节点已审批,系统自动同意";
+    private static final String LOCAL_UNIT_GROUP_TOKEN = ":UNIT:";
 
     private final BizApprovalNodeConfigMapper bizApprovalNodeConfigMapper;
     private final ApprovalInstanceMapper approvalInstanceMapper;
     private final ApprovalTaskMapper approvalTaskMapper;
     private final MpUserMapper mpUserMapper;
+    private final SysDeptMapper sysDeptMapper;
     private final MpPassLocalUnitMapper mpPassLocalUnitMapper;
     private final MpPassLocalUnitMemberMapper mpPassLocalUnitMemberMapper;
     private final MpStaffGroupMemberMapper mpStaffGroupMemberMapper;
@@ -118,15 +122,15 @@
         }
         if (ApprovalNodeCode.LEVEL2_DEPT_LEADER.equals(nodeCode)) {
             Long deptId = resolveVisitedDeptId(order);
-            return listEmployeeIdsByDeptAndLeaderFlag(deptId, true);
+            return getDeptLeaderIds(deptId);
         }
         if (ApprovalNodeCode.LEVEL4_VISIT_DEPT.equals(nodeCode)) {
             Long competentDeptId = getVisitCompetentDeptId();
-            return listEmployeeIdsByDeptAndLeaderFlag(competentDeptId, false);
+            return listEmployeeIdsByDeptWithLeaderFallback(competentDeptId);
         }
         if (ApprovalNodeCode.LEVEL5_VISIT_DEPT_LEADER.equals(nodeCode)) {
             Long competentDeptId = getVisitCompetentDeptId();
-            return listEmployeeIdsByDeptAndLeaderFlag(competentDeptId, true);
+            return getDeptLeaderIds(competentDeptId);
         }
         if (ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER.equals(nodeCode)) {
             return List.of();
@@ -161,7 +165,59 @@
         }
     }
 
-    private List<Long> listEmployeeIdsByDeptAndLeaderFlag(Long deptId, boolean leaderFlag) {
+    private List<Long> getDeptLeaderIds(Long deptId) {
+        if (deptId == null || deptId <= 0) {
+            return List.of();
+        }
+        SysDept dept = sysDeptMapper.selectById(deptId);
+        if (dept == null || dept.getDelFlag() != null && dept.getDelFlag() == 1) {
+            return List.of();
+        }
+        List<Long> leaderIds = parseDeptLeaderIds(dept);
+        if (leaderIds.isEmpty()) {
+            return List.of();
+        }
+        List<MpUser> leaders =
+                mpUserMapper.selectList(
+                        new LambdaQueryWrapper<MpUser>()
+                                .eq(MpUser::getDelFlag, 0)
+                                .eq(MpUser::getStatus, 1)
+                                .eq(MpUser::getUserType, MiniUserType.EMPLOYEE)
+                                .in(MpUser::getId, leaderIds));
+        Map<Long, MpUser> leaderMap = new LinkedHashMap<>();
+        for (MpUser leader : leaders) {
+            leaderMap.put(leader.getId(), leader);
+        }
+        List<Long> result = new ArrayList<>();
+        for (Long id : leaderIds) {
+            if (leaderMap.containsKey(id)) {
+                result.add(id);
+            }
+        }
+        return result;
+    }
+
+    private List<Long> parseDeptLeaderIds(SysDept dept) {
+        List<Long> ids = new ArrayList<>();
+        Set<Long> seen = new LinkedHashSet<>();
+        if (StringUtils.hasText(dept.getLeaderIds())) {
+            for (String part : dept.getLeaderIds().split(",")) {
+                if (!StringUtils.hasText(part)) {
+                    continue;
+                }
+                try {
+                    Long id = Long.parseLong(part.trim());
+                    if (id > 0 && seen.add(id)) {
+                        ids.add(id);
+                    }
+                } catch (NumberFormatException ignored) {
+                }
+            }
+        }
+        return ids;
+    }
+
+    private List<Long> listAllActiveEmployeeIdsByDept(Long deptId) {
         if (deptId == null || deptId <= 0) {
             return List.of();
         }
@@ -171,9 +227,12 @@
                                 .eq(MpUser::getDelFlag, 0)
                                 .eq(MpUser::getStatus, 1)
                                 .eq(MpUser::getUserType, MiniUserType.EMPLOYEE)
-                                .eq(MpUser::getDeptId, deptId)
-                                .eq(MpUser::getDeptLeaderFlag, leaderFlag));
-        return users.stream().map(MpUser::getId).filter(Objects::nonNull).toList();
+                                .eq(MpUser::getDeptId, deptId));
+        return users.stream().map(MpUser::getId).filter(Objects::nonNull).distinct().toList();
+    }
+
+    private List<Long> listEmployeeIdsByDeptWithLeaderFallback(Long deptId) {
+        return listAllActiveEmployeeIdsByDept(deptId);
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -252,7 +311,7 @@
         inst.setStatus(ApprovalInstanceStatus.REJECTED);
         inst.setFinishedAt(LocalDateTime.now());
         approvalInstanceMapper.updateById(inst);
-        List<ApprovalTask> pending =
+        List<ApprovalTask> remainingTasks =
                 approvalTaskMapper.selectList(
                         new LambdaQueryWrapper<ApprovalTask>()
                                 .eq(ApprovalTask::getInstanceId, inst.getId())
@@ -260,9 +319,9 @@
                                         ApprovalTask::getTaskStatus,
                                         ApprovalTaskStatus.PENDING,
                                         ApprovalTaskStatus.WAITING));
-        for (ApprovalTask t : pending) {
+        for (ApprovalTask t : remainingTasks) {
             t.setTaskStatus(ApprovalTaskStatus.REJECTED);
-            t.setComment(reason);
+            t.setComment(null);
             approvalTaskMapper.updateById(t);
         }
     }
@@ -380,94 +439,16 @@
     }
 
     private int createTasksForLocalUnitNode(Long instanceId, AppointmentOrder order, String initialStatus) {
-        List<Long> localUnitIds = parseLongJsonArray(order.getPassLocalUnitIds());
-        if (localUnitIds.isEmpty()) {
-            return 0;
-        }
-        List<MpPassLocalUnit> units =
-                mpPassLocalUnitMapper.selectList(
-                        new LambdaQueryWrapper<MpPassLocalUnit>()
-                                .eq(MpPassLocalUnit::getDelFlag, 0)
-                                .in(MpPassLocalUnit::getId, localUnitIds));
-        if (units.isEmpty()) {
-            return 0;
-        }
-        Map<Long, MpPassLocalUnit> unitMap =
-                units.stream().collect(java.util.stream.Collectors.toMap(MpPassLocalUnit::getId, x -> x, (a, b) -> a));
-
-        LinkedHashSet<Long> deptIds = new LinkedHashSet<>();
-        LinkedHashSet<Long> groupIds = new LinkedHashSet<>();
-        LinkedHashMap<String, List<Long>> tempGroups = new LinkedHashMap<>();
-
-        for (Long unitId : localUnitIds) {
-            MpPassLocalUnit unit = unitMap.get(unitId);
-            if (unit == null || unit.getApproverType() == null) {
-                continue;
-            }
-            if (unit.getApproverType() == LocalUnitApproverType.DEPT) {
-                for (Long deptId : parseLongJsonArray(unit.getApproverDeptIds())) {
-                    if (deptId != null && deptId > 0) {
-                        deptIds.add(deptId);
-                    }
-                }
-                continue;
-            }
-            if (unit.getApproverType() == LocalUnitApproverType.STAFF_GROUP) {
-                Long gid = unit.getApproverGroupId();
-                if (gid != null && gid > 0) {
-                    groupIds.add(gid);
-                }
-                continue;
-            }
-            if (unit.getApproverType() == LocalUnitApproverType.STAFF) {
-                List<MpPassLocalUnitMember> members =
-                        mpPassLocalUnitMemberMapper.selectList(
-                                new LambdaQueryWrapper<MpPassLocalUnitMember>()
-                                        .eq(MpPassLocalUnitMember::getDelFlag, 0)
-                                        .eq(MpPassLocalUnitMember::getUnitId, unitId)
-                                        .orderByAsc(MpPassLocalUnitMember::getId));
-                LinkedHashSet<Long> mids = new LinkedHashSet<>();
-                for (MpPassLocalUnitMember m : members) {
-                    if (m.getMpUserId() != null && m.getMpUserId() > 0) {
-                        mids.add(m.getMpUserId());
-                    }
-                }
-                if (mids.isEmpty()) {
-                    continue;
-                }
-                List<Long> ordered = mids.stream().toList();
-                String sign = buildTempGroupSign(ordered);
-                tempGroups.putIfAbsent(sign, ordered);
-            }
-        }
-
+        List<LocalUnitApprovalGroup> groups = resolveLocalUnitApprovalGroups(order, false);
         int total = 0;
-        for (Long deptId : deptIds) {
-            List<Long> assignees = listEmployeeIdsByDeptAndLeaderFlag(deptId, true);
-            String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":DEPT:" + deptId;
-            total += createTasksWithGroupKey(instanceId, ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, key, assignees, initialStatus);
-        }
-        for (Long groupId : groupIds) {
-            List<MpStaffGroupMember> members =
-                    mpStaffGroupMemberMapper.selectList(
-                            new LambdaQueryWrapper<MpStaffGroupMember>()
-                                    .eq(MpStaffGroupMember::getDelFlag, 0)
-                                    .eq(MpStaffGroupMember::getGroupId, groupId)
-                                    .orderByAsc(MpStaffGroupMember::getId));
-            LinkedHashSet<Long> mids = new LinkedHashSet<>();
-            for (MpStaffGroupMember m : members) {
-                if (m.getMpUserId() != null && m.getMpUserId() > 0) {
-                    mids.add(m.getMpUserId());
-                }
-            }
-            List<Long> assignees = filterActiveEmployeeIds(mids.stream().toList());
-            String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":GROUP:" + groupId;
-            total += createTasksWithGroupKey(instanceId, ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, key, assignees, initialStatus);
-        }
-        for (Map.Entry<String, List<Long>> e : tempGroups.entrySet()) {
-            List<Long> assignees = filterActiveEmployeeIds(e.getValue());
-            String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":TMP:" + e.getKey();
-            total += createTasksWithGroupKey(instanceId, ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER, key, assignees, initialStatus);
+        for (LocalUnitApprovalGroup group : groups) {
+            total +=
+                    createTasksWithGroupKey(
+                            instanceId,
+                            ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER,
+                            buildLocalUnitGroupKey(group.unitId()),
+                            group.assigneeIds(),
+                            initialStatus);
         }
         return total;
     }
@@ -493,122 +474,15 @@
                     "节点无审批人: " + resolveNodeName(ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER));
         }
 
-        List<MpPassLocalUnit> units =
-                mpPassLocalUnitMapper.selectList(
-                        new LambdaQueryWrapper<MpPassLocalUnit>()
-                                .eq(MpPassLocalUnit::getDelFlag, 0)
-                                .in(MpPassLocalUnit::getId, localUnitIds));
-        if (units.size() != localUnitIds.size()) {
-            throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位配置缺失,无法生成审批人");
-        }
-        Map<Long, MpPassLocalUnit> unitMap =
-                units.stream()
-                        .collect(
-                                java.util.stream.Collectors.toMap(
-                                        MpPassLocalUnit::getId, x -> x, (a, b) -> a));
-
-        LinkedHashSet<Long> deptIds = new LinkedHashSet<>();
-        LinkedHashSet<Long> groupIds = new LinkedHashSet<>();
-        LinkedHashMap<String, List<Long>> tempGroups = new LinkedHashMap<>();
-
-        for (Long unitId : localUnitIds) {
-            MpPassLocalUnit unit = unitMap.get(unitId);
-            if (unit == null || unit.getApproverType() == null) {
-                throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批类型缺失: " + unitId);
-            }
-            if (unit.getApproverType() == LocalUnitApproverType.DEPT) {
-                List<Long> ids = parseLongJsonArray(unit.getApproverDeptIds());
-                if (ids.isEmpty()) {
-                    throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批部门未配置: " + unitId);
-                }
-                deptIds.addAll(ids);
-                continue;
-            }
-            if (unit.getApproverType() == LocalUnitApproverType.STAFF_GROUP) {
-                Long gid = unit.getApproverGroupId();
-                if (gid == null || gid <= 0) {
-                    throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批分组未配置: " + unitId);
-                }
-                groupIds.add(gid);
-                continue;
-            }
-            if (unit.getApproverType() == LocalUnitApproverType.STAFF) {
-                List<MpPassLocalUnitMember> members =
-                        mpPassLocalUnitMemberMapper.selectList(
-                                new LambdaQueryWrapper<MpPassLocalUnitMember>()
-                                        .eq(MpPassLocalUnitMember::getDelFlag, 0)
-                                        .eq(MpPassLocalUnitMember::getUnitId, unitId)
-                                        .orderByAsc(MpPassLocalUnitMember::getId));
-                LinkedHashSet<Long> mids = new LinkedHashSet<>();
-                for (MpPassLocalUnitMember m : members) {
-                    if (m.getMpUserId() != null && m.getMpUserId() > 0) {
-                        mids.add(m.getMpUserId());
-                    }
-                }
-                if (mids.isEmpty()) {
-                    throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批人员未配置: " + unitId);
-                }
-                List<Long> ordered = mids.stream().toList();
-                String sign = buildTempGroupSign(ordered);
-                tempGroups.putIfAbsent(sign, ordered);
-                continue;
-            }
-            throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批类型无效: " + unitId);
-        }
-
+        List<LocalUnitApprovalGroup> groups = resolveLocalUnitApprovalGroups(order, true);
         int total = 0;
-        for (Long deptId : deptIds) {
-            List<Long> assignees = listEmployeeIdsByDeptAndLeaderFlag(deptId, true);
-            if (assignees.isEmpty()) {
-                throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "审批部门无负责人: " + deptId);
-            }
-            String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":DEPT:" + deptId;
+        for (LocalUnitApprovalGroup group : groups) {
             total +=
                     createTasksWithGroupKey(
                             instanceId,
                             ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER,
-                            key,
-                            assignees,
-                            initialStatus);
-        }
-        for (Long groupId : groupIds) {
-            List<MpStaffGroupMember> members =
-                    mpStaffGroupMemberMapper.selectList(
-                            new LambdaQueryWrapper<MpStaffGroupMember>()
-                                    .eq(MpStaffGroupMember::getDelFlag, 0)
-                                    .eq(MpStaffGroupMember::getGroupId, groupId)
-                                    .orderByAsc(MpStaffGroupMember::getId));
-            LinkedHashSet<Long> mids = new LinkedHashSet<>();
-            for (MpStaffGroupMember m : members) {
-                if (m.getMpUserId() != null && m.getMpUserId() > 0) {
-                    mids.add(m.getMpUserId());
-                }
-            }
-            List<Long> assignees = filterActiveEmployeeIds(mids.stream().toList());
-            if (assignees.isEmpty()) {
-                throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "审批分组无有效成员: " + groupId);
-            }
-            String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":GROUP:" + groupId;
-            total +=
-                    createTasksWithGroupKey(
-                            instanceId,
-                            ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER,
-                            key,
-                            assignees,
-                            initialStatus);
-        }
-        for (Map.Entry<String, List<Long>> e : tempGroups.entrySet()) {
-            List<Long> assignees = filterActiveEmployeeIds(e.getValue());
-            if (assignees.isEmpty()) {
-                throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "临时审批组无有效成员");
-            }
-            String key = ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + ":TMP:" + e.getKey();
-            total +=
-                    createTasksWithGroupKey(
-                            instanceId,
-                            ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER,
-                            key,
-                            assignees,
+                            buildLocalUnitGroupKey(group.unitId()),
+                            group.assigneeIds(),
                             initialStatus);
         }
         if (total <= 0) {
@@ -617,6 +491,125 @@
                     "节点无审批人: " + resolveNodeName(ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER));
         }
         return total;
+    }
+
+    private List<LocalUnitApprovalGroup> resolveLocalUnitApprovalGroups(
+            AppointmentOrder order, boolean strict) {
+        List<Long> localUnitIds = parseLongJsonArray(order.getPassLocalUnitIds());
+        if (localUnitIds.isEmpty()) {
+            return List.of();
+        }
+        List<MpPassLocalUnit> units =
+                mpPassLocalUnitMapper.selectList(
+                        new LambdaQueryWrapper<MpPassLocalUnit>()
+                                .eq(MpPassLocalUnit::getDelFlag, 0)
+                                .in(MpPassLocalUnit::getId, localUnitIds));
+        Map<Long, MpPassLocalUnit> unitMap =
+                units.stream()
+                        .collect(
+                                java.util.stream.Collectors.toMap(
+                                        MpPassLocalUnit::getId, x -> x, (a, b) -> a));
+        if (strict && unitMap.size() != localUnitIds.size()) {
+            throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位配置缺失,无法生成审批人");
+        }
+
+        List<LocalUnitApprovalGroup> groups = new ArrayList<>();
+        for (Long unitId : localUnitIds) {
+            MpPassLocalUnit unit = unitMap.get(unitId);
+            if (unit == null) {
+                if (strict) {
+                    throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位配置缺失,无法生成审批人");
+                }
+                continue;
+            }
+            List<Long> assignees = resolveLocalUnitAssignees(unitId, unit, strict);
+            if (assignees.isEmpty()) {
+                continue;
+            }
+            groups.add(new LocalUnitApprovalGroup(unitId, assignees));
+        }
+        return groups;
+    }
+
+    private List<Long> resolveLocalUnitAssignees(Long unitId, MpPassLocalUnit unit, boolean strict) {
+        Integer approverType = unit.getApproverType();
+        if (approverType == null) {
+            if (strict) {
+                throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批类型缺失: " + unitId);
+            }
+            return List.of();
+        }
+        if (approverType == LocalUnitApproverType.DEPT) {
+            List<Long> deptIds = parseLongJsonArray(unit.getApproverDeptIds());
+            if (deptIds.isEmpty()) {
+                if (strict) {
+                    throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批部门未配置: " + unitId);
+                }
+                return List.of();
+            }
+            LinkedHashSet<Long> assignees = new LinkedHashSet<>();
+            for (Long deptId : deptIds) {
+                List<Long> deptApprovers = listAllActiveEmployeeIdsByDept(deptId);
+                if (strict && deptApprovers.isEmpty()) {
+                    throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "审批部门无可用审批人: " + deptId);
+                }
+                assignees.addAll(deptApprovers);
+            }
+            return assignees.stream().toList();
+        }
+        if (approverType == LocalUnitApproverType.STAFF_GROUP) {
+            Long groupId = unit.getApproverGroupId();
+            if (groupId == null || groupId <= 0) {
+                if (strict) {
+                    throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批分组未配置: " + unitId);
+                }
+                return List.of();
+            }
+            List<MpStaffGroupMember> members =
+                    mpStaffGroupMemberMapper.selectList(
+                            new LambdaQueryWrapper<MpStaffGroupMember>()
+                                    .eq(MpStaffGroupMember::getDelFlag, 0)
+                                    .eq(MpStaffGroupMember::getGroupId, groupId)
+                                    .orderByAsc(MpStaffGroupMember::getId));
+            LinkedHashSet<Long> mids = new LinkedHashSet<>();
+            for (MpStaffGroupMember member : members) {
+                if (member.getMpUserId() != null && member.getMpUserId() > 0) {
+                    mids.add(member.getMpUserId());
+                }
+            }
+            List<Long> assignees = filterActiveEmployeeIds(mids.stream().toList());
+            if (strict && assignees.isEmpty()) {
+                throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "审批分组无有效成员: " + groupId);
+            }
+            return assignees;
+        }
+        if (approverType == LocalUnitApproverType.STAFF) {
+            List<MpPassLocalUnitMember> members =
+                    mpPassLocalUnitMemberMapper.selectList(
+                            new LambdaQueryWrapper<MpPassLocalUnitMember>()
+                                    .eq(MpPassLocalUnitMember::getDelFlag, 0)
+                                    .eq(MpPassLocalUnitMember::getUnitId, unitId)
+                                    .orderByAsc(MpPassLocalUnitMember::getId));
+            LinkedHashSet<Long> mids = new LinkedHashSet<>();
+            for (MpPassLocalUnitMember member : members) {
+                if (member.getMpUserId() != null && member.getMpUserId() > 0) {
+                    mids.add(member.getMpUserId());
+                }
+            }
+            List<Long> assignees = filterActiveEmployeeIds(mids.stream().toList());
+            if (strict && assignees.isEmpty()) {
+                throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批人员未配置: " + unitId);
+            }
+            return assignees;
+        }
+        if (strict) {
+            throw new BizException(BizErrorCode.CONFIG_NOT_FOUND, "属地单位审批类型无效: " + unitId);
+        }
+        return List.of();
+    }
+
+    private String buildLocalUnitGroupKey(Long unitId) {
+        return ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER + LOCAL_UNIT_GROUP_TOKEN + unitId;
     }
 
     private String resolveNodeName(String nodeCode) {
@@ -743,11 +736,5 @@
         return out;
     }
 
-    private String buildTempGroupSign(List<Long> memberIds) {
-        String joined = memberIds.stream().map(String::valueOf).collect(java.util.stream.Collectors.joining("-"));
-        if (joined.length() <= 40) {
-            return joined;
-        }
-        return Integer.toHexString(joined.hashCode());
-    }
+    private record LocalUnitApprovalGroup(Long unitId, List<Long> assigneeIds) {}
 }

--
Gitblit v1.7.1