longz
2026-04-27 25df88d0ab9d7444ed1d162b9efa1259ac2f6f66
backend/src/main/java/com/sinata/appointment/service/PostApprovalOrchestrationService.java
@@ -8,6 +8,7 @@
import com.sinata.appointment.constants.QrcodeTicketStatus;
import com.sinata.appointment.constants.SystemSettingKeys;
import com.sinata.appointment.entity.ApprovalInstance;
import com.sinata.appointment.entity.ApprovalTask;
import com.sinata.appointment.entity.AppointmentOrder;
import com.sinata.appointment.entity.AppointmentVisitor;
import com.sinata.appointment.entity.BizVisitReason;
@@ -17,6 +18,7 @@
import com.sinata.appointment.mapper.AppointmentOrderMapper;
import com.sinata.appointment.mapper.AppointmentVisitorMapper;
import com.sinata.appointment.mapper.ApprovalInstanceMapper;
import com.sinata.appointment.mapper.ApprovalTaskMapper;
import com.sinata.appointment.mapper.BizVisitReasonMapper;
import com.sinata.appointment.mapper.MpUserMapper;
import com.sinata.appointment.mapper.MpVisitorMapper;
@@ -30,6 +32,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -51,6 +54,7 @@
    private final QrcodeTicketMapper qrcodeTicketMapper;
    private final AppointmentOrderMapper appointmentOrderMapper;
    private final ApprovalInstanceMapper approvalInstanceMapper;
    private final ApprovalTaskMapper approvalTaskMapper;
    private final AppointmentVisitorMapper appointmentVisitorMapper;
    private final MpVisitorMapper mpVisitorMapper;
    private final MpUserMapper mpUserMapper;
@@ -147,6 +151,8 @@
        try {
            integrationWechatService.notifyApprovalFinalResult(order, true);
            integrationWechatService.notifyApprovalNoticeUsers(
                    order, true, loadNoticeUsers(latestInstance.getId()), visitors.size());
        } catch (Exception e) {
            log.warn("{} orderId={} failed: {}", IntegrationConstant.WECHAT_NOTIFY_EVENT, order.getId(), e.getMessage());
        }
@@ -164,6 +170,16 @@
        appointmentOrderMapper.updateById(order);
        try {
            integrationWechatService.notifyApprovalFinalResult(order, false);
            ApprovalInstance latestInstance = loadLatestInstance(order.getId());
            if (latestInstance != null) {
                List<AppointmentVisitor> visitors =
                        appointmentVisitorMapper.selectList(
                                new LambdaQueryWrapper<AppointmentVisitor>()
                                        .eq(AppointmentVisitor::getDelFlag, 0)
                                        .eq(AppointmentVisitor::getOrderId, order.getId()));
                integrationWechatService.notifyApprovalNoticeUsers(
                        order, false, loadNoticeUsers(latestInstance.getId()), visitors.size());
            }
        } catch (Exception e) {
            log.warn(
                    "{} orderId={} failed: {}",
@@ -173,6 +189,72 @@
        }
    }
    private ApprovalInstance loadLatestInstance(Long orderId) {
        if (orderId == null) {
            return null;
        }
        return approvalInstanceMapper.selectOne(
                new LambdaQueryWrapper<ApprovalInstance>()
                        .eq(ApprovalInstance::getDelFlag, 0)
                        .eq(ApprovalInstance::getOrderId, orderId)
                        .orderByDesc(ApprovalInstance::getId)
                        .last("limit 1"));
    }
    private List<MpUser> loadNoticeUsers(Long instanceId) {
        if (instanceId == null) {
            return List.of();
        }
        List<ApprovalTask> tasks =
                approvalTaskMapper.selectList(
                        new LambdaQueryWrapper<ApprovalTask>()
                                .eq(ApprovalTask::getDelFlag, 0)
                                .eq(ApprovalTask::getInstanceId, instanceId)
                                .isNotNull(ApprovalTask::getNoticeIds)
                                .ne(ApprovalTask::getNoticeIds, "")
                                .orderByAsc(ApprovalTask::getId));
        if (tasks.isEmpty()) {
            return List.of();
        }
        LinkedHashSet<Long> noticeUserIds = new LinkedHashSet<>();
        for (ApprovalTask task : tasks) {
            noticeUserIds.addAll(parseCommaSeparatedIds(task.getNoticeIds()));
        }
        if (noticeUserIds.isEmpty()) {
            return List.of();
        }
        List<MpUser> users =
                mpUserMapper.selectList(
                        new LambdaQueryWrapper<MpUser>()
                                .eq(MpUser::getDelFlag, 0)
                                .in(MpUser::getId, noticeUserIds));
        Map<Long, MpUser> userMap = new LinkedHashMap<>();
        for (MpUser user : users) {
            userMap.putIfAbsent(user.getId(), user);
        }
        return noticeUserIds.stream().map(userMap::get).filter(Objects::nonNull).toList();
    }
    private List<Long> parseCommaSeparatedIds(String raw) {
        if (!StringUtils.hasText(raw)) {
            return List.of();
        }
        return Stream.of(raw.split(","))
                .filter(StringUtils::hasText)
                .map(String::trim)
                .map(value -> {
                    try {
                        return Long.parseLong(value);
                    } catch (NumberFormatException ex) {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .filter(id -> id > 0)
                .distinct()
                .toList();
    }
    private Map<Long, MpVisitor> loadVisitorProfileMap(List<AppointmentVisitor> visitors) {
        if (visitors == null || visitors.isEmpty()) {
            return Map.of();