Просмотр исходного кода

fix(order): 修复学校订单取消时库存恢复问题

- 限制查询订单产品信息时排除已取消状态的子订单
- 取消学校订单时按productId分组统计待恢复库存数量
- 排除保险类型子订单库存恢复逻辑
- 更新数据库中对应产品的库存数量
- 同步更新Redis缓存的库存信息
- 确保订单产品状态更新为取消状态
wzq 1 неделя назад
Родитель
Сommit
b3ae57c33f

+ 30 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -582,6 +582,7 @@ public class OrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> impl
                     List<String> familyIds = Arrays.stream(createOrderForm.getFamilyIds().split(",")).collect(Collectors.toList());
                     AppOrderProInfo proInfo = appOrderProInfoMapper.selectOne(Wrappers.<AppOrderProInfo>lambdaQuery()
                             .eq(AppOrderProInfo::getProductId, productId)
+                            .ne(AppOrderProInfo::getOrderStatus, 4)
                             .in(AppOrderProInfo::getFamilyUserId, familyIds)
                             .last("limit 1")
                     );
@@ -2556,6 +2557,7 @@ public class OrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> impl
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Boolean cancelSchoolOrder(String orderId) {
 
         AppOrder appOrder = appOrderMapper.selectById(orderId);
@@ -2568,6 +2570,34 @@ public class OrderServiceImpl extends ServiceImpl<AppOrderMapper, AppOrder> impl
         }
         List<AppOrderProInfo> orderProInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, orderId));
         if (CollUtil.isNotEmpty(orderProInfoList)) {
+            // 按productId分组统计需要恢复的库存数量(排除保险类型的子订单)
+            Map<String, Long> productStockMap = orderProInfoList.stream()
+                    .filter(info -> !Objects.equals(info.getType(), CommonConstant.ORDER_PRO_INFO_TYPE_6))
+                    .collect(Collectors.groupingBy(AppOrderProInfo::getProductId, Collectors.counting()));
+
+            // 恢复库存
+            for (Map.Entry<String, Long> entry : productStockMap.entrySet()) {
+                String productId = entry.getKey();
+                int restoreCount = entry.getValue().intValue();
+
+                // 恢复数据库库存
+                AppSitePriceRules priceRules = appSitePriceRulesMapper.selectById(productId);
+                if (ObjectUtil.isNotEmpty(priceRules)) {
+                    int newTicketNum = (priceRules.getTicketNum() == null ? 0 : priceRules.getTicketNum()) + restoreCount;
+                    appSitePriceRulesMapper.update(null, Wrappers.<AppSitePriceRules>lambdaUpdate()
+                            .eq(AppSitePriceRules::getId, productId)
+                            .set(AppSitePriceRules::getTicketNum, newTicketNum));
+                    log.info("取消学校订单恢复库存,productId={},恢复数量={},恢复后库存={}", productId, restoreCount, newTicketNum);
+
+                    // 恢复Redis缓存库存
+                    String stockKey = "ORDER_TYPE_1_PRODUCT_STOCK_" + productId;
+                    Integer cachedStock = (Integer) redisTemplate.opsForValue().get(stockKey);
+                    if (cachedStock != null) {
+                        redisTemplate.opsForValue().increment(stockKey, restoreCount);
+                    }
+                }
+            }
+
             for (AppOrderProInfo appOrderProInfo : orderProInfoList) {
                 appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_4);
                 appOrderProInfoMapper.updateById(appOrderProInfo);

+ 14 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/utils/HolidayUtil.java

@@ -3,6 +3,7 @@ package org.jeecg.modules.quartz.utils;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.util.DateUtils;
 
 import java.io.BufferedReader;
 import java.io.InputStream;
@@ -185,5 +186,18 @@ public class HolidayUtil {
         return weekDays[w];
     }
 
+    public static void main(String[] args) {
+        int year = 2025;
+        Map<String, List<String>> HolidayMap = HolidayUtil.getYearHoliday(String.valueOf(2026));
+        HolidayMap.forEach((key, value) -> {
+            System.out.println(key + ":" + value);
+        });
+        Date beginDate = DateUtils.str2Date((year + 1) + "-01-01 00:00:00", new SimpleDateFormat("yyyy-MM-dd"));
+        Date endDate = DateUtils.str2Date((year + 2) + "-01-01 00:00:00", new SimpleDateFormat("yyyy-MM-dd"));
+        List<Date> daysBetweenDates = getDaysBetweenDates(beginDate, endDate);
+        for (Date daysBetweenDate : daysBetweenDates) {
+            System.out.println(daysBetweenDate);
+        }
+    }
 
 }

+ 1 - 1
national-motion-module-system/national-motion-system-start/src/main/resources/application-dev.yml

@@ -162,7 +162,7 @@ spring:
 #          url: jdbc:mysql://192.168.110.241:3306/national_motion?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
 #          username: root
 #          password: c7ix0bJv2GvyhbkRw6
-          url: jdbc:mysql://47.109.67.112:3306/national_motion?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          url: jdbc:mysql://47.109.67.112:3306/national_motion_test?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
           username: root
           password: TtbTeGJBnDvH4hMx
           # 多数据源配置