| | |
| | | import com.sinata.appointment.util.SensitiveDataUtil; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.UUID; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | .eq(AppointmentVisitor::getDelFlag, 0) |
| | | .eq(AppointmentVisitor::getOrderId, order.getId()) |
| | | .orderByAsc(AppointmentVisitor::getId)); |
| | | Map<Long, MpVisitor> visitorProfileMap = loadVisitorProfileMap(visitors); |
| | | Map<Long, QrcodeTicket> existingTicketMap = loadActiveUnusedTicketMap(order.getId(), visitors); |
| | | int validMinutes = getMaxConsecutiveDays() * 24 * 60; |
| | | LocalDateTime generateTime = resolveGenerateTime(order); |
| | | LocalDateTime expireTime = generateTime.plusMinutes(validMinutes); |
| | |
| | | |
| | | int createdCount = 0; |
| | | for (AppointmentVisitor visitor : visitors) { |
| | | QrcodeTicket existed = findActiveUnusedTicket(order.getId(), visitor.getMpVisitorId()); |
| | | QrcodeTicket existed = existingTicketMap.get(visitor.getMpVisitorId()); |
| | | if (existed != null) { |
| | | log.info( |
| | | "{} orderId={} mpVisitorId={} reuse ticketId={}", |
| | |
| | | existed.getId()); |
| | | continue; |
| | | } |
| | | MpVisitor visitorProfile = loadVisitor(visitor.getMpVisitorId()); |
| | | MpVisitor visitorProfile = visitorProfileMap.get(visitor.getMpVisitorId()); |
| | | String ticketUuid = UUID.randomUUID().toString().replace("-", ""); |
| | | String visitorIdCardPlain = resolveVisitorIdCardPlain(visitor, visitorProfile); |
| | | String payload = |
| | |
| | | ticket.setGenerateTime(generateTime); |
| | | ticket.setExpireTime(expireTime); |
| | | qrcodeTicketMapper.insert(ticket); |
| | | existingTicketMap.put(visitor.getMpVisitorId(), ticket); |
| | | createdCount++; |
| | | log.info( |
| | | "{} raw-payload orderId={} mpVisitorId={} payload={}", |
| | |
| | | } |
| | | } |
| | | |
| | | private QrcodeTicket findActiveUnusedTicket(Long orderId, Long mpVisitorId) { |
| | | LambdaQueryWrapper<QrcodeTicket> query = |
| | | private Map<Long, MpVisitor> loadVisitorProfileMap(List<AppointmentVisitor> visitors) { |
| | | if (visitors == null || visitors.isEmpty()) { |
| | | return Map.of(); |
| | | } |
| | | List<Long> visitorIds = |
| | | visitors.stream() |
| | | .map(AppointmentVisitor::getMpVisitorId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .toList(); |
| | | if (visitorIds.isEmpty()) { |
| | | return Map.of(); |
| | | } |
| | | List<MpVisitor> rows = |
| | | mpVisitorMapper.selectList( |
| | | new LambdaQueryWrapper<MpVisitor>() |
| | | .eq(MpVisitor::getDelFlag, 0) |
| | | .in(MpVisitor::getId, visitorIds)); |
| | | Map<Long, MpVisitor> result = new LinkedHashMap<>(); |
| | | for (MpVisitor row : rows) { |
| | | result.putIfAbsent(row.getId(), row); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private Map<Long, QrcodeTicket> loadActiveUnusedTicketMap(Long orderId, List<AppointmentVisitor> visitors) { |
| | | if (orderId == null || visitors == null || visitors.isEmpty()) { |
| | | return new LinkedHashMap<>(); |
| | | } |
| | | LinkedHashSet<Long> visitorIds = |
| | | visitors.stream() |
| | | .map(AppointmentVisitor::getMpVisitorId) |
| | | .filter(Objects::nonNull) |
| | | .collect(java.util.stream.Collectors.toCollection(LinkedHashSet::new)); |
| | | if (visitorIds.isEmpty()) { |
| | | return new LinkedHashMap<>(); |
| | | } |
| | | List<QrcodeTicket> rows = |
| | | qrcodeTicketMapper.selectList( |
| | | new LambdaQueryWrapper<QrcodeTicket>() |
| | | .eq(QrcodeTicket::getDelFlag, 0) |
| | | .eq(QrcodeTicket::getOrderId, orderId) |
| | | .eq(QrcodeTicket::getTicketStatus, QrcodeTicketStatus.UNUSED) |
| | | .orderByDesc(QrcodeTicket::getId) |
| | | .last("limit 1"); |
| | | if (mpVisitorId == null) { |
| | | query.isNull(QrcodeTicket::getMpVisitorId); |
| | | } else { |
| | | query.eq(QrcodeTicket::getMpVisitorId, mpVisitorId); |
| | | .in(QrcodeTicket::getMpVisitorId, visitorIds) |
| | | .orderByDesc(QrcodeTicket::getId)); |
| | | Map<Long, QrcodeTicket> result = new LinkedHashMap<>(); |
| | | for (QrcodeTicket row : rows) { |
| | | if (row.getMpVisitorId() != null) { |
| | | result.putIfAbsent(row.getMpVisitorId(), row); |
| | | } |
| | | return qrcodeTicketMapper.selectOne(query); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | private LocalDateTime resolveGenerateTime(AppointmentOrder order) { |