Kaynağa Gözat

fix: 消费服务
1.原始消费记录和明细Id缓存改为map

luoyb 10 ay önce
ebeveyn
işleme
e90dfe32b9

+ 1 - 1
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/business/ConsumeBusiness.java

@@ -191,7 +191,7 @@ public class ConsumeBusiness {
             }
         }
         if (R.isError(result)) {
-            log.info("[上传交易异步处理尝试3次失败,需要手工处理]-[{}]", JSONUtil.toJsonStr(bo));
+            log.info("[上传交易异步处理尝试3次失败,需要手工处理]-[{}]-[{}]", JSONUtil.toJsonStr(bo),JSONUtil.toJsonStr(result.getData()));
         }
         log.info("[上传交易异步处理完成]");
     }

+ 4 - 4
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/check/CommonCheck.java

@@ -592,10 +592,10 @@ public class CommonCheck {
         Long userId = bo.getUserId();
         BigDecimal balance = bo.getBalance();
 
-        // 将当笔原始消费记录标识放入缓存,1天过期
-        Set<String> originalId = Collections.singleton(bo.getOriginalId());
-        RedisUtils.setCacheSet(CacheNames.XF_ORIGINAL_ID, originalId);
-        RedisUtils.expire(CacheNames.XF_ORIGINAL_ID, Duration.ofHours(5));
+        //// 将当笔原始消费记录标识放入缓存,1天过期
+        //Set<String> originalId = Collections.singleton(bo.getOriginalId());
+        //RedisUtils.setCacheSet(CacheNames.XF_ORIGINAL_ID, originalId);
+        //RedisUtils.expire(CacheNames.XF_ORIGINAL_ID, Duration.ofHours(5));
 
         // if (ObjectUtil.equals(currentDateStr, consumeDateStr)) {
         // 重置卡天当日消费数据

+ 22 - 16
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/check/ConsumeRequestCheck.java

@@ -28,6 +28,7 @@ import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.text.MessageFormat;
+import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -75,8 +76,8 @@ public class ConsumeRequestCheck {
         RemoteMealTypeVo remoteMealTypeVo = commonCheck.getMealType(consumeDate);
         if (ObjectUtil.isEmpty(remoteMealTypeVo)) {
             return commonCheck.createErrorResponse(400, ApiErrorTypeConstants.NOT_FOUND, "不在交易时段",
-                                                   MessageFormat.format("非营业时段,不允许交易。消费时间[{0}]",
-                                                                        DateUtil.format(consumeDate, "HH:mm:ss")));
+                MessageFormat.format("非营业时段,不允许交易。消费时间[{0}]",
+                    DateUtil.format(consumeDate, "HH:mm:ss")));
         }
         // 设置消费记录的当前餐类
         bo.setMealType(Long.valueOf(remoteMealTypeVo.getTypeId()));
@@ -84,7 +85,7 @@ public class ConsumeRequestCheck {
         XfCardLimitedVo xfCardLimitedVo = new XfCardLimitedVo();
         int statusFlag = bo.getStatusFlag();
         if (statusFlag == Integer.parseInt(ConsumeRecordTypeEnum.XFJXF_1.code())
-                || statusFlag == Integer.parseInt(ConsumeRecordTypeEnum.XFJXF_4.code())) {
+            || statusFlag == Integer.parseInt(ConsumeRecordTypeEnum.XFJXF_4.code())) {
 
             // 设备是否可以消费验证
             result = checkTermLimitedAndOther(bo, useTermVo, userCardVo, remoteMealTypeVo);
@@ -107,7 +108,7 @@ public class ConsumeRequestCheck {
         return R.ok();
     }
 
-    private  R<ErrorInfo> obtainResult(R<ErrorInfo> result){
+    private R<ErrorInfo> obtainResult(R<ErrorInfo> result) {
         ErrorInfo data = result.getData();
         String details = Optional.ofNullable(data).map(ErrorInfo::getDetils).orElse("超过消费限制");
         String msg = Optional.ofNullable(data).map(ErrorInfo::getMessage).orElse("消费限制判断存在问题");
@@ -152,12 +153,12 @@ public class ConsumeRequestCheck {
         }
         if (consumeMoney.compareTo(totalBalance) > 0) {
             return commonCheck.createErrorResponse(400, ApiErrorTypeConstants.CONSUME_CHECK_FAIL, "账户余额不足",
-                                                   MessageFormat.format("总余额[{0}],消费金额[{1}]", totalBalance, consumeMoney));
+                MessageFormat.format("总余额[{0}],消费金额[{1}]", totalBalance, consumeMoney));
         }
         // 计算扣费后的余额
         BigDecimal balance = totalBalance.subtract(consumeMoney);
         bo.setBalance(balance);
-        baseBusiness.resetUserBalance(bo.getUserId(),balance);
+        baseBusiness.resetUserBalance(bo.getUserId(), balance);
         return R.ok();
     }
 
@@ -172,19 +173,24 @@ public class ConsumeRequestCheck {
      * @return 如果原始消费记录ID重复,返回包含错误信息的响应对象;否则返回成功的响应对象
      */
     private R<ErrorInfo> checkRepeatOriginalId(ConsumptionBo bo) {
-        Set<String> originalIdSet = RedisUtils.getCacheSet(CacheNames.XF_ORIGINAL_ID);
+        //Set<String> originalIdSet = RedisUtils.getCacheSet(CacheNames.XF_ORIGINAL_ID);
 
         String originalId = bo.getOriginalId();
         if (ObjectUtil.isEmpty(originalId)) {
             originalId = RecordIdUtils.getRecordId(bo.getConsumeDate(), bo.getTermNo().shortValue(),
-                                                   bo.getTermRecordId().shortValue(), bo.getUserNo().shortValue(), 0);
+                bo.getTermRecordId().shortValue(), bo.getUserNo().shortValue(), 0);
         }
-        if (originalIdSet.contains(originalId)) {
+        String originalIdCache = RedisUtils.getCacheMapValue(CacheNames.XF_ORIGINAL_ID, originalId);
+        if (originalIdCache != null && originalIdCache.equals(originalId)) {
             return commonCheck.createErrorResponse(400, ApiErrorTypeConstants.CONSUME_CHECK_FAIL, "原始消费记录存在",
-                                                   MessageFormat.format("原始消费记录已存在:{0}", originalId));
+                MessageFormat.format("原始消费记录已存在:{0}", originalId));
         }
         bo.setOriginalId(originalId);
 
+        // 将当笔原始消费记录标识放入缓存,4小时过期
+        RedisUtils.setCacheMapValue(CacheNames.XF_ORIGINAL_ID, originalId, originalId);
+        RedisUtils.expire(CacheNames.XF_ORIGINAL_ID, Duration.ofHours(4));
+
         return R.ok();
     }
 
@@ -284,7 +290,7 @@ public class ConsumeRequestCheck {
                     R<ErrorInfo> result = task.get();
                     // 如果发现错误且尚未设置错误结果
                     if (result != null && R.isError(result) &&
-                            firstError.compareAndSet(null, result)) {
+                        firstError.compareAndSet(null, result)) {
                         // 取消其他任务(通过中断)
                         taskExecutor.getThreadPoolExecutor().getQueue().clear();
                     }
@@ -321,30 +327,30 @@ public class ConsumeRequestCheck {
         long intervalMin = (currentSec - lastPaySec) / 60;
 
         return intervalMin < ctx.getTermSwipeInterval() ?
-                   commonCheck.createError(TradeStatusEnum.TimeInterval) : null;
+            commonCheck.createError(TradeStatusEnum.TimeInterval) : null;
     }
 
     private R<ErrorInfo> validateSingleLimit(TermConsumeValidationContext ctx) {
         if (ctx.getTermSingleMoney().compareTo(BigDecimal.ZERO) <= 0) return null;
         return ctx.getConsumeValue().compareTo(ctx.getTermSingleMoney()) > 0 ?
-                   commonCheck.createError(TradeStatusEnum.OnceBigMoney) : null;
+            commonCheck.createError(TradeStatusEnum.OnceBigMoney) : null;
     }
 
     private R<ErrorInfo> validateCardValidity(TermConsumeValidationContext ctx) {
         if (ctx.getFactoryId() == 0 || !ctx.isTermUseValidity()) return null;
         return ctx.getCurrentTime().isAfter(ctx.getExpiryTime()) ?
-                   commonCheck.createError(TradeStatusEnum.CardValidDate) : null;
+            commonCheck.createError(TradeStatusEnum.CardValidDate) : null;
     }
 
     private R<ErrorInfo> validateCardType(TermConsumeValidationContext ctx) {
         int mask = 1 << (ctx.getCardType() - 1);
         return (mask & ctx.getTermCardType()) == 0 ?
-                   commonCheck.createError(TradeStatusEnum.CardTypeLimit) : null;
+            commonCheck.createError(TradeStatusEnum.CardTypeLimit) : null;
     }
 
     private R<ErrorInfo> validateMealLimit(TermConsumeValidationContext ctx) {
         return ctx.getTermMealCount() > 0 && ctx.getMealCount() >= ctx.getTermMealCount() ?
-                   commonCheck.createError(TradeStatusEnum.MealLimitTimes) : null;
+            commonCheck.createError(TradeStatusEnum.MealLimitTimes) : null;
     }
 
     private R<ErrorInfo> validateDailyLimit(TermConsumeValidationContext ctx) {

+ 8 - 4
ruoyi-server/ruoyi-server-consume/src/main/java/org/dromara/server/consume/check/ConsumeUploadCheck.java

@@ -65,13 +65,17 @@ public class ConsumeUploadCheck {
         // 检验之前先检查这条记录是否上传过,如果上传过则返回已上传的错误,如未上传,将记录Id存入缓存
         String detailId = RecordIdUtils.getRecordId(bo.getConsumeDate(), bo.getTermNo().shortValue(),
             bo.getTermRecordId().shortValue(), bo.getUserNo().intValue(), 0);
-        Set<String> detailIdSet = RedisUtils.getCacheSet(CacheNames.XF_DETAIL_ID);
-        if (detailIdSet.contains(detailId)) {
+        //Set<String> detailIdSet = RedisUtils.getCacheSet(CacheNames.XF_DETAIL_ID);
+        String detailIdSet = RedisUtils.getCacheMapValue(CacheNames.XF_DETAIL_ID,detailId);
+
+        if (detailIdSet!=null && detailIdSet.equals(detailId)) {
             return commonCheck.createErrorResponse(400, ApiErrorTypeConstants.CONSUME_CHECK_FAIL, "消费记录已上传",
                 MessageFormat.format("消费记录已上传:{0}", detailId));
         }
-        RedisUtils.setCacheSet(CacheNames.XF_DETAIL_ID, Collections.singleton(detailId));
-        RedisUtils.expire(CacheNames.XF_DETAIL_ID, Duration.ofHours(5));
+
+
+        RedisUtils.setCacheMapValue(CacheNames.XF_DETAIL_ID, detailId,detailId);
+        RedisUtils.expire(CacheNames.XF_DETAIL_ID, Duration.ofHours(2));
 
         R<ErrorInfo> result = checkOriginalRecord(bo, userAccountVo);
         if (R.isError(result)) {