Helius
2022-05-27 4351e71d782741143a98f86f6648acd16689165f
zq-erp/src/main/java/com/matrix/system/shopXcx/api/service/OrderCouponGroupService.java
New file
@@ -0,0 +1,282 @@
package com.matrix.system.shopXcx.api.service;
import com.matrix.system.common.init.UserCacheManager;
import com.matrix.core.exception.GlobleException;
import com.matrix.core.tools.LogUtil;
import com.matrix.system.common.dao.BusParameterSettingsDao;
import com.matrix.system.shopXcx.api.pojo.OrderCouponGroup;
import com.matrix.system.shopXcx.api.pojo.OrderItemDto;
import com.matrix.system.shopXcx.bean.ShopCoupon;
import com.matrix.system.shopXcx.bean.ShopShoppingCart;
import com.matrix.system.shopXcx.dao.ShopProductDao;
import com.matrix.system.shopXcx.dao.ShopShoppingCartDao;
import com.matrix.system.shopXcx.dao.ShopSkuDao;
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 OrderCouponGroupService {
    @Autowired
    private ShopShoppingCartDao shoppingCartDao;
    @Autowired
    private UserCacheManager userCacheManager;
    @Autowired
    WxShopCouponService shopCouponService;
    @Autowired
    BusParameterSettingsDao busParameterSettingsDao;
    @Autowired
    ShopProductDao shopProductDao;
    @Autowired
    ShopSkuDao shopSkuDao;
    /**
     * 初始化OrderCouponElement
     * @param skuId
     * @param count
     * @param payType
     * @return
     */
    public OrderItemDto buildOrderCouponElement(OrderItemDto orderItemDto){
        orderItemDto.setShopSku(shopSkuDao.selectById(orderItemDto.getSkuId()));
        orderItemDto.setShopProduct(shopProductDao.selectById(orderItemDto.getProductId()));
        return orderItemDto;
    }
    /**
     * 计算用户的产品可以参与的店铺优惠活动分组
     */
    public List<OrderCouponGroup> buildOrderCouponGroupList(List<OrderItemDto> list) {
        //定义购物车优惠分组
        List<OrderCouponGroup> orderCouponGroupList = new ArrayList<>();
        // 1表示没有优惠的默认分组
        OrderCouponGroup def = new OrderCouponGroup();
        def.setSatisfactionCoupon(true);
        def.setMsg("商城");
        def.setOrderItemDtos(new ArrayList<>());
        // 组合默认分组
        orderCouponGroupList.add(def);
        // 记录所有优惠券,一个优惠券(活动)表示一组
        Map<Integer, ShopCoupon> shopCouponMap = new HashMap<>();
        //查询购物车中的产品匹配上的所有优惠活动
        for (OrderItemDto orderItemDto : list) {
            if(orderItemDto.getPayType()== ShopShoppingCart.CAR_TYPE_SCORE){
                // 积分兑换产品不参加优惠
                def.getOrderItemDtos().add(orderItemDto);
            }else{
                List<ShopCoupon> shopCouponList = shopCouponService.getHdListByProductId(orderItemDto.getProductId());
                if (CollectionUtils.isNotEmpty(shopCouponList)) {
                    // 把所有的优惠券和购物车条目先关联一下,后续可以计算优惠升级的情况
                    orderItemDto.setShopCoupons(shopCouponList);
                    for (ShopCoupon shopCoupon : shopCouponList) {
                        shopCouponMap.put(shopCoupon.getId(), shopCoupon);
                    }
                } else {
                    // 该产品没有参加优惠券
                    def.getOrderItemDtos().add(orderItemDto);
                }
            }
        }
        //计算没有优惠组的价格
        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);
            OrderCouponGroup shopCarVo = new OrderCouponGroup();
            shopCarVo.setCoupon(shopCoupon);
            shopCarVo.setOrderItemDtos(new ArrayList<>());
            orderCouponGroupList.add(i, shopCarVo);
            // 获取所有购物车条目
            for (OrderItemDto orderItemDto : list) {
                // 如果匹配到的产品已经出现在其他优惠组中,则需要判断是否移除之前的组
                boolean needRemove = false;
                // 判断当前购物车条目是否已经在合适的组里了
                if (isInGroupAndSatisfaction(orderItemDto, orderCouponGroupList)) {
                    continue;
                } else if (isInGroupNotSatisfaction(orderItemDto, orderCouponGroupList)) {
                    needRemove = true;
                }
                List<ShopCoupon> cartCouons = orderItemDto.getShopCoupons();
                if (cartCouons != null) {
                    // 获取每个购物车条目满足的优惠
                    for (ShopCoupon cartCouon : cartCouons) {
                        if (cartCouon.getId().equals(shopCoupon.getId())) {
                            //匹配成功,加入本组
                            LogUtil.debug("购物车" + orderItemDto.getProductId() + "和优惠券" + cartCouon.getCName() + "匹配");
                            if (needRemove) {
                                removeNotSatisfaction(orderItemDto, orderCouponGroupList);
                            }
                            shopCarVo.getOrderItemDtos().add(orderItemDto);
                            break;
                        }
                    }
                }
            }
            // 计算本组优惠券是否已经满足优惠条件
            countPrice(shopCarVo);
        }
        // 因为有些优惠中可能没有产品,所以要去除cartList中没有产品的分组
        List<OrderCouponGroup> cartListCopy = new ArrayList<>();
        for (OrderCouponGroup orderCouponGroup : orderCouponGroupList) {
            if (CollectionUtils.isNotEmpty(orderCouponGroup.getOrderItemDtos())) {
                cartListCopy.add(orderCouponGroup);
            }
        }
        return cartListCopy;
    }
    /**
     * 购车条目在组中并且组是否已经满足优惠的
     *
     * @param cartList
     * @return
     */
    private boolean isInGroupAndSatisfaction(OrderItemDto orderItemDto, List<OrderCouponGroup> cartList) {
        boolean result = false;
        for (OrderCouponGroup cartVo : cartList) {
            if (cartVo.isSatisfactionCoupon() && cartVo.getOrderItemDtos().contains(orderItemDto)) {
                result = true;
            }
        }
        return result;
    }
    /**
     * 购物车条目在组中,但是组中产品没有达到优惠条件
     * @param cartList
     * @return
     */
    private boolean isInGroupNotSatisfaction(OrderItemDto orderItemDto, List<OrderCouponGroup> cartList) {
        boolean result = false;
        for (OrderCouponGroup cartVo : cartList) {
            if (!cartVo.isSatisfactionCoupon() && cartVo.getOrderItemDtos().contains(orderItemDto)) {
                result = true;
            }
        }
        return result;
    }
    /**
     * 删除购物车条目所在分组中的引用
     *
     * @param cartList
     */
    private void removeNotSatisfaction(OrderItemDto orderItemDto, List<OrderCouponGroup> cartList) {
        for (OrderCouponGroup cartVo : cartList) {
            if (cartVo.getOrderItemDtos().remove(orderItemDto)) {
                LogUtil.debug("删除购物车所在组" + cartVo.getCoupon().getCName() + "," + orderItemDto.getProductId());
            }
        }
    }
    /**
     * 计算购物车价格和优惠信息
     *
     * @author JIANGYOUYAO
     * @email 935090232@qq.com
     * @date 2019年8月27日
     */
    private void countPrice(OrderCouponGroup orderCouponGroup) {
        List<OrderItemDto> orderItemDtoList = orderCouponGroup.getOrderItemDtos();
        // 计算总价
        BigDecimal sum = BigDecimal.ZERO;
        //抵扣总积分
        BigDecimal scoreSum = BigDecimal.ZERO;
        for (OrderItemDto orderCouponElement : orderItemDtoList) {
            if(ShopShoppingCart.CAR_TYPE_MICRO==orderCouponElement.getPayType()){
                //直接购买
                sum = sum.add(orderCouponElement.getShopSku().getPrice().multiply(BigDecimal.valueOf(orderCouponElement.getCount())));
            }else if(ShopShoppingCart.CAR_TYPE_SCORE==orderCouponElement.getPayType()){
                //积分兑换
                sum = sum.add(orderCouponElement.getShopSku().getScorePrice().multiply(BigDecimal.valueOf(orderCouponElement.getCount())));
                scoreSum = scoreSum.add(new BigDecimal(orderCouponElement.getShopSku().getScoreCount() * orderCouponElement.getCount()));
            }else{
                throw new GlobleException("参数错误");
            }
        }
        if (orderCouponGroup.getCoupon() != null) {
            // 存在优惠券
            if (sum.compareTo(orderCouponGroup.getCoupon().getMinAmount()) >= 0) {
                //标记为合理分组
                orderCouponGroup.setSatisfactionCoupon(true);
                if (sum.compareTo(orderCouponGroup.getCoupon().getMinAmount()) >= 0) {
                    orderCouponGroup.setSubtotal(sum.subtract(orderCouponGroup.getCoupon().getOffsetAmount()));
                    orderCouponGroup.setSrcPrice(sum);
                    orderCouponGroup.setCouponPrice(orderCouponGroup.getCoupon().getOffsetAmount());
                    orderCouponGroup.setMsg(orderCouponGroup.getCoupon().getCName() + ",已优惠"
                            + orderCouponGroup.getCoupon().getOffsetAmount().stripTrailingZeros().toPlainString() + "元");
                }
            }
            if (sum.compareTo(orderCouponGroup.getCoupon().getMinAmount()) < 0) {
                orderCouponGroup.setSatisfactionCoupon(false);
                orderCouponGroup.setSubtotal(sum);
                orderCouponGroup.setSrcPrice(sum);
                orderCouponGroup.setMsg(orderCouponGroup.getCoupon().getCName());
                if (sum.doubleValue() > 0) {
                    orderCouponGroup.setMsg(orderCouponGroup.getCoupon().getCName() + ",再买"
                            + (orderCouponGroup.getCoupon().getMinAmount().subtract(sum)).stripTrailingZeros()
                            .toPlainString()
                            + "元立减" + orderCouponGroup.getCoupon().getOffsetAmount().stripTrailingZeros().toPlainString()
                            + "元");
                }
            }
        } else {
            orderCouponGroup.setSubtotal(sum);
            orderCouponGroup.setSrcPrice(sum);
            orderCouponGroup.setSatisfactionCoupon(true);
        }
        orderCouponGroup.setScorePay(scoreSum);
    }
}