package com.slodon.b2b2c.model.business;

import com.slodon.b2b2c.business.dto.OrderSubmitParamDTO;
import com.slodon.b2b2c.business.example.CartExample;
import com.slodon.b2b2c.business.pojo.Cart;
import com.slodon.b2b2c.core.constant.*;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.util.AssertUtil;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.dao.read.business.CartReadMapper;
import com.slodon.b2b2c.dao.read.goods.GoodsPromotionReadMapper;
import com.slodon.b2b2c.dao.read.goods.GoodsReadMapper;
import com.slodon.b2b2c.dao.read.goods.ProductReadMapper;
import com.slodon.b2b2c.dao.read.promotion.*;
import com.slodon.b2b2c.dao.write.business.CartWriteMapper;
import com.slodon.b2b2c.goods.example.GoodsPromotionExample;
import com.slodon.b2b2c.goods.pojo.Goods;
import com.slodon.b2b2c.goods.pojo.GoodsPromotion;
import com.slodon.b2b2c.goods.pojo.Product;
import com.slodon.b2b2c.model.promotion.PromotionCommonModel;
import com.slodon.b2b2c.promotion.example.LadderGroupGoodsExample;
import com.slodon.b2b2c.promotion.example.PresellGoodsExample;
import com.slodon.b2b2c.promotion.example.SeckillStageProductExample;
import com.slodon.b2b2c.promotion.example.SpellGoodsExample;
import com.slodon.b2b2c.promotion.pojo.*;
import com.slodon.b2b2c.vo.business.OrderSubmitCheckVO;
import com.slodon.b2b2c.vo.business.OrderSubmitPageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author Slodon
 */
@Component
@Slf4j
public class CartModel {

    @Resource
    private CartReadMapper cartReadMapper;
    @Resource
    private CartWriteMapper cartWriteMapper;
    @Resource
    private LadderGroupReadMapper ladderGroupReadMapper;
    @Resource
    private PresellReadMapper presellReadMapper;
    @Resource
    private PresellGoodsReadMapper presellGoodsReadMapper;
    @Resource
    private SpellReadMapper spellReadMapper;
    @Resource
    private SpellGoodsReadMapper spellGoodsReadMapper;
    @Resource
    private SeckillStageProductReadMapper seckillStageProductReadMapper;
    @Resource
    private LadderGroupGoodsReadMapper ladderGroupGoodsReadMapper;
    @Resource
    private GoodsPromotionReadMapper goodsPromotionReadMapper;
    @Resource
    private ProductReadMapper productReadMapper;
    @Resource
    private GoodsReadMapper goodsReadMapper;
    @Resource
    private PromotionCommonModel promotionCommonModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 购物车列表刷新用户购物车
     * 1.商品下架，货品禁用、删除、锁定（预售、拼团活动锁定sku）时，将购物车置为失效
     * 2.sku库存不足时，取消选中状态
     * 3.更新购物车货品其他信息
     *
     * @param memberId 会员id
     */
    public void refreshCart(Integer memberId) {
        CartExample cartExample = new CartExample();
        cartExample.setMemberId(memberId);

        List<Cart> cartList = cartReadMapper.listByExample(cartExample);
        if (CollectionUtils.isEmpty(cartList)) {
            return;
        }
        for (Cart cartDb : cartList) {//商品信息
            Goods goods = goodsReadMapper.getByPrimaryKey(cartDb.getGoodsId());
            //查询货品信息
            Product product = productReadMapper.getByPrimaryKey(cartDb.getProductId());
            if (!goods.getState().equals(GoodsConst.GOODS_STATE_UPPER)) {
                //商品下架，置为失效
                this.invalidCart(cartDb.getCartId());
                continue;
            }
            if (product.getState().equals(GoodsConst.PRODUCT_STATE_0) || product.getState().equals(GoodsConst.PRODUCT_STATE_2)) {
                //货品禁用或删除，置为失效
                this.invalidCart(cartDb.getCartId());
                continue;
            }
            if (product.getState().equals(GoodsConst.PRODUCT_STATE_3)) {
                //商品为锁定状态，查询商品活动信息
                GoodsPromotion singlePromotion = this.getSinglePromotion(product.getProductId());
                if (singlePromotion != null) {
                    if (singlePromotion.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_104)) {
                        //秒杀
                        if (promotionCommonModel.isPromotionAvailable(singlePromotion.getPromotionType(), product.getProductId().toString())) {
                            //秒杀活动进行中，置为失效
                            this.invalidCart(cartDb.getCartId());
                            continue;
                        }
                    }
                    //其他单品活动
                    if (promotionCommonModel.isPromotionAvailable(singlePromotion.getPromotionType(), singlePromotion.getPromotionId().toString())) {
                        //活动进行中，置为失效
                        this.invalidCart(cartDb.getCartId());
                        continue;
                    }
                }
            }
            if (cartDb.getBuyNum().compareTo(product.getProductStock()) > 0) {
                //2.sku库存不足时，取消选中状态
                if (!cartDb.getProductState().equals(CartConst.STATTE_INVALID)) {
                    Cart update = new Cart();
                    update.setCartId(cartDb.getCartId());
                    update.setProductState(CartConst.STATTE_LACK);
                    update.setUpdateTime(new Date());
                    update.setIsChecked(CartConst.IS_CHECKED_NO);
                    cartWriteMapper.updateByPrimaryKeySelective(update);
                    continue;
                }
            }
            if (!cartDb.getProductState().equals(CartConst.STATTE_NORMAL)) {
                //修改为正常状态
                Cart update = new Cart();
                update.setCartId(cartDb.getCartId());
                update.setProductState(CartConst.STATTE_NORMAL);
                update.setUpdateTime(new Date());
                update.setIsChecked(CartConst.IS_CHECKED_NO);
                cartWriteMapper.updateByPrimaryKeySelective(update);
                continue;
            }

            if (cartDb.getIsChecked() == CartConst.IS_CHECKED_YES) {
                //3.更新购物车货品其他信息（货品单价、满减等活动信息）
                boolean changed = false;//购物车信息是否发生改变
                if (cartDb.getProductPrice().compareTo(product.getProductPrice()) != 0) {
                    //货品单价发生改变
                    cartDb.setProductPrice(product.getProductPrice());
                    changed = true;
                }
                if (!StringUtil.isNullOrZero(cartDb.getPromotionType())
                        && !promotionCommonModel.isPromotionAvailable(cartDb.getPromotionType(), cartDb.getPromotionId().toString())) {
                    //选中的购物车参与了活动并且活动失效,重新选择活动
                    this.getBestPromotion(product, cartDb);
                    changed = true;
                }
                if (changed) {
                    this.updateCart(cartDb);
                }
            }

        }
    }

    /**
     * 将购物车置为失效
     *
     * @param cartId 购物车id
     */
    private void invalidCart(Integer cartId) {
        Cart update = new Cart();
        update.setCartId(cartId);
        update.setProductState(CartConst.STATTE_INVALID);
        update.setUpdateTime(new Date());
        update.setIsChecked(CartConst.IS_CHECKED_NO);
        cartWriteMapper.updateByPrimaryKeySelective(update);
    }

    /**
     * 订单确认、订单提交前预检测商品状态
     *
     * @param dto 前端参数
     * @return 订单提交OrderSubmitCheckVO
     */
    public OrderSubmitCheckVO orderPreCheck(OrderSubmitParamDTO dto, Integer memberId) {
        OrderSubmitCheckVO vo = new OrderSubmitCheckVO();
        if (!StringUtil.isEmpty(dto.getOrderSn())) {
            //如果订单号不为空，说明是付尾款，不检测直接返回
            return vo;
        }

        //key-商品ID, value-商品信息，减少查库次数
        Map<Long, Goods> goodsMap = new HashMap<>();
        //key-货品ID, value-货品信息，减少查库次数
        Map<Long, Product> productMap = new HashMap<>();

        //购物车列表
        List<Cart> cartList = this.getCartList(dto, memberId, goodsMap, productMap);

        //检测下架
        vo = this.checkOffShelf(cartList, goodsMap, productMap);
        if (!CollectionUtils.isEmpty(vo.getProductList())) {
            //检测出有下架货品
            if (vo.getProductList().size() == cartList.size()) {
                //全部下架
                vo.setState(OrderSubmitCheckVO.STATE_1);
            } else {
                //部分下架
                vo.setState(OrderSubmitCheckVO.STATE_2);
            }
            return vo;
        }

        //检测库存
        vo = this.checkStock(cartList, goodsMap, productMap);
        if (!CollectionUtils.isEmpty(vo.getProductList())) {
            //检测出有库存不足货品
            if (vo.getProductList().size() == cartList.size()) {
                //全部无货
                vo.setState(OrderSubmitCheckVO.STATE_3);
            } else {
                //部分无货
                vo.setState(OrderSubmitCheckVO.STATE_4);
            }
            return vo;
        }

        //检测活动
        vo = this.checkActivity(cartList);
        if (!CollectionUtils.isEmpty(vo.getProductList())) {
            //检测出有活动失效货品
            vo.setState(OrderSubmitCheckVO.STATE_5);
            return vo;
        }

        //检测限购
        vo = this.checkLimitPurchase(cartList);
        if (!CollectionUtils.isEmpty(vo.getProductList())) {
            //检测出有限购的货品
            vo.setState(OrderSubmitCheckVO.STATE_6);
            return vo;
        }

        //检测价格
        vo = this.checkPrice(cartList, productMap, dto.getIsAloneBuy(), dto.getSpellTeamId());
        if (!CollectionUtils.isEmpty(vo.getProductList())) {
            //检测出有限购的货品
            vo.setState(OrderSubmitCheckVO.STATE_7);
            return vo;
        }
        return vo;
    }

    /**
     * 获取购物车列表
     *
     * @param dto        前端参数
     * @param memberId   会员id
     * @param goodsMap   商品集合
     * @param productMap 货品集合
     * @return
     */
    public List<Cart> getCartList(OrderSubmitParamDTO dto, Integer memberId, Map<Long, Goods> goodsMap, Map<Long, Product> productMap) {
        List<Cart> cartList;
        if (dto.getIsCart()) {
            //检测购物车商品状态
            CartExample cartExample = new CartExample();
            cartExample.setMemberId(memberId);
            cartExample.setIsChecked(CartConst.IS_CHECKED_YES);
            cartList = cartReadMapper.listByExample(cartExample);
            AssertUtil.notEmpty(cartList, "请选择要购买的商品！");
        } else {
            //检测非购物车下单商品状态(立即购买或活动下单)
            AssertUtil.isTrue(StringUtil.isNullOrZero(dto.getProductId()), "请选择要购买的商品");
            AssertUtil.isTrue(StringUtil.isNullOrZero(dto.getNumber()), "请选择要购买的数量");
            AssertUtil.isTrue(StringUtil.isNullOrZero(dto.getProductPrice()), "商品价格不能为空");

            Product product = this.getProductByProductId(productMap, dto.getProductId());
            Goods goods = this.getGoodsByGoodsId(goodsMap, product.getGoodsId());

            Cart cart = new Cart();
            cart.setMemberId(memberId);
            cart.setStoreId(product.getStoreId());
            cart.setStoreName(product.getStoreName());
            cart.setGoodsId(product.getGoodsId());
            cart.setGoodsName(product.getGoodsName());
            cart.setIsVirtualGoods(goods.getIsVirtualGoods());
            cart.setProductImage(product.getMainImage());
            cart.setSpecValueIds(product.getSpecValueIds());
            cart.setSpecValues(product.getSpecValues());
            cart.setIsChecked(CartConst.IS_CHECKED_YES);
            cart.setBuyNum(dto.getNumber());
            cart.setProductId(dto.getProductId());
            cart.setProductPrice(dto.getProductPrice());
            cart.setPromotionId(dto.getPromotionId());
            cart.setPromotionType(dto.getPromotionType());
            cart.setOrderSn(dto.getOrderSn());
            cartList = Collections.singletonList(cart);
        }
        return cartList;
    }

    /**
     * 检测下架
     *
     * @param cartList   购物车列表
     * @param goodsMap   商品集合
     * @param productMap 货品集合
     * @return OrderSubmitCheckVO
     */
    public OrderSubmitCheckVO checkOffShelf(List<Cart> cartList, Map<Long, Goods> goodsMap, Map<Long, Product> productMap) {
        OrderSubmitCheckVO vo = new OrderSubmitCheckVO();
        cartList.forEach(cart -> {
            Goods goods = this.getGoodsByGoodsId(goodsMap, cart.getGoodsId());
            if (!goods.getState().equals(GoodsConst.GOODS_STATE_UPPER)) {
                //商品已下架
                vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
            } else {
                //商品未下架，查看货品状态
                Product product = this.getProductByProductId(productMap, cart.getProductId());
                if (product.getState().equals(GoodsConst.PRODUCT_STATE_0) || product.getState().equals(GoodsConst.PRODUCT_STATE_2)) {
                    //删除或禁用
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                } else if (product.getState().equals(GoodsConst.PRODUCT_STATE_3)) {
                    //锁定状态
                    GoodsPromotion singlePromotion = this.getSinglePromotion(product.getProductId());
                    if (singlePromotion != null && cart.getCartId() != null) {
                        //购物车下单，如果活动正在进行则置为下架
                        if (singlePromotion.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_104)) {
                            //秒杀
                            if (promotionCommonModel.isPromotionAvailable(singlePromotion.getPromotionType(), product.getProductId().toString())) {
                                //秒杀活动进行中，置为失效
                                vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                            }
                        } else if (promotionCommonModel.isPromotionAvailable(singlePromotion.getPromotionType(), singlePromotion.getPromotionId().toString())) {
                            //其他单品活动
                            //活动进行中，置为失效
                            vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                        }
                    }
                }
            }
        });
        return vo;
    }

    /**
     * 检测库存
     *
     * @param cartList   购物车列表
     * @param goodsMap   商品集合
     * @param productMap 货品集合
     * @return OrderSubmitCheckVO
     */
    public OrderSubmitCheckVO checkStock(List<Cart> cartList, Map<Long, Goods> goodsMap, Map<Long, Product> productMap) {
        OrderSubmitCheckVO vo = new OrderSubmitCheckVO();
        cartList.forEach(cart -> {
            if (cart.getPromotionType() != null && cart.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_104)) {
                //有正在进行的秒杀，检测秒杀库存
                if (!this.checkSecKillStock(cart.getProductId(), cart.getBuyNum())) {
                    //库存不足
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            } else if (cart.getPromotionType() != null && cart.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_103)) {
                //有正在进行的预售，检测预售库存
                if (!this.checkPreSellStock(cart.getPromotionId(), cart.getProductId(), cart.getBuyNum())) {
                    //库存不足
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            } else if (cart.getPromotionType() != null && cart.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_102)) {
                //有正在进行的拼团，检测拼团库存
                if (!this.checkSpellStock(cart.getPromotionId(), cart.getProductId(), cart.getBuyNum())) {
                    //库存不足
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            } else {
                Product product = this.getProductByProductId(productMap, cart.getProductId());
                Integer totalStock = product.getProductStock();

                //查询是否有未开始的秒杀
                String stockStr = stringRedisTemplate.opsForValue().get(RedisConst.REDIS_SECKILL_PRODUCT_STOCK_PREFIX + cart.getProductId());
                if (stockStr != null) {
                    totalStock = totalStock - Integer.parseInt(stockStr);
                }

                if (totalStock.compareTo(cart.getBuyNum()) < 0) {
                    //库存不足
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            }
        });
        return vo;
    }

    /**
     * 检测活动
     *
     * @param cartList 购物车列表
     * @return OrderSubmitCheckVO
     */
    public OrderSubmitCheckVO checkActivity(List<Cart> cartList) {
        OrderSubmitCheckVO vo = new OrderSubmitCheckVO();
        cartList.forEach(cart -> {
            if (!StringUtil.isNullOrZero(cart.getPromotionType())) {
                String promotionId = "";
                if (cart.getPromotionType() == PromotionConst.PROMOTION_TYPE_104) {
                    //秒杀活动传货品id
                    promotionId = cart.getProductId().toString();
                } else {
                    promotionId = cart.getPromotionId().toString();
                }
                if (!promotionCommonModel.isPromotionAvailable(cart.getPromotionType(), promotionId)) {
                    //参与了活动并且活动失效
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            }
        });
        return vo;
    }

    /**
     * 检测限购
     *
     * @param cartList 购物车列表
     * @return OrderSubmitCheckVO
     */
    public OrderSubmitCheckVO checkLimitPurchase(List<Cart> cartList) {
        OrderSubmitCheckVO vo = new OrderSubmitCheckVO();
        cartList.forEach(cart -> {
            if (cart.getPromotionType() != null && cart.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_102)) {
                //有正在进行的拼团，检测拼团限购
                if (!this.checkSpellLimit(cart.getPromotionId(), cart.getGoodsId(), cart.getMemberId(), cart.getBuyNum())) {
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            }
            if (cart.getPromotionType() != null && cart.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_103)) {
                //有正在进行的预售，检测预售限购
                if (!this.checkPreSellLimit(cart.getPromotionId(), cart.getGoodsId(), cart.getMemberId(), cart.getBuyNum())) {
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            }
            if (cart.getPromotionType() != null && cart.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_104)) {
                //有正在进行的秒杀，检测秒杀限购
                if (!this.checkSecKillLimit(cart.getProductId(), cart.getMemberId(), cart.getBuyNum())) {
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            }
            if (cart.getPromotionType() != null && cart.getPromotionType().equals(PromotionConst.PROMOTION_TYPE_105)) {
                //有正在进行的阶梯团，检测阶梯团限购
                if (!this.checkLadderGroupLimit(cart.getPromotionId(), cart.getGoodsId(), cart.getMemberId(), cart.getBuyNum())) {
                    vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
                }
            }
        });
        return vo;
    }

    /**
     * 检测价格
     *
     * @param cartList    购物车列表
     * @param productMap  货品集合
     * @param isAloneBuy  是否单独购买
     * @param spellTeamId 拼团团队id（参团使用）
     * @return OrderSubmitCheckVO
     */
    public OrderSubmitCheckVO checkPrice(List<Cart> cartList, Map<Long, Product> productMap, Boolean isAloneBuy, Integer spellTeamId) {
        OrderSubmitCheckVO vo = new OrderSubmitCheckVO();
        cartList.forEach(cart -> {
            BigDecimal productPrice = getPromotionPrice(cart.getGoodsId(), cart.getProductId(), productMap, isAloneBuy, spellTeamId);
            if (cart.getProductPrice().compareTo(productPrice) != 0) {
                //货品单价发生改变
                cart.setProductPrice(productPrice);
                vo.getProductList().add(new OrderSubmitPageVO.StoreGroupVO.ProductVO(cart));
            }
        });
        return vo;
    }

    /**
     * 获取价格
     *
     * @param goodsId     商品信息
     * @param productId   商品信息
     * @param productMap  货品集合
     * @param isAloneBuy  是否单独购买
     * @param spellTeamId 拼团团队id（参团使用）
     * @return 价格
     */
    public BigDecimal getPromotionPrice(Long goodsId, Long productId, Map<Long, Product> productMap, Boolean isAloneBuy, Integer spellTeamId) {
        Product product = this.getProductByProductId(productMap, productId);
        if (isAloneBuy) {
            //拼团单独买直接返回原价
            return product.getProductPrice();
        }
        //商品参与的活动
        GoodsPromotionExample example = new GoodsPromotionExample();
        example.setGoodsId(goodsId);
        example.setProductId(productId);
        example.setIsEffective(PromotionConst.IS_EFFECTIVE_YES);
        example.setBindType(PromotionConst.BIND_TYPE_1);
        example.setStartTimeBefore(new Date());
        example.setEndTimeAfter(new Date());
        List<GoodsPromotion> list = goodsPromotionReadMapper.listByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            return product.getProductPrice();
        }
        GoodsPromotion goodsPromotion = list.get(0);
        BigDecimal promotionPrice = this.promotionPrice(goodsPromotion.getPromotionType(), goodsPromotion.getPromotionId(),
                goodsPromotion.getProductId(), spellTeamId);
        if (promotionPrice.compareTo(BigDecimal.ZERO) > 0) {
            return promotionPrice;
        } else {
            return product.getProductPrice();
        }
    }

    /**
     * 活动价格
     *
     * @param promotionType 活动类型
     * @param promotionId   活动id
     * @param productId     货品id
     * @param spellTeamId   拼团团队id（参团使用）
     * @return 活动价格
     */
    public BigDecimal promotionPrice(Integer promotionType, Integer promotionId, Long productId, Integer spellTeamId) {
        if (promotionType == PromotionConst.PROMOTION_TYPE_102) {
            //查询拼团活动类型
            SpellGoodsExample example = new SpellGoodsExample();
            example.setSpellId(promotionId);
            example.setProductId(productId);
            List<SpellGoods> list = spellGoodsReadMapper.listByExample(example);
            if (!CollectionUtils.isEmpty(list)) {
                SpellGoods spellGoods = list.get(0);
                if (StringUtil.isNullOrZero(spellTeamId) && !StringUtil.isNullOrZero(spellGoods.getLeaderPrice())) {
                    //拼团团队id为空并且团长优惠价不为空时取团长优惠价
                    return spellGoods.getLeaderPrice();
                } else {
                    return spellGoods.getSpellPrice();
                }
            }
        } else if (promotionType == PromotionConst.PROMOTION_TYPE_103) {
            //查询预售活动类型
            Presell presell = presellReadMapper.getByPrimaryKey(promotionId);
            AssertUtil.notNull(presell, "预售活动不存在");
            PresellGoodsExample example = new PresellGoodsExample();
            example.setPresellId(promotionId);
            example.setProductId(productId);
            List<PresellGoods> list = presellGoodsReadMapper.listByExample(example);
            if (!CollectionUtils.isEmpty(list)) {
                PresellGoods presellGoods = list.get(0);
                if (presell.getType() == PreSellConst.PRE_SELL_TYPE_1) {
                    //定金预售
                    return presellGoods.getFirstMoney();
                } else {
                    //全款预售
                    return presellGoods.getPresellPrice();
                }
            }
        } else if (promotionType == PromotionConst.PROMOTION_TYPE_104) {
            //查询秒杀活动类型
            SeckillStageProductExample example = new SeckillStageProductExample();
            example.setSeckillId(promotionId);
            example.setProductId(productId);
            List<SeckillStageProduct> list = seckillStageProductReadMapper.listByExample(example);
            if (!CollectionUtils.isEmpty(list)) {
                return list.get(0).getSeckillPrice();
            }
        } else if (promotionType == PromotionConst.PROMOTION_TYPE_105) {
            //查询阶梯团活动类型
            LadderGroupGoodsExample example = new LadderGroupGoodsExample();
            example.setGroupId(promotionId);
            example.setProductId(productId);
            List<LadderGroupGoods> list = ladderGroupGoodsReadMapper.listByExample(example);
            if (!CollectionUtils.isEmpty(list)) {
                return list.get(0).getAdvanceDeposit();
            }
        }
        return BigDecimal.ZERO;
    }

    /**
     * 拼团活动检测商品库存
     *
     * @param promotionId 活动id
     * @param productId   货品id
     * @param buyNum      此次购买数量
     * @return true==可以购买
     */
    private Boolean checkSpellStock(Integer promotionId, Long productId, Integer buyNum) {
        //剩余库存
        SpellGoodsExample example = new SpellGoodsExample();
        example.setSpellId(promotionId);
        example.setProductId(productId);
        List<SpellGoods> goodsList = spellGoodsReadMapper.listByExample(example);
        //没有说明是脏数据，不处理
        if (CollectionUtils.isEmpty(goodsList)) {
            return true;
        }
        Integer spellStock = goodsList.get(0).getSpellStock();
        //购买数量大于库存
        return spellStock != null && buyNum.compareTo(spellStock) <= 0;
    }

    /**
     * 预售活动检测商品库存
     *
     * @param promotionId 活动id
     * @param productId   货品id
     * @param buyNum      此次购买数量
     * @return true==可以购买
     */
    private Boolean checkPreSellStock(Integer promotionId, Long productId, Integer buyNum) {
        //剩余库存
        PresellGoodsExample example = new PresellGoodsExample();
        example.setPresellId(promotionId);
        example.setProductId(productId);
        List<PresellGoods> goodsList = presellGoodsReadMapper.listByExample(example);
        //没有说明是脏数据，不处理
        if (CollectionUtils.isEmpty(goodsList)) {
            return true;
        }
        Integer preSellStock = goodsList.get(0).getPresellStock();
        //购买数量大于库存
        return preSellStock != null && buyNum.compareTo(preSellStock) <= 0;
    }

    /**
     * 秒杀活动，从redis中检测商品库存
     *
     * @param productId 货品id
     * @param buyNum    此次购买数量
     * @return true==可以购买
     */
    private Boolean checkSecKillStock(Long productId, Integer buyNum) {
        //剩余库存
        String stockStr = stringRedisTemplate.opsForValue().get(RedisConst.REDIS_SECKILL_PRODUCT_STOCK_PREFIX + productId);
        //购买数量大于库存
        return stockStr != null && buyNum.compareTo(Integer.parseInt(stockStr)) <= 0;
    }

    /**
     * 校验拼团活动限购
     *
     * @param promotionId 促销id
     * @param goodsId     商品id
     * @param memberId    会员id
     * @param buyNum      购买数量
     * @return 是否满足限购
     */
    private Boolean checkSpellLimit(Integer promotionId, Long goodsId, Integer memberId, Integer buyNum) {
        //限购数量
        Spell spell = spellReadMapper.getByPrimaryKey(promotionId);
        AssertUtil.notNull(spell, "获取拼团活动信息为空，请重试！");
        if (spell.getBuyLimit() == 0) {
            //不限购
            return true;
        }
        if (buyNum.compareTo(spell.getBuyLimit()) > 0) {
            //购买数量大于限购数量
            return false;
        }
        //会员已购数量
        String memberAlreadyBuyNumStr = stringRedisTemplate.opsForValue().get(RedisConst.SPELL_PURCHASED_NUM_PREFIX + goodsId + "_" + memberId);
        if (StringUtils.isEmpty(memberAlreadyBuyNumStr)) {
            //会员未购买过
            return true;
        }
        //判断此次购买后是否超过限购数量
        return Integer.parseInt(memberAlreadyBuyNumStr) + buyNum <= spell.getBuyLimit();
    }

    /**
     * 校验预售活动限购
     *
     * @param promotionId 促销id
     * @param goodsId     商品id
     * @param memberId    会员id
     * @param buyNum      购买数量
     * @return 是否满足限购
     */
    private Boolean checkPreSellLimit(Integer promotionId, Long goodsId, Integer memberId, Integer buyNum) {
        //限购数量
        Presell presell = presellReadMapper.getByPrimaryKey(promotionId);
        AssertUtil.notNull(presell, "获取预售活动信息为空，请重试！");
        if (presell.getBuyLimit() == 0) {
            //不限购
            return true;
        }
        if (buyNum.compareTo(presell.getBuyLimit()) > 0) {
            //购买数量大于限购数量
            return false;
        }
        //会员已购数量
        String memberAlreadyBuyNumStr = stringRedisTemplate.opsForValue().get(RedisConst.PRE_SELL_PURCHASED_NUM_PREFIX + goodsId + "_" + memberId);
        if (StringUtils.isEmpty(memberAlreadyBuyNumStr)) {
            //会员未购买过
            return true;
        }
        //判断此次购买后是否超过限购数量
        return Integer.parseInt(memberAlreadyBuyNumStr) + buyNum <= presell.getBuyLimit();
    }

    /**
     * 秒杀活动，从redis中检测商品限购
     *
     * @param productId 货品id
     * @param memberId  会员id
     * @param buyNum    购买数量
     * @return 是否满足秒杀限购
     */
    private Boolean checkSecKillLimit(Long productId, Integer memberId, Integer buyNum) {
        //限购数量
        String buyLimitStr = stringRedisTemplate.opsForValue().get(RedisConst.REDIS_SECKILL_PRODUCT_BUY_LIMIT_PREFIX + productId);
        if (StringUtils.isEmpty(buyLimitStr) || Integer.parseInt(buyLimitStr) == 0) {
            //不限购
            return true;
        }
        if (buyNum.compareTo(Integer.valueOf(buyLimitStr)) > 0) {
            //购买数量大于限购数量
            return false;
        }
        //会员已购数量
        String memberAlreadyBuyNumStr = stringRedisTemplate.opsForValue().get(RedisConst.REDIS_SECKILL_MEMBER_BUY_NUM_PREFIX + productId + "_" + memberId);
        if (StringUtils.isEmpty(memberAlreadyBuyNumStr)) {
            //会员未购买过
            return true;
        }
        //判断此次购买后是否超过限购数量
        return Integer.parseInt(memberAlreadyBuyNumStr) + buyNum <= Integer.parseInt(buyLimitStr);
    }

    /**
     * 校验阶梯团活动限购
     *
     * @param promotionId 促销id
     * @param goodsId     商品id
     * @param memberId    会员id
     * @param buyNum      购买数量
     * @return 是否满足限购
     */
    private Boolean checkLadderGroupLimit(Integer promotionId, Long goodsId, Integer memberId, Integer buyNum) {
        //限购数量
        LadderGroup ladderGroup = ladderGroupReadMapper.getByPrimaryKey(promotionId);
        AssertUtil.notNull(ladderGroup, "获取阶梯团活动信息为空，请重试！");
        if (ladderGroup.getBuyLimitNum() == 0) {
            //不限购
            return true;
        }
        if (buyNum.compareTo(ladderGroup.getBuyLimitNum()) > 0) {
            //购买数量大于限购数量
            return false;
        }
        //会员已购数量
        String memberAlreadyBuyNumStr = stringRedisTemplate.opsForValue().get(RedisConst.LADDER_GROUP_PURCHASED_NUM_PREFIX + goodsId + "_" + memberId);
        if (StringUtils.isEmpty(memberAlreadyBuyNumStr)) {
            //会员未购买过
            return true;
        }
        //判断此次购买后是否超过限购数量
        return Integer.parseInt(memberAlreadyBuyNumStr) + buyNum <= ladderGroup.getBuyLimitNum();
    }

    /**
     * 根据商品id获取商品，从map中取商品或者读取数据库
     *
     * @param goodsMap goodsMap
     * @param goodsId  商品id
     * @return goods
     */
    private Goods getGoodsByGoodsId(Map<Long, Goods> goodsMap, Long goodsId) {
        if (goodsMap.containsKey(goodsId)) {
            return goodsMap.get(goodsId);
        }
        Goods goods = goodsReadMapper.getByPrimaryKey(goodsId);
        goodsMap.put(goodsId, goods);
        return goods;
    }

    /**
     * 根据skuId获取货品，从map中取商品或者读取数据库
     *
     * @param productMap productMap
     * @param productId  货品id
     * @return product
     */
    private Product getProductByProductId(Map<Long, Product> productMap, Long productId) {
        if (productMap.containsKey(productId)) {
            return productMap.get(productId);
        }
        Product product = productReadMapper.getByPrimaryKey(productId);
        productMap.put(productId, product);
        return product;
    }

    /**
     * 新增商城购物车
     *
     * @param cart 购物车
     * @return 返回值
     */
    public Integer saveCart(Cart cart) {
        int count = cartWriteMapper.insert(cart);
        if (count == 0) {
            throw new MallException("添加商城购物车失败，请重试");
        }
        return count;
    }

    /**
     * 根据cartId删除商城购物车
     *
     * @param cartId cartId
     * @return 返回值
     */
    public Integer deleteCart(Integer cartId) {
        if (StringUtils.isEmpty(cartId)) {
            throw new MallException("请选择要删除的数据");
        }
        int count = cartWriteMapper.deleteByPrimaryKey(cartId);
        if (count == 0) {
            log.error("根据cartId：" + cartId + "删除商城购物车失败");
            throw new MallException("删除商城购物车失败,请重试");
        }
        return count;
    }

    /**
     * 根据条件删除商城购物车
     *
     * @param example example
     */
    public void deleteCartByExample(CartExample example) {
        cartWriteMapper.deleteByExample(example);
    }

    /**
     * 根据cartId更新商城购物车
     *
     * @param cart 购物车
     * @return 返回值
     */
    public Integer updateCart(Cart cart) {
        if (StringUtils.isEmpty(cart.getCartId())) {
            throw new MallException("请选择要修改的数据");
        }
        int count = cartWriteMapper.updateByPrimaryKeySelective(cart);
        if (count == 0) {
            log.error("根据cartId：" + cart.getCartId() + "更新商城购物车失败");
            throw new MallException("更新商城购物车失败,请重试");
        }
        return count;
    }

    /**
     * 根据条件更新商城购物车
     *
     * @param cart        购物车
     * @param cartExample 查询条件
     */
    public void updateCartByExample(Cart cart, CartExample cartExample) {
        cartWriteMapper.updateByExampleSelective(cart, cartExample);
    }

    /**
     * 根据cartId获取商城购物车详情
     *
     * @param cartId cartId
     * @return 购物车信息
     */
    public Cart getCartByCartId(Integer cartId) {
        return cartReadMapper.getByPrimaryKey(cartId);
    }

    /**
     * 根据条件获取商城购物车列表
     *
     * @param example 查询条件信息
     * @param pager   分页信息
     * @return 购物车列表
     */
    public List<Cart> getCartList(CartExample example, PagerInfo pager) {
        List<Cart> cartList;
        if (pager != null) {
            pager.setRowsCount(cartReadMapper.countByExample(example));
            cartList = cartReadMapper.listPageByExample(example, pager.getStart(), pager.getPageSize());
        } else {
            cartList = cartReadMapper.listByExample(example);
        }
        return cartList;
    }

    /**
     * 根据条件获取商城购物车列表数量
     *
     * @param example 查询条件信息
     * @return 购物车数量
     */
    public Integer getCartListCount(CartExample example) {
        return cartReadMapper.countByExample(example);
    }

    /**
     * 添加到购物车
     *
     * @param product  货品明细
     * @param number   购买数量
     * @param memberId 会员id
     */
    public void addToCart(Product product, Integer number, Integer memberId) {
        //查询购物车中是否已经有当前货品
        CartExample cartExample = new CartExample();
        cartExample.setProductId(product.getProductId());
        cartExample.setMemberId(memberId);
        List<Cart> cartList = cartReadMapper.listByExample(cartExample);
        if (CollectionUtils.isEmpty(cartList)) {
            //没有当前货品，新增购物车
            this.newCart(product, number, memberId);
        } else {
            //有当前货品的购物车，修改数量
            Cart updateCart = new Cart();
            updateCart.setCartId(cartList.get(0).getCartId());
            //选中
            updateCart.setIsChecked(CartConst.IS_CHECKED_YES);
            updateCart.setUpdateTime(new Date());
            //数量相加
            updateCart.setBuyNum(cartList.get(0).getBuyNum() + number);
            updateCart.setProductState(CartConst.STATTE_NORMAL);
            //更新价格
            updateCart.setProductPrice(product.getProductPrice());
            this.updateCart(updateCart);
        }
    }

    /**
     * 新增购物车
     *
     * @param product  货品明细
     * @param number   购买数量
     * @param memberId 会员id
     */
    private void newCart(Product product, Integer number, Integer memberId) {
        Cart cart = new Cart();
        cart.setMemberId(memberId);
        cart.setStoreId(product.getStoreId());
        cart.setStoreName(product.getStoreName());
        cart.setGoodsId(product.getGoodsId());
        cart.setGoodsName(product.getGoodsName());
        cart.setProductId(product.getProductId());
        cart.setBuyNum(number);
        //优先取活动价
        cart.setProductPrice(product.getProductPrice());
        cart.setProductImage(product.getMainImage());
        cart.setSpecValueIds(product.getSpecValueIds());
        cart.setSpecValues(product.getSpecValues());
        cart.setIsChecked(CartConst.IS_CHECKED_YES);
        cart.setUpdateTime(new Date());
        cart.setProductState(CartConst.STATTE_NORMAL);
        //获取单条购物车可参与的最优惠的活动
        this.getBestPromotion(product, cart);
        this.saveCart(cart);
    }

    /**
     * 获取单条购物车可参与的最优惠的活动
     *
     * @param product product
     * @param cart    cart
     */
    public void getBestPromotion(Product product, Cart cart) {
        //查询当前商品参与的活动
        List<GoodsPromotion> promotionList = this.getPromotionList(product);
        if (!CollectionUtils.isEmpty(promotionList)) {
            BigDecimal maxDiscount = new BigDecimal("-1.00");//最大优惠
            GoodsPromotion bestPromotion = null;
            //查询最优惠的活动
            for (GoodsPromotion goodsPromotion : promotionList) {
                cart.setPromotionId(goodsPromotion.getPromotionId());
                cart.setPromotionType(goodsPromotion.getPromotionType());
                BigDecimal currentDiscount = promotionCommonModel.calculationCartDiscount(cart);
                if (maxDiscount.compareTo(currentDiscount) < 0) {
                    //更优惠的活动
                    maxDiscount = currentDiscount;
                    bestPromotion = goodsPromotion;
                }
            }
            if (bestPromotion == null) {
                bestPromotion = promotionList.get(0);
            }
            log.debug("---------------------------------------------------------------------------");
            log.debug("默认最优活动：type-" + bestPromotion.getPromotionType() + ",id-" + bestPromotion.getPromotionId());
            log.debug("---------------------------------------------------------------------------");
            cart.setPromotionType(bestPromotion.getPromotionType());
            cart.setPromotionId(bestPromotion.getPromotionId());
            cart.setPromotionDescription(bestPromotion.getDescription());
        } else {
            cart.setPromotionType(0);
            cart.setPromotionId(0);
            cart.setPromotionDescription("");
        }
    }

    /**
     * 获取当前货品参与的单品活动
     *
     * @param productId 货品id
     * @return 单品活动信息
     */
    public GoodsPromotion getSinglePromotion(Long productId) {
        //查询商品级别的活动
        GoodsPromotionExample example = new GoodsPromotionExample();
        example.setBindType(PromotionConst.BIND_TYPE_1);
        example.setIsEffective(PromotionConst.IS_EFFECTIVE_YES);
        example.setProductId(productId);
        List<GoodsPromotion> singlePromotionList = goodsPromotionReadMapper.listByExample(example);
        if (!CollectionUtils.isEmpty(singlePromotionList)) {
            GoodsPromotion goodsPromotion = singlePromotionList.get(0);
            String promotionId;
            if (goodsPromotion.getPromotionType() == PromotionConst.PROMOTION_TYPE_104) {
                //秒杀活动传货品id
                promotionId = goodsPromotion.getProductId().toString();
            } else {
                promotionId = goodsPromotion.getPromotionId().toString();
            }
            if (promotionCommonModel.isPromotionAvailable(goodsPromotion.getPromotionType(), promotionId)) {
                //活动可用
                return goodsPromotion;
            }
        }
        //无可用的单品活动
        return null;
    }

    /**
     * 获取当前货品可用的活动列表（店铺活动、平台活动）
     *
     * @param product product
     * @return 活动列表
     */
    public List<GoodsPromotion> getPromotionList(Product product) {
        List<GoodsPromotion> list = new ArrayList<>();
        //查询店铺活动
        GoodsPromotionExample example = new GoodsPromotionExample();
        example.setBindType(PromotionConst.BIND_TYPE_2);
        example.setIsEffective(PromotionConst.IS_EFFECTIVE_YES);
        example.setStoreId(product.getStoreId());
        List<GoodsPromotion> storeList = goodsPromotionReadMapper.listByExample(example);
        if (!CollectionUtils.isEmpty(storeList)) {
            storeList.forEach(goodsPromotion -> {
                if (promotionCommonModel.isPromotionAvailable(goodsPromotion.getPromotionType(), goodsPromotion.getPromotionId().toString())) {
                    //活动可用
                    list.add(goodsPromotion);
                }
            });
        }

        //查询平台活动
        example.setStoreId(null);
        example.setBindType(PromotionConst.BIND_TYPE_3);
        example.setGoodsCategoryId3(product.getCategoryId3());
        List<GoodsPromotion> platformList = goodsPromotionReadMapper.listByExample(example);
        if (!CollectionUtils.isEmpty(platformList)) {
            platformList.forEach(goodsPromotion -> {
                if (promotionCommonModel.isPromotionAvailable(goodsPromotion.getPromotionType(), goodsPromotion.getPromotionId().toString())) {
                    //活动可用
                    list.add(goodsPromotion);
                }
            });
        }
        return list;
    }

    /**
     * 登录时添加离线购物车信息
     *
     * @param cartList 购物车列表
     * @param memberId 会员id
     */
    public void addCartByMemberId(List<Cart> cartList, Integer memberId) {
        if (!CollectionUtils.isEmpty(cartList)) {
            for (Cart cart : cartList) {
                Product product = productReadMapper.getByPrimaryKey(cart.getProductId());
                AssertUtil.notNull(product, "获取商品sku信息为空");
                this.addToCart(product, cart.getBuyNum(), memberId);
            }
        }
    }
}