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/ApprovalFlowViewApplicationService.java |  180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 179 insertions(+), 1 deletions(-)

diff --git a/backend/src/main/java/com/sinata/appointment/service/ApprovalFlowViewApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/ApprovalFlowViewApplicationService.java
index 48d82c5..d09f696 100644
--- a/backend/src/main/java/com/sinata/appointment/service/ApprovalFlowViewApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/ApprovalFlowViewApplicationService.java
@@ -8,10 +8,12 @@
 import com.sinata.appointment.dto.ApprovalFlowGroupVo;
 import com.sinata.appointment.dto.ApprovalFlowNodeVo;
 import com.sinata.appointment.dto.ApprovalFlowTaskUserVo;
+import com.sinata.appointment.dto.MiniVisitedUserVo;
 import com.sinata.appointment.entity.AppointmentOrder;
 import com.sinata.appointment.entity.ApprovalInstance;
 import com.sinata.appointment.entity.ApprovalTask;
 import com.sinata.appointment.entity.BizApprovalNodeConfig;
+import com.sinata.appointment.entity.MpPassLocalUnit;
 import com.sinata.appointment.entity.MpStaffGroup;
 import com.sinata.appointment.entity.MpUser;
 import com.sinata.appointment.entity.SysDept;
@@ -19,6 +21,7 @@
 import com.sinata.appointment.mapper.ApprovalInstanceMapper;
 import com.sinata.appointment.mapper.ApprovalTaskMapper;
 import com.sinata.appointment.mapper.BizApprovalNodeConfigMapper;
+import com.sinata.appointment.mapper.MpPassLocalUnitMapper;
 import com.sinata.appointment.mapper.MpStaffGroupMapper;
 import com.sinata.appointment.mapper.MpUserMapper;
 import com.sinata.appointment.mapper.SysDeptMapper;
@@ -30,6 +33,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
@@ -39,6 +43,7 @@
 public class ApprovalFlowViewApplicationService {
 
     private static final TypeReference<List<String>> STRING_LIST_TYPE = new TypeReference<>() {};
+    private static final TypeReference<List<Long>> LONG_LIST_TYPE = new TypeReference<>() {};
 
     private final ApprovalInstanceMapper approvalInstanceMapper;
     private final ApprovalTaskMapper approvalTaskMapper;
@@ -47,6 +52,7 @@
     private final MpUserMapper mpUserMapper;
     private final SysDeptMapper sysDeptMapper;
     private final MpStaffGroupMapper mpStaffGroupMapper;
+    private final MpPassLocalUnitMapper mpPassLocalUnitMapper;
     private final ObjectMapper objectMapper;
 
     public List<ApprovalFlowNodeVo> treeByOrderId(Long orderId) {
@@ -81,6 +87,7 @@
         Map<Long, String> deptNameMap = loadDeptNameMap(tasks);
         Map<Long, String> staffGroupNameMap = loadStaffGroupNameMap(tasks);
         List<String> localUnitNames = parseStringList(order == null ? null : order.getPassLocalUnitNames());
+        Map<Long, String> localUnitNameMap = loadLocalUnitNameMap(order, tasks);
 
         LinkedHashMap<String, LinkedHashMap<String, List<ApprovalTask>>> byNode = new LinkedHashMap<>();
         for (ApprovalTask t : tasks) {
@@ -102,7 +109,15 @@
                 List<ApprovalTask> groupTasks = groupEntry.getValue();
                 ApprovalFlowGroupVo g = new ApprovalFlowGroupVo();
                 g.setGroupKey(groupKey);
-                GroupMeta meta = resolveGroupMeta(nodeCode, groupKey, deptNameMap, staffGroupNameMap, localUnitNames, tmpIdx);
+                GroupMeta meta =
+                        resolveGroupMeta(
+                                nodeCode,
+                                groupKey,
+                                deptNameMap,
+                                staffGroupNameMap,
+                                localUnitNames,
+                                localUnitNameMap,
+                                tmpIdx);
                 if ("TEMP_GROUP".equals(meta.groupType())) {
                     tmpIdx++;
                 }
@@ -120,6 +135,7 @@
                     u.setTaskStatus(t.getTaskStatus());
                     u.setComment(t.getComment());
                     u.setActionTime(t.getUpdateTime());
+                    u.setNoticeUsers(loadNoticeUsers(t.getNoticeIds(), userMap, deptNameMap));
                     g.getUsers().add(u);
                 }
                 nodeVo.getGroups().add(g);
@@ -221,15 +237,67 @@
         return out;
     }
 
+    private Map<Long, String> loadLocalUnitNameMap(AppointmentOrder order, List<ApprovalTask> tasks) {
+        Set<Long> unitIds = new LinkedHashSet<>();
+        for (ApprovalTask task : tasks) {
+            Long unitId = parseTailId(task.getGroupKey(), ":UNIT:");
+            if (unitId != null && unitId > 0) {
+                unitIds.add(unitId);
+            }
+        }
+        if (unitIds.isEmpty()) {
+            return Map.of();
+        }
+
+        Map<Long, String> out = new LinkedHashMap<>();
+        if (order != null) {
+            List<Long> orderUnitIds = parseLongList(order.getPassLocalUnitIds());
+            List<String> orderUnitNames = parseStringList(order.getPassLocalUnitNames());
+            int size = Math.min(orderUnitIds.size(), orderUnitNames.size());
+            for (int i = 0; i < size; i++) {
+                Long unitId = orderUnitIds.get(i);
+                String unitName = orderUnitNames.get(i);
+                if (unitId != null && unitId > 0 && StringUtils.hasText(unitName)) {
+                    out.put(unitId, unitName);
+                }
+            }
+        }
+
+        Set<Long> missingIds =
+                unitIds.stream()
+                        .filter(id -> !out.containsKey(id))
+                        .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (missingIds.isEmpty()) {
+            return out;
+        }
+        List<MpPassLocalUnit> rows =
+                mpPassLocalUnitMapper.selectList(
+                        new LambdaQueryWrapper<MpPassLocalUnit>()
+                                .eq(MpPassLocalUnit::getDelFlag, 0)
+                                .in(MpPassLocalUnit::getId, missingIds));
+        for (MpPassLocalUnit row : rows) {
+            if (row.getId() != null && StringUtils.hasText(row.getUnitName())) {
+                out.put(row.getId(), row.getUnitName());
+            }
+        }
+        return out;
+    }
+
     private GroupMeta resolveGroupMeta(
             String nodeCode,
             String groupKey,
             Map<Long, String> deptNameMap,
             Map<Long, String> staffGroupNameMap,
             List<String> localUnitNames,
+            Map<Long, String> localUnitNameMap,
             int tmpIdx) {
         if (!ApprovalNodeCode.LEVEL3_LOCAL_DEPT_LEADER.equals(nodeCode)) {
             return new GroupMeta("DEFAULT", "审批人");
+        }
+        Long localUnitId = parseTailId(groupKey, ":UNIT:");
+        if (localUnitId != null) {
+            String name = localUnitNameMap.getOrDefault(localUnitId, "属地#" + localUnitId);
+            return new GroupMeta("TEMP_GROUP", name);
         }
         Long deptId = parseTailId(groupKey, ":DEPT:");
         if (deptId != null) {
@@ -294,17 +362,118 @@
         }
     }
 
+    private List<Long> parseLongList(String json) {
+        if (!StringUtils.hasText(json)) {
+            return List.of();
+        }
+        try {
+            List<Long> rows = objectMapper.readValue(json, LONG_LIST_TYPE);
+            if (rows == null) {
+                return List.of();
+            }
+            List<Long> out = new ArrayList<>();
+            for (Long row : rows) {
+                if (row != null && row > 0) {
+                    out.add(row);
+                }
+            }
+            return out;
+        } catch (Exception ex) {
+            return List.of();
+        }
+    }
+
+    private List<MiniVisitedUserVo> loadNoticeUsers(
+            String noticeIds, Map<Long, MpUser> existingUserMap, Map<Long, String> existingDeptNameMap) {
+        List<Long> ids = parseCommaSeparatedIds(noticeIds);
+        if (ids.isEmpty()) {
+            return List.of();
+        }
+        Map<Long, MpUser> userMap = existingUserMap;
+        LinkedHashSet<Long> missingIds = ids.stream()
+                .filter(id -> !existingUserMap.containsKey(id))
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (!missingIds.isEmpty()) {
+            List<MpUser> extraUsers =
+                    mpUserMapper.selectList(
+                            new LambdaQueryWrapper<MpUser>()
+                                    .eq(MpUser::getDelFlag, 0)
+                                    .in(MpUser::getId, missingIds));
+            userMap = new LinkedHashMap<>(existingUserMap);
+            for (MpUser extraUser : extraUsers) {
+                userMap.put(extraUser.getId(), extraUser);
+            }
+        }
+
+        Map<Long, String> deptNameMap = existingDeptNameMap;
+        LinkedHashSet<Long> missingDeptIds = ids.stream()
+                .map(userMap::get)
+                .filter(Objects::nonNull)
+                .map(MpUser::getDeptId)
+                .filter(Objects::nonNull)
+                .filter(id -> id > 0 && !existingDeptNameMap.containsKey(id))
+                .collect(Collectors.toCollection(LinkedHashSet::new));
+        if (!missingDeptIds.isEmpty()) {
+            deptNameMap = new LinkedHashMap<>(existingDeptNameMap);
+            List<SysDept> depts =
+                    sysDeptMapper.selectList(
+                            new LambdaQueryWrapper<SysDept>()
+                                    .eq(SysDept::getDelFlag, 0)
+                                    .in(SysDept::getId, missingDeptIds));
+            for (SysDept dept : depts) {
+                deptNameMap.put(dept.getId(), dept.getDeptName());
+            }
+        }
+
+        List<MiniVisitedUserVo> result = new ArrayList<>();
+        for (Long id : ids) {
+            MpUser user = userMap.get(id);
+            if (user == null) {
+                continue;
+            }
+            MiniVisitedUserVo vo = new MiniVisitedUserVo();
+            vo.setId(user.getId());
+            vo.setRealName(resolveUserName(user));
+            vo.setDeptName(user.getDeptId() == null ? null : deptNameMap.get(user.getDeptId()));
+            result.add(vo);
+        }
+        return result;
+    }
+
+    private List<Long> parseCommaSeparatedIds(String raw) {
+        if (!StringUtils.hasText(raw)) {
+            return List.of();
+        }
+        LinkedHashSet<Long> out = new LinkedHashSet<>();
+        for (String part : raw.split(",")) {
+            if (!StringUtils.hasText(part)) {
+                continue;
+            }
+            try {
+                long id = Long.parseLong(part.trim());
+                if (id > 0) {
+                    out.add(id);
+                }
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return new ArrayList<>(out);
+    }
+
     private String calcNodeStatus(List<ApprovalFlowGroupVo> groups) {
         if (groups.isEmpty()) {
             return ApprovalTaskStatus.WAITING;
         }
         boolean hasRejected = false;
+        boolean hasCancelled = false;
         boolean hasPending = false;
         boolean hasWaiting = false;
         for (ApprovalFlowGroupVo g : groups) {
             String s = g.getGroupStatus();
             if (ApprovalTaskStatus.REJECTED.equals(s)) {
                 hasRejected = true;
+            } else if (ApprovalTaskStatus.CANCELLED.equals(s)) {
+                hasCancelled = true;
             } else if (ApprovalTaskStatus.PENDING.equals(s)) {
                 hasPending = true;
             } else if (ApprovalTaskStatus.WAITING.equals(s)) {
@@ -313,6 +482,9 @@
         }
         if (hasRejected) {
             return ApprovalTaskStatus.REJECTED;
+        }
+        if (hasCancelled) {
+            return ApprovalTaskStatus.CANCELLED;
         }
         if (hasPending) {
             return ApprovalTaskStatus.PENDING;
@@ -328,11 +500,14 @@
             return ApprovalTaskStatus.WAITING;
         }
         boolean hasRejected = false;
+        boolean hasCancelled = false;
         boolean hasPending = false;
         boolean hasWaiting = false;
         for (ApprovalTask t : tasks) {
             if (ApprovalTaskStatus.REJECTED.equals(t.getTaskStatus())) {
                 hasRejected = true;
+            } else if (ApprovalTaskStatus.CANCELLED.equals(t.getTaskStatus())) {
+                hasCancelled = true;
             } else if (ApprovalTaskStatus.PENDING.equals(t.getTaskStatus())) {
                 hasPending = true;
             } else if (ApprovalTaskStatus.WAITING.equals(t.getTaskStatus())) {
@@ -342,6 +517,9 @@
         if (hasRejected) {
             return ApprovalTaskStatus.REJECTED;
         }
+        if (hasCancelled) {
+            return ApprovalTaskStatus.CANCELLED;
+        }
         if (hasPending) {
             return ApprovalTaskStatus.PENDING;
         }

--
Gitblit v1.7.1