From 2b0b64182263d922b946ec898070e59b602382dc Mon Sep 17 00:00:00 2001
From: Bang Hu <hu_bang@hotmail.com>
Date: 星期四, 11 九月 2025 18:38:09 +0800
Subject: [PATCH] 交易审批多节点问题处理完善

---
 src/main/java/com/webmanage/service/impl/CartServiceImpl.java |  148 ++++++++++++++++++++++++++++++-------------------
 1 files changed, 90 insertions(+), 58 deletions(-)

diff --git a/src/main/java/com/webmanage/service/impl/CartServiceImpl.java b/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
index 716c8a2..258e3bd 100644
--- a/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
+++ b/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
@@ -65,8 +65,8 @@
             }
 
             // 鏋勫缓璐墿杞ey
-            String cartKey = buildCartKey(userId,unitId);
-            String cartItemKey = buildCartItemKey(userId, unitId, cartItemDTO.getPricingId());
+            String cartKey = buildCartKey(userId,unitId, cartItemDTO.getProductId());
+            String cartItemKey = buildCartItemKey(userId, unitId, cartItemDTO.getProductId(),cartItemDTO.getPricingId());
 
             // 妫�鏌ュ晢鍝佹槸鍚﹀凡鍦ㄨ喘鐗╄溅涓�
             CartItemVO existingItem = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
@@ -91,7 +91,7 @@
             redisTemplate.opsForValue().set(cartItemKey, existingItem, (cartProperties.getExpireDays() != null ? cartProperties.getExpireDays() : CART_EXPIRE_DAYS), TimeUnit.DAYS);
 
             // 鏇存柊璐墿杞﹀晢鍝佸垪琛�
-            updateCartItemList(userId, unitId, cartItemDTO.getPricingId(), true);
+            updateCartItemList(userId, unitId, cartItemDTO.getProductId(), cartItemDTO.getPricingId(), true);
 
             // 璁剧疆璐墿杞﹁繃鏈熸椂闂�
             redisTemplate.expire(cartKey, (cartProperties.getExpireDays() != null ? cartProperties.getExpireDays() : CART_EXPIRE_DAYS), TimeUnit.DAYS);
@@ -111,19 +111,19 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean removeFromCart(String userId, String unitId, Long pricingId) {
+    public boolean removeFromCart(String userId, String unitId, String productId, Long pricingId) {
         try {
-            String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+            String cartItemKey = buildCartItemKey(userId, unitId, productId, pricingId);
 
             // 浠嶳edis涓垹闄ゅ晢鍝侀」
             Boolean removed = redisTemplate.delete(cartItemKey);
             if (Boolean.TRUE.equals(removed)) {
                 // 鏇存柊璐墿杞﹀晢鍝佸垪琛�
-                updateCartItemList(userId, unitId, pricingId, false);
+                updateCartItemList(userId, unitId, productId, pricingId, false);
 
                 // 寮傛浠庢暟鎹簱涓垹闄わ紙鏍规嵁閰嶇疆锛�
                 if (Boolean.TRUE.equals(cartProperties.getEnablePersistence()) && "realtime".equalsIgnoreCase(cartProperties.getSyncStrategy())) {
-                    cartPersistenceService.remove(userId, unitId, pricingId);
+                    cartPersistenceService.remove(userId, unitId, productId,pricingId);
                 }
 
                 log.info("鐢ㄦ埛{}鎴愬姛浠庤喘鐗╄溅绉婚櫎鍟嗗搧{}", userId, pricingId);
@@ -138,13 +138,13 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean updateCartItemQuantity(String userId, String unitId, Long pricingId, Integer quantity) {
+    public boolean updateCartItemQuantity(String userId, String unitId, String productId, Long pricingId, Integer quantity) {
         try {
             if (quantity <= 0) {
-                return removeFromCart(userId, unitId, pricingId);
+                return removeFromCart(userId, unitId, productId, pricingId);
             }
 
-            String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+            String cartItemKey = buildCartItemKey(userId, unitId, productId, pricingId);
             CartItemVO cartItem = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
             if (cartItem == null) {
                 throw new BusinessException("璐墿杞﹀晢鍝佷笉瀛樺湪");
@@ -170,16 +170,48 @@
         }
     }
 
+
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean clearCart(String userId, String unitId) {
+    public boolean updateCartItemDuration(String userId, String unitId, String productId, Long pricingId, Integer duration) {
         try {
-            String cartKey = buildCartKey(userId, unitId);
-            List<Long> pricingIds = getCartItemPricingIds(userId, unitId);
+
+            String cartItemKey = buildCartItemKey(userId, unitId, productId, pricingId);
+            CartItemVO cartItem = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
+            if (cartItem == null) {
+                throw new BusinessException("璐墿杞﹀晢鍝佷笉瀛樺湪");
+            }
+
+            cartItem.setDuration(duration);
+            cartItem.setUpdateTime(LocalDateTime.now());
+
+            // 鏇存柊鍒癛edis
+            redisTemplate.opsForValue().set(cartItemKey, cartItem, (cartProperties.getExpireDays() != null ? cartProperties.getExpireDays() : CART_EXPIRE_DAYS), TimeUnit.DAYS);
+
+            // 寮傛鎸佷箙鍖栧埌鏁版嵁搴擄紙鏍规嵁閰嶇疆锛�
+            if (Boolean.TRUE.equals(cartProperties.getEnablePersistence()) && "realtime".equalsIgnoreCase(cartProperties.getSyncStrategy())) {
+                cartPersistenceService.saveOrUpdate(userId, unitId, cartItem);
+            }
+
+            log.info("鐢ㄦ埛{}鎴愬姛鏇存柊璐墿杞﹀晢鍝亄}骞撮檺涓簕}", userId, pricingId, duration);
+            return true;
+        } catch (Exception e) {
+            log.error("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐�", e);
+            throw new BusinessException("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐ワ細" + e.getMessage());
+        }
+    }
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean clearCart(String userId, String unitId, String productId) {
+        try {
+            String cartKey = buildCartKey(userId, unitId, productId);
+            List<Long> pricingIds = getCartItemPricingIds(userId, unitId, productId);
 
             // 鍒犻櫎鎵�鏈夊晢鍝侀」
             for (Long pricingId : pricingIds) {
-                String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+                String cartItemKey = buildCartItemKey(userId, unitId, productId,pricingId);
                 redisTemplate.delete(cartItemKey);
             }
 
@@ -188,7 +220,7 @@
 
             // 寮傛娓呯┖鏁版嵁搴撲腑鐨勮喘鐗╄溅鏁版嵁锛堟牴鎹厤缃級
             if (Boolean.TRUE.equals(cartProperties.getEnablePersistence()) && "realtime".equalsIgnoreCase(cartProperties.getSyncStrategy())) {
-                cartPersistenceService.clear(userId, unitId);
+                cartPersistenceService.clear(userId, unitId, productId);
             }
 
             log.info("鐢ㄦ埛{}鎴愬姛娓呯┖璐墿杞�", userId);
@@ -200,14 +232,14 @@
     }
 
     @Override
-    public CartVO getCart(String userId, String unitId) {
+    public CartVO getCart(String userId, String unitId, String productId) {
         try {
             CartVO cartVO = new CartVO();
             cartVO.setUserId(userId);
             if (StringUtils.hasText(unitId)){
                 cartVO.setUnitId(unitId);
             }
-            List<CartItemVO> items = getCartItems(userId, unitId);
+            List<CartItemVO> items = getCartItems(userId, unitId, productId);
             cartVO.setItems(items);
 
             // 璁$畻鎬绘暟閲忓拰鎬婚噾棰�
@@ -228,21 +260,21 @@
     }
 
     @Override
-    public List<CartItemVO> getCartItems(String userId, String unitId) {
+    public List<CartItemVO> getCartItems(String userId, String unitId,String productId) {
         try {
             // 浼樺厛浠嶳edis鑾峰彇
-            List<CartItemVO> items = getCartItemsFromRedis(userId, unitId);
+            List<CartItemVO> items = getCartItemsFromRedis(userId, unitId,productId);
             if (items != null && !items.isEmpty()) {
                 return items;
             }
 
             // Redis涓病鏈夋暟鎹紝浠庢暟鎹簱鍔犺浇
             log.info("Redis涓棤璐墿杞︽暟鎹紝浠庢暟鎹簱鍔犺浇鐢ㄦ埛{}鐨勮喘鐗╄溅", userId);
-            return loadCartFromDatabase(userId, unitId) ? getCartItemsFromRedis(userId, unitId) : new ArrayList<>();
+            return loadCartFromDatabase(userId, unitId, productId) ? getCartItemsFromRedis(userId, unitId, productId) : new ArrayList<>();
         } catch (Exception e) {
             log.error("鑾峰彇璐墿杞﹀晢鍝佸垪琛ㄥけ璐�", e);
             // 闄嶇骇鍒版暟鎹簱鏌ヨ
-            return getCartItemsFromDatabase(userId, unitId);
+            return getCartItemsFromDatabase(userId, unitId, productId);
         }
     }
 
@@ -254,14 +286,14 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean batchRemoveFromCart(String userId, String unitId, List<Long> pricingIds) {
+    public boolean batchRemoveFromCart(String userId, String unitId, String productId,List<Long> pricingIds) {
         try {
             if (CollectionUtils.isEmpty(pricingIds)) {
                 return true;
             }
 
             for (Long pricingId : pricingIds) {
-                removeFromCart(userId, unitId, pricingId);
+                removeFromCart(userId, unitId, productId,pricingId);
             }
 
             return true;
@@ -272,17 +304,17 @@
     }
 
     @Override
-    public Integer getCartItemCount(String userId, String unitId) {
+    public Integer getCartItemCount(String userId, String unitId, String productId) {
         try {
             // 浼樺厛浠嶳edis鑾峰彇
-            String cartKey = buildCartKey(userId, unitId);
+            String cartKey = buildCartKey(userId, unitId, productId);
             List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
             if (pricingIds != null) {
                 return pricingIds.size();
             }
 
             // 浠庢暟鎹簱鑾峰彇
-            return cartMapper.countByUserIdAndUnitId(userId, unitId);
+            return cartMapper.countByUserIdAndUnitId(userId, unitId, productId);
         } catch (Exception e) {
             log.error("鑾峰彇璐墿杞﹀晢鍝佹暟閲忓け璐�", e);
             return 0;
@@ -290,19 +322,19 @@
     }
 
     @Override
-    public boolean loadCartFromDatabase(String userId, String unitId) {
+    public boolean loadCartFromDatabase(String userId, String unitId, String productId) {
         try {
-            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId, productId);
             if (CollectionUtils.isEmpty(cartItems)) {
                 return false;
             }
 
-            String cartKey = buildCartKey(userId, unitId);
+            String cartKey = buildCartKey(userId, unitId, productId);
             List<Long> pricingIds = new ArrayList<>();
 
             for (Cart cartItem : cartItems) {
                 CartItemVO itemVO = convertCartToCartItemVO(cartItem);
-                String cartItemKey = buildCartItemKey(userId, unitId, cartItem.getPricingId());
+                String cartItemKey = buildCartItemKey(userId, unitId,cartItem.getProductId(), cartItem.getPricingId());
 
                 // 淇濆瓨鍒癛edis
                 redisTemplate.opsForValue().set(cartItemKey, itemVO, CART_EXPIRE_DAYS, TimeUnit.DAYS);
@@ -321,19 +353,19 @@
     }
 
     @Override
-    public boolean syncCartToDatabase(String userId, String unitId) {
+    public boolean syncCartToDatabase(String userId, String unitId, String productId) {
         try {
-            List<CartItemVO> redisItems = getCartItemsFromRedis(userId, unitId);
+            List<CartItemVO> redisItems = getCartItemsFromRedis(userId, unitId, productId);
             if (CollectionUtils.isEmpty(redisItems)) {
                 return true;
             }
 
             // 娓呯┖鏁版嵁搴撲腑鐨勮喘鐗╄溅鏁版嵁
-            clearCartFromDatabase(userId, unitId);
+            clearCartFromDatabase(userId, unitId, productId);
 
             // 鍚屾Redis鏁版嵁鍒版暟鎹簱
             for (CartItemVO item : redisItems) {
-                syncCartItemToDatabase(userId, unitId, item);
+                syncCartItemToDatabase(userId, unitId,productId, item);
             }
 
             log.info("鎴愬姛鍚屾Redis璐墿杞︽暟鎹埌鏁版嵁搴擄紝鐢ㄦ埛{}", userId);
@@ -345,10 +377,10 @@
     }
 
     @Override
-    public boolean checkCartConsistency(String userId, String unitId) {
+    public boolean checkCartConsistency(String userId, String unitId, String productId) {
         try {
-            List<CartItemVO> redisItems = getCartItemsFromRedis(userId, unitId);
-            List<Cart> dbItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            List<CartItemVO> redisItems = getCartItemsFromRedis(userId, unitId, productId);
+            List<Cart> dbItems = cartMapper.selectByUserIdAndUnitId(userId, unitId, productId);
 
             if (redisItems.size() != dbItems.size()) {
                 log.warn("璐墿杞︽暟鎹笉涓�鑷达細Redis鏁伴噺{}锛屾暟鎹簱鏁伴噺{}", redisItems.size(), dbItems.size());
@@ -380,22 +412,22 @@
 
     // ==================== 绉佹湁鏂规硶 ====================
 
-    private String buildCartKey(String userId, String unitId) {
+    private String buildCartKey(String userId, String unitId,String productId) {
         if(StringUtils.hasText(unitId)){
-            return CART_KEY_PREFIX + userId + ":" + unitId;
+            return CART_KEY_PREFIX + userId + ":" + unitId + ":" + productId;
         }
-        return CART_KEY_PREFIX + userId;
+        return CART_KEY_PREFIX + userId + ":" + productId;
     }
 
-    private String buildCartItemKey(String userId, String unitId, Long pricingId) {
+    private String buildCartItemKey(String userId, String unitId,String productId, Long pricingId) {
         if(StringUtils.hasText(unitId)){
-            return CART_ITEM_KEY_PREFIX + userId + ":" + unitId + ":" + pricingId;
+            return CART_ITEM_KEY_PREFIX + userId + ":" + unitId + ":" + productId + ":" + pricingId;
         }
-        return CART_ITEM_KEY_PREFIX + userId + ":" + pricingId;
+        return CART_ITEM_KEY_PREFIX + userId + ":" + productId + ":" + pricingId;
     }
 
-    private void updateCartItemList(String userId, String unitId, Long pricingId, boolean add) {
-        String cartKey = buildCartKey(userId, unitId);
+    private void updateCartItemList(String userId, String unitId,String productId ,Long pricingId, boolean add) {
+        String cartKey = buildCartKey(userId, unitId, productId);
         List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
 
         if (pricingIds == null) {
@@ -411,15 +443,15 @@
         redisTemplate.opsForValue().set(cartKey, pricingIds, CART_EXPIRE_DAYS, TimeUnit.DAYS);
     }
 
-    private List<Long> getCartItemPricingIds(String userId, String unitId) {
-        String cartKey = buildCartKey(userId, unitId);
+    private List<Long> getCartItemPricingIds(String userId, String unitId, String productId) {
+        String cartKey = buildCartKey(userId, unitId, productId);
         List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
         return pricingIds != null ? pricingIds : new ArrayList<>();
     }
 
-    private List<CartItemVO> getCartItemsFromRedis(String userId, String unitId) {
+    private List<CartItemVO> getCartItemsFromRedis(String userId, String unitId, String productId) {
         try {
-            String cartKey = buildCartKey(userId, unitId);
+            String cartKey = buildCartKey(userId, unitId, productId);
             List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
 
             if (CollectionUtils.isEmpty(pricingIds)) {
@@ -428,7 +460,7 @@
 
             List<CartItemVO> items = new ArrayList<>();
             for (Long pricingId : pricingIds) {
-                String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
+                String cartItemKey = buildCartItemKey(userId, unitId, productId,pricingId);
                 CartItemVO item = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
                 if (item != null) {
                     items.add(item);
@@ -442,9 +474,9 @@
         }
     }
     
-    private List<CartItemVO> getCartItemsFromDatabase(String userId, String unitId) {
+    private List<CartItemVO> getCartItemsFromDatabase(String userId, String unitId, String productId) {
         try {
-            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId, productId);
             List<CartItemVO> items = new ArrayList<>();
             
             for (Cart cartItem : cartItems) {
@@ -464,7 +496,7 @@
         return itemVO;
     }
     
-    private void syncCartItemToDatabase(String userId, String unitId, CartItemVO item) {
+    private void syncCartItemToDatabase(String userId, String unitId, String productId,CartItemVO item) {
         try {
             Cart cart = new Cart();
             BeanUtils.copyProperties(item, cart);
@@ -473,7 +505,7 @@
             cart.setUpdateTime(LocalDateTime.now());
             
             // 妫�鏌ユ槸鍚﹀凡瀛樺湪
-            Cart existingCart = cartMapper.selectByUserIdUnitIdAndPricingId(userId, unitId, item.getPricingId());
+            Cart existingCart = cartMapper.selectByUserIdUnitIdAndPricingId(userId, unitId, productId,item.getPricingId());
             if (existingCart != null) {
                 // 鏇存柊
                 cart.setId(existingCart.getId());
@@ -488,9 +520,9 @@
         }
     }
     
-    private void removeCartItemFromDatabase(String userId, String unitId, Long pricingId) {
+    private void removeCartItemFromDatabase(String userId, String unitId, String productId, Long pricingId) {
         try {
-            Cart existingCart = cartMapper.selectByUserIdUnitIdAndPricingId(userId, unitId, pricingId);
+            Cart existingCart = cartMapper.selectByUserIdUnitIdAndPricingId(userId, unitId, productId,pricingId);
             if (existingCart != null) {
                 cartMapper.deleteByCustomerCondition(existingCart.getId());
             }
@@ -499,10 +531,10 @@
         }
     }
     
-    private void clearCartFromDatabase(String userId, String unitId) {
+    private void clearCartFromDatabase(String userId, String unitId, String productId) {
         try {
             // 浣跨敤閫昏緫鍒犻櫎
-            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
+            List<Cart> cartItems = cartMapper.selectByUserIdAndUnitId(userId, unitId, productId);
             for (Cart item : cartItems) {
                 cartMapper.deleteById(item.getId());
             }

--
Gitblit v1.8.0