diff --git a/src/main/java/com/ycwl/basic/pricing/service/impl/VoucherPrintServiceImpl.java b/src/main/java/com/ycwl/basic/pricing/service/impl/VoucherPrintServiceImpl.java index 56858ae..99790bc 100644 --- a/src/main/java/com/ycwl/basic/pricing/service/impl/VoucherPrintServiceImpl.java +++ b/src/main/java/com/ycwl/basic/pricing/service/impl/VoucherPrintServiceImpl.java @@ -23,6 +23,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; /** * 优惠券打印服务实现 @@ -44,7 +45,9 @@ public class VoucherPrintServiceImpl implements VoucherPrintService { private RedisTemplate redisTemplate; private static final String PRINT_LOCK_KEY = "voucher_print_lock:%s:%s:%s"; // faceId:brokerId:scenicId - private static final String CODE_PREFIX = "VT"; // Voucher Ticket + + // 原子计数器,确保流水号唯一性 + private static final AtomicLong counter = new AtomicLong(0); @Override @Transactional(rollbackFor = Exception.class) @@ -56,10 +59,12 @@ public class VoucherPrintServiceImpl implements VoucherPrintService { if (request.getBrokerId() == null) { throw new BaseException("经纪人ID不能为空"); } - if (request.getScenicId() == null) { - throw new BaseException("景区ID不能为空"); + FaceEntity face = faceRepository.getFace(request.getFaceId()); + if (face == null) { + throw new BaseException("请上传人脸"); } - + request.setScenicId(face.getScenicId()); + Long currentUserId = Long.valueOf(BaseContextHandler.getUserId()); // 验证faceId是否属于当前用户 @@ -149,13 +154,16 @@ public class VoucherPrintServiceImpl implements VoucherPrintService { } /** - * 生成流水号 + * 生成流水号(优化版本) + * 使用原子计数器确保唯一性,解决原方法在高并发下的重复问题 */ private String generateCode() { - SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + // 方案:使用毫秒级时间戳 + 原子计数器 + // 格式:5位计数器 + SSS + SimpleDateFormat sdf = new SimpleDateFormat("SSS"); String timestamp = sdf.format(new Date()); - String randomSuffix = String.valueOf((int)(Math.random() * 1000)).formatted("%03d"); - return CODE_PREFIX + timestamp + randomSuffix; + long count = counter.incrementAndGet() % 100000; // 5位计数,循环使用 + return String.format("%05d", count) + timestamp; } /**