yuhongqi 1 неделя назад
Родитель
Сommit
8478e056c0
45 измененных файлов с 887 добавлено и 190 удалено
  1. 5 5
      fs-common/src/main/java/com/fs/common/core/redis/service/StockDeductService.java
  2. 43 9
      fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java
  3. 5 0
      fs-service/pom.xml
  4. 3 0
      fs-service/src/main/java/com/fs/course/mapper/FsCoursePlaySourceConfigMapper.java
  5. 9 0
      fs-service/src/main/java/com/fs/erp/service/IErpOrderService.java
  6. 8 0
      fs-service/src/main/java/com/fs/erp/service/impl/DfOrderServiceImpl.java
  7. 11 0
      fs-service/src/main/java/com/fs/erp/service/impl/ErpOrderServiceImpl.java
  8. 9 0
      fs-service/src/main/java/com/fs/erp/service/impl/HzOMSErpOrderServiceImpl.java
  9. 186 0
      fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java
  10. 9 0
      fs-service/src/main/java/com/fs/erp/service/impl/K9OrderScrmServiceImpl.java
  11. 8 0
      fs-service/src/main/java/com/fs/erp/service/impl/WdtErpOrderServiceImpl.java
  12. 3 0
      fs-service/src/main/java/com/fs/his/mapper/MerchantAppConfigMapper.java
  13. 4 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsShippingTemplatesRegionScrmMapper.java
  14. 4 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsShippingTemplatesScrmMapper.java
  15. 4 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreCouponUserScrmMapper.java
  16. 5 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductAttrValueScrmMapper.java
  17. 4 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductPurchaseLimitScrmMapper.java
  18. 4 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java
  19. 3 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsUserAddressScrmMapper.java
  20. 3 0
      fs-service/src/main/java/com/fs/hisStore/mapper/FsUserScrmMapper.java
  21. 7 2
      fs-service/src/main/java/com/fs/live/domain/LiveGoods.java
  22. 3 0
      fs-service/src/main/java/com/fs/live/mapper/LiveCompletionPointsRecordMapper.java
  23. 5 0
      fs-service/src/main/java/com/fs/live/mapper/LiveCouponUserMapper.java
  24. 7 0
      fs-service/src/main/java/com/fs/live/mapper/LiveDataMapper.java
  25. 6 1
      fs-service/src/main/java/com/fs/live/mapper/LiveGoodsMapper.java
  26. 3 0
      fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java
  27. 1 0
      fs-service/src/main/java/com/fs/live/mapper/LiveOrderItemMapper.java
  28. 14 1
      fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java
  29. 3 0
      fs-service/src/main/java/com/fs/live/mapper/LiveOrderPaymentMapper.java
  30. 6 1
      fs-service/src/main/java/com/fs/live/mapper/LiveUserFirstEntryMapper.java
  31. 3 0
      fs-service/src/main/java/com/fs/live/mapper/LiveWatchUserMapper.java
  32. 2 1
      fs-service/src/main/java/com/fs/live/service/ILiveGoodsService.java
  33. 3 0
      fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java
  34. 9 1
      fs-service/src/main/java/com/fs/live/service/impl/LiveGoodsServiceImpl.java
  35. 238 156
      fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java
  36. 9 2
      fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java
  37. 2 2
      fs-service/src/main/resources/application-config-druid-bjzm-test.yml
  38. 2 2
      fs-service/src/main/resources/application-config-druid-bjzm.yml
  39. 1 1
      fs-service/src/main/resources/application-druid-bjzm-test.yml
  40. 31 0
      fs-service/src/main/resources/mapper/live/LiveOrderItemMapper.xml
  41. 163 0
      fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml
  42. 22 0
      fs-user-app/src/main/java/com/fs/app/controller/course/CourseQwLoginController.java
  43. 13 1
      fs-user-app/src/main/java/com/fs/app/controller/live/LiveOrderController.java
  44. 2 3
      fs-user-app/src/main/java/com/fs/app/controller/store/ProductScrmController.java
  45. 2 2
      fs-user-app/src/test/java/com/fs/test/StockDeductTest.java

+ 5 - 5
fs-common/src/main/java/com/fs/common/core/redis/service/StockDeductService.java

@@ -53,8 +53,8 @@ public class StockDeductService {
      * @param productId 商品ID
      * @param initStock 初始库存
      */
-    public void initStock(Long productId, Integer initStock) {
-        String stockKey = RedisConstant.STOCK_KEY_PREFIX + productId;
+    public void initStock(Long productId, Long liveId, Integer initStock) {
+        String stockKey = RedisConstant.STOCK_KEY_PREFIX + liveId + ":" + productId;
         redisTemplate.opsForValue().set(stockKey, initStock, 24 * 60 * 60, TimeUnit.SECONDS);
         log.info("商品" + productId + "库存初始化完成,初始库存:" + initStock);
     }
@@ -66,13 +66,13 @@ public class StockDeductService {
      * @param deductNum 扣减数量(默认1)
      * @return 扣减结果:true=成功,false=失败
      */
-    public CompletableFuture<Boolean> deductStockAsync(Long productId, Integer deductNum, Long userId) {
+    public CompletableFuture<Boolean> deductStockAsync(Long productId, Long liveId, Integer deductNum, Long userId) {
         // Java 8 CompletableFuture 异步处理,提升高并发吞吐量
         return CompletableFuture.supplyAsync(() -> {
             // 1. 参数校验(Java 8 Optional 空值处理)
             Integer num = Optional.ofNullable(deductNum).orElse(1);
-            String stockKey = RedisConstant.STOCK_KEY_PREFIX + productId;
-            String lockKey = RedisConstant.LOCK_KEY_PREFIX + productId;
+            String stockKey = RedisConstant.STOCK_KEY_PREFIX + liveId + ":" + productId;
+            String lockKey = RedisConstant.LOCK_KEY_PREFIX + liveId + ":" + productId;
 
             // 3. 尝试获取分布式锁(非阻塞重试,Java 8 Stream API 实现重试)
 // 3. 尝试获取分布式锁(优化:加入随机延迟,避免惊群效应)

+ 43 - 9
fs-live-app/src/main/java/com/fs/live/websocket/service/WebSocketServer.java

@@ -110,7 +110,7 @@ public class WebSocketServer {
         if (live == null) {
             throw new BaseException("未找到直播间");
         }
-        long companyId = live.getCompanyId() == null ? -1L : live.getCompanyId();
+        long companyId = -1L;
         long companyUserId = -1L;
         if (!Objects.isNull(userProperties.get("companyId"))) {
             companyId = (long) userProperties.get("companyId");
@@ -131,7 +131,15 @@ public class WebSocketServer {
 
         // 记录连接信息 管理员不记录
         if (userType == 0) {
-            FsUserScrm fsUser = fsUserService.selectFsUserById(userId);
+            // 缓存用户信息,过期时间4小时
+            String userCacheKey = "fs:user:" + userId;
+            FsUserScrm fsUser = redisCache.getCacheObject(userCacheKey);
+            if (fsUser == null) {
+                fsUser = fsUserService.selectFsUserById(userId);
+                if (fsUser != null) {
+                    redisCache.setCacheObject(userCacheKey, fsUser, 4, TimeUnit.HOURS);
+                }
+            }
             if (Objects.isNull(fsUser)) {
                 throw new BaseException("用户信息错误");
             }
@@ -195,7 +203,15 @@ public class WebSocketServer {
                 broadcastWebMessage(liveId, JSONObject.toJSONString(R.ok().put("data", sendMsgVo)));
             }
 
-            LiveUserFirstEntry liveUserFirstEntry = liveUserFirstEntryService.selectEntityByLiveIdUserId(liveId, userId);
+            // 缓存用户首次进入记录,过期时间4小时
+            String liveUserFirstEntryCacheKey = "live:userFirstEntry:" + liveId + ":" + userId;
+            LiveUserFirstEntry liveUserFirstEntry = redisCache.getCacheObject(liveUserFirstEntryCacheKey);
+            if (liveUserFirstEntry == null) {
+                liveUserFirstEntry = liveUserFirstEntryService.selectEntityByLiveIdUserId(liveId, userId);
+                if (liveUserFirstEntry != null) {
+                    redisCache.setCacheObject(liveUserFirstEntryCacheKey, liveUserFirstEntry, 4, TimeUnit.HOURS);
+                }
+            }
             // 如果用户连上了 socket,并且公司ID和销售ID大于0,更新 LiveWatchLog 的 logType
 
             if ((qwUserId > 0 && externalContactId > 0) || (liveUserFirstEntry != null && liveUserFirstEntry.getCompanyId() > 0 && liveUserFirstEntry.getCompanyUserId() > 0 )) {
@@ -226,9 +242,19 @@ public class WebSocketServer {
             } else {
                 // 这个用户A邀请用户b,b的业绩算a的销售的
                 if (companyId == -2L) {
-                    LiveUserFirstEntry clientB = liveUserFirstEntryService.selectEntityByLiveIdUserId(liveId, companyUserId);
-                    companyId = clientB.getCompanyId();
-                    companyUserId = clientB.getCompanyUserId();
+                    // 缓存用户首次进入记录,过期时间4小时
+                    String clientBCacheKey = "live:userFirstEntry:" + liveId + ":" + companyUserId;
+                    LiveUserFirstEntry clientB = redisCache.getCacheObject(clientBCacheKey);
+                    if (clientB == null) {
+                        clientB = liveUserFirstEntryService.selectEntityByLiveIdUserId(liveId, companyUserId);
+                        if (clientB != null) {
+                            redisCache.setCacheObject(clientBCacheKey, clientB, 4, TimeUnit.HOURS);
+                        }
+                    }
+                    if (clientB != null) {
+                        companyId = clientB.getCompanyId();
+                        companyUserId = clientB.getCompanyUserId();
+                    }
                 }
                 Date date = new Date();
                 liveUserFirstEntry = new LiveUserFirstEntry();
@@ -247,10 +273,10 @@ public class WebSocketServer {
                 }
                 liveUserFirstEntryService.insertLiveUserFirstEntry(liveUserFirstEntry);
             }
-            redisCache.setCacheObject( "live:user:first:entry:" + liveId + ":" + userId, liveUserFirstEntry,1, TimeUnit.HOURS);
+            redisCache.setCacheObject( "live:user:first:entry:" + liveId + ":" + userId, liveUserFirstEntry, 4, TimeUnit.HOURS);
 
             // 推送完课积分倒计时配置信息给前端
-            sendCompletionPointsConfigToUser(session, liveId, userId, live);
+//            sendCompletionPointsConfigToUser(session, liveId, userId, live);
 
 
         } else {
@@ -287,7 +313,15 @@ public class WebSocketServer {
         ConcurrentHashMap<Long, Session> room = getRoom(liveId);
         List<Session> adminRoom = getAdminRoom(liveId);
         if (userType == 0) {
-            FsUserScrm fsUser = fsUserService.selectFsUserById(userId);
+            // 缓存用户信息,过期时间4小时
+            String userCacheKey = "fs:user:" + userId;
+            FsUserScrm fsUser = redisCache.getCacheObject(userCacheKey);
+            if (fsUser == null) {
+                fsUser = fsUserService.selectFsUserById(userId);
+                if (fsUser != null) {
+                    redisCache.setCacheObject(userCacheKey, fsUser, 4, TimeUnit.HOURS);
+                }
+            }
             if (Objects.isNull(fsUser)) {
                 throw new BaseException("用户信息错误");
             }

+ 5 - 0
fs-service/pom.xml

@@ -297,6 +297,11 @@
             <artifactId>volc-sdk-java</artifactId>
             <version>1.0.250</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.retry</groupId>
+            <artifactId>spring-retry</artifactId>
+            <version>1.3.1</version>
+        </dependency>
 
 
     </dependencies>

+ 3 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCoursePlaySourceConfigMapper.java

@@ -1,6 +1,8 @@
 package com.fs.course.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.course.domain.FsCoursePlaySourceConfig;
 import com.fs.course.vo.FsCoursePlaySourceConfigVO;
 import org.apache.ibatis.annotations.Param;
@@ -15,5 +17,6 @@ public interface FsCoursePlaySourceConfigMapper extends BaseMapper<FsCoursePlayS
      */
     List<FsCoursePlaySourceConfigVO> selectCoursePlaySourceConfigVOListByMap(@Param("params") Map<String, Object> params);
 
+    @DataSource(DataSourceType.SLAVE)
     FsCoursePlaySourceConfig selectCoursePlaySourceConfigByAppId(String appId);
 }

+ 9 - 0
fs-service/src/main/java/com/fs/erp/service/IErpOrderService.java

@@ -7,6 +7,8 @@ import com.fs.his.domain.FsStoreOrder;
 import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.live.domain.LiveOrder;
 
+import java.util.List;
+
 public interface IErpOrderService
 {
 
@@ -34,5 +36,12 @@ public interface IErpOrderService
 
     void getOrderScrmDeliveryStatus(FsStoreOrderScrm order);
     void getOrderLiveDeliveryStatus(LiveOrder order);
+    
+    /**
+     * 批量查询直播订单
+     * @param orderList 订单列表
+     * @return 查询结果
+     */
+    ErpOrderQueryResponse batchGetLiveOrder(List<LiveOrder> orderList);
 }
 

+ 8 - 0
fs-service/src/main/java/com/fs/erp/service/impl/DfOrderServiceImpl.java

@@ -1020,6 +1020,14 @@ public class DfOrderServiceImpl implements IErpOrderService {
         }
     }
 
+    @Override
+    public ErpOrderQueryResponse batchGetLiveOrder(List<LiveOrder> orderList) {
+        ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+        response.setOrders(Collections.emptyList());
+        response.setSuccess(true);
+        return response;
+    }
+
     private void cancelOrderLive(LiveOrder order) {
         Integer deliveryStatus = order.getDeliveryStatus();
         if (deliveryStatus == null || deliveryStatus == 0) {

+ 11 - 0
fs-service/src/main/java/com/fs/erp/service/impl/ErpOrderServiceImpl.java

@@ -15,6 +15,9 @@ import com.fs.hisStore.domain.FsStoreOrderScrm;
 import com.fs.live.domain.LiveOrder;
 import com.fs.live.mapper.LiveOrderMapper;
 import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.List;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -193,4 +196,12 @@ public class ErpOrderServiceImpl implements IErpOrderService
     public void getOrderLiveDeliveryStatus(LiveOrder order) {
 
     }
+
+    @Override
+    public ErpOrderQueryResponse batchGetLiveOrder(List<LiveOrder> orderList) {
+        ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+        response.setOrders(Collections.emptyList());
+        response.setSuccess(true);
+        return response;
+    }
 }

+ 9 - 0
fs-service/src/main/java/com/fs/erp/service/impl/HzOMSErpOrderServiceImpl.java

@@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -345,6 +346,14 @@ public class HzOMSErpOrderServiceImpl implements IErpOrderService {
 
     }
 
+    @Override
+    public ErpOrderQueryResponse batchGetLiveOrder(List<LiveOrder> orderList) {
+        ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+        response.setOrders(Collections.emptyList());
+        response.setSuccess(true);
+        return response;
+    }
+
     /**
      * 构建瀚智创建订单参数
      *

+ 186 - 0
fs-service/src/main/java/com/fs/erp/service/impl/JSTErpOrderServiceImpl.java

@@ -1135,5 +1135,191 @@ public class JSTErpOrderServiceImpl implements IErpOrderService {
     public void getOrderLiveDeliveryStatus(LiveOrder order) {
 
     }
+
+    /**
+     * 批量查询直播订单
+     * @param orderList 订单列表
+     * @return 查询结果
+     */
+    @Override
+    public ErpOrderQueryResponse batchGetLiveOrder(List<LiveOrder> orderList) {
+        if (CollectionUtils.isEmpty(orderList)) {
+            ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+            response.setOrders(Collections.emptyList());
+            response.setSuccess(true);
+            return response;
+        }
+
+        // 提取所有 extendOrderId
+        List<Long> extendOrderIds = orderList.stream()
+                .filter(order -> StringUtils.isNotEmpty(order.getExtendOrderId()))
+                .map(order -> Long.valueOf(order.getExtendOrderId()))
+                .collect(Collectors.toList());
+
+        if (CollectionUtils.isEmpty(extendOrderIds)) {
+            ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+            response.setOrders(Collections.emptyList());
+            response.setSuccess(true);
+            return response;
+        }
+
+        // 构建批量查询请求
+        OrderQueryRequestDTO requestDTO = new OrderQueryRequestDTO();
+        requestDTO.setOIds(extendOrderIds);
+        requestDTO.setOrderItemFlds(Arrays.asList("status"));
+
+        // 调用ERP服务查询订单
+        OrderQueryResponseDTO query = jstErpHttpService.query(requestDTO);
+
+        // 构建响应对象
+        ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+        List<Map<String, Object>> channelUpdateList = new ArrayList<>();
+        List<ErpOrderQuery> erpOrders = new ArrayList<>();
+
+        if (query.getOrders() != null && !query.getOrders().isEmpty()) {
+            // 创建订单映射,方便查找
+            Map<String, LiveOrder> orderMap = orderList.stream()
+                    .collect(Collectors.toMap(
+                            LiveOrder::getExtendOrderId,
+                            order -> order,
+                            (existing, replacement) -> existing
+                    ));
+
+            List<LiveOrder> splitOrders = new ArrayList<>();
+            // 收集需要更新channel字段的订单(其他状态)
+
+
+            // 处理查询结果
+            for (OrderQueryResponseDTO.Order order : query.getOrders()) {
+                String status = order.getStatus();
+                LiveOrder liveOrder = orderMap.get(String.valueOf(order.getOId()));
+
+                if (liveOrder == null) {
+                    continue;
+                }
+
+                // 如果是 sent 状态,正常处理
+                if (ErpQueryOrderStatusEnum.SENT.getCode().equals(status)) {
+                    ErpOrderQuery erpOrder = convertToErpOrderQueryLive(order);
+                    erpOrders.add(erpOrder);
+                }
+                // 如果是 split 状态,收集起来后续处理
+                else if ("Split".equals(status)) {
+                    splitOrders.add(liveOrder);
+                }
+                // 其他状态,收集起来最后统一批量更新
+                else {
+                    Map<String, Object> updateMap = new HashMap<>();
+                    updateMap.put("orderId", liveOrder.getOrderId());
+                    updateMap.put("channel", status);
+                    channelUpdateList.add(updateMap);
+                    log.info("订单状态待写入channel字段,orderCode: {}, status: {}", liveOrder.getOrderCode(), status);
+                }
+            }
+
+            // 处理 split 状态的订单,按照 getLiveOrder 的逻辑处理
+            if (!splitOrders.isEmpty()) {
+                // 对每个拆分订单,使用 soId 重新查询聚水潭,获取所有相关订单
+                for (LiveOrder splitLiveOrder : splitOrders) {
+                    try {
+                        // 使用订单号(soId)重新查询聚水潭,获取所有相关订单
+                        OrderQueryRequestDTO splitRequestDTO = new OrderQueryRequestDTO();
+                        splitRequestDTO.setSoIds(Collections.singletonList(splitLiveOrder.getOrderCode()));
+                        splitRequestDTO.setOrderItemFlds(Arrays.asList("status"));
+
+                        // 重新查询聚水潭
+                        OrderQueryResponseDTO splitQuery = jstErpHttpService.query(splitRequestDTO);
+
+                        if (splitQuery != null && splitQuery.getOrders() != null && !splitQuery.getOrders().isEmpty()) {
+                            // 查找状态不为拆分并且已发货的订单
+                            OrderQueryResponseDTO.Order sentOrder = splitQuery.getOrders().stream()
+                                    .filter(order -> !"Split".equals(order.getStatus()) 
+                                            && ErpQueryOrderStatusEnum.SENT.getCode().equals(order.getStatus()))
+                                    .findFirst()
+                                    .orElse(null);
+
+                            if (sentOrder != null) {
+                                // 找到符合条件的订单,同步物流状态并转换
+                                // 同步物流状态 - 更新订单的物流信息
+                                LiveOrder updateOrder = new LiveOrder();
+                                updateOrder.setOrderId(splitLiveOrder.getOrderId());
+                                if (StringUtils.isNotEmpty(sentOrder.getLogisticsCompany())) {
+                                    updateOrder.setDeliveryName(sentOrder.getLogisticsCompany());
+                                }
+                                if (StringUtils.isNotEmpty(sentOrder.getLId())) {
+                                    updateOrder.setDeliverySn(sentOrder.getLId());
+                                }
+                                if (StringUtils.isNotEmpty(sentOrder.getLcId())) {
+                                    updateOrder.setDeliveryCode(sentOrder.getLcId());
+                                }
+                                if (StringUtils.isNotEmpty(sentOrder.getSendDate())) {
+                                    try {
+                                        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                        Date sendDate = formatter.parse(sentOrder.getSendDate());
+                                        updateOrder.setDeliverySendTime(sendDate);
+                                        updateOrder.setDeliveryTime(sentOrder.getSendDate());
+                                    } catch (Exception e) {
+                                        log.error("解析发货时间失败: {}", sentOrder.getSendDate(), e);
+                                    }
+                                }
+                                liveOrderMapper.updateLiveOrder(updateOrder);
+                                log.info("拆分订单查询:找到已发货订单并同步物流状态,orderCode: {}, status: {}, logisticsCompany: {}, deliverySn: {}", 
+                                        sentOrder.getSoId(), sentOrder.getStatus(), sentOrder.getLogisticsCompany(), sentOrder.getLId());
+
+                                // 转换并添加到结果中
+                                ErpOrderQuery erpOrder = convertToErpOrderQueryLive(sentOrder);
+                                erpOrders.add(erpOrder);
+                            } else {
+                                // 如果没有找到已发货的订单,记录日志
+                                log.warn("拆分订单查询:未找到已发货的非拆分订单,orderCode: {}", splitLiveOrder.getOrderCode());
+                            }
+                        } else {
+                            // 重新查询失败,记录日志
+                            log.error("拆分订单查询:重新查询聚水潭失败,orderCode: {}", splitLiveOrder.getOrderCode());
+                        }
+                    } catch (Exception e) {
+                        log.error("处理拆分订单异常,orderCode: {}", splitLiveOrder.getOrderCode(), e);
+                    }
+                }
+            }
+
+            response.setOrders(erpOrders);
+        } else {
+            response.setOrders(Collections.emptyList());
+        }
+
+        // 统一批量更新其他状态的订单channel字段
+        if (!channelUpdateList.isEmpty()) {
+            batchUpdateChannel(channelUpdateList);
+        }
+
+        response.setSuccess(true);
+        return response;
+    }
+
+    /**
+     * 批量更新订单channel字段
+     * @param channelUpdateList 订单ID和channel的映射列表
+     */
+    private void batchUpdateChannel(List<Map<String, Object>> channelUpdateList) {
+        try {
+            liveOrderMapper.batchUpdateChannelByOrderIds(channelUpdateList);
+            log.info("批量更新订单channel字段完成,共更新{}条记录", channelUpdateList.size());
+        } catch (Exception e) {
+            log.error("批量更新订单channel字段失败", e);
+            // 如果批量更新失败,可以降级为单个更新
+            for (Map<String, Object> updateMap : channelUpdateList) {
+                try {
+                    LiveOrder updateOrder = new LiveOrder();
+                    updateOrder.setOrderId((Long) updateMap.get("orderId"));
+                    updateOrder.setChannel((String) updateMap.get("channel"));
+                    liveOrderMapper.updateLiveOrder(updateOrder);
+                } catch (Exception ex) {
+                    log.error("单个更新订单channel字段失败,orderId: {}, channel: {}", 
+                            updateMap.get("orderId"), updateMap.get("channel"), ex);
+                }
+            }
+        }
+    }
 }
 

+ 9 - 0
fs-service/src/main/java/com/fs/erp/service/impl/K9OrderScrmServiceImpl.java

@@ -36,6 +36,7 @@ import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -636,4 +637,12 @@ public class K9OrderScrmServiceImpl implements IErpOrderService {
     public void getOrderLiveDeliveryStatus(LiveOrder order) {
 
     }
+
+    @Override
+    public ErpOrderQueryResponse batchGetLiveOrder(List<LiveOrder> orderList) {
+        ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+        response.setOrders(Collections.emptyList());
+        response.setSuccess(true);
+        return response;
+    }
 }

+ 8 - 0
fs-service/src/main/java/com/fs/erp/service/impl/WdtErpOrderServiceImpl.java

@@ -1309,6 +1309,14 @@ public class WdtErpOrderServiceImpl implements IErpOrderService {
 
     }
 
+    @Override
+    public ErpOrderQueryResponse batchGetLiveOrder(List<LiveOrder> orderList) {
+        ErpOrderQueryResponse response = new ErpOrderQueryResponse();
+        response.setOrders(Collections.emptyList());
+        response.setSuccess(true);
+        return response;
+    }
+
     public static String convertToSnakeCase(Object obj) {
         SerializeConfig config = new SerializeConfig();
         config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;

+ 3 - 0
fs-service/src/main/java/com/fs/his/mapper/MerchantAppConfigMapper.java

@@ -2,6 +2,8 @@ package com.fs.his.mapper;
 
 import java.util.List;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.his.domain.MerchantAppConfig;
 
 /**
@@ -30,6 +32,7 @@ public interface MerchantAppConfigMapper extends BaseMapper<MerchantAppConfig>{
      * @param id 商户应用配置主键
      * @return 商户应用配置
      */
+    @DataSource(DataSourceType.SLAVE)
     MerchantAppConfig selectMerchantAppConfigById(Long id);
 
     /**

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsShippingTemplatesRegionScrmMapper.java

@@ -1,6 +1,9 @@
 package com.fs.hisStore.mapper;
 
 import java.util.List;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.hisStore.domain.FsShippingTemplatesRegionScrm;
 import org.apache.ibatis.annotations.Delete;
 import org.apache.ibatis.annotations.Param;
@@ -65,5 +68,6 @@ public interface FsShippingTemplatesRegionScrmMapper
     @Delete("delete from fs_shipping_templates_region where temp_id=#{tempId}")
     int deleteFsShippingTemplatesRegionByTempId(Long tempId);
     @Select("select * from fs_shipping_templates_region where find_in_set(temp_id,#{tempIds}) and find_in_set(city_id,#{cityIds})")
+    @DataSource(DataSourceType.SLAVE)
     List<FsShippingTemplatesRegionScrm> selectFsShippingTemplatesRegionListByTempIdsAndCityIds(@Param("tempIds") String tempIds, @Param("cityIds") String cityIds);
 }

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsShippingTemplatesScrmMapper.java

@@ -1,6 +1,9 @@
 package com.fs.hisStore.mapper;
 
 import java.util.List;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.hisStore.domain.FsShippingTemplatesScrm;
 import org.apache.ibatis.annotations.Select;
 
@@ -59,6 +62,7 @@ public interface FsShippingTemplatesScrmMapper
      * @return 结果
      */
     public int deleteFsShippingTemplatesByIds(Long[] id);
+    @DataSource(DataSourceType.SLAVE)
     @Select("select * from fs_shipping_templates where find_in_set(id,#{ids})")
     List<FsShippingTemplatesScrm> selectFsShippingTemplatesByIds(String ids);
 }

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreCouponUserScrmMapper.java

@@ -1,6 +1,9 @@
 package com.fs.hisStore.mapper;
 
 import java.util.List;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.hisStore.domain.FsStoreCouponUserScrm;
 import com.fs.hisStore.param.FsCouponUserEnableParam;
 import com.fs.hisStore.vo.FsStoreCouponUserVO;
@@ -22,6 +25,7 @@ public interface FsStoreCouponUserScrmMapper
      * @param id 优惠券发放记录ID
      * @return 优惠券发放记录
      */
+    @DataSource(DataSourceType.SLAVE)
     public FsStoreCouponUserScrm selectFsStoreCouponUserById(Long id);
 
     /**

+ 5 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductAttrValueScrmMapper.java

@@ -2,6 +2,8 @@ package com.fs.hisStore.mapper;
 
 import java.util.List;
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.hisStore.config.MedicalMallConfig;
 import com.fs.hisStore.domain.FsStoreProductAttrValueScrm;
 import com.fs.hisStore.param.FsProductAttrValueParam;
@@ -29,6 +31,7 @@ public interface FsStoreProductAttrValueScrmMapper
      * @param id 商品属性值ID
      * @return 商品属性值
      */
+    @DataSource(DataSourceType.SLAVE)
         public FsStoreProductAttrValueScrm selectFsStoreProductAttrValueById(Long id);
 
     /**
@@ -73,6 +76,7 @@ public interface FsStoreProductAttrValueScrmMapper
     @Delete("delete from fs_store_product_attr_value_scrm where product_id=#{productId}")
     int deleteFsStoreProductAttrValueByProductId(Long productId);
     @Select("select * from fs_store_product_attr_value_scrm where  product_id=#{productId}")
+    @DataSource(DataSourceType.SLAVE)
     List<FsStoreProductAttrValueScrm> selectFsStoreProductAttrValueByProductId(Long productId);
     @Select("select ifnull(stock,0) from fs_store_product_attr_value_scrm where  id=#{productAttrValueId}")
     int selectFsStoreProductStockById(Long productAttrValueId);
@@ -81,6 +85,7 @@ public interface FsStoreProductAttrValueScrmMapper
      * 使用行锁查询规格库存
      */
     @Select("select ifnull(stock,0) from fs_store_product_attr_value_scrm where id=#{productAttrValueId} for update")
+    @DataSource(DataSourceType.SLAVE)
     Integer selectProductAttrStockForUpdate(@Param("productAttrValueId") Long productAttrValueId);
 
     @Update("update fs_store_product_attr_value_scrm set stock=stock-#{num},sales=sales+#{num}" +

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductPurchaseLimitScrmMapper.java

@@ -1,6 +1,9 @@
 package com.fs.hisStore.mapper;
 
 import java.util.List;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.hisStore.domain.FsStoreProductPurchaseLimitScrm;
 import org.apache.ibatis.annotations.Param;
 
@@ -35,6 +38,7 @@ public interface FsStoreProductPurchaseLimitScrmMapper
      * @param userId 用户ID
      * @return 商品限购
      */
+    @DataSource(DataSourceType.SLAVE)
     public FsStoreProductPurchaseLimitScrm selectByProductIdAndUserId(@Param("productId") Long productId, @Param("userId") Long userId);
 
     /**

+ 4 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreProductScrmMapper.java

@@ -3,6 +3,8 @@ package com.fs.hisStore.mapper;
 import java.util.List;
 import java.util.Map;
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.common.param.BaseQueryParam;
 import com.fs.his.domain.FsStoreProduct;
 import com.fs.his.param.FsStoreProductListSParam;
@@ -34,6 +36,7 @@ public interface FsStoreProductScrmMapper
      * @param productId 商品ID
      * @return 商品
      */
+    @DataSource(DataSourceType.SLAVE)
     public FsStoreProductScrm selectFsStoreProductById(Long productId);
 
     /**
@@ -260,6 +263,7 @@ public interface FsStoreProductScrmMapper
      * 使用行锁查询商品库存
      */
     @Select("select stock from fs_store_product_scrm where product_id=#{productId} for update")
+    @DataSource(DataSourceType.SLAVE)
     Integer selectProductStockForUpdate(@Param("productId") Long productId);
     @Update("update fs_store_product_scrm set stock=stock+#{num}, sales=sales-#{num}" +
             " where product_id=#{productId}")

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsUserAddressScrmMapper.java

@@ -2,6 +2,8 @@ package com.fs.hisStore.mapper;
 
 import java.util.List;
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.his.domain.FsUserAddress;
 import com.fs.hisStore.domain.FsUserAddressScrm;
 import org.apache.ibatis.annotations.Select;
@@ -72,5 +74,6 @@ public interface FsUserAddressScrmMapper
     Integer delAllAddress(Long userId);
 
     @Select("select * from fs_user_address where user_id=#{uid} and is_default=1 and is_del=0 limit 1")
+    @DataSource(DataSourceType.SLAVE)
     FsUserAddress selectFsUserAddressByDefault(long userId);
 }

+ 3 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsUserScrmMapper.java

@@ -1,5 +1,7 @@
 package com.fs.hisStore.mapper;
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.course.vo.newfs.FsCourseAnalysisCountVO;
 import com.fs.his.domain.FsUser;
 import com.fs.his.vo.OptionsVO;
@@ -41,6 +43,7 @@ public interface FsUserScrmMapper
      * @param userId 用户ID
      * @return 用户
      */
+    @DataSource(DataSourceType.SLAVE)
     public FsUserScrm selectFsUserById(Long userId);
 
     /**

+ 7 - 2
fs-service/src/main/java/com/fs/live/domain/LiveGoods.java

@@ -1,8 +1,12 @@
 package com.fs.live.domain;
 
 
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.fs.common.annotation.Excel;
 import com.fs.common.core.domain.BaseEntity;
+import com.fs.common.core.domain.BaseEntityTow;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 
@@ -13,10 +17,10 @@ import lombok.EqualsAndHashCode;
  * @date 2025-07-08
  */
 @Data
-@EqualsAndHashCode(callSuper = true)
 public class LiveGoods extends BaseEntity{
 
     /** ID */
+    @TableId(type = IdType.AUTO)
     private Long goodsId;
 
     /** 直播ID */
@@ -60,8 +64,9 @@ public class LiveGoods extends BaseEntity{
     private Long sort;
 
     /** 商品名称搜索关键字*/
-
+    @TableField(exist = false)
     private String keywords;
+    @TableField(exist = false)
     private String productName;
 
 

+ 3 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveCompletionPointsRecordMapper.java

@@ -1,5 +1,7 @@
 package com.fs.live.mapper;
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.LiveCompletionPointsRecord;
 import org.apache.ibatis.annotations.Param;
 
@@ -36,6 +38,7 @@ public interface LiveCompletionPointsRecordMapper {
     /**
      * 查询用户在某直播间最近一次完课记录(不限制日期)
      */
+    @DataSource(DataSourceType.SLAVE)
     LiveCompletionPointsRecord selectLatestByUserAndLiveId(@Param("liveId") Long liveId, 
                                                             @Param("userId") Long userId);
 

+ 5 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveCouponUserMapper.java

@@ -1,6 +1,9 @@
 package com.fs.live.mapper;
 
 import java.util.List;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.LiveCouponUser;
 import com.fs.live.param.CouponPO;
 import org.apache.ibatis.annotations.Param;
@@ -20,6 +23,7 @@ public interface LiveCouponUserMapper
      * @param id 优惠券发放记录ID
      * @return 优惠券发放记录
      */
+    @DataSource(DataSourceType.SLAVE)
     public LiveCouponUser selectLiveCouponUserById(Long id);
 
     /**
@@ -71,5 +75,6 @@ public interface LiveCouponUserMapper
             " and (lcu.goods_id= #{coupon.goodsId} or lcu.goods_id is null or lcu.goods_id = 0)" +
             " </if>" +
             "</script>")
+    @DataSource(DataSourceType.SLAVE)
     List<LiveCouponUser> curCoupon(@Param("coupon") CouponPO coupon);
 }

+ 7 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveDataMapper.java

@@ -1,6 +1,8 @@
 package com.fs.live.mapper;
 
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.LiveData;
 import com.fs.live.vo.LiveDashBoardDataVo;
 import com.fs.live.vo.LiveDataDetailVo;
@@ -140,6 +142,7 @@ public interface LiveDataMapper {
             "FROM " +
             "    live_data ld " +
             "where ld.live_id=#{liveId}")
+    @DataSource(DataSourceType.SLAVE)
     Map<String, Integer> selectDashboardCount(@Param("liveId") Long liveId);
 
     /**
@@ -147,6 +150,7 @@ public interface LiveDataMapper {
      * @param liveIds 直播间ID列表
      * @return 统计数据
      */
+    @DataSource(DataSourceType.SLAVE)
     LiveDataStatisticsVo selectLiveDataStatistics(@Param("liveIds") List<Long> liveIds);
 
     /**
@@ -154,6 +158,7 @@ public interface LiveDataMapper {
      * @param liveIds 直播间ID列表
      * @return 列表数据
      */
+    @DataSource(DataSourceType.SLAVE)
     List<LiveDataListVo> selectLiveDataListByLiveIds(@Param("liveIds") List<Long> liveIds);
 
     /**
@@ -161,6 +166,7 @@ public interface LiveDataMapper {
      * @param liveId 直播间ID
      * @return 详情数据
      */
+    @DataSource(DataSourceType.SLAVE)
     LiveDataDetailVo selectLiveDataDetailBySql(@Param("liveId") Long liveId);
 
     /**
@@ -168,5 +174,6 @@ public interface LiveDataMapper {
      * @param liveId 直播间ID
      * @return 用户详情列表
      */
+    @DataSource(DataSourceType.SLAVE)
     List<LiveUserDetailVo> selectLiveUserDetailListBySql(@Param("liveId") Long liveId,@Param("companyId") Long companyId,@Param("companyUserId") Long companyUserId);
 }

+ 6 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveGoodsMapper.java

@@ -1,5 +1,8 @@
 package com.fs.live.mapper;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.LiveGoods;
 import com.fs.live.domain.LiveOrder;
 import com.fs.live.vo.LiveGoodsListVo;
@@ -17,7 +20,7 @@ import java.util.Map;
  * @author fs
  * @date 2025-07-08
  */
-public interface LiveGoodsMapper {
+public interface LiveGoodsMapper extends BaseMapper<LiveGoods> {
     /**
      * 查询直播商品
      *
@@ -90,6 +93,7 @@ public interface LiveGoodsMapper {
      * @param liveGoods 直播商品
      * @return 商品信息集合
      */
+    @DataSource(DataSourceType.SLAVE)
     List<LiveGoodsVo> selectProductListByLiveId(LiveGoods liveGoods);
 
     /**
@@ -112,6 +116,7 @@ public interface LiveGoodsMapper {
     List<LiveGoodsVo> selectProductListByOrder(LiveOrder liveOrder);
 
     @Select("select * from live_goods where live_id = #{liveId} and product_id = #{productId}")
+    @DataSource(DataSourceType.SLAVE)
     LiveGoods selectLiveGoodsByProductId(@Param("liveId") Long liveId,@Param("productId") Long productId);
 
     /**

+ 3 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveMapper.java

@@ -1,6 +1,8 @@
 package com.fs.live.mapper;
 
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.Live;
 import com.fs.live.param.LiveDataParam;
 import com.fs.live.vo.LiveListVo;
@@ -24,6 +26,7 @@ public interface LiveMapper
      * @param liveId 直播主键
      * @return 直播
      */
+    @DataSource(DataSourceType.SLAVE)
     public Live selectLiveByLiveId(Long liveId);
 
     /**

+ 1 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveOrderItemMapper.java

@@ -41,6 +41,7 @@ public interface LiveOrderItemMapper {
      * @return 结果
      */
     int insertLiveOrderItem(LiveOrderItem liveOrderItem);
+    int insertLiveOrderItemTest(LiveOrderItem liveOrderItem);
 
     /**
      * 修改订单详情

+ 14 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveOrderMapper.java

@@ -1,6 +1,8 @@
 package com.fs.live.mapper;
 
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.hisStore.vo.FsStoreOrderItemExportZMVO;
 import com.fs.live.domain.LiveOrder;
 import com.fs.live.dto.LiveOrderDeliveryNoteDTO;
@@ -41,6 +43,7 @@ public interface LiveOrderMapper {
      * @param liveOrder 订单
      * @return 订单集合
      */
+    @DataSource(DataSourceType.SLAVE)
     List<LiveOrder> selectLiveOrderList(LiveOrder liveOrder);
 
     /**
@@ -50,6 +53,7 @@ public interface LiveOrderMapper {
      * @return 结果
      */
     int insertLiveOrder(LiveOrder liveOrder);
+    int insertLiveOrderTest(LiveOrder liveOrder);
 
     /**
      * 修改订单
@@ -103,14 +107,17 @@ public interface LiveOrderMapper {
             "</where> " +
             "order by create_time desc" +
             "</script>"})
+    @DataSource(DataSourceType.SLAVE)
     List<LiveOrderListVo> selectLiveOrderListVo(@Param("userId") String userId,@Param("status") Integer status);
 
     @Select("select * from live_order where `status` = 3 AND TIMESTAMPDIFF(HOUR, start_time, NOW()) >= 48  ")
     List<LiveOrder> selectLiveOrderByFinish();
 
     @Select("select * from live_order where `status` = 1 and extend_order_id is not null and (delivery_sn is null or delivery_code = '') and refund_status = 0 and is_pay = 1 order by update_time ")
+    @DataSource(DataSourceType.SLAVE)
     List<LiveOrder> selectUpdateExpress();
 
+
     @Select("select order_id from live_order where `status` = 2 and delivery_code is not null and delivery_sn is not null and is_pay = 1")
     List<Long> selectSyncExpressIds();
 
@@ -480,6 +487,12 @@ public interface LiveOrderMapper {
      */
     void batchUpdateInOrderCode(@Param("list") List<LiveOrderDeliveryNoteDTO> dtoList);
 
+    /**
+     * 批量更新订单channel字段
+     * @param maps 订单ID和channel的映射列表,每个map包含orderId和channel
+     */
+    void batchUpdateChannelByOrderIds(@Param("maps") List<Map<String, Object>> maps);
+
     @Select("SELECT * FROM live_order WHERE user_id=#{userId} LIMIT 1")
     LiveOrder selectOrderByUserIdLimit1(@Param("userId") Long userId);
 
@@ -489,7 +502,7 @@ public interface LiveOrderMapper {
     /*
     * 查询订单创建时间为最近30分钟的订单
     * */
-    @Select("SELECT * FROM live_order WHERE create_time >= DATE_SUB(NOW(), INTERVAL 15 MINUTE) and status = 0 and refund_status = 0")
+    @Select("SELECT * FROM live_order WHERE create_time >= '2026-01-15 19:00:00' and status = 0 and refund_status = 0")
     List<LiveOrder> selectBankOrder();
 
 

+ 3 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveOrderPaymentMapper.java

@@ -1,6 +1,8 @@
 package com.fs.live.mapper;
 
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.LiveOrderPayment;
 import com.fs.live.vo.LiveOrderPaymentVo;
 import org.apache.ibatis.annotations.Param;
@@ -22,6 +24,7 @@ public interface LiveOrderPaymentMapper {
      * @param paymentId 支付明细主键
      * @return 支付明细
      */
+    @DataSource(DataSourceType.SLAVE)
     LiveOrderPayment selectLiveOrderPaymentByPaymentId(Long paymentId);
 
     /**

+ 6 - 1
fs-service/src/main/java/com/fs/live/mapper/LiveUserFirstEntryMapper.java

@@ -1,6 +1,8 @@
 package com.fs.live.mapper;
 
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.LiveUserFirstEntry;
 import com.fs.live.vo.LiveDashBoardDataVo;
 import com.fs.live.vo.LiveUserFirstProfit;
@@ -71,10 +73,11 @@ public interface LiveUserFirstEntryMapper {
 
     @Select("select count(*) from live_user_first_entry where user_id=#{userId} and DATE(entry_date)=DATE(#{now})")
     int selectTodayEntry(@Param("userId") long userId,@Param("now") Date now);
-
+    @DataSource(DataSourceType.SLAVE)
     List<LiveUserFirstProfit> selectLiveProfitList();
 
     @Select("select * from live_user_first_entry where live_id=#{liveId} and user_id=#{userId}")
+    @DataSource(DataSourceType.SLAVE)
     LiveUserFirstEntry selectEntityByLiveIdUserId(@Param("liveId") long liveId,@Param("userId") long userId);
 
     @Select("SELECT  " +
@@ -90,6 +93,7 @@ public interface LiveUserFirstEntryMapper {
             "ORDER BY  " +
             "  invite_num DESC   " +
             "  LIMIT 10")
+    @DataSource(DataSourceType.SLAVE)
     List<LiveUserFirstVo> selectDashboardInviteCount(@Param("liveId") Long liveId);
 
     @Select("SELECT  " +
@@ -104,6 +108,7 @@ public interface LiveUserFirstEntryMapper {
             "  lufe.company_user_id   " +
             "ORDER BY  " +
             "  invite_num DESC   ")
+    @DataSource(DataSourceType.SLAVE)
     List<LiveUserFirstVo> inviteList(@Param("liveId") Long liveId);
 
     @Select("SELECT  sum(case when company_user_id > 0 then 1 else 0 end ) as shareUrlNum, " +

+ 3 - 0
fs-service/src/main/java/com/fs/live/mapper/LiveWatchUserMapper.java

@@ -1,6 +1,8 @@
 package com.fs.live.mapper;
 
 
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
 import com.fs.live.domain.LiveWatchUser;
 import com.fs.live.vo.LiveDashBoardDataVo;
 import com.fs.live.vo.LiveWatchUserEntry;
@@ -148,6 +150,7 @@ public interface LiveWatchUserMapper {
     @Select("select lufe.company_id,lufe.company_user_id,lwu.* from live_watch_user lwu" +
             " left join live_user_first_entry lufe on lwu.live_id = lufe.live_id and lwu.user_id = lufe.user_id" +
             " where lwu.live_id = #{liveId} and lwu.user_id = #{userId} and lwu.live_flag = #{liveFlag} and lwu.replay_flag = #{replayFlag} limit 1 ")
+    @DataSource(DataSourceType.SLAVE)
     LiveWatchUserEntry selectLiveWatchAndCompanyUserByFlag(@Param("liveId") Long liveId,@Param("userId") Long userId,@Param("liveFlag") Integer liveFlag,@Param("replayFlag") Integer replayFlag);
 
     /**

+ 2 - 1
fs-service/src/main/java/com/fs/live/service/ILiveGoodsService.java

@@ -1,6 +1,7 @@
 package com.fs.live.service;
 
 
+import com.baomidou.mybatisplus.extension.service.IService;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.entity.SysUser;
 import com.fs.company.domain.CompanyUser;
@@ -17,7 +18,7 @@ import java.util.Map;
  * @author fs
  * @date 2025-07-08
  */
-public interface ILiveGoodsService {
+public interface ILiveGoodsService extends IService<LiveGoods> {
     /**
      * 查询直播商品
      *

+ 3 - 0
fs-service/src/main/java/com/fs/live/service/ILiveOrderService.java

@@ -125,6 +125,7 @@ public interface ILiveOrderService {
      * @return
      */
     R createLiveOrder(LiveOrder liveOrder);
+    R createLiveOrderTest(LiveOrder liveOrder);
 
     /**
      * 订单确认
@@ -272,4 +273,6 @@ public interface ILiveOrderService {
     void payConfirmPayment(Long existPayedRecordId);
 
     void updateTime(LiveOrder order);
+
+    void initStock();
 }

+ 9 - 1
fs-service/src/main/java/com/fs/live/service/impl/LiveGoodsServiceImpl.java

@@ -1,8 +1,10 @@
 package com.fs.live.service.impl;
 
 
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fs.common.core.domain.R;
 import com.fs.common.core.domain.entity.SysUser;
+import com.fs.common.core.redis.service.StockDeductService;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.DateUtils;
 import com.fs.company.domain.CompanyUser;
@@ -33,10 +35,12 @@ import java.util.stream.Collectors;
  * @date 2025-07-08
  */
 @Service
-public class LiveGoodsServiceImpl  implements ILiveGoodsService {
+public class LiveGoodsServiceImpl extends ServiceImpl<LiveGoodsMapper, LiveGoods> implements ILiveGoodsService {
 
     @Autowired
     private FsStoreProductScrmMapper fsStoreProductMapper;
+    @Autowired
+    private StockDeductService stockDeductService;
 
     @Autowired
     private LiveGoodsMapper baseMapper;
@@ -98,6 +102,7 @@ public class LiveGoodsServiceImpl  implements ILiveGoodsService {
             if(fsStoreProduct == null) return R.error("商品不存在");
             if(fsStoreProduct.getIsShow() == 0 || existGoods.getStatus() == 0) return R.error("商品已下架");
             if(fsStoreProduct.getStock() < liveGoods.getStock()) return R.error("商品库存不足");
+            stockDeductService.initStock(existGoods.getProductId(), liveGoods.getLiveId(), liveGoods.getStock().intValue());
         }
         baseMapper.updateLiveGoods(liveGoods);
         return R.ok();
@@ -377,6 +382,9 @@ public class LiveGoodsServiceImpl  implements ILiveGoodsService {
                 .collect(Collectors.toList());
 //
 //        // 批量插入
+        liveGoodsList.forEach(e -> {
+            stockDeductService.initStock(e.getProductId(), liveId, e.getStock().intValue());
+        });
         return baseMapper.insertLiveGoodsList(liveGoodsList);
     }
 

Разница между файлами не показана из-за своего большого размера
+ 238 - 156
fs-service/src/main/java/com/fs/live/service/impl/LiveOrderServiceImpl.java


+ 9 - 2
fs-service/src/main/java/com/fs/live/service/impl/LiveWatchUserServiceImpl.java

@@ -304,8 +304,15 @@ public class LiveWatchUserServiceImpl implements ILiveWatchUserService {
     @Override
     public LiveWatchUser join(FsUserScrm fsUser,long liveId, long userId, String location) {
 
-        // 查询直播间信息
-        Live live = liveMapper.selectLiveByLiveId(liveId);
+        // 缓存直播间信息,过期时间4小时
+        String liveCacheKey = "live:" + liveId;
+        Live live = redisCache.getCacheObject(liveCacheKey);
+        if (live == null) {
+            live = liveMapper.selectLiveByLiveId(liveId);
+            if (live != null) {
+                redisCache.setCacheObject(liveCacheKey, live, 4, TimeUnit.HOURS);
+            }
+        }
         if (live == null) {
             throw new RuntimeException("直播间不存在");
         }

+ 2 - 2
fs-service/src/main/resources/application-config-druid-bjzm-test.yml

@@ -15,8 +15,8 @@ logging:
 wx:
   miniapp:
     configs:
-      - appid: wx30d1ed5dbbdc5cc5   #乐享优品百域臻品
-        secret: 63624481b94437ecbd3ce34c19543746 #北京卓美
+      - appid: wxcc2de555e32acb08   #百域佳选
+        secret: 76eaf5e27ad79abb237c7a83ed8b80a3 #北京卓美
         token: cbnd7lJvkripVOpyTFAna6NAWCxCrvC
         aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
         msgDataFormat: JSON

+ 2 - 2
fs-service/src/main/resources/application-config-druid-bjzm.yml

@@ -10,8 +10,8 @@ logging:
 wx:
   miniapp:
     configs:
-      - appid: wx30d1ed5dbbdc5cc5   #乐享优品百域臻品
-        secret: 63624481b94437ecbd3ce34c19543746 #北京卓美
+      - appid: wxcc2de555e32acb08   #百域佳选
+        secret: 76eaf5e27ad79abb237c7a83ed8b80a3 #北京卓美
         token: cbnd7lJvkripVOpyTFAna6NAWCxCrvC
         aesKey: HlEiBB55eaWUaeBVAQO3cWKWPYv1vOVQSq7nFNICw4E
         msgDataFormat: JSON

+ 1 - 1
fs-service/src/main/resources/application-druid-bjzm-test.yml

@@ -46,7 +46,7 @@ spring:
                 slave:
                     # 从数据源开关/默认关闭
                     enabled: true
-                    url: jdbc:mysql://gz-cdb-ofgnuz1n.sql.tencentcdb.com:26872/fs_his?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    url: jdbc:mysql://gz-cdb-ofgnuz1n-readonly.sql.tencentcdb.com:26683/fs_his?allowMultiQueries=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                     username: root
                     password: Ylrz_1q2w3e4r5t6y
                 # 初始连接数

+ 31 - 0
fs-service/src/main/resources/mapper/live/LiveOrderItemMapper.xml

@@ -109,6 +109,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="isGift != null">#{isGift},</if>
          </trim>
     </insert>
+    <insert id="insertLiveOrderItemTest" parameterType="LiveOrderItem" useGeneratedKeys="true" keyProperty="itemId">
+        insert into live_order_item_test
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="orderId != null and orderId != ''">order_id,</if>
+            <if test="orderCode != null">order_code,</if>
+            <if test="cartId != null and cartId != ''">cart_id,</if>
+            <if test="goodsId != null">goods_id,</if>
+            <if test="productId != null and productId != ''">product_id,</if>
+            <if test="productAttrValueId != null">product_attr_value_id,</if>
+            <if test="jsonInfo != null">json_info,</if>
+            <if test="num != null">num,</if>
+            <if test="isAfterSales != null">is_after_sales,</if>
+            <if test="isPrescribe != null">is_prescribe,</if>
+            <if test="storeId != null">store_id,</if>
+            <if test="isGift != null">is_gift,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="orderId != null and orderId != ''">#{orderId},</if>
+            <if test="orderCode != null">#{orderCode},</if>
+            <if test="cartId != null and cartId != ''">#{cartId},</if>
+            <if test="goodsId != null">#{goodsId},</if>
+            <if test="productId != null and productId != ''">#{productId},</if>
+            <if test="productAttrValueId != null">#{productAttrValueId},</if>
+            <if test="jsonInfo != null">#{jsonInfo},</if>
+            <if test="num != null">#{num},</if>
+            <if test="isAfterSales != null">#{isAfterSales},</if>
+            <if test="isPrescribe != null">#{isPrescribe},</if>
+            <if test="storeId != null">#{storeId},</if>
+            <if test="isGift != null">#{isGift},</if>
+         </trim>
+    </insert>
 
     <insert id="insertBatchList" parameterType="java.util.List">
         insert into live_order_item

+ 163 - 0
fs-service/src/main/resources/mapper/live/LiveOrderMapper.xml

@@ -356,6 +356,155 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="appId != null and appId != ''">#{appId},</if>
          </trim>
     </insert>
+    <insert id="insertLiveOrderTest" parameterType="LiveOrder" useGeneratedKeys="true" keyProperty="orderId">
+        insert into live_order_test
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="liveId != null">live_id,</if>
+            <if test="storeId != null">store_id,</if>
+            <if test="orderCode != null and orderCode != ''">order_code,</if>
+            <if test="userId != null and userId != ''">user_id,</if>
+            <if test="realName != null">real_name,</if>
+            <if test="userName != null">user_name,</if>
+            <if test="userPhone != null">user_phone,</if>
+            <if test="userAddress != null">user_address,</if>
+            <if test="cartId != null">cart_id,</if>
+            <if test="totalNum != null and totalNum != ''">total_num,</if>
+            <if test="totalPrice != null">total_price,</if>
+            <if test="payPrice != null">pay_price,</if>
+            <if test="payMoney != null">pay_money,</if>
+            <if test="isPay != null">is_pay,</if>
+            <if test="payTime != null">pay_time,</if>
+            <if test="payType != null">pay_type,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="status != null">status,</if>
+            <if test="refundStatus != null">refund_status,</if>
+            <if test="refundImg != null">refund_img,</if>
+            <if test="refundExplain != null">refund_explain,</if>
+            <if test="refundTime != null">refund_time,</if>
+            <if test="refundReason != null">refund_reason,</if>
+            <if test="refundMoney != null">refund_money,</if>
+            <if test="deliveryCode != null">delivery_code,</if>
+            <if test="deliveryName != null">delivery_name,</if>
+            <if test="deliverySn != null">delivery_sn,</if>
+            <if test="remark != null">remark,</if>
+            <if test="isDel != null">is_del,</if>
+            <if test="costPrice != null">cost_price,</if>
+            <if test="verifyCode != null">verify_code,</if>
+            <if test="shippingType != null">shipping_type,</if>
+            <if test="isChannel != null">is_channel,</if>
+            <if test="finishTime != null">finish_time,</if>
+            <if test="deliveryTime != null">delivery_time,</if>
+            <if test="tuiMoney != null">tui_money,</if>
+            <if test="tuiMoneyStatus != null">tui_money_status,</if>
+            <if test="tuiUserId != null">tui_user_id,</if>
+            <if test="itemJson != null">item_json,</if>
+            <if test="discountMoney != null">discount_money,</if>
+            <if test="userCouponId != null">user_coupon_id,</if>
+            <if test="companyId != null">company_id,</if>
+            <if test="companyUserId != null">company_user_id,</if>
+            <if test="storeHouseCode != null">store_house_code,</if>
+            <if test="extendOrderId != null">extend_order_id,</if>
+            <if test="payDelivery != null">pay_delivery,</if>
+            <if test="payRemain != null">pay_remain,</if>
+            <if test="deliveryStatus != null">delivery_status,</if>
+            <if test="deliveryPayStatus != null">delivery_pay_status,</if>
+            <if test="deliveryPayTime != null">delivery_pay_time,</if>
+            <if test="deliveryType != null">delivery_type,</if>
+            <if test="deliveryPayMoney != null">delivery_pay_money,</if>
+            <if test="deliveryImportTime != null">delivery_import_time,</if>
+            <if test="deliverySendTime != null">delivery_send_time,</if>
+            <if test="isAfterSales != null">is_after_sales,</if>
+            <if test="deptId != null">dept_id,</if>
+            <if test="channel != null">channel,</if>
+            <if test="source != null">source,</if>
+            <if test="billPrice != null">bill_price,</if>
+            <if test="totalPostage != null">total_postage,</if>
+            <if test="payPostage != null">pay_postage,</if>
+            <if test="gainIntegral != null">gain_integral,</if>
+            <if test="useIntegral != null">use_integral,</if>
+            <if test="payIntegral != null">pay_integral,</if>
+            <if test="backIntegral != null">back_integral,</if>
+            <if test="isEditMoney != null">is_edit_money,</if>
+            <if test="productId != null">product_id,</if>
+            <if test="customerId != null">customer_id,</if>
+            <if test="couponPrice != null">coupon_price,</if>
+            <if test="appId != null and appId != ''">app_id,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="liveId != null">#{liveId},</if>
+            <if test="storeId != null">#{storeId},</if>
+            <if test="orderCode != null and orderCode != ''">#{orderCode},</if>
+            <if test="userId != null and userId != ''">#{userId},</if>
+            <if test="realName != null">#{realName},</if>
+            <if test="userName != null">#{userName},</if>
+            <if test="userPhone != null">#{userPhone},</if>
+            <if test="userAddress != null">#{userAddress},</if>
+            <if test="cartId != null">#{cartId},</if>
+            <if test="totalNum != null and totalNum != ''">#{totalNum},</if>
+            <if test="totalPrice != null">#{totalPrice},</if>
+            <if test="payPrice != null">#{payPrice},</if>
+            <if test="payMoney != null">#{payMoney},</if>
+            <if test="isPay != null">#{isPay},</if>
+            <if test="payTime != null">#{payTime},</if>
+            <if test="payType != null">#{payType},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="status != null">#{status},</if>
+            <if test="refundStatus != null">#{refundStatus},</if>
+            <if test="refundImg != null">#{refundImg},</if>
+            <if test="refundExplain != null">#{refundExplain},</if>
+            <if test="refundTime != null">#{refundTime},</if>
+            <if test="refundReason != null">#{refundReason},</if>
+            <if test="refundMoney != null">#{refundMoney},</if>
+            <if test="deliveryCode != null">#{deliveryCode},</if>
+            <if test="deliveryName != null">#{deliveryName},</if>
+            <if test="deliverySn != null">#{deliverySn},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="isDel != null">#{isDel},</if>
+            <if test="costPrice != null">#{costPrice},</if>
+            <if test="verifyCode != null">#{verifyCode},</if>
+            <if test="shippingType != null">#{shippingType},</if>
+            <if test="isChannel != null">#{isChannel},</if>
+            <if test="finishTime != null">#{finishTime},</if>
+            <if test="deliveryTime != null">#{deliveryTime},</if>
+            <if test="tuiMoney != null">#{tuiMoney},</if>
+            <if test="tuiMoneyStatus != null">#{tuiMoneyStatus},</if>
+            <if test="tuiUserId != null">#{tuiUserId},</if>
+            <if test="itemJson != null">#{itemJson},</if>
+            <if test="discountMoney != null">#{discountMoney},</if>
+            <if test="userCouponId != null">#{userCouponId},</if>
+            <if test="companyId != null">#{companyId},</if>
+            <if test="companyUserId != null">#{companyUserId},</if>
+            <if test="storeHouseCode != null">#{storeHouseCode},</if>
+            <if test="extendOrderId != null">#{extendOrderId},</if>
+            <if test="payDelivery != null">#{payDelivery},</if>
+            <if test="payRemain != null">#{payRemain},</if>
+            <if test="deliveryStatus != null">#{deliveryStatus},</if>
+            <if test="deliveryPayStatus != null">#{deliveryPayStatus},</if>
+            <if test="deliveryPayTime != null">#{deliveryPayTime},</if>
+            <if test="deliveryType != null">#{deliveryType},</if>
+            <if test="deliveryPayMoney != null">#{deliveryPayMoney},</if>
+            <if test="deliveryImportTime != null">#{deliveryImportTime},</if>
+            <if test="deliverySendTime != null">#{deliverySendTime},</if>
+            <if test="isAfterSales != null">#{isAfterSales},</if>
+            <if test="deptId != null">#{deptId},</if>
+            <if test="channel != null">#{channel},</if>
+            <if test="source != null">#{source},</if>
+            <if test="billPrice != null">#{billPrice},</if>
+            <if test="totalPostage != null">#{totalPostage},</if>
+            <if test="payPostage != null">#{payPostage},</if>
+            <if test="gainIntegral != null">#{gainIntegral},</if>
+            <if test="useIntegral != null">#{useIntegral},</if>
+            <if test="payIntegral != null">#{payIntegral},</if>
+            <if test="backIntegral != null">#{backIntegral},</if>
+            <if test="isEditMoney != null">#{isEditMoney},</if>
+            <if test="productId != null">#{productId},</if>
+            <if test="customerId != null">#{customerId},</if>
+            <if test="couponPrice != null">#{couponPrice},</if>
+            <if test="appId != null and appId != ''">#{appId},</if>
+         </trim>
+    </insert>
 
     <update id="updateLiveOrder" parameterType="LiveOrder">
         update live_order
@@ -476,6 +625,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
     </update>
 
+    <update id="batchUpdateChannelByOrderIds">
+        UPDATE live_order
+        SET channel =
+        <trim prefix="CASE order_id" suffix="END">
+            <foreach collection="maps" item="map">
+                WHEN #{map.orderId} THEN #{map.channel}
+            </foreach>
+        </trim>
+        WHERE order_id IN
+        <foreach collection="maps" item="map" open="(" separator="," close=")">
+            #{map.orderId}
+        </foreach>
+    </update>
+
     <select id="selectLiveOrderInId" resultType="com.fs.live.domain.LiveOrder">
         <include refid="selectLiveOrderVo"/>
         where order_id IN <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">

+ 22 - 0
fs-user-app/src/main/java/com/fs/app/controller/course/CourseQwLoginController.java

@@ -22,6 +22,8 @@ import com.fs.his.mapper.FsUserLoginLogMapper;
 import com.fs.his.service.IFsUserService;
 import com.fs.his.service.IFsUserWxService;
 import com.fs.his.utils.ConfigUtil;
+import com.fs.live.service.ILiveOrderService;
+import com.fs.live.service.impl.LiveOrderServiceImpl;
 import com.fs.system.domain.SysConfig;
 import com.fs.system.mapper.SysConfigMapper;
 import io.swagger.annotations.Api;
@@ -66,6 +68,8 @@ public class CourseQwLoginController extends AppBaseController {
     IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService;
     @Autowired
     RedisCache redisCache;
+    @Autowired
+    private ILiveOrderService liveOrderServiceImpl;
 
 
     @ApiOperation("小程序看课登录")
@@ -90,6 +94,24 @@ public class CourseQwLoginController extends AppBaseController {
                 () -> WxMaConfiguration.getMaService(matchedConfig.getAppid()),
                 matchedConfig.getName());
     }
+    @ApiOperation("小程序看课登录测试")
+    @GetMapping("/courseLoginTest")
+    public R courseLogin(Long id) {
+        FsUser user = userService.selectFsUserById(id);
+        String token = jwtUtils.generateToken(user.getUserId());
+        Map<String,Object> map = new HashMap<>();
+        map.put("token", token);
+        map.put("user", user);
+        map.put("isNew", false);
+        return R.ok(map);
+    }
+
+    @ApiOperation("初始化库存")
+    @GetMapping("/initStock")
+    public R initStock(Long id) {
+        liveOrderServiceImpl.initStock();
+        return R.ok();
+    }
 
     /**
      * 公共登录处理方法

+ 13 - 1
fs-user-app/src/main/java/com/fs/app/controller/live/LiveOrderController.java

@@ -182,7 +182,6 @@ public class LiveOrderController extends AppBaseController
     @GetMapping(value = "/liveOrderUser/{liveId}")
     public R liveOrderUser(@PathVariable  String liveId)
     {
-        log.info("正在购买的用户 参数: {}",liveId);
         return orderService.liveOrderUser(liveId);
     }
 
@@ -342,6 +341,19 @@ public class LiveOrderController extends AppBaseController
         param.setUserId(userId);
         return orderService.createLiveOrder(param);
     }
+    @Login
+    @ApiOperation("创建订单测试")
+    @PostMapping("/createTest")
+    public R createTest(@Validated @RequestBody LiveOrder param, HttpServletRequest request){
+        // 校验appId
+        if (StringUtils.isEmpty(param.getAppId())) {
+            return R.error("appId不能为空");
+        }
+        String userId= getUserId();
+        log.info("开始创建订单,登录用户id:{}", userId);
+        param.setUserId(userId);
+        return orderService.createLiveOrder(param);
+    }
 
     @Login
     @GetMapping(value = "/info/{orderId}")

+ 2 - 3
fs-user-app/src/main/java/com/fs/app/controller/store/ProductScrmController.java

@@ -270,9 +270,8 @@ public class ProductScrmController extends AppBaseController {
             if(userId == null){
                 return R.error("用户未登录");
             }
-            
-            FsStoreProductPurchaseLimitScrm purchaseLimit = purchaseLimitService.selectByProductIdAndUserId(
-                    productId, Long.parseLong(userId));
+            // TODO 做REDIS缓存
+            FsStoreProductPurchaseLimitScrm purchaseLimit = purchaseLimitService.selectByProductIdAndUserId(productId, Long.parseLong(userId));
             int purchasedNum = 0;
             if (purchaseLimit != null) {
                 purchasedNum = purchaseLimit.getNum();

+ 2 - 2
fs-user-app/src/test/java/com/fs/test/StockDeductTest.java

@@ -39,7 +39,7 @@ public class StockDeductTest {
      */
     @Test
     public void testHighConcurrencyDeduct() throws InterruptedException, ExecutionException {
-        stockDeductService.initStock(PRODUCT_ID, INIT_STOCK);
+        stockDeductService.initStock(PRODUCT_ID, 1L, INIT_STOCK);
         // Java 8 ExecutorService 线程池(固定线程池,适配高并发)
         ExecutorService executorService = createHighConcurrencyPool();
 
@@ -48,7 +48,7 @@ public class StockDeductTest {
 
         // 提交50万请求
         for (int i = 0; i < TOTAL_REQUESTS; i++) {
-            futureList.add(stockDeductService.deductStockAsync(PRODUCT_ID, 1, (long) i));
+//            futureList.add(stockDeductService.deductStockAsync(PRODUCT_ID, 1L, (long) i));
         }
 
         // 等待所有任务完成(Java 8 CompletableFuture 批量处理)

Некоторые файлы не были показаны из-за большого количества измененных файлов