From 84c6e1df4b6bd48ee0517a33778b514008022875 Mon Sep 17 00:00:00 2001
From: seatonwan9
Date: 星期二, 19 八月 2025 18:10:44 +0800
Subject: [PATCH] 产品订购

---
 src/main/java/com/webmanage/service/impl/CartServiceImpl.java |  165 ++++++++++++++++++++++++++++++------------------------
 1 files changed, 91 insertions(+), 74 deletions(-)

diff --git a/src/main/java/com/webmanage/service/impl/CartServiceImpl.java b/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
index 304a9fe..7072069 100644
--- a/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
+++ b/src/main/java/com/webmanage/service/impl/CartServiceImpl.java
@@ -7,11 +7,14 @@
 import com.webmanage.mapper.CartMapper;
 import com.webmanage.mapper.ProductPricingMapper;
 import com.webmanage.service.CartService;
+import com.webmanage.service.CartPersistenceService;
 import com.webmanage.vo.CartItemVO;
 import com.webmanage.vo.CartVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
+import com.webmanage.config.CartProperties;
 import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.format.datetime.DateFormatter;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
@@ -39,11 +42,17 @@
     @Resource
     private ProductPricingMapper productPricingMapper;
     
+    @Resource
+    private CartPersistenceService cartPersistenceService;
+    
+    @Resource
+    private CartProperties cartProperties;
+    
     // Redis key鍓嶇紑
     private static final String CART_KEY_PREFIX = "cart:";
     private static final String CART_ITEM_KEY_PREFIX = "cart_item:";
     private static final int CART_EXPIRE_DAYS = 30; // 璐墿杞﹁繃鏈熸椂闂�30澶�
-    
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean addToCart(Long userId, Long unitId, CartItemDTO cartItemDTO) {
@@ -53,11 +62,11 @@
             if (pricing == null) {
                 throw new BusinessException("鍟嗗搧瀹氫环涓嶅瓨鍦�");
             }
-            
+
             // 鏋勫缓璐墿杞ey
             String cartKey = buildCartKey(userId, unitId);
             String cartItemKey = buildCartItemKey(userId, unitId, cartItemDTO.getPricingId());
-            
+
             // 妫�鏌ュ晢鍝佹槸鍚﹀凡鍦ㄨ喘鐗╄溅涓�
             CartItemVO existingItem = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
             if (existingItem != null) {
@@ -76,19 +85,21 @@
                     existingItem.setTotalPrice(existingItem.getUnitPrice().multiply(BigDecimal.valueOf(existingItem.getQuantity())));
                 }
             }
-            
+
             // 淇濆瓨鍒癛edis
-            redisTemplate.opsForValue().set(cartItemKey, existingItem, CART_EXPIRE_DAYS, TimeUnit.DAYS);
-            
+            redisTemplate.opsForValue().set(cartItemKey, existingItem, (cartProperties.getExpireDays() != null ? cartProperties.getExpireDays() : CART_EXPIRE_DAYS), TimeUnit.DAYS);
+
             // 鏇存柊璐墿杞﹀晢鍝佸垪琛�
             updateCartItemList(userId, unitId, cartItemDTO.getPricingId(), true);
-            
+
             // 璁剧疆璐墿杞﹁繃鏈熸椂闂�
-            redisTemplate.expire(cartKey, CART_EXPIRE_DAYS, TimeUnit.DAYS);
-            
-            // 鍚屾鍒版暟鎹簱
-            syncCartItemToDatabase(userId, unitId, existingItem);
-            
+            redisTemplate.expire(cartKey, (cartProperties.getExpireDays() != null ? cartProperties.getExpireDays() : CART_EXPIRE_DAYS), TimeUnit.DAYS);
+
+            // 寮傛鎸佷箙鍖栧埌鏁版嵁搴擄紙鏍规嵁閰嶇疆锛�
+            if (Boolean.TRUE.equals(cartProperties.getEnablePersistence()) && "realtime".equalsIgnoreCase(cartProperties.getSyncStrategy())) {
+                cartPersistenceService.saveOrUpdate(userId, unitId, existingItem);
+            }
+
             log.info("鐢ㄦ埛{}鎴愬姛娣诲姞鍟嗗搧{}鍒拌喘鐗╄溅", userId, cartItemDTO.getProductName());
             return true;
         } catch (Exception e) {
@@ -96,22 +107,24 @@
             throw new BusinessException("娣诲姞鍟嗗搧鍒拌喘鐗╄溅澶辫触锛�" + e.getMessage());
         }
     }
-    
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean removeFromCart(Long userId, Long unitId, Long pricingId) {
         try {
             String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
-            
+
             // 浠嶳edis涓垹闄ゅ晢鍝侀」
             Boolean removed = redisTemplate.delete(cartItemKey);
             if (Boolean.TRUE.equals(removed)) {
                 // 鏇存柊璐墿杞﹀晢鍝佸垪琛�
                 updateCartItemList(userId, unitId, pricingId, false);
-                
-                // 浠庢暟鎹簱涓垹闄�
-                removeCartItemFromDatabase(userId, unitId, pricingId);
-                
+
+                // 寮傛浠庢暟鎹簱涓垹闄わ紙鏍规嵁閰嶇疆锛�
+                if (Boolean.TRUE.equals(cartProperties.getEnablePersistence()) && "realtime".equalsIgnoreCase(cartProperties.getSyncStrategy())) {
+                    cartPersistenceService.remove(userId, unitId, pricingId);
+                }
+
                 log.info("鐢ㄦ埛{}鎴愬姛浠庤喘鐗╄溅绉婚櫎鍟嗗搧{}", userId, pricingId);
                 return true;
             }
@@ -121,7 +134,7 @@
             throw new BusinessException("浠庤喘鐗╄溅绉婚櫎鍟嗗搧澶辫触锛�" + e.getMessage());
         }
     }
-    
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean updateCartItemQuantity(Long userId, Long unitId, Long pricingId, Integer quantity) {
@@ -129,23 +142,25 @@
             if (quantity <= 0) {
                 return removeFromCart(userId, unitId, pricingId);
             }
-            
+
             String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
             CartItemVO cartItem = (CartItemVO) redisTemplate.opsForValue().get(cartItemKey);
             if (cartItem == null) {
                 throw new BusinessException("璐墿杞﹀晢鍝佷笉瀛樺湪");
             }
-            
+
             cartItem.setQuantity(quantity);
             cartItem.setTotalPrice(cartItem.getUnitPrice().multiply(BigDecimal.valueOf(quantity)));
             cartItem.setUpdateTime(LocalDateTime.now());
-            
+
             // 鏇存柊鍒癛edis
-            redisTemplate.opsForValue().set(cartItemKey, cartItem, CART_EXPIRE_DAYS, TimeUnit.DAYS);
-            
-            // 鍚屾鍒版暟鎹簱
-            syncCartItemToDatabase(userId, unitId, cartItem);
-            
+            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, quantity);
             return true;
         } catch (Exception e) {
@@ -153,26 +168,28 @@
             throw new BusinessException("鏇存柊璐墿杞﹀晢鍝佹暟閲忓け璐ワ細" + e.getMessage());
         }
     }
-    
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean clearCart(Long userId, Long unitId) {
         try {
             String cartKey = buildCartKey(userId, unitId);
             List<Long> pricingIds = getCartItemPricingIds(userId, unitId);
-            
+
             // 鍒犻櫎鎵�鏈夊晢鍝侀」
             for (Long pricingId : pricingIds) {
                 String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
                 redisTemplate.delete(cartItemKey);
             }
-            
+
             // 鍒犻櫎璐墿杞﹀垪琛�
             redisTemplate.delete(cartKey);
-            
-            // 娓呯┖鏁版嵁搴撲腑鐨勮喘鐗╄溅鏁版嵁
-            clearCartFromDatabase(userId, unitId);
-            
+
+            // 寮傛娓呯┖鏁版嵁搴撲腑鐨勮喘鐗╄溅鏁版嵁锛堟牴鎹厤缃級
+            if (Boolean.TRUE.equals(cartProperties.getEnablePersistence()) && "realtime".equalsIgnoreCase(cartProperties.getSyncStrategy())) {
+                cartPersistenceService.clear(userId, unitId);
+            }
+
             log.info("鐢ㄦ埛{}鎴愬姛娓呯┖璐墿杞�", userId);
             return true;
         } catch (Exception e) {
@@ -180,34 +197,34 @@
             throw new BusinessException("娓呯┖璐墿杞﹀け璐ワ細" + e.getMessage());
         }
     }
-    
+
     @Override
     public CartVO getCart(Long userId, Long unitId) {
         try {
             CartVO cartVO = new CartVO();
             cartVO.setUserId(userId);
             cartVO.setUnitId(unitId);
-            
+
             List<CartItemVO> items = getCartItems(userId, unitId);
             cartVO.setItems(items);
-            
+
             // 璁$畻鎬绘暟閲忓拰鎬婚噾棰�
             int totalQuantity = items.stream().mapToInt(item -> item.getQuantity()).sum();
             BigDecimal totalAmount = items.stream()
                     .map(item -> item.getTotalPrice())
                     .reduce(BigDecimal.ZERO, BigDecimal::add);
-            
+
             cartVO.setTotalQuantity(totalQuantity);
             cartVO.setTotalAmount(totalAmount);
             cartVO.setLastUpdateTime(LocalDateTime.now());
-            
+
             return cartVO;
         } catch (Exception e) {
             log.error("鑾峰彇璐墿杞︿俊鎭け璐�", e);
             throw new BusinessException("鑾峰彇璐墿杞︿俊鎭け璐ワ細" + e.getMessage());
         }
     }
-    
+
     @Override
     public List<CartItemVO> getCartItems(Long userId, Long unitId) {
         try {
@@ -216,7 +233,7 @@
             if (items != null && !items.isEmpty()) {
                 return items;
             }
-            
+
             // Redis涓病鏈夋暟鎹紝浠庢暟鎹簱鍔犺浇
             log.info("Redis涓棤璐墿杞︽暟鎹紝浠庢暟鎹簱鍔犺浇鐢ㄦ埛{}鐨勮喘鐗╄溅", userId);
             return loadCartFromDatabase(userId, unitId) ? getCartItemsFromRedis(userId, unitId) : new ArrayList<>();
@@ -226,13 +243,13 @@
             return getCartItemsFromDatabase(userId, unitId);
         }
     }
-    
+
     @Override
     public boolean checkCartItemStock(Long userId, Long unitId, Long pricingId) {
         // TODO: 瀹炵幇搴撳瓨妫�鏌ラ�昏緫
         return true;
     }
-    
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean batchRemoveFromCart(Long userId, Long unitId, List<Long> pricingIds) {
@@ -240,18 +257,18 @@
             if (CollectionUtils.isEmpty(pricingIds)) {
                 return true;
             }
-            
+
             for (Long pricingId : pricingIds) {
                 removeFromCart(userId, unitId, pricingId);
             }
-            
+
             return true;
         } catch (Exception e) {
             log.error("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佸け璐�", e);
             throw new BusinessException("鎵归噺鍒犻櫎璐墿杞﹀晢鍝佸け璐ワ細" + e.getMessage());
         }
     }
-    
+
     @Override
     public Integer getCartItemCount(Long userId, Long unitId) {
         try {
@@ -261,7 +278,7 @@
             if (pricingIds != null) {
                 return pricingIds.size();
             }
-            
+
             // 浠庢暟鎹簱鑾峰彇
             return cartMapper.countByUserIdAndUnitId(userId, unitId);
         } catch (Exception e) {
@@ -269,7 +286,7 @@
             return 0;
         }
     }
-    
+
     @Override
     public boolean loadCartFromDatabase(Long userId, Long unitId) {
         try {
@@ -277,22 +294,22 @@
             if (CollectionUtils.isEmpty(cartItems)) {
                 return false;
             }
-            
+
             String cartKey = buildCartKey(userId, unitId);
             List<Long> pricingIds = new ArrayList<>();
-            
+
             for (Cart cartItem : cartItems) {
                 CartItemVO itemVO = convertCartToCartItemVO(cartItem);
                 String cartItemKey = buildCartItemKey(userId, unitId, cartItem.getPricingId());
-                
+
                 // 淇濆瓨鍒癛edis
                 redisTemplate.opsForValue().set(cartItemKey, itemVO, CART_EXPIRE_DAYS, TimeUnit.DAYS);
                 pricingIds.add(cartItem.getPricingId());
             }
-            
+
             // 淇濆瓨璐墿杞﹀垪琛ㄥ埌Redis
             redisTemplate.opsForValue().set(cartKey, pricingIds, CART_EXPIRE_DAYS, TimeUnit.DAYS);
-            
+
             log.info("鎴愬姛浠庢暟鎹簱鍔犺浇鐢ㄦ埛{}鐨勮喘鐗╄溅鏁版嵁鍒癛edis", userId);
             return true;
         } catch (Exception e) {
@@ -300,7 +317,7 @@
             return false;
         }
     }
-    
+
     @Override
     public boolean syncCartToDatabase(Long userId, Long unitId) {
         try {
@@ -308,15 +325,15 @@
             if (CollectionUtils.isEmpty(redisItems)) {
                 return true;
             }
-            
+
             // 娓呯┖鏁版嵁搴撲腑鐨勮喘鐗╄溅鏁版嵁
             clearCartFromDatabase(userId, unitId);
-            
+
             // 鍚屾Redis鏁版嵁鍒版暟鎹簱
             for (CartItemVO item : redisItems) {
                 syncCartItemToDatabase(userId, unitId, item);
             }
-            
+
             log.info("鎴愬姛鍚屾Redis璐墿杞︽暟鎹埌鏁版嵁搴擄紝鐢ㄦ埛{}", userId);
             return true;
         } catch (Exception e) {
@@ -324,18 +341,18 @@
             return false;
         }
     }
-    
+
     @Override
     public boolean checkCartConsistency(Long userId, Long unitId) {
         try {
             List<CartItemVO> redisItems = getCartItemsFromRedis(userId, unitId);
             List<Cart> dbItems = cartMapper.selectByUserIdAndUnitId(userId, unitId);
-            
+
             if (redisItems.size() != dbItems.size()) {
                 log.warn("璐墿杞︽暟鎹笉涓�鑷达細Redis鏁伴噺{}锛屾暟鎹簱鏁伴噺{}", redisItems.size(), dbItems.size());
                 return false;
             }
-            
+
             // 妫�鏌ユ瘡涓晢鍝侀」鏄惁涓�鑷�
             for (CartItemVO redisItem : redisItems) {
                 boolean found = false;
@@ -351,56 +368,56 @@
                     return false;
                 }
             }
-            
+
             return true;
         } catch (Exception e) {
             log.error("妫�鏌ヨ喘鐗╄溅鏁版嵁涓�鑷存�уけ璐�", e);
             return false;
         }
     }
-    
+
     // ==================== 绉佹湁鏂规硶 ====================
-    
+
     private String buildCartKey(Long userId, Long unitId) {
         return CART_KEY_PREFIX + userId + ":" + unitId;
     }
-    
+
     private String buildCartItemKey(Long userId, Long unitId, Long pricingId) {
         return CART_ITEM_KEY_PREFIX + userId + ":" + unitId + ":" + pricingId;
     }
-    
+
     private void updateCartItemList(Long userId, Long unitId, Long pricingId, boolean add) {
         String cartKey = buildCartKey(userId, unitId);
         List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
-        
+
         if (pricingIds == null) {
             pricingIds = new ArrayList<>();
         }
-        
+
         if (add && !pricingIds.contains(pricingId)) {
             pricingIds.add(pricingId);
         } else if (!add) {
             pricingIds.remove(pricingId);
         }
-        
+
         redisTemplate.opsForValue().set(cartKey, pricingIds, CART_EXPIRE_DAYS, TimeUnit.DAYS);
     }
-    
+
     private List<Long> getCartItemPricingIds(Long userId, Long unitId) {
         String cartKey = buildCartKey(userId, unitId);
         List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
         return pricingIds != null ? pricingIds : new ArrayList<>();
     }
-    
+
     private List<CartItemVO> getCartItemsFromRedis(Long userId, Long unitId) {
         try {
             String cartKey = buildCartKey(userId, unitId);
             List<Long> pricingIds = (List<Long>) redisTemplate.opsForValue().get(cartKey);
-            
+
             if (CollectionUtils.isEmpty(pricingIds)) {
                 return new ArrayList<>();
             }
-            
+
             List<CartItemVO> items = new ArrayList<>();
             for (Long pricingId : pricingIds) {
                 String cartItemKey = buildCartItemKey(userId, unitId, pricingId);
@@ -409,7 +426,7 @@
                     items.add(item);
                 }
             }
-            
+
             return items;
         } catch (Exception e) {
             log.error("浠嶳edis鑾峰彇璐墿杞﹀晢鍝佸垪琛ㄥけ璐�", e);
@@ -467,7 +484,7 @@
         try {
             Cart existingCart = cartMapper.selectByUserIdUnitIdAndPricingId(userId, unitId, pricingId);
             if (existingCart != null) {
-                cartMapper.deleteById(existingCart.getId());
+                cartMapper.deleteByCustomerCondition(existingCart.getId());
             }
         } catch (Exception e) {
             log.error("浠庢暟鎹簱鍒犻櫎璐墿杞﹀晢鍝佸け璐�", e);

--
Gitblit v1.8.0