Jelajahi Sumber

申请售后添加唯一锁

yuhongqi 5 hari lalu
induk
melakukan
cd3524881a

+ 27 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreAfterSalesScrmServiceImpl.java

@@ -11,6 +11,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.fs.common.annotation.DataScope;
 import com.fs.common.annotation.RepeatSubmit;
 import com.fs.common.core.domain.R;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.CustomException;
 import com.fs.common.utils.CloudHostUtils;
 import com.fs.common.utils.DateUtils;
@@ -91,6 +92,7 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -155,6 +157,9 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
     @Autowired
     private ISysConfigService configService;
 
+    @Autowired
+    private RedisCache redisCache;
+
     @Autowired
     SysConfigMapper sysConfigMapper;
 
@@ -291,7 +296,29 @@ public class FsStoreAfterSalesScrmServiceImpl implements IFsStoreAfterSalesScrmS
     @Transactional
     public R applyForAfterSales(long userId, FsStoreAfterSalesParam storeAfterSalesParam) {
         logger.info("申请退款请求信息:"+JSONUtil.toJsonStr(storeAfterSalesParam));
+        if (StringUtils.isEmpty(storeAfterSalesParam.getOrderCode())) {
+            return R.error("订单号不能为空");
+        }
+        String lockKey = "after_sales:apply:" + storeAfterSalesParam.getOrderCode();
+        String lockVal = IdUtil.fastSimpleUUID();
+        if (!redisCache.setIfAbsent(lockKey, lockVal, 10, TimeUnit.SECONDS)) {
+            logger.warn("申请售后未获取到分布式锁,orderCode={}", storeAfterSalesParam.getOrderCode());
+            return R.error("售后申请处理中,请稍后再试");
+        }
+        try {
+            return doApplyForAfterSales(userId, storeAfterSalesParam);
+        } finally {
+            Object cached = redisCache.getCacheObject(lockKey);
+            if (cached != null && lockVal.equals(String.valueOf(cached))) {
+                redisCache.deleteObject(lockKey);
+            }
+        }
+    }
 
+    /**
+     * 售后申请业务(由 {@link #applyForAfterSales} 在 Redis 分布式锁内调用,按订单号互斥)
+     */
+    private R doApplyForAfterSales(long userId, FsStoreAfterSalesParam storeAfterSalesParam) {
         // 查询配置:是否删除历史售后数据
         try {
             String deleteAfterSalesConfig = configService.selectConfigByKey("delete_after_sales");