From 53c315297a3906e567b01107a85836528a664206 Mon Sep 17 00:00:00 2001 From: seatonwan9 Date: 星期二, 19 八月 2025 18:11:38 +0800 Subject: [PATCH] 产品订购sql --- 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