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/IntegrationWechatService.java |  295 +++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 187 insertions(+), 108 deletions(-)

diff --git a/backend/src/main/java/com/sinata/appointment/service/IntegrationWechatService.java b/backend/src/main/java/com/sinata/appointment/service/IntegrationWechatService.java
index 09fad61..940cdec 100644
--- a/backend/src/main/java/com/sinata/appointment/service/IntegrationWechatService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/IntegrationWechatService.java
@@ -6,11 +6,13 @@
 import com.sinata.appointment.constants.ApprovalNodeCode;
 import com.sinata.appointment.constants.ApprovalTaskStatus;
 import com.sinata.appointment.entity.ApprovalTask;
+import com.sinata.appointment.entity.AppointmentVisitor;
 import com.sinata.appointment.entity.AppointmentOrder;
 import com.sinata.appointment.entity.BizVisitReason;
 import com.sinata.appointment.entity.MpUser;
 import com.sinata.appointment.integration.WechatMiniGateway;
 import com.sinata.appointment.mapper.ApprovalTaskMapper;
+import com.sinata.appointment.mapper.AppointmentVisitorMapper;
 import com.sinata.appointment.mapper.BizVisitReasonMapper;
 import com.sinata.appointment.mapper.MpUserMapper;
 import java.time.LocalDate;
@@ -19,6 +21,7 @@
 import java.util.Map;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
@@ -31,12 +34,12 @@
 public class IntegrationWechatService {
 
     private static final String APPROVAL_RESULT_TEMPLATE_ID =
-            "4FQovCBNFM7rth42AWHTusHajO788eT9VpplSN4ZG2s";
+            "rIJpfN51_q818RTpJAqTe5ssTwWCHnxDM5rpq64uuKM";
     private static final String NOTICE_RESULT_TEMPLATE_ID =
-            "GC1S3T2qHCbz8ow130u7elRczuqW6Z8q54mKRCYE-xo";
+            "Wip0ODJgybZpeFpcvev_0GK1wQXEqZw-LHOjS-UyDLw";
     private static final String APPROVAL_RESULT_PAGE = "pages/record/index";
     private static final String APPROVAL_TODO_TEMPLATE_ID =
-            "BX49OBHvRcoYiCw0ZLqx04BiWQ9KaEQwuVth_Lh_M2A";
+            "QlNwG99WXWztRDgtlLcE0fHxfY2VwaX8PRMrwGpEync";
     private static final String APPROVAL_TODO_PAGE = "pages/reviewList/index";
     private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
     private static final DateTimeFormatter TEMPLATE_TIME_FORMATTER =
@@ -45,115 +48,177 @@
     private final WechatMiniGateway wechatMiniGateway;
     private final MpUserMapper mpUserMapper;
     private final ApprovalTaskMapper approvalTaskMapper;
+    private final AppointmentVisitorMapper appointmentVisitorMapper;
     private final BizVisitReasonMapper bizVisitReasonMapper;
 
+    @Async
     public void notifyApprovalFinalResult(AppointmentOrder order, boolean approved) {
-        if (order == null || order.getSubmitterId() == null) {
-            return;
-        }
-        MpUser submitter =
-                mpUserMapper.selectOne(
-                        new LambdaQueryWrapper<MpUser>()
-                                .eq(MpUser::getDelFlag, 0)
-                                .eq(MpUser::getId, order.getSubmitterId())
-                                .last("limit 1"));
-        if (submitter == null || !StringUtils.hasText(submitter.getOpenId())) {
-            log.info(
-                    "Skip mini subscribe notify, submitter not found or openId empty. submitterId={} orderNo={}",
-                    order.getSubmitterId(),
-                    order.getOrderNo());
-            return;
-        }
-        Map<String, String> templateData = new LinkedHashMap<>();
-        templateData.put("thing1", approved ? "审核通过" : "审核未通过");
-        templateData.put("thing2", abbreviate(resolveSubmitterName(submitter), 20));
-        templateData.put("time3", buildVisitTemplateTimeValue(order));
-        templateData.put("thing4", abbreviate(buildVisitReasonText(order), 20));
-        wechatMiniGateway.sendSubscribeMessage(
-                submitter.getOpenId(), APPROVAL_RESULT_TEMPLATE_ID, APPROVAL_RESULT_PAGE, templateData);
-        log.info(
-                "Mini subscribe notify sent submitterId={} orderNo={} result={}",
-                order.getSubmitterId(),
-                order.getOrderNo(),
-                approved ? AppointmentOrderStatus.APPROVED : AppointmentOrderStatus.REJECTED);
-    }
-
-    public void notifyApprovalNoticeUsers(
-            AppointmentOrder order, boolean approved, java.util.Collection<MpUser> noticeUsers, int visitorCount) {
-        if (order == null || noticeUsers == null || noticeUsers.isEmpty()) {
-            return;
-        }
-        Map<String, String> templateData = new LinkedHashMap<>();
-        templateData.put("thing6", buildVisitorCountText(visitorCount));
-        templateData.put("time18", buildVisitTemplateTimeValue(order));
-        templateData.put("thing20", abbreviate(buildNoticeBusinessTypeText(order, approved), 20));
-        for (MpUser noticeUser : noticeUsers) {
-            if (noticeUser == null || !StringUtils.hasText(noticeUser.getOpenId())) {
-                continue;
+        try {
+            if (order == null || order.getSubmitterId() == null) {
+                log.info("Mini subscribe final result skipped, order or submitter empty. orderId={}",
+                        order == null ? null : order.getId());
+                return;
             }
-            wechatMiniGateway.sendSubscribeMessage(
-                    noticeUser.getOpenId(), NOTICE_RESULT_TEMPLATE_ID, APPROVAL_RESULT_PAGE, templateData);
-            log.info(
-                    "Mini subscribe notice sent noticeUserId={} orderNo={} result={}",
-                    noticeUser.getId(),
-                    order.getOrderNo(),
-                    approved ? AppointmentOrderStatus.APPROVED : AppointmentOrderStatus.REJECTED);
-        }
-    }
-
-    public void notifyCurrentApprovers(AppointmentOrder order, Long instanceId) {
-        if (order == null || instanceId == null) {
-            return;
-        }
-        java.util.List<ApprovalTask> pendingTasks =
-                approvalTaskMapper.selectList(
-                        new LambdaQueryWrapper<ApprovalTask>()
-                                .eq(ApprovalTask::getDelFlag, 0)
-                                .eq(ApprovalTask::getInstanceId, instanceId)
-                                .eq(ApprovalTask::getTaskStatus, ApprovalTaskStatus.PENDING)
-                                .orderByAsc(ApprovalTask::getId));
-        if (pendingTasks.isEmpty()) {
-            return;
-        }
-        java.util.LinkedHashMap<Long, java.util.LinkedHashSet<String>> userNodeNames = new java.util.LinkedHashMap<>();
-        for (ApprovalTask task : pendingTasks) {
-            if (task.getAssigneeUserId() == null) {
-                continue;
-            }
-            userNodeNames.computeIfAbsent(task.getAssigneeUserId(), key -> new java.util.LinkedHashSet<>());
-            userNodeNames.get(task.getAssigneeUserId()).add(resolveNodeName(task.getNodeCode()));
-        }
-        if (userNodeNames.isEmpty()) {
-            return;
-        }
-        java.util.List<MpUser> users =
-                mpUserMapper.selectList(
-                        new LambdaQueryWrapper<MpUser>()
-                                .eq(MpUser::getDelFlag, 0)
-                                .in(MpUser::getId, userNodeNames.keySet()));
-        java.util.Map<Long, MpUser> userMap = new java.util.LinkedHashMap<>();
-        for (MpUser user : users) {
-            userMap.putIfAbsent(user.getId(), user);
-        }
-        for (java.util.Map.Entry<Long, java.util.LinkedHashSet<String>> entry : userNodeNames.entrySet()) {
-            MpUser user = userMap.get(entry.getKey());
-            if (user == null || !StringUtils.hasText(user.getOpenId())) {
-                continue;
+            MpUser submitter =
+                    mpUserMapper.selectOne(
+                            new LambdaQueryWrapper<MpUser>()
+                                    .eq(MpUser::getDelFlag, 0)
+                                    .eq(MpUser::getId, order.getSubmitterId())
+                                    .last("limit 1"));
+            if (submitter == null || !StringUtils.hasText(submitter.getOpenId())) {
+                log.info(
+                        "Mini subscribe final result skipped, submitter not found or openId empty. submitterId={} orderNo={}",
+                        order.getSubmitterId(),
+                        order.getOrderNo());
+                return;
             }
             Map<String, String> templateData = new LinkedHashMap<>();
-            templateData.put("thing1", abbreviate(buildTodoTaskName(order), 20));
-            templateData.put("thing3", abbreviate(String.join("、", entry.getValue()), 20));
+            templateData.put("phrase4", approved ? "通过" : "未通过");
+            templateData.put("time2", buildVisitTemplateTimeValue(order));
+            templateData.put("thing5", approved ? "预约审核通过" : "预约审核未通过");
             wechatMiniGateway.sendSubscribeMessage(
-                    user.getOpenId(), APPROVAL_TODO_TEMPLATE_ID, APPROVAL_TODO_PAGE, templateData);
+                    submitter.getOpenId(), APPROVAL_RESULT_TEMPLATE_ID, APPROVAL_RESULT_PAGE, templateData);
             log.info(
-                    "Mini subscribe todo notify sent approverId={} orderNo={} stages={}",
-                    user.getId(),
+                    "Mini subscribe final result success. submitterId={} orderNo={} result={}",
+                    order.getSubmitterId(),
                     order.getOrderNo(),
-                    entry.getValue());
+                    approved ? AppointmentOrderStatus.APPROVED : AppointmentOrderStatus.REJECTED);
+        } catch (Exception ex) {
+            log.warn("Mini subscribe final result failed. orderId={} orderNo={}",
+                    order == null ? null : order.getId(), order == null ? null : order.getOrderNo(), ex);
+        }
+    }
+
+    @Async
+    public void notifyApprovalNoticeUsers(
+            AppointmentOrder order, boolean approved, java.util.Collection<MpUser> noticeUsers, int visitorCount) {
+        try {
+            if (order == null || noticeUsers == null || noticeUsers.isEmpty()) {
+                log.info("Mini subscribe notice skipped, order or notice users empty. orderId={}",
+                        order == null ? null : order.getId());
+                return;
+            }
+            Map<String, String> templateData = new LinkedHashMap<>();
+            MpUser submitter = loadSubmitter(order);
+            templateData.put("name1", abbreviate(resolveSubmitterName(submitter), 10));
+            templateData.put("number36", buildVisitorCountNumber(visitorCount));
+            templateData.put("date3", buildVisitTemplateTimeValue(order));
+            int successCount = 0;
+            int skippedCount = 0;
+            int failedCount = 0;
+            for (MpUser noticeUser : noticeUsers) {
+                if (noticeUser == null || !StringUtils.hasText(noticeUser.getOpenId())) {
+                    skippedCount++;
+                    continue;
+                }
+                try {
+                    wechatMiniGateway.sendSubscribeMessage(
+                            noticeUser.getOpenId(), NOTICE_RESULT_TEMPLATE_ID, APPROVAL_RESULT_PAGE, templateData);
+                    successCount++;
+                    log.info(
+                            "Mini subscribe notice success. noticeUserId={} orderNo={} result={}",
+                            noticeUser.getId(),
+                            order.getOrderNo(),
+                            approved ? AppointmentOrderStatus.APPROVED : AppointmentOrderStatus.REJECTED);
+                } catch (Exception ex) {
+                    failedCount++;
+                    log.warn("Mini subscribe notice failed. noticeUserId={} orderId={} orderNo={}",
+                            noticeUser.getId(), order.getId(), order.getOrderNo(), ex);
+                }
+            }
+            log.info("Mini subscribe notice completed. orderId={} orderNo={} success={} skipped={} failed={}",
+                    order.getId(), order.getOrderNo(), successCount, skippedCount, failedCount);
+        } catch (Exception ex) {
+            log.warn("Mini subscribe notice batch failed. orderId={} orderNo={}",
+                    order == null ? null : order.getId(), order == null ? null : order.getOrderNo(), ex);
+        }
+    }
+
+    @Async
+    public void notifyCurrentApprovers(AppointmentOrder order, Long instanceId) {
+        try {
+            if (order == null || instanceId == null) {
+                log.info("Mini subscribe todo skipped, order or instance empty. orderId={} instanceId={}",
+                        order == null ? null : order.getId(), instanceId);
+                return;
+            }
+            java.util.List<ApprovalTask> pendingTasks =
+                    approvalTaskMapper.selectList(
+                            new LambdaQueryWrapper<ApprovalTask>()
+                                    .eq(ApprovalTask::getDelFlag, 0)
+                                    .eq(ApprovalTask::getInstanceId, instanceId)
+                                    .eq(ApprovalTask::getTaskStatus, ApprovalTaskStatus.PENDING)
+                                    .orderByAsc(ApprovalTask::getId));
+            if (pendingTasks.isEmpty()) {
+                log.info("Mini subscribe todo skipped, no pending tasks. orderId={} instanceId={}",
+                        order.getId(), instanceId);
+                return;
+            }
+            java.util.LinkedHashMap<Long, java.util.LinkedHashSet<String>> userNodeNames =
+                    new java.util.LinkedHashMap<>();
+            for (ApprovalTask task : pendingTasks) {
+                if (task.getAssigneeUserId() == null) {
+                    continue;
+                }
+                userNodeNames.computeIfAbsent(task.getAssigneeUserId(), key -> new java.util.LinkedHashSet<>());
+                userNodeNames.get(task.getAssigneeUserId()).add(resolveNodeName(task.getNodeCode()));
+            }
+            if (userNodeNames.isEmpty()) {
+                log.info("Mini subscribe todo skipped, no assignee users. orderId={} instanceId={}",
+                        order.getId(), instanceId);
+                return;
+            }
+            java.util.List<MpUser> users =
+                    mpUserMapper.selectList(
+                            new LambdaQueryWrapper<MpUser>()
+                                    .eq(MpUser::getDelFlag, 0)
+                                    .in(MpUser::getId, userNodeNames.keySet()));
+            java.util.Map<Long, MpUser> userMap = new java.util.LinkedHashMap<>();
+            for (MpUser user : users) {
+                userMap.putIfAbsent(user.getId(), user);
+            }
+            int successCount = 0;
+            int skippedCount = 0;
+            int failedCount = 0;
+            for (java.util.Map.Entry<Long, java.util.LinkedHashSet<String>> entry : userNodeNames.entrySet()) {
+                MpUser user = userMap.get(entry.getKey());
+                if (user == null || !StringUtils.hasText(user.getOpenId())) {
+                    skippedCount++;
+                    continue;
+                }
+                Map<String, String> templateData = new LinkedHashMap<>();
+                MpUser submitter = loadSubmitter(order);
+                templateData.put("name1", abbreviate(resolveSubmitterName(submitter), 10));
+                templateData.put("number15", buildVisitorCountNumber(countVisitors(order)));
+                templateData.put("time16", buildVisitTemplateTimeValue(order));
+                templateData.put("thing5", abbreviate(buildVisitReasonText(order), 20));
+                try {
+                    wechatMiniGateway.sendSubscribeMessage(
+                            user.getOpenId(), APPROVAL_TODO_TEMPLATE_ID, APPROVAL_TODO_PAGE, templateData);
+                    successCount++;
+                    log.info(
+                            "Mini subscribe todo success. approverId={} orderNo={} stages={}",
+                            user.getId(),
+                            order.getOrderNo(),
+                            entry.getValue());
+                } catch (Exception ex) {
+                    failedCount++;
+                    log.warn("Mini subscribe todo failed. approverId={} orderId={} orderNo={} stages={}",
+                            user.getId(), order.getId(), order.getOrderNo(), entry.getValue(), ex);
+                }
+            }
+            log.info("Mini subscribe todo completed. orderId={} orderNo={} success={} skipped={} failed={}",
+                    order.getId(), order.getOrderNo(), successCount, skippedCount, failedCount);
+        } catch (Exception ex) {
+            log.warn("Mini subscribe todo batch failed. orderId={} instanceId={}",
+                    order == null ? null : order.getId(), instanceId, ex);
         }
     }
 
     private String resolveSubmitterName(MpUser submitter) {
+        if (submitter == null) {
+            return "预约人";
+        }
         if (StringUtils.hasText(submitter.getNickName())) {
             return submitter.getNickName().trim();
         }
@@ -161,6 +226,17 @@
             return submitter.getMobile().trim();
         }
         return "预约人";
+    }
+
+    private MpUser loadSubmitter(AppointmentOrder order) {
+        if (order == null || order.getSubmitterId() == null) {
+            return null;
+        }
+        return mpUserMapper.selectOne(
+                new LambdaQueryWrapper<MpUser>()
+                        .eq(MpUser::getDelFlag, 0)
+                        .eq(MpUser::getId, order.getSubmitterId())
+                        .last("limit 1"));
     }
 
     private String buildVisitTimeText(AppointmentOrder order) {
@@ -206,8 +282,7 @@
             return "拜访";
         }
         if (AppointmentBizConstants.VISIT_REASON_OTHER.equalsIgnoreCase(reasonCode)) {
-            String other = safeTrim(order.getVisitReasonOther());
-            return StringUtils.hasText(other) ? "其他:" + other : "其他";
+            return "其他";
         }
         BizVisitReason reason =
                 bizVisitReasonMapper.selectOne(
@@ -221,16 +296,20 @@
         return reasonCode;
     }
 
-    private String buildVisitorCountText(int visitorCount) {
-        return Math.max(visitorCount, 0) + "人";
+    private String buildVisitorCountNumber(int visitorCount) {
+        return String.valueOf(Math.max(visitorCount, 0));
     }
 
-    private String buildNoticeBusinessTypeText(AppointmentOrder order, boolean approved) {
-        String reason = buildVisitReasonText(order);
-        if (!StringUtils.hasText(reason)) {
-            return approved ? "预约通过" : "预约驳回";
+    private int countVisitors(AppointmentOrder order) {
+        if (order == null || order.getId() == null) {
+            return 0;
         }
-        return reason;
+        Long count =
+                appointmentVisitorMapper.selectCount(
+                        new LambdaQueryWrapper<AppointmentVisitor>()
+                                .eq(AppointmentVisitor::getDelFlag, 0)
+                                .eq(AppointmentVisitor::getOrderId, order.getId()));
+        return count == null ? 0 : count.intValue();
     }
 
     private String buildTodoTaskName(AppointmentOrder order) {

--
Gitblit v1.7.1