yuhongqi 1 день назад
Родитель
Сommit
3eacbf35d9

+ 143 - 113
fs-service/src/main/java/com/fs/live/service/impl/LiveAfterSalesServiceImpl.java

@@ -85,6 +85,9 @@ import com.fs.live.service.ILiveAfterSalesService;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 售后记录Service业务层处理
@@ -162,6 +165,9 @@ public class LiveAfterSalesServiceImpl implements ILiveAfterSalesService {
 //    @Autowired
 //    private FsStoreDeliversMapper fsStoreDeliversMapper;
 
+    @Autowired
+    private RedissonClient redissonClient;
+
 
     /**
      * 查询售后记录
@@ -388,139 +394,163 @@ public class LiveAfterSalesServiceImpl implements ILiveAfterSalesService {
     @Transactional
     public R applyForAfterSales(String userId, LiveAfterSalesParam param) {
         log.info("申请退款请求信息:"+JSONUtil.toJsonStr(param));
-        LiveOrder order=liveOrderService.selectOrderIdByOrderCode(param.getOrderCode());
-        if(!order.getUserId().equals(userId)){
-            throw new CustomException("非法操作");
-        }
-        if(order.getStatus()==0){
-            return R.error("未支付订单不能申请售后");
-        }
-        if("1".equals(configUtil.generateConfigByKey(SysConfigEnum.HIS_CONFIG.getKey()).getString("erpOpen"))
-                && StringUtils.isEmpty(order.getExtendOrderId())
-                && !CloudHostUtils.hasCloudHostName("康年堂")){
-            log.info("erpOpen:{}",configUtil.generateConfigByKey(SysConfigEnum.HIS_CONFIG.getKey()).getString("erpOpen"));
-            return R.error("仓库未生成订单,暂时不能申请退款,请联系客服");
-        }
-        if(order.getStatus()== OrderInfoEnum.STATUS_NE3.getValue()){
-            return R.error("已取消订单不能申请售后");
-        }
-        if(order.getStatus()== OrderInfoEnum.STATUS_NE1.getValue()){
-            return R.error("已提交申请,等待处理");
-        }
+        
+        // 使用Redis分布式锁,确保同一订单只能有一个服务器处理申请售后 因为卓美有一个订单生成了三个售后订单,数据一摸一样,除了id
+        String lockKey = "live:afterSales:apply:" + param.getOrderCode();
+        RLock lock = redissonClient.getLock(lockKey);
+        
+        try {
+            // 尝试获取锁,等待时间3秒,锁过期时间30秒
+            boolean locked = lock.tryLock(3, 30, TimeUnit.SECONDS);
+            if (!locked) {
+                log.warn("申请售后订单锁获取失败,订单号:{}", param.getOrderCode());
+                return R.error("系统繁忙,请稍后重试");
+            }
+            
+            log.info("申请售后订单锁获取成功,订单号:{}", param.getOrderCode());
+            
+            LiveOrder order=liveOrderService.selectOrderIdByOrderCode(param.getOrderCode());
+            if(!order.getUserId().equals(userId)){
+                throw new CustomException("非法操作");
+            }
+            if(order.getStatus()==0){
+                return R.error("未支付订单不能申请售后");
+            }
+            if("1".equals(configUtil.generateConfigByKey(SysConfigEnum.HIS_CONFIG.getKey()).getString("erpOpen"))
+                    && StringUtils.isEmpty(order.getExtendOrderId())
+                    && !CloudHostUtils.hasCloudHostName("康年堂")){
+                log.info("erpOpen:{}",configUtil.generateConfigByKey(SysConfigEnum.HIS_CONFIG.getKey()).getString("erpOpen"));
+                return R.error("仓库未生成订单,暂时不能申请退款,请联系客服");
+            }
+            if(order.getStatus()== OrderInfoEnum.STATUS_NE3.getValue()){
+                return R.error("已取消订单不能申请售后");
+            }
+            if(order.getStatus()== OrderInfoEnum.STATUS_NE1.getValue()){
+                return R.error("已提交申请,等待处理");
+            }
 //        if(storeAfterSalesParam.getRefundAmount().compareTo(order.getPayPrice())==1){
 //            return R.error("退款金额不能大于支付金额");
 //        }
-        //已完成订单七天后不能申请退款
-        if(order.getStatus().equals(OrderInfoEnum.STATUS_3.getValue())) {
-            String json=configService.selectConfigByKey("store.config");
-            com.fs.hisStore.config.StoreConfig config=JSONUtil.toBean(json, com.fs.hisStore.config.StoreConfig.class);
-            //已完成订单
-            if (order.getFinishTime() != null) {
-                if (config.getStoreAfterSalesDay() != null && config.getStoreAfterSalesDay() > 0) {
-                    //判断完成时间是否超过指定时间
-                    Calendar calendarAfterSales = new GregorianCalendar();
-                    calendarAfterSales.setTime(order.getFinishTime());
-                    calendarAfterSales.add(calendarAfterSales.DATE, config.getStoreAfterSalesDay()); //把日期往后增加一天,整数  往后推,负数往前移动
-                    if (calendarAfterSales.getTime().getTime() < new Date().getTime()) {
-                        return R.error("此订单已超过售后时间,不能提交售后");
-                    }
+            //已完成订单七天后不能申请退款
+            if(order.getStatus().equals(OrderInfoEnum.STATUS_3.getValue())) {
+                String json=configService.selectConfigByKey("store.config");
+                com.fs.hisStore.config.StoreConfig config=JSONUtil.toBean(json, com.fs.hisStore.config.StoreConfig.class);
+                //已完成订单
+                if (order.getFinishTime() != null) {
+                    if (config.getStoreAfterSalesDay() != null && config.getStoreAfterSalesDay() > 0) {
+                        //判断完成时间是否超过指定时间
+                        Calendar calendarAfterSales = new GregorianCalendar();
+                        calendarAfterSales.setTime(order.getFinishTime());
+                        calendarAfterSales.add(calendarAfterSales.DATE, config.getStoreAfterSalesDay()); //把日期往后增加一天,整数  往后推,负数往前移动
+                        if (calendarAfterSales.getTime().getTime() < new Date().getTime()) {
+                            return R.error("此订单已超过售后时间,不能提交售后");
+                        }
 
+                    }
                 }
             }
-        }
-        //商品除去优惠后的总价格
-        //BigDecimal totalPrice = BigDecimal.ZERO;
-        //拿到所有的商品
-        List<LiveOrderItem> orderItems = liveOrderItemService.selectCheckedByOrderId(order.getOrderId());
-        for (LiveOrderItem item : orderItems) {
-            StoreOrderProductDTO cartInfo = JSONObject.parseObject(item.getJsonInfo(), StoreOrderProductDTO.class);
-            LiveAfterSalesProductParam prosuctParam = param.getProductList().stream().filter(p -> p.getProductId().equals(item.getProductId())).findFirst().orElse(new LiveAfterSalesProductParam());
-            if (prosuctParam.getProductId() != null) {
+            //商品除去优惠后的总价格
+            //BigDecimal totalPrice = BigDecimal.ZERO;
+            //拿到所有的商品
+            List<LiveOrderItem> orderItems = liveOrderItemService.selectCheckedByOrderId(order.getOrderId());
+            for (LiveOrderItem item : orderItems) {
+                StoreOrderProductDTO cartInfo = JSONObject.parseObject(item.getJsonInfo(), StoreOrderProductDTO.class);
+                LiveAfterSalesProductParam prosuctParam = param.getProductList().stream().filter(p -> p.getProductId().equals(item.getProductId())).findFirst().orElse(new LiveAfterSalesProductParam());
+                if (prosuctParam.getProductId() != null) {
 //                //商品优惠前总金额
 //                BigDecimal totalAmountOfGoods = NumberUtil.mul(cartInfo.getPrice(), item.getNum());
 //                //商品优惠总金额
 //                BigDecimal commodityDiscountAmount = NumberUtil.mul(NumberUtil.div(totalAmountOfGoods, NumberUtil.sub(order.getTotalPrice(), order.getPayPostage())), order.getCouponPrice());
 //                //商品优惠后总金额
 //                totalPrice = NumberUtil.add(totalPrice, NumberUtil.sub(totalAmountOfGoods, commodityDiscountAmount));
-                item.setIsAfterSales(1);
-                LiveOrderItem orderItem=new LiveOrderItem();
+                    item.setIsAfterSales(1);
+                    LiveOrderItem orderItem=new LiveOrderItem();
 //                BeanUtil.copyProperties(item, orderItem);
-                try {
-                    BeanUtils.copyProperties(orderItem,item);
-                } catch (IllegalAccessException e) {
-                    throw new RuntimeException(e);
-                } catch (InvocationTargetException e) {
-                    throw new RuntimeException(e);
-                }
-                liveOrderItemService.updateLiveOrderItem(orderItem);
+                    try {
+                        BeanUtils.copyProperties(orderItem,item);
+                    } catch (IllegalAccessException e) {
+                        throw new RuntimeException(e);
+                    } catch (InvocationTargetException e) {
+                        throw new RuntimeException(e);
+                    }
+                    liveOrderItemService.updateLiveOrderItem(orderItem);
 
+                }
             }
-        }
-        //更新订单状态
-        Integer orderStatus=order.getStatus();
-        order.setStatus(OrderInfoEnum.STATUS_NE1.getValue());
-        order.setRefundStatus(String.valueOf(OrderInfoEnum.REFUND_STATUS_1.getValue()));
-        order.setRefundExplain(param.getReasons());
-        order.setCancelReason(param.getExplains());
-        order.setIsAfterSales(1);
-        order.setRefundTime(new Date());
-        liveOrderService.updateLiveOrder(order);
-        //生成售后订单
-        LiveAfterSales storeAfterSales = new LiveAfterSales();
-        storeAfterSales.setOrderId(order.getOrderId());
-        storeAfterSales.setRefundAmount(param.getRefundAmount());
-        storeAfterSales.setRefundType(param.getServiceType());
-        storeAfterSales.setReasons(param.getReasons());
-        storeAfterSales.setExplains(param.getExplains());
-        storeAfterSales.setExplainImg(param.getExplainImg());
-        storeAfterSales.setStatus(AfterSalesStatusEnum.STATUS_0.getValue());
-        storeAfterSales.setSalesStatus(0);
-        storeAfterSales.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
-        storeAfterSales.setIsDel(0);
-        storeAfterSales.setOrderStatus(orderStatus);
-        storeAfterSales.setUserId(Long.valueOf(userId));
-        storeAfterSales.setCompanyId(order.getCompanyId());
-        storeAfterSales.setCompanyUserId(order.getCompanyUserId());
-        liveAfterSalesService.insertLiveAfterSales(storeAfterSales);
-        //售后商品详情
-        for (LiveAfterSalesProductParam productParam : param.getProductList()) {
-            LiveOrderItem item = orderItems.stream().filter(p -> p.getProductId().equals(productParam.getProductId())).findFirst().orElse(new LiveOrderItem());
-            LiveAfterSalesItem storeAfterSalesItem = new LiveAfterSalesItem();
-            storeAfterSalesItem.setAfterSalesId(storeAfterSales.getId());
-            storeAfterSalesItem.setProductId(item.getProductId());
-            storeAfterSalesItem.setJsonInfo(item.getJsonInfo());
-            storeAfterSalesItem.setIsDel(0);
-            liveAfterSalesItemMapper.insertLiveAfterSalesItem(storeAfterSalesItem);
-        }
-        //操作记录
-        LiveAfterSalesLogs storeAfterSalesStatus = new LiveAfterSalesLogs();
-        storeAfterSalesStatus.setStoreAfterSalesId(storeAfterSales.getId());
-        storeAfterSalesStatus.setChangeType(0);
-        storeAfterSalesStatus.setChangeMessage(AfterSalesStatusEnum.STATUS_0.getDesc());
-        storeAfterSalesStatus.setChangeTime(Timestamp.valueOf(LocalDateTime.now()));
-        FsUserScrm user=userService.selectFsUserById(Long.valueOf(userId));
-        storeAfterSalesStatus.setOperator(user.getNickname());
-        liveAfterSalesLogsMapper.insertLiveAfterSalesLogs(storeAfterSalesStatus);
+            //更新订单状态
+            Integer orderStatus=order.getStatus();
+            order.setStatus(OrderInfoEnum.STATUS_NE1.getValue());
+            order.setRefundStatus(String.valueOf(OrderInfoEnum.REFUND_STATUS_1.getValue()));
+            order.setRefundExplain(param.getReasons());
+            order.setCancelReason(param.getExplains());
+            order.setIsAfterSales(1);
+            order.setRefundTime(new Date());
+            liveOrderService.updateLiveOrder(order);
+            //生成售后订单
+            LiveAfterSales storeAfterSales = new LiveAfterSales();
+            storeAfterSales.setOrderId(order.getOrderId());
+            storeAfterSales.setRefundAmount(param.getRefundAmount());
+            storeAfterSales.setRefundType(param.getServiceType());
+            storeAfterSales.setReasons(param.getReasons());
+            storeAfterSales.setExplains(param.getExplains());
+            storeAfterSales.setExplainImg(param.getExplainImg());
+            storeAfterSales.setStatus(AfterSalesStatusEnum.STATUS_0.getValue());
+            storeAfterSales.setSalesStatus(0);
+            storeAfterSales.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
+            storeAfterSales.setIsDel(0);
+            storeAfterSales.setOrderStatus(orderStatus);
+            storeAfterSales.setUserId(Long.valueOf(userId));
+            storeAfterSales.setCompanyId(order.getCompanyId());
+            storeAfterSales.setCompanyUserId(order.getCompanyUserId());
+            liveAfterSalesService.insertLiveAfterSales(storeAfterSales);
+            //售后商品详情
+            for (LiveAfterSalesProductParam productParam : param.getProductList()) {
+                LiveOrderItem item = orderItems.stream().filter(p -> p.getProductId().equals(productParam.getProductId())).findFirst().orElse(new LiveOrderItem());
+                LiveAfterSalesItem storeAfterSalesItem = new LiveAfterSalesItem();
+                storeAfterSalesItem.setAfterSalesId(storeAfterSales.getId());
+                storeAfterSalesItem.setProductId(item.getProductId());
+                storeAfterSalesItem.setJsonInfo(item.getJsonInfo());
+                storeAfterSalesItem.setIsDel(0);
+                liveAfterSalesItemMapper.insertLiveAfterSalesItem(storeAfterSalesItem);
+            }
+            //操作记录
+            LiveAfterSalesLogs storeAfterSalesStatus = new LiveAfterSalesLogs();
+            storeAfterSalesStatus.setStoreAfterSalesId(storeAfterSales.getId());
+            storeAfterSalesStatus.setChangeType(0);
+            storeAfterSalesStatus.setChangeMessage(AfterSalesStatusEnum.STATUS_0.getDesc());
+            storeAfterSalesStatus.setChangeTime(Timestamp.valueOf(LocalDateTime.now()));
+            FsUserScrm user=userService.selectFsUserById(Long.valueOf(userId));
+            storeAfterSalesStatus.setOperator(user.getNickname());
+            liveAfterSalesLogsMapper.insertLiveAfterSalesLogs(storeAfterSalesStatus);
 
 //        //更新OMS
-        IErpOrderService erpOrderService = getErpService();
-        ErpRefundUpdateRequest request=new ErpRefundUpdateRequest();
-        request.setTid(order.getOrderCode());
-        request.setOid(order.getOrderCode());
-        request.setRefund_state(1);
-        request.setStoreAfterSalesId(storeAfterSales.getId());
-        request.setOrderStatus(orderStatus);
-        if (StringUtils.isNotBlank(order.getExtendOrderId())){
-            BaseResponse response=erpOrderService.refundUpdateLive(request);
-            if(response.getSuccess()){
-                return R.ok();
+            IErpOrderService erpOrderService = getErpService();
+            ErpRefundUpdateRequest request=new ErpRefundUpdateRequest();
+            request.setTid(order.getOrderCode());
+            request.setOid(order.getOrderCode());
+            request.setRefund_state(1);
+            request.setStoreAfterSalesId(storeAfterSales.getId());
+            request.setOrderStatus(orderStatus);
+            if (StringUtils.isNotBlank(order.getExtendOrderId())){
+                BaseResponse response=erpOrderService.refundUpdateLive(request);
+                if(response.getSuccess()){
+                    return R.ok();
+                }
+                else{
+                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
+                    return R.error(response.getErrorDesc());
+                }
             }
-            else{
-                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
-                return R.error(response.getErrorDesc());
+            return R.ok();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        } finally {
+            // 释放锁
+            if (lock.isHeldByCurrentThread()) {
+                lock.unlock();
+                log.info("申请售后订单锁释放成功,订单号:{}", param.getOrderCode());
             }
         }
-        return R.ok();
     }
 
     @Override

+ 15 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java

@@ -400,7 +400,21 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
         try {
             // 从 Redis 获取用户进入时间
             String entryTimeKey = String.format(USER_ENTRY_TIME_KEY, liveId, userId);
-            Long entryTime = redisCache.getCacheObject(entryTimeKey);
+            Object entryTimeObj = redisCache.getCacheObject(entryTimeKey);
+            Long entryTime = null;
+            if (entryTimeObj != null) {
+                if (entryTimeObj instanceof Long) {
+                    entryTime = (Long) entryTimeObj;
+                } else if (entryTimeObj instanceof String) {
+                    try {
+                        entryTime = Long.parseLong((String) entryTimeObj);
+                    } catch (NumberFormatException e) {
+                        log.warn("无法解析进入时间字符串为Long: {}", entryTimeObj);
+                    }
+                } else if (entryTimeObj instanceof Number) {
+                    entryTime = ((Number) entryTimeObj).longValue();
+                }
+            }
             // 获取当前直播/回放状态
             Map<String, Integer> flagMap = this.getLiveFlagWithCache(liveId);
             Integer currentLiveFlag = flagMap.get("liveFlag");