From 700f9d0da314a4ea701fe9f68d305b67d72ec5fb Mon Sep 17 00:00:00 2001
From: longz <longzhaoz@qq.com>
Date: 星期三, 08 七月 2026 15:08:37 +0800
Subject: [PATCH] 各类修复fix
---
backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java | 216 +++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 191 insertions(+), 25 deletions(-)
diff --git a/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java b/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java
index 1436d30..6006207 100644
--- a/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java
+++ b/backend/src/main/java/com/sinata/appointment/service/MiniAppointmentApplicationService.java
@@ -14,6 +14,7 @@
import com.sinata.appointment.constants.QrcodeTicketStatus;
import com.sinata.appointment.constants.SystemSettingKeys;
import com.sinata.appointment.dto.MiniAppointmentCreateRequest;
+import com.sinata.appointment.dto.MiniAppointmentCreateResultVo;
import com.sinata.appointment.dto.MiniAppointmentListVo;
import com.sinata.appointment.dto.MiniApprovalHistoryRow;
import com.sinata.appointment.dto.MiniAppointmentVehicleItemRequest;
@@ -72,6 +73,7 @@
import org.springframework.util.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
import com.sinata.appointment.service.event.AppointmentApprovedEvent;
+import com.sinata.appointment.service.event.AppointmentApproversNotifyEvent;
@Slf4j
@Service
@@ -99,14 +101,15 @@
private final BizHolidayDateCacheService bizHolidayDateCacheService;
private final SysBizSettingCacheService sysBizSettingCacheService;
private final ApprovalEngineService approvalEngineService;
- private final IntegrationWechatService integrationWechatService;
private final PostApprovalOrchestrationService postApprovalOrchestrationService;
private final ApprovalFlowViewApplicationService approvalFlowViewApplicationService;
+ private final SensitiveWordFilterService sensitiveWordFilterService;
+ private final IntegrationHikvisionService integrationHikvisionService;
private final ObjectMapper objectMapper;
private final ApplicationEventPublisher applicationEventPublisher;
@Transactional(rollbackFor = Exception.class)
- public Long create(MiniAppointmentCreateRequest req) {
+ public MiniAppointmentCreateResultVo create(MiniAppointmentCreateRequest req) {
MpUser current = miniAuthApplicationService.currentMpUser();
FieldRequiredContext required = loadFieldRequiredContext();
MpUser visited = loadVisitedUser(req.getVisitedUserId());
@@ -148,7 +151,7 @@
order.setVisitedUserName(StringUtils.hasText(visited.getNickName()) ? visited.getNickName() : "员工");
order.setVisitedDeptId(visited.getDeptId());
order.setVisitReasonCode(req.getVisitReasonCode().trim());
- order.setVisitReasonOther(trimToNull(req.getVisitReasonOther()));
+ order.setVisitReasonOther(sensitiveWordFilterService.filter(trimToNull(req.getVisitReasonOther())));
order.setVisitorOrg(resolveVisitorOrg(visitorMap.values()));
order.setVisitTimeMode(mode);
order.setVisitTimeSlot(
@@ -194,14 +197,14 @@
if (inst == null) {
applicationEventPublisher.publishEvent(new AppointmentApprovedEvent(order.getId()));
} else {
- try {
- integrationWechatService.notifyCurrentApprovers(order, inst.getId());
- } catch (Exception ex) {
- log.warn("notify current approvers failed, orderId={}", order.getId(), ex);
- }
+ applicationEventPublisher.publishEvent(
+ new AppointmentApproversNotifyEvent(order.getId(), inst.getId()));
}
}
- return order.getId();
+ MiniAppointmentCreateResultVo result = new MiniAppointmentCreateResultVo();
+ result.setId(order.getId());
+ result.setUuid(order.getUuid());
+ return result;
}
@Transactional(rollbackFor = Exception.class)
@@ -276,6 +279,9 @@
List<AppointmentOrder> orders = rows.stream().map(this::toOrderSnapshot).toList();
Map<Long, String> deptNameMap = loadDeptNameMap(orders);
Map<String, String> reasonNameMap = loadReasonNameMap(orders);
+ List<Long> orderIds = orders.stream().map(AppointmentOrder::getId).filter(Objects::nonNull).toList();
+ Map<Long, String> visitorDisplayMap = loadVisitorDisplayMapByOrderIds(orderIds);
+ Map<Long, String> plateTextMap = loadPlateTextMapByOrderIds(orderIds);
List<MiniAppointmentListVo> records = new ArrayList<>();
for (MiniApprovalHistoryRow row : rows) {
AppointmentOrder order = toOrderSnapshot(row);
@@ -286,6 +292,8 @@
vo.setVisitTimeText(buildVisitTimeText(order));
vo.setVisitReasonText(buildVisitReasonText(order, reasonNameMap));
vo.setAccessAreaText(buildAccessAreaText(order.getPassAccessAreaNames()));
+ vo.setVisitorDisplayText(visitorDisplayMap.get(order.getId()));
+ vo.setPlateNoText(plateTextMap.get(order.getId()));
records.add(vo);
}
result.setRecords(records);
@@ -306,13 +314,20 @@
result.setRecords(List.of());
return result;
}
+ Map<String, String> reasonNameMap = loadReasonNameMap(orders);
+ List<Long> orderIds = orders.stream().map(AppointmentOrder::getId).filter(Objects::nonNull).toList();
Map<Long, List<String>> visitorNamesMap = loadVisitorNamesMap(orders.stream().map(AppointmentOrder::getId).toList());
+ Map<Long, String> visitorDisplayMap = loadVisitorDisplayMapByOrderIds(orderIds);
+ Map<Long, String> plateTextMap = loadPlateTextMapByOrderIds(orderIds);
List<MiniVisitRecordListVo> records = new ArrayList<>();
for (AppointmentOrder order : orders) {
MiniVisitRecordListVo vo = new MiniVisitRecordListVo();
vo.setOrderId(order.getId());
vo.setOrderNo(order.getOrderNo());
vo.setVisitorNames(visitorNamesMap.getOrDefault(order.getId(), List.of()));
+ vo.setVisitorDisplayText(visitorDisplayMap.get(order.getId()));
+ vo.setPlateNoText(plateTextMap.get(order.getId()));
+ vo.setVisitReasonText(buildVisitReasonText(order, reasonNameMap));
vo.setVisitStartDate(order.getVisitStartDate());
vo.setVisitEndDate(order.getVisitEndDate());
vo.setVisitTimeMode(order.getVisitTimeMode());
@@ -387,6 +402,36 @@
return vo;
}
return rows.get(0);
+ }
+
+ public MiniMyVisitorCodeOrderVo getSharedVisitorCodeByTicketUuid(String ticketUuid) {
+ QrcodeTicket ticket = loadTicketByUuid(ticketUuid);
+ AppointmentOrder order = loadApprovedOrderById(ticket.getOrderId());
+ String deptName = loadDeptName(order.getVisitedDeptId());
+
+ MiniMyVisitorCodeOrderVo vo = new MiniMyVisitorCodeOrderVo();
+ vo.setOrderId(order.getId());
+ vo.setOrderUuid(order.getUuid());
+ vo.setVisitedUserDisplay(buildVisitedUserDisplay(order.getVisitedUserName(), deptName));
+ vo.setAccessAreaText(buildAccessAreaText(order.getPassAccessAreaNames()));
+ vo.setVisitTimeText(buildVisitTimeText(order));
+ vo.setValidStartTime(ticket.getGenerateTime());
+ vo.setValidEndTime(ticket.getExpireTime());
+
+ if (!QrcodeTicketStatus.UNUSED.equals(ticket.getTicketStatus())) {
+ vo.setQrCodes(List.of());
+ return vo;
+ }
+
+ Map<Long, MpVisitor> visitorMap =
+ loadMpVisitorMap(
+ ticket.getMpVisitorId() == null
+ ? Set.of()
+ : Set.of(ticket.getMpVisitorId()));
+ List<AppointmentVisitor> orderVisitors =
+ loadOrderVisitorRows(List.of(order.getId())).getOrDefault(order.getId(), List.of());
+ vo.setQrCodes(List.of(toMyVisitorCodeTicketVo(ticket, orderVisitors, visitorMap)));
+ return vo;
}
private List<MiniMyVisitorCodeOrderVo> buildVisitorCodeOrders(
@@ -473,6 +518,40 @@
return order;
}
+ private AppointmentOrder loadApprovedOrderById(Long orderId) {
+ if (orderId == null || orderId <= 0) {
+ throw new BizException(BizErrorCode.ORDER_NOT_FOUND, "预约单不存在");
+ }
+ AppointmentOrder order =
+ appointmentOrderMapper.selectOne(
+ new LambdaQueryWrapper<AppointmentOrder>()
+ .eq(AppointmentOrder::getDelFlag, 0)
+ .eq(AppointmentOrder::getId, orderId)
+ .eq(AppointmentOrder::getStatus, AppointmentOrderStatus.APPROVED)
+ .last("limit 1"));
+ if (order == null) {
+ throw new BizException(BizErrorCode.ORDER_NOT_FOUND, "预约单不存在");
+ }
+ return order;
+ }
+
+ private QrcodeTicket loadTicketByUuid(String ticketUuid) {
+ String normalizedTicketUuid = trimToNull(ticketUuid);
+ if (!StringUtils.hasText(normalizedTicketUuid)) {
+ throw new BizException(BizErrorCode.ORDER_NOT_FOUND, "访客码不存在");
+ }
+ QrcodeTicket ticket =
+ qrcodeTicketMapper.selectOne(
+ new LambdaQueryWrapper<QrcodeTicket>()
+ .eq(QrcodeTicket::getDelFlag, 0)
+ .eq(QrcodeTicket::getUuid, normalizedTicketUuid)
+ .last("limit 1"));
+ if (ticket == null) {
+ throw new BizException(BizErrorCode.ORDER_NOT_FOUND, "访客码不存在");
+ }
+ return ticket;
+ }
+
public MiniMyAppointmentDetailVo detailMyOrder(Long orderId, String uuid) {
if (orderId == null || orderId <= 0) {
throw new BizException(BizErrorCode.ORDER_NOT_FOUND, "预约单不存在");
@@ -541,14 +620,14 @@
if (!StringUtils.hasText(c)) {
throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "拜访事由不能为空");
}
+ String txt = trimToNull(other);
+ if (!StringUtils.hasText(txt)) {
+ throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "请输入事由说明");
+ }
+ if (txt.length() > 15) {
+ throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "事由说明不能超过15个字");
+ }
if (AppointmentBizConstants.VISIT_REASON_OTHER.equalsIgnoreCase(c)) {
- String txt = trimToNull(other);
- if (!StringUtils.hasText(txt)) {
- throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "选择其他时须填写自定义内容");
- }
- if (txt.length() > 255) {
- throw new BizException(BizErrorCode.AUTH_INVALID_CREDENTIALS, "自定义内容不能超过255字");
- }
return;
}
Long cnt =
@@ -793,6 +872,7 @@
vo.setVisitStartDate(row.getVisitStartDate());
vo.setVisitEndDate(row.getVisitEndDate());
vo.setVisitReasonCode(row.getVisitReasonCode());
+ vo.setVisitReasonOther(row.getVisitReasonOther());
vo.setCreateTime(row.getCreateTime());
return vo;
}
@@ -906,6 +986,92 @@
return StringUtils.hasText(dept) ? dept : "-";
}
+ private Map<Long, String> loadVisitorDisplayMapByOrderIds(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 = loadMpVisitorCompanyMap(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 text = entry.getValue().stream().distinct().collect(Collectors.joining("、"));
+ if (StringUtils.hasText(text)) {
+ result.put(entry.getKey(), text);
+ }
+ }
+ return result;
+ }
+
+ private Map<Long, String> loadMpVisitorCompanyMap(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> loadPlateTextMapByOrderIds(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 text = entry.getValue().stream().distinct().collect(Collectors.joining("、"));
+ if (StringUtils.hasText(text)) {
+ result.put(entry.getKey(), text);
+ }
+ }
+ return result;
+ }
+
private String resolveOrderStatusText(AppointmentOrder row) {
return switch (trimToNull(row.getStatus())) {
case AppointmentOrderStatus.PENDING_APPROVAL -> "审批中";
@@ -947,9 +1113,9 @@
private String buildVisitTimeText(AppointmentOrder row) {
if (AppointmentBizConstants.TIME_MODE_SINGLE.equals(row.getVisitTimeMode())) {
String slotLabel = switch (trimToNull(row.getVisitTimeSlot())) {
- case AppointmentBizConstants.TIME_SLOT_ALL_DAY -> "全天";
- case AppointmentBizConstants.TIME_SLOT_AM -> "上午";
- case AppointmentBizConstants.TIME_SLOT_PM -> "下午";
+ case AppointmentBizConstants.TIME_SLOT_ALL_DAY -> "00:00-23:59";
+ case AppointmentBizConstants.TIME_SLOT_AM -> "00:00-11:59";
+ case AppointmentBizConstants.TIME_SLOT_PM -> "12:00-23:59";
default -> "";
};
if (row.getVisitStartDate() == null) {
@@ -969,12 +1135,12 @@
}
private String buildVisitReasonText(AppointmentOrder row, Map<String, String> reasonNameMap) {
- if (AppointmentBizConstants.VISIT_REASON_OTHER.equalsIgnoreCase(trimToNull(row.getVisitReasonCode()))) {
- String other = trimToNull(row.getVisitReasonOther());
- return StringUtils.hasText(other) ? "其他-" + other : "其他";
+ String code = trimToNull(row.getVisitReasonCode());
+ if (AppointmentBizConstants.VISIT_REASON_OTHER.equalsIgnoreCase(code)) {
+ return "其他";
}
- String reasonName = reasonNameMap.get(trimToNull(row.getVisitReasonCode()));
- return StringUtils.hasText(reasonName) ? reasonName : trimToNull(row.getVisitReasonCode());
+ String reasonName = reasonNameMap.get(code);
+ return StringUtils.hasText(reasonName) ? reasonName : code;
}
private String buildAccessAreaText(String rawJson) {
@@ -1043,7 +1209,7 @@
vo.setTicketId(ticket.getId());
vo.setTicketUuid(ticket.getUuid());
vo.setMpVisitorId(ticket.getMpVisitorId());
- vo.setPayload(ticket.getPayload());
+ vo.setPayload(integrationHikvisionService.encryptQrcodePayload(ticket.getPayload()));
vo.setGenerateTime(ticket.getGenerateTime());
vo.setExpireTime(ticket.getExpireTime());
vo.setVisitorName(resolveVisitorName(ticket.getMpVisitorId(), orderVisitors, visitorMap));
--
Gitblit v1.7.1