From 11029948d45564975527b2c21e9c2def1903164a Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期四, 14 五月 2026 14:30:23 +0800
Subject: [PATCH] 优化fix
---
backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java | 204 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 194 insertions(+), 10 deletions(-)
diff --git a/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java
index 6eb5035..9ce707b 100644
--- a/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/MiniHandlerApprovalApplicationService.java
@@ -15,16 +15,24 @@
import com.sinata.appointment.dto.MiniHandlerApprovalActionRequest;
import com.sinata.appointment.dto.MiniHandlerApprovalTodoVo;
import com.sinata.appointment.entity.AppointmentOrder;
+import com.sinata.appointment.entity.AppointmentVehicle;
+import com.sinata.appointment.entity.AppointmentVisitor;
import com.sinata.appointment.entity.ApprovalInstance;
import com.sinata.appointment.entity.ApprovalTask;
import com.sinata.appointment.entity.BizApprovalNodeConfig;
+import com.sinata.appointment.entity.BizVisitReason;
import com.sinata.appointment.entity.MpPassAccessArea;
import com.sinata.appointment.entity.MpPassLocalUnit;
+import com.sinata.appointment.entity.MpVisitor;
import com.sinata.appointment.exception.BizException;
import com.sinata.appointment.mapper.AppointmentOrderMapper;
+import com.sinata.appointment.mapper.AppointmentVehicleMapper;
+import com.sinata.appointment.mapper.AppointmentVisitorMapper;
import com.sinata.appointment.mapper.ApprovalInstanceMapper;
import com.sinata.appointment.mapper.ApprovalTaskMapper;
import com.sinata.appointment.mapper.BizApprovalNodeConfigMapper;
+import com.sinata.appointment.mapper.BizVisitReasonMapper;
+import com.sinata.appointment.mapper.MpVisitorMapper;
import com.sinata.appointment.mapper.MpPassAccessAreaMapper;
import com.sinata.appointment.mapper.MpPassLocalUnitMapper;
import java.time.LocalDate;
@@ -33,8 +41,10 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.stream.Stream;
import java.util.stream.Collectors;
+import java.util.LinkedHashMap;
import lombok.extern.slf4j.Slf4j;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -50,6 +60,10 @@
private final ApprovalTaskMapper approvalTaskMapper;
private final ApprovalInstanceMapper approvalInstanceMapper;
private final AppointmentOrderMapper appointmentOrderMapper;
+ private final AppointmentVisitorMapper appointmentVisitorMapper;
+ private final AppointmentVehicleMapper appointmentVehicleMapper;
+ private final MpVisitorMapper mpVisitorMapper;
+ private final BizVisitReasonMapper bizVisitReasonMapper;
private final ApprovalEngineService approvalEngineService;
private final IntegrationWechatService integrationWechatService;
private final PostApprovalOrchestrationService postApprovalOrchestrationService;
@@ -87,11 +101,14 @@
.filter(Objects::nonNull)
.toList();
Map<Long, AppointmentOrder> orderMap = loadOrderMap(orderIds);
+ Map<Long, String> visitorDisplayMap = loadVisitorDisplayMap(orderIds);
+ Map<Long, String> plateTextMap = loadPlateTextMap(orderIds);
+ Map<String, String> reasonNameMap = loadReasonNameMap(orderMap.values());
Map<String, String> nodeNameMap = loadNodeNameMap();
List<MiniApprovalTodoVo> rowsAll =
tasks.stream()
- .filter(t -> matchTodoFilters(t, instanceMap, orderMap, visitedUserNameKeyword, visitDate))
- .map(t -> toMiniTodoVo(t, instanceMap, orderMap, nodeNameMap))
+ .filter(t -> matchTodoFilters(t, instanceMap, orderMap, visitorDisplayMap, visitedUserNameKeyword, visitDate))
+ .map(t -> toMiniTodoVo(t, instanceMap, orderMap, nodeNameMap, visitorDisplayMap, plateTextMap, reasonNameMap))
.toList();
return slicePage(page, size, rowsAll);
}
@@ -126,9 +143,10 @@
.filter(Objects::nonNull)
.toList();
Map<Long, AppointmentOrder> orderMap = loadOrderMap(orderIds);
+ Map<Long, String> visitorDisplayMap = loadVisitorDisplayMap(orderIds);
List<MiniHandlerApprovalTodoVo> rowsAll =
tasks.stream()
- .filter(t -> matchTodoFilters(t, instanceMap, orderMap, visitedUserNameKeyword, visitDate))
+ .filter(t -> matchTodoFilters(t, instanceMap, orderMap, visitorDisplayMap, visitedUserNameKeyword, visitDate))
.map(t -> toTodoVo(t, instanceMap, orderMap))
.toList();
return slicePage(page, size, rowsAll);
@@ -151,10 +169,7 @@
if (!Objects.equals(task.getAssigneeUserId(), uid)) {
throw new BizException(BizErrorCode.AUTH_FORBIDDEN, "无权处理该任务");
}
- String comment = req.getComment().trim();
- if (!StringUtils.hasText(comment)) {
- throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "审批意见不能为空");
- }
+ String comment = req.getComment() == null ? null : req.getComment().trim();
ApprovalInstance inst = approvalInstanceMapper.selectById(task.getInstanceId());
if (inst == null || (inst.getDelFlag() != null && inst.getDelFlag() == 1)) {
@@ -166,6 +181,10 @@
}
if (Boolean.FALSE.equals(req.getApprove())) {
+ if (!StringUtils.hasText(comment)) {
+ throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "审批意见不能为空");
+ }
+ validateRejectCommentLength(comment);
task.setTaskStatus(ApprovalTaskStatus.REJECTED);
task.setComment(comment);
approvalTaskMapper.updateById(task);
@@ -227,6 +246,9 @@
String comment = req.getComment() == null ? null : req.getComment().trim();
appendNoticeIdsIfNeeded(task, req.getNoticeIds());
if (Boolean.FALSE.equals(req.getApprove())) {
+ if (StringUtils.hasText(comment)) {
+ validateRejectCommentLength(comment);
+ }
String reason = StringUtils.hasText(comment) ? comment : "拒绝";
task.setTaskStatus(ApprovalTaskStatus.REJECTED);
task.setComment(reason);
@@ -358,7 +380,10 @@
ApprovalTask task,
Map<Long, ApprovalInstance> instanceMap,
Map<Long, AppointmentOrder> orderMap,
- Map<String, String> nodeNameMap) {
+ Map<String, String> nodeNameMap,
+ Map<Long, String> visitorDisplayMap,
+ Map<Long, String> plateTextMap,
+ Map<String, String> reasonNameMap) {
MiniApprovalTodoVo vo = new MiniApprovalTodoVo();
vo.setTaskId(task.getId());
vo.setTaskUuid(task.getUuid());
@@ -377,9 +402,13 @@
vo.setOrderUuid(order.getUuid());
vo.setOrderNo(order.getOrderNo());
vo.setVisitedUserName(order.getVisitedUserName());
+ vo.setVisitorDisplayText(visitorDisplayMap.get(order.getId()));
+ vo.setPlateNoText(plateTextMap.get(order.getId()));
vo.setVisitStartDate(order.getVisitStartDate());
vo.setVisitEndDate(order.getVisitEndDate());
vo.setVisitReasonCode(order.getVisitReasonCode());
+ vo.setVisitReasonText(buildVisitReasonText(order, reasonNameMap));
+ vo.setVisitTimeText(buildVisitTimeText(order));
return vo;
}
@@ -453,6 +482,12 @@
return out.stream().toList();
}
+ private void validateRejectCommentLength(String comment) {
+ if (comment.length() > 30) {
+ throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "驳回原因最多30个字");
+ }
+ }
+
private String writeJson(Object value) {
try {
return objectMapper.writeValueAsString(value);
@@ -465,6 +500,7 @@
ApprovalTask task,
Map<Long, ApprovalInstance> instanceMap,
Map<Long, AppointmentOrder> orderMap,
+ Map<Long, String> visitorDisplayMap,
String visitedUserNameKeyword,
LocalDate visitDate) {
ApprovalInstance inst = instanceMap.get(task.getInstanceId());
@@ -476,8 +512,9 @@
return false;
}
if (StringUtils.hasText(visitedUserNameKeyword)) {
- String name = order.getVisitedUserName();
- if (!StringUtils.hasText(name) || !name.contains(visitedUserNameKeyword.trim())) {
+ String keyword = visitedUserNameKeyword.trim();
+ String visitorDisplayText = visitorDisplayMap.get(order.getId());
+ if (!StringUtils.hasText(visitorDisplayText) || !visitorDisplayText.contains(keyword)) {
return false;
}
}
@@ -492,6 +529,153 @@
return true;
}
+ private Map<Long, String> loadVisitorDisplayMap(List<Long> orderIds) {
+ if (orderIds == null || orderIds.isEmpty()) {
+ return Map.of();
+ }
+ List<AppointmentVisitor> rows =
+ appointmentVisitorMapper.selectList(
+ new LambdaQueryWrapper<AppointmentVisitor>()
+ .eq(AppointmentVisitor::getDelFlag, 0)
+ .in(AppointmentVisitor::getOrderId, orderIds)
+ .orderByAsc(AppointmentVisitor::getId));
+ Set<Long> visitorIds =
+ rows.stream()
+ .map(AppointmentVisitor::getMpVisitorId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ Map<Long, String> companyMap = loadVisitorCompanyMap(visitorIds);
+ Map<Long, List<String>> grouped = new LinkedHashMap<>();
+ for (AppointmentVisitor row : rows) {
+ if (row.getOrderId() == null) {
+ continue;
+ }
+ String name = trimToNull(row.getName());
+ if (!StringUtils.hasText(name)) {
+ continue;
+ }
+ String company = companyMap.get(row.getMpVisitorId());
+ String display = StringUtils.hasText(company) ? name + "(" + company + ")" : name;
+ grouped.computeIfAbsent(row.getOrderId(), key -> new ArrayList<>()).add(display);
+ }
+ Map<Long, String> result = new LinkedHashMap<>();
+ for (Map.Entry<Long, List<String>> entry : grouped.entrySet()) {
+ String joined = entry.getValue().stream().distinct().collect(Collectors.joining(","));
+ if (StringUtils.hasText(joined)) {
+ result.put(entry.getKey(), joined);
+ }
+ }
+ return result;
+ }
+
+ private Map<Long, String> loadVisitorCompanyMap(Set<Long> visitorIds) {
+ if (visitorIds == null || visitorIds.isEmpty()) {
+ return Map.of();
+ }
+ List<MpVisitor> rows =
+ mpVisitorMapper.selectList(
+ new LambdaQueryWrapper<MpVisitor>()
+ .eq(MpVisitor::getDelFlag, 0)
+ .in(MpVisitor::getId, visitorIds));
+ Map<Long, String> result = new LinkedHashMap<>();
+ for (MpVisitor row : rows) {
+ result.put(row.getId(), trimToNull(row.getVisitorCompany()));
+ }
+ return result;
+ }
+
+ private Map<Long, String> loadPlateTextMap(List<Long> orderIds) {
+ if (orderIds == null || orderIds.isEmpty()) {
+ return Map.of();
+ }
+ List<AppointmentVehicle> rows =
+ appointmentVehicleMapper.selectList(
+ new LambdaQueryWrapper<AppointmentVehicle>()
+ .eq(AppointmentVehicle::getDelFlag, 0)
+ .in(AppointmentVehicle::getOrderId, orderIds)
+ .orderByAsc(AppointmentVehicle::getId));
+ Map<Long, List<String>> grouped = new LinkedHashMap<>();
+ for (AppointmentVehicle row : rows) {
+ if (row.getOrderId() == null) {
+ continue;
+ }
+ String plateNo = trimToNull(row.getPlateNo());
+ if (!StringUtils.hasText(plateNo)) {
+ continue;
+ }
+ grouped.computeIfAbsent(row.getOrderId(), key -> new ArrayList<>()).add(plateNo);
+ }
+ Map<Long, String> result = new LinkedHashMap<>();
+ for (Map.Entry<Long, List<String>> entry : grouped.entrySet()) {
+ String joined = entry.getValue().stream().distinct().collect(Collectors.joining(","));
+ if (StringUtils.hasText(joined)) {
+ result.put(entry.getKey(), joined);
+ }
+ }
+ return result;
+ }
+
+ private Map<String, String> loadReasonNameMap(java.util.Collection<AppointmentOrder> orders) {
+ Set<String> codes =
+ orders.stream()
+ .map(AppointmentOrder::getVisitReasonCode)
+ .filter(StringUtils::hasText)
+ .map(String::trim)
+ .filter(code -> !"OTHER".equalsIgnoreCase(code))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ if (codes.isEmpty()) {
+ return Map.of();
+ }
+ List<BizVisitReason> rows =
+ bizVisitReasonMapper.selectList(
+ new LambdaQueryWrapper<BizVisitReason>()
+ .eq(BizVisitReason::getDelFlag, 0)
+ .in(BizVisitReason::getReasonCode, codes));
+ return rows.stream().collect(Collectors.toMap(BizVisitReason::getReasonCode, BizVisitReason::getReasonName, (a, b) -> a));
+ }
+
+ private String buildVisitReasonText(AppointmentOrder order, Map<String, String> reasonNameMap) {
+ String reasonCode = trimToNull(order.getVisitReasonCode());
+ if ("OTHER".equalsIgnoreCase(reasonCode)) {
+ String other = trimToNull(order.getVisitReasonOther());
+ return StringUtils.hasText(other) ? other : "其他";
+ }
+ String reasonName = reasonNameMap.get(reasonCode);
+ return StringUtils.hasText(reasonName) ? reasonName : reasonCode;
+ }
+
+ private String buildVisitTimeText(AppointmentOrder order) {
+ if ("SINGLE".equals(order.getVisitTimeMode())) {
+ String slotLabel = switch (trimToNull(order.getVisitTimeSlot())) {
+ case "ALL_DAY" -> "00:00-23:59";
+ case "AM" -> "00:00-11:59";
+ case "PM" -> "12:00-23:59";
+ default -> "";
+ };
+ if (order.getVisitStartDate() == null) {
+ return slotLabel;
+ }
+ return StringUtils.hasText(slotLabel)
+ ? order.getVisitStartDate() + " " + slotLabel
+ : order.getVisitStartDate().toString();
+ }
+ if (order.getVisitStartDate() == null && order.getVisitEndDate() == null) {
+ return "-";
+ }
+ if (Objects.equals(order.getVisitStartDate(), order.getVisitEndDate()) || order.getVisitEndDate() == null) {
+ return String.valueOf(order.getVisitStartDate());
+ }
+ return order.getVisitStartDate() + " 至 " + order.getVisitEndDate();
+ }
+
+ private String trimToNull(String text) {
+ if (text == null) {
+ return null;
+ }
+ String t = text.trim();
+ return t.isEmpty() ? null : t;
+ }
+
private <T> IPage<T> slicePage(long page, long size, List<T> rowsAll) {
long total = rowsAll == null ? 0 : rowsAll.size();
long current = Math.max(1L, page);
--
Gitblit v1.7.1