package com.matrix.system.shopXcx.api.service; import com.matrix.core.tools.LogUtil; import com.matrix.biz.bean.BizUser; import com.matrix.system.common.bean.BusParameterSettings; import com.matrix.system.common.bean.CustomerDataDictionary; import com.matrix.system.common.dao.BusParameterSettingsDao; import com.matrix.system.common.dao.CustomerDataDictionaryDao; import com.matrix.component.redis.RedisUserLoginUtils; import com.matrix.system.common.constance.AppConstance; import com.matrix.system.shopXcx.bean.ShopCoupon; import com.matrix.system.shopXcx.bean.ShopShoppingCart; import com.matrix.system.shopXcx.dao.ShopShoppingCartDao; import com.matrix.system.shopXcx.api.vo.ShopCartBillVo; import com.matrix.system.shopXcx.api.vo.ShopCartVo; 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 cartList) { ShopCartBillVo shopCartBillVo = new ShopCartBillVo(); //计算购车选中项总价以及优惠金额 BigDecimal billTotal = BigDecimal.ZERO; BigDecimal billCouponTotal = BigDecimal.ZERO; //未优惠之前的金额 BigDecimal srcTotal = BigDecimal.ZERO; //计算是否存在选中的产品 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; } /** * 计算用户的购物车产品优惠分组 * * @return * @param shopId */ public List findUserCartList(Long shopId) { BizUser loginUser = redisUserLoginUtils.getLoginUser(BizUser.class); String userId = loginUser.getOpenId(); List list = shoppingCartDao.selectByCartUserId(shopId,userId); List cartList = buildShopCart(list); return cartList; } /** * 组装购物车优惠信息 * * @param list * @return */ @SuppressWarnings("unchecked") private List buildShopCart(List list) { //定义购物车优惠分组 List cartList = new ArrayList<>(); // 1表示没有优惠的默认分组 ShopCartVo def = new ShopCartVo(); /** * 同城配送标题 * //DataDictionary qsfy = dataDictionaryDao.selectByTypeCode(AppConstance.QSFY); * //def.setMsg("2公里内满" + qsfy.getValue() + "元免配送费"); */ def.setMsg("商城"); def.setCartList(new ArrayList<>()); // 组合默认分组 cartList.add(def); // 记录所有优惠券,一个优惠券(活动)表示一组 Map shopCouponMap = new HashMap<>(); //查询购物车中的产品匹配上的所有优惠活动 for (ShopShoppingCart shoppingCart : list) { List 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 keys = shopCouponMap.keySet(); List 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 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 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 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 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 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 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) { selectSum = selectSum .add(shopShoppingCart.getPrice().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 { BusParameterSettings qsfy= busParameterSettingsDao.selectCompanyParamByCode(AppConstance.IN_PROVINCE_PACKAGE_LIST,17L); shopCartVo.setSubtotal(selectSum); shopCartVo.setSrcPrice(selectSum); if (selectSum.compareTo(new BigDecimal(qsfy.getParamValue())) < 0) { shopCartVo.setSatisfactionCoupon(false); } else { shopCartVo.setSatisfactionCoupon(true); } } } }