| package com.matrix.system.shopXcx.api.service; | 
|   | 
| import com.matrix.component.redis.RedisUserLoginUtils; | 
| import com.matrix.core.tools.LogUtil; | 
| import com.matrix.system.common.dao.BusParameterSettingsDao; | 
| import com.matrix.system.shopXcx.api.vo.ShopCartBillVo; | 
| import com.matrix.system.shopXcx.api.vo.ShopCartVo; | 
| import com.matrix.system.shopXcx.bean.ShopCoupon; | 
| import com.matrix.system.shopXcx.bean.ShopShoppingCart; | 
| import com.matrix.system.shopXcx.dao.ShopShoppingCartDao; | 
| import org.apache.commons.collections.CollectionUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Service; | 
|   | 
| import java.math.BigDecimal; | 
| import java.util.*; | 
|   | 
| @Service | 
| public class ShoppingCartService { | 
|   | 
|     @Autowired | 
|     private ShopShoppingCartDao shoppingCartDao; | 
|     @Autowired | 
|     private RedisUserLoginUtils redisUserLoginUtils; | 
|   | 
|     @Autowired | 
|     WxShopCouponService shopCouponService; | 
|   | 
|   | 
|   | 
|     @Autowired | 
|     BusParameterSettingsDao busParameterSettingsDao; | 
|   | 
|     //计算购车选中项总价以及优惠金额 | 
|     public ShopCartBillVo buildShopCartBillVo(List<ShopCartVo> cartList) { | 
|   | 
|         ShopCartBillVo shopCartBillVo = new ShopCartBillVo(); | 
|   | 
|   | 
|         //计算是否存在选中的产品 | 
|         Integer selectCount = 0; | 
|         //购物车总条数 | 
|         Integer cartCount = 0; | 
|   | 
|         for (ShopCartVo shopCartVo : cartList) { | 
|   | 
|             if (shopCartVo.getSubtotal() != null) { | 
|                 shopCartBillVo.setBillTotal(shopCartBillVo.getBillTotal().add(shopCartVo.getSubtotal())); | 
|                 shopCartBillVo.setSrcTotal(shopCartBillVo.getSrcTotal().add(shopCartVo.getSrcPrice())); | 
|             } | 
|   | 
|             if (shopCartVo.getCouponPrice() != null) { | 
|                 if (shopCartVo.isSatisfactionCoupon()) { | 
|                     shopCartBillVo.setBillCouponTotal(shopCartBillVo.getBillCouponTotal().add(shopCartVo.getCouponPrice())); | 
|                 } | 
|             } | 
|             for (ShopShoppingCart shopCart : shopCartVo.getCartList()) { | 
|                 if (shopCart.getIsSelected() == 1) { | 
|                     selectCount += shopCart.getCartNumber(); | 
|                 } | 
|                 cartCount += shopCart.getCartNumber(); | 
|             } | 
|         } | 
|         shopCartBillVo.setCartCount(cartCount); | 
|         shopCartBillVo.setSelectCount(selectCount); | 
|         return shopCartBillVo; | 
|     } | 
|   | 
|   | 
|   | 
|   | 
|     /** | 
|      * 组装购物车优惠信息 | 
|      * | 
|      * @param list | 
|      * @return | 
|      */ | 
|     @SuppressWarnings("unchecked") | 
|     public List<ShopCartVo> buildShopCart(List<ShopShoppingCart> list) { | 
|   | 
|   | 
|         //定义购物车优惠分组 | 
|         List<ShopCartVo> cartList = new ArrayList<>(); | 
|         // 1表示没有优惠的默认分组 | 
|         ShopCartVo def = new ShopCartVo(); | 
|   | 
|   | 
|   | 
|         def.setMsg("商城"); | 
|         def.setCartList(new ArrayList<>()); | 
|         // 组合默认分组 | 
|         cartList.add(def); | 
|   | 
|         // 记录所有优惠券,一个优惠券(活动)表示一组 | 
|         Map<Integer, ShopCoupon> shopCouponMap = new HashMap<>(); | 
|   | 
|         //查询购物车中的产品匹配上的所有优惠活动 | 
|         for (ShopShoppingCart shoppingCart : list) { | 
|   | 
|             List<ShopCoupon> shopCoupons = shopCouponService.getHdListByProductId(shoppingCart.getCartProductId()); | 
|   | 
|             if (CollectionUtils.isNotEmpty(shopCoupons)) { | 
|                 // 把所有的优惠券和购物车条目先关联一下,后续可以计算优惠升级的情况 | 
|                 shoppingCart.setShopCoupons(shopCoupons); | 
|                 for (ShopCoupon shopCoupon : shopCoupons) { | 
|                     shopCouponMap.put(shopCoupon.getId(), shopCoupon); | 
|                 } | 
|             } else { | 
|                 // 该产品没有参加优惠券 | 
|                 def.getCartList().add(shoppingCart); | 
|   | 
|             } | 
|         } | 
|   | 
|         //计算没有优惠组的价格 | 
|         countPrice(def); | 
|   | 
|   | 
|         /* | 
|          * 计算优惠券分组 1、获取到所有的优惠券,从最高满减开始,找寻合适的产品,找到后加入对应的购物车组 | 
|          * 2、计算组内价格,只计算选中状态的 | 
|          */ | 
|         Set<Integer> keys = shopCouponMap.keySet(); | 
|         List<ShopCoupon> allShopCoupons = new ArrayList<>(); | 
|         for (Integer key : keys) { | 
|             allShopCoupons.add(shopCouponMap.get(key)); | 
|         } | 
|   | 
|         //根据优惠力度排序,优惠力度大的先参与计算 | 
|         Collections.sort(allShopCoupons, new Comparator() { | 
|             @Override | 
|             public int compare(Object o1, Object o2) { | 
|                 ShopCoupon e1 = (ShopCoupon) o1; | 
|                 ShopCoupon e2 = (ShopCoupon) o2; | 
|                 return e2.getMinAmount().compareTo(e1.getMinAmount()); | 
|             } | 
|         }); | 
|   | 
|   | 
|         // 进行购物车和优惠券的匹配,匹配成功的加入到优惠组中, | 
|         for (int i = 0; i < allShopCoupons.size(); i++) { | 
|             ShopCoupon shopCoupon = allShopCoupons.get(i); | 
|             ShopCartVo shopCarVo = new ShopCartVo(); | 
|             shopCarVo.setCoupon(shopCoupon); | 
|             shopCarVo.setCartList(new ArrayList<>()); | 
|             cartList.add(i, shopCarVo); | 
|   | 
|             // 获取所有购物车条目 | 
|             for (ShopShoppingCart shoppingCart : list) { | 
|   | 
|                 // 如果匹配到的产品已经出现在其他优惠组中,则需要判断是否移除之前的组 | 
|                 boolean needRemove = false; | 
|   | 
|                 // 判断当前购物车条目是否已经在合适的组里了 | 
|                 if (isInGroupAndSatisfaction(shoppingCart, cartList)) { | 
|                     continue; | 
|   | 
|                 } else if (isInGroupNotSatisfaction(shoppingCart, cartList)) { | 
|                     needRemove = true; | 
|                 } | 
|   | 
|                 List<ShopCoupon> cartCouons = shoppingCart.getShopCoupons(); | 
|                 if (cartCouons != null) { | 
|                     // 获取每个购物车条目满足的优惠 | 
|                     for (ShopCoupon cartCouon : cartCouons) { | 
|                         if (cartCouon.getId().equals(shopCoupon.getId())) { | 
|                             //匹配成功,加入本组 | 
|                             LogUtil.debug("购物车" + shoppingCart.getName() + "和优惠券" + cartCouon.getCName() + "匹配"); | 
|                             if (needRemove) { | 
|                                 removeNotSatisfaction(shoppingCart, cartList); | 
|                             } | 
|                             shopCarVo.getCartList().add(shoppingCart); | 
|                             break; | 
|                         } | 
|                     } | 
|                 } | 
|   | 
|             } | 
|   | 
|             // 计算本组优惠券是否已经满足优惠条件 | 
|             countPrice(shopCarVo); | 
|         } | 
|   | 
|   | 
|         // 因为有些优惠中可能没有产品,所以要去除cartList中没有产品的分组 | 
|         List<ShopCartVo> cartListCopy = new ArrayList<>(); | 
|         for (ShopCartVo shopCartVo : cartList) { | 
|             if (CollectionUtils.isNotEmpty(shopCartVo.getCartList())) { | 
|                 cartListCopy.add(shopCartVo); | 
|             } | 
|         } | 
|         return cartListCopy; | 
|     } | 
|   | 
|     /** | 
|      * 购车条目在组中并且组是否已经满足优惠的 | 
|      * | 
|      * @param shopShoppingCart | 
|      * @param cartList | 
|      * @return | 
|      */ | 
|     private boolean isInGroupAndSatisfaction(ShopShoppingCart shopShoppingCart, List<ShopCartVo> cartList) { | 
|         boolean result = false; | 
|         for (ShopCartVo cartVo : cartList) { | 
|             if (cartVo.isSatisfactionCoupon() && cartVo.getCartList().contains(shopShoppingCart)) { | 
|                 result = true; | 
|             } | 
|         } | 
|         return result; | 
|     } | 
|   | 
|     /** | 
|      * 购物车条目在组中,但是组中产品没有达到优惠条件 | 
|      * | 
|      * @param shopShoppingCart | 
|      * @param cartList | 
|      * @return | 
|      */ | 
|     private boolean isInGroupNotSatisfaction(ShopShoppingCart shopShoppingCart, List<ShopCartVo> cartList) { | 
|         boolean result = false; | 
|         for (ShopCartVo cartVo : cartList) { | 
|             if (!cartVo.isSatisfactionCoupon() && cartVo.getCartList().contains(shopShoppingCart)) { | 
|                 result = true; | 
|             } | 
|         } | 
|         return result; | 
|     } | 
|   | 
|     /** | 
|      * 删除购物车条目所在分组中的引用 | 
|      * | 
|      * @param shopShoppingCart | 
|      * @param cartList | 
|      */ | 
|     private void removeNotSatisfaction(ShopShoppingCart shopShoppingCart, List<ShopCartVo> cartList) { | 
|         for (ShopCartVo cartVo : cartList) { | 
|             if (cartVo.getCartList().remove(shopShoppingCart)) { | 
|                 LogUtil.debug("删除购物车所在组" + cartVo.getCoupon().getCName() + "," + shopShoppingCart.getName()); | 
|             } | 
|         } | 
|     } | 
|   | 
|     /** | 
|      * 计算购物车价格和优惠信息 | 
|      * | 
|      * @author JIANGYOUYAO | 
|      * @email 935090232@qq.com | 
|      * @date 2019年8月27日 | 
|      */ | 
|     private void countPrice(ShopCartVo shopCartVo) { | 
|         List<ShopShoppingCart> cartList = shopCartVo.getCartList(); | 
|         // 计算总价 | 
|         BigDecimal sum = BigDecimal.ZERO; | 
|         // 选中项总价 | 
|         BigDecimal selectSum = BigDecimal.ZERO; | 
|         for (ShopShoppingCart shopShoppingCart : cartList) { | 
|             sum = sum.add(shopShoppingCart.getPrice().multiply(BigDecimal.valueOf(shopShoppingCart.getCartNumber()))); | 
|             if (shopShoppingCart.getIsSelected() == 1) { | 
|                 if(shopShoppingCart.getCartType()==ShopShoppingCart.CAR_TYPE_MICRO){ | 
|                     selectSum = selectSum | 
|                             .add(shopShoppingCart.getPrice().multiply(BigDecimal.valueOf(shopShoppingCart.getCartNumber()))); | 
|                 }else { | 
|                     selectSum = selectSum | 
|                             .add(shopShoppingCart.getScorePrice().multiply(BigDecimal.valueOf(shopShoppingCart.getCartNumber()))); | 
|                 } | 
|   | 
|             } | 
|         } | 
|   | 
|         if (shopCartVo.getCoupon() != null) { | 
|             // 存在优惠券 | 
|             if (sum.compareTo(shopCartVo.getCoupon().getMinAmount()) >= 0) { | 
|                 //标记为合理分组 | 
|                 shopCartVo.setSatisfactionCoupon(true); | 
|                 if (selectSum.compareTo(shopCartVo.getCoupon().getMinAmount()) >= 0) { | 
|                     shopCartVo.setSubtotal(selectSum.subtract(shopCartVo.getCoupon().getOffsetAmount())); | 
|                     shopCartVo.setSrcPrice(selectSum); | 
|                     shopCartVo.setCouponPrice(shopCartVo.getCoupon().getOffsetAmount()); | 
|                     shopCartVo.setMsg(shopCartVo.getCoupon().getCName() + ",已优惠" | 
|                             + shopCartVo.getCoupon().getOffsetAmount().stripTrailingZeros().toPlainString() + "元"); | 
|                 } | 
|             } | 
|             if (selectSum.compareTo(shopCartVo.getCoupon().getMinAmount()) < 0) { | 
|                 shopCartVo.setSatisfactionCoupon(false); | 
|                 shopCartVo.setSubtotal(selectSum); | 
|                 shopCartVo.setSrcPrice(selectSum); | 
|                 shopCartVo.setMsg(shopCartVo.getCoupon().getCName()); | 
|                 if (selectSum.doubleValue() > 0) { | 
|                     shopCartVo.setMsg(shopCartVo.getCoupon().getCName() + ",再买" | 
|                             + (shopCartVo.getCoupon().getMinAmount().subtract(selectSum)).stripTrailingZeros() | 
|                             .toPlainString() | 
|                             + "元立减" + shopCartVo.getCoupon().getOffsetAmount().stripTrailingZeros().toPlainString() | 
|                             + "元"); | 
|                 } | 
|             } | 
|         } else { | 
|             shopCartVo.setSubtotal(selectSum); | 
|             shopCartVo.setSrcPrice(selectSum); | 
|             shopCartVo.setSatisfactionCoupon(true); | 
|         } | 
|     } | 
| } |