package cn.freemud.service.impl;

import cn.freemud.adapter.ActivityAdapter;
import cn.freemud.adapter.CouponAdapter;
import cn.freemud.adapter.ShoppingCartConvertAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.entities.dto.*;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.calculate.ActivityCalculationDiscountRequestDto;
import cn.freemud.entities.dto.calculate.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.pay.SVCCardAmountRequest;
import cn.freemud.entities.dto.pay.SVCCardAmountResponse;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.ActivityChannelEnum;
import cn.freemud.enums.CouponTypeEnum;
import cn.freemud.enums.ResponseResult;
import cn.freemud.factory.AbstractShoppingCartImpl;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.*;
import cn.freemud.service.thirdparty.ActivityClient;
import cn.freemud.service.thirdparty.SvcAppClient;
import cn.freemud.service.thirdparty.SvcComPayClient;
import cn.freemud.utils.PropertyConvertUtil;
import cn.freemud.utils.RedisLock;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.base.SDKCommonBaseContextWare;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CollageMemberState;
import com.freemud.sdk.api.assortment.shoppingcart.domain.CollageOrderDto;
import com.freemud.sdk.api.assortment.shoppingcart.enums.BusinessTypeEnum;
import com.freemud.sdk.api.assortment.shoppingcart.request.CheckCartRequest;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.CollageCartBaseServiceImpl;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.CollageOrderBaseServiceImpl;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import com.freemud.sdk.api.assortment.shoppingcart.util.ShoppingSdkLogUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

//import com.freemud.card.sdk.log.ErrorLog;

/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @version V1.0assortmentSdkService
 * @Title: null.java
 * @Package
 * @Description: (用一句话描述该文件做什么)
 * @author: pegnfei.liu
 * @date: 2020-9-24
 * @Copyright: 2020 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目的
 */

@Service
public class ShoppingCartCollageServiceImpl extends AbstractShoppingCartImpl implements ShoppingCartNewService, ShoppingCartCollageService {

    @Autowired
    private AssortmentSdkService assortmentSdkService;

    @Autowired
    private CollageCartBaseServiceImpl collageCartBaseService;

    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;

    @Autowired
    private ActivityAdapter activityAdapter;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private CouponService couponService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private ActivityClient activityClient;

    @Autowired
    private CouponAdapter couponAdapter;

    @Autowired
    private ProductService productService;

    @Autowired
    private CollageOrderBaseServiceImpl collageOrderBaseService;

    @Autowired
    private SvcAppClient svcAppClient;

    @Autowired
    private SvcComPayClient svcComPayClient;


    @Override
    public BaseResponse addGoodsByCard(AddGoodsByWeixinCardRequestVo request) {
        return null;
    }

    @Override
    public BaseResponse addGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo) {

        ShoppingCartConvertAdapter.convent2SkuId(addShoppingCartGoodsRequestVo);
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();

        // 获取当前登陆用户信息
        CustomerInfoVo currentUserInfoVo = getCustomerInfoVo(addShoppingCartGoodsRequestVo.getSessionId());
        // 当前用户必须登陆
        if (null == currentUserInfoVo || StringUtils.isEmpty(currentUserInfoVo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
//            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(currentUserInfoVo);

        String currentUserId = currentUserInfoVo.getMemberId();
        String partnerId = addShoppingCartGoodsRequestVo.getPartnerId();
        String storeId = addShoppingCartGoodsRequestVo.getShopId();
        String appId = addShoppingCartGoodsRequestVo.getAppId();
        String spuId = addShoppingCartGoodsRequestVo.getSpuId();
        String skuId = addShoppingCartGoodsRequestVo.getSkuId();
        String goodsId = StringUtils.isEmpty(skuId) ? spuId : skuId;
        String menuType = addShoppingCartGoodsRequestVo.getMenuType();
        Integer orderType = addShoppingCartGoodsRequestVo.getOrderType();
        String receiveId = addShoppingCartGoodsRequestVo.getReceiveId();
        // 获取拼单发起人id
        String crateUserId = addShoppingCartGoodsRequestVo.getCreateCollageUserId();

        // 拼单相关条件校验
        check(partnerId, storeId, crateUserId,spuId,currentUserId);

        CartGoods cartGoods = ShoppingCartConvertAdapter.convent2CartGoods(addShoppingCartGoodsRequestVo);
        cartGoods.setUserId(currentUserId);
        cartGoods.setOpenId(currentUserInfoVo.getOpenId());
        cartGoods.setUserName(currentUserInfoVo.getNickName());
        cartGoods.setPhotoUrl(currentUserInfoVo.getPhotoUrl());
        cartGoods.setAddCartTime(System.currentTimeMillis());

        List<Long> productIds = new ArrayList<>();
        productIds.add(Long.parseLong(goodsId));

        // 获取商品详细信息
        List<ProductBeanDTO> productBeanListSpuClass = assortmentSdkService.getProductsInfoSdk(partnerId, storeId, Collections.singletonList(spuId),addShoppingCartGoodsRequestVo.getMenuType(), this.shoppingCartBaseService);

        List<CartGoods> allCartGoodsList = null;
        String productName = null;

        try {
            //缓存中获取购物车商品信息
            allCartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, crateUserId, currentUserId, null, collageCartBaseService,null);
            if (CollectionUtils.isEmpty(allCartGoodsList)) {
                allCartGoodsList = new ArrayList<>();
            }

            Integer sumSkuQty = this.sumSkuQty(allCartGoodsList, cartGoods);
            //查询多个商品库存信息
            this.queryManyGoodsStocks(addShoppingCartGoodsRequestVo, productIds, productBeanListSpuClass, skuId, sumSkuQty);
            productName = null;

            //添加非商品券商品
            List<CartGoods> cartGoodsRedisList= addNotProductCouponGoods(addShoppingCartGoodsRequestVo, cartGoods, goodsId, crateUserId, shoppingCartGoodsResponseVo, allCartGoodsList);

            // 当商品数量被设为0时
            if (Objects.equals(cartGoods.getQty(), 0)) {
                cartGoodsRedisList = assortmentSdkService.updateGoodsQtyBySdk(partnerId, currentUserId, storeId, cartGoods.getCartGoodsUid(), 0, "", collageCartBaseService,null);
            }

            // 更新拼单购物车人员缓存中的的购物车行id集合
            List<String> cartGoodsUids = new ArrayList<>();
            if(null != cartGoodsRedisList){
                cartGoodsUids = cartGoodsRedisList.stream().filter(cartGoods1 -> currentUserId.equals(cartGoods1.getUserId())).map(CartGoods::getCartGoodsUid).collect(Collectors.toList());
            }
            collageCartBaseService.updateCollageCartGoodsUids(cartGoodsUids,partnerId, storeId, crateUserId,currentUserId);

        } catch (Exception e) {
            ShoppingSdkLogUtil.errorConvertJson(SDKCommonBaseContextWare.getAppName(), LogThreadLocal.getTrackingNo(), getClass(), "updateGoodsQty:" + e.getMessage(), e);
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_VERSION_ERROR, "购物车商品有变动，请手动刷新再修改");
        }

        // 配送费
        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo);

        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
                =getCalculationDiscountResult(menuType,partnerId,storeId,currentUserId,appId,userLoginInfoDto.getWxAppid(),orderType,currentUserInfoVo.isMemberPaid(), allCartGoodsList,new ArrayList(),new ArrayList<>(),null,deliveryAmount);

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, currentUserId, appId, addShoppingCartGoodsRequestVo.getOrderType());

        // 促销活动的优惠金额计算
        updateShoppingCartGoodsDiscount(null, activityQueryDto, calculationDiscountResult, allCartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto, addShoppingCartGoodsRequestVo.getMenuType(), deliveryAmount);
        clearMsg(shoppingCartGoodsResponseVo, cartGoods.getCartGoodsUid());
        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, allCartGoodsList, null, partnerId, storeId, currentUserId, ShoppingCartConstant.ADD_AND_UPDATE, null);
        // 设置购物车版本号
        shoppingCartGoodsResponseVo.setCarVer(collageCartBaseService.incrementCartVersion(partnerId, storeId, crateUserId));
        //埋点添加购物车行为
        this.buriedPointShoppingCart(addShoppingCartGoodsRequestVo, spuId, productName);

        // 根据人员分类购物车
        ShoppingCartCollageResponseVo shoppingCartCollageResponseVo = splitByUser(shoppingCartGoodsResponseVo,crateUserId,partnerId,storeId,currentUserId);

        return ResponseUtil.success(shoppingCartCollageResponseVo);
    }

    /**
     * 根据人员分类购物车，方便前端展示
     * @param shoppingCartGoodsResponseVo
     * @return
     */
    public ShoppingCartCollageResponseVo splitByUser(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,String createUserId,String partnerId,String storeId,String currentUserId){

        ShoppingCartCollageResponseVo shoppingCartCollageResponseVo = new ShoppingCartCollageResponseVo();

        BeanUtils.copyProperties(shoppingCartGoodsResponseVo,shoppingCartCollageResponseVo);

        List<CartGoods> cartGoods = shoppingCartGoodsResponseVo.getProducts();

        // 获取参单人员信息
        CollageOrderDto collageOrderDto = CollageOrderDto.builder()
                                            .createCollageUserId(createUserId)
                                            .partnerId(partnerId)
                                            .storeId(storeId)
                                            .build();
        List<CollageMemberState> collageMemberState = collageOrderBaseService.getCollageMemberState(collageOrderDto).getResult();
        if(collageMemberState == null || collageMemberState.isEmpty()){
            ShoppingSdkLogUtil.printLog("splitByUser 参单人员为空，createUserId:{}，currentUserId：{}",createUserId,currentUserId);
            return null;
        }

        if(StringUtils.isNotEmpty(currentUserId)){
            collageMemberState = collageMemberState.stream().filter(cms -> cms.getUserId().equals(currentUserId)).collect(Collectors.toList());
        }

        Map<String,List<CartGoods>> userGoods = new HashMap<>();
        if(cartGoods != null && !cartGoods.isEmpty()){
            // 若拼单发起人未购买商品，则将赠品按购物车行分给加购人，若未找到加购行id，默认给创建人
            cartGoods.stream().filter(good -> null == good.getUserId()).collect(Collectors.toList()).forEach(cartGoodsNullUser -> {
                CartGoods parentGood = cartGoods.stream().filter(good -> (StringUtils.isBlank(good.getOriginalGoodsUid()) && good.getCartGoodsUid().equals(cartGoodsNullUser.getOriginalGoodsUid()))).findFirst().orElse(null);
                cartGoodsNullUser.setUserId(parentGood == null ? createUserId : parentGood.getUserId());
                cartGoodsNullUser.setOpenId(parentGood == null ? null : parentGood.getOpenId());
                cartGoodsNullUser.setUserName(parentGood == null ? null : parentGood.getUserName());
                cartGoodsNullUser.setPhotoUrl(parentGood == null ? null : parentGood.getPhotoUrl());
            });

            userGoods = cartGoods.stream().filter(good -> null != good.getUserId()).collect(Collectors.groupingBy(CartGoods::getUserId));
        }

        List<ShoppingCartCollageGoodsResponseVo> userProducts = new ArrayList<>();
        for(CollageMemberState cmbs:collageMemberState){
            ShoppingCartCollageGoodsResponseVo shoppingCartCollageGoodsResponseVo = new ShoppingCartCollageGoodsResponseVo();
            shoppingCartCollageGoodsResponseVo.setUserName(cmbs.getNickName());
            shoppingCartCollageGoodsResponseVo.setPhotoUrl(cmbs.getPhotoUrl());
            shoppingCartCollageGoodsResponseVo.setUid(cmbs.getUserId());
            shoppingCartCollageGoodsResponseVo.setOpenId(cmbs.getOpenId());
            // 包装费
            Long packPrice = 0L;
            // 商品数量
            Integer productsCount = 0;
            // 商品原价总价
            Long originalAmount = 0L;
            Long totalAmount = 0L;
            List<CartGoods> products = userGoods.get(cmbs.getUserId());
            if(products != null && !products.isEmpty()){
                for(CartGoods cg :products){
                    packPrice = packPrice + (cg.getPackPrice() == null ? 0 : cg.getPackPrice());
                    productsCount = productsCount + (cg.getQty() == null ? 0 : cg.getQty());
                    originalAmount = originalAmount + (cg.getOriginalAmount() == null ? 0 : cg.getOriginalAmount());
                    totalAmount = totalAmount + (cg.getAmount() == null ? 0 : cg.getAmount());
                }
            }
            // 只有总的包装费不为0、null时才计算个人包装费
            if(shoppingCartGoodsResponseVo.getNewPackAmount() != null && shoppingCartGoodsResponseVo.getNewPackAmount().longValue() != 0){
                shoppingCartCollageGoodsResponseVo.setPackPrice(packPrice);
            }
            shoppingCartCollageGoodsResponseVo.setProductsCount(productsCount);
            shoppingCartCollageGoodsResponseVo.setTotalAmount(totalAmount);
            shoppingCartCollageGoodsResponseVo.setOriginalTotalAmount(originalAmount);
            shoppingCartCollageGoodsResponseVo.setProducts(products);
            shoppingCartCollageGoodsResponseVo.setStates(cmbs.getState());
            userProducts.add(shoppingCartCollageGoodsResponseVo);
        }

        shoppingCartCollageResponseVo.setUserProducts(userProducts);

        // 个人购物车将个人数据覆盖整单数据
        if (!StringUtils.isEmpty(currentUserId) && userProducts.size() > 0) {
            // 个人购物车隐藏满减提示
            shoppingCartCollageResponseVo.setActivityTip(new ActivityTip());
            // 个人购物车不展示
            shoppingCartCollageResponseVo.setTotalAmount(userProducts.get(0).getTotalAmount());
            shoppingCartCollageResponseVo.setOriginalTotalAmount(userProducts.get(0).getOriginalTotalAmount());
            shoppingCartCollageResponseVo.setTotalDiscountAmount(0L);
            shoppingCartCollageResponseVo.setNewPackAmount(userProducts.get(0).getPackPrice());
            shoppingCartCollageResponseVo.setProductsCount(userProducts.get(0).getProductsCount());
            shoppingCartCollageResponseVo.setFullDiscount(0L);
            shoppingCartCollageResponseVo.setCouponDiscount(0L);
        }

        return shoppingCartCollageResponseVo;
    }

    @Override
    public BaseResponse updateGoodsQty(UpdateShoppingCartGoodsQtyRequestVo updateShoppingCartGoodsQtyRequestVo) {

        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        CustomerInfoVo currentUserInfoVo = getCustomerInfoVo(updateShoppingCartGoodsQtyRequestVo.getSessionId());
        // 当前用户必须登陆
        if (null == currentUserInfoVo || StringUtils.isEmpty(currentUserInfoVo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
//            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(currentUserInfoVo);
        String currentUserId = userLoginInfoDto.getMemberId();
        String partnerId = updateShoppingCartGoodsQtyRequestVo.getPartnerId();
        String storeId = updateShoppingCartGoodsQtyRequestVo.getShopId();
        String appId = updateShoppingCartGoodsQtyRequestVo.getAppId();
        String cartGoodsUid = updateShoppingCartGoodsQtyRequestVo.getCartGoodsUid();
        Integer qty = updateShoppingCartGoodsQtyRequestVo.getQty();
        String menuType = updateShoppingCartGoodsQtyRequestVo.getMenuType();
        Integer orderType=updateShoppingCartGoodsQtyRequestVo.getOrderType();
        String receiveId = updateShoppingCartGoodsQtyRequestVo.getReceiveId();

        // 获取拼单发起人id
        String crateUserId = updateShoppingCartGoodsQtyRequestVo.getCreateCollageUserId();

        // 拼单相关条件校验
        check(partnerId, storeId, crateUserId,null,currentUserId);

        // 校验需要修改的商品行和操作人的关系
        List<String> goodsUids = collageCartBaseService.getCollageCartGoodsUids(partnerId,storeId,crateUserId,currentUserId);
        if(null == goodsUids || !goodsUids.contains(updateShoppingCartGoodsQtyRequestVo.getCartGoodsUid())){
            return ResponseUtil.error(ResponseResult.COLLAGE_GOOD_NOT_ONESELF);
//            throw new ServiceException(ResponseResult.COLLAGE_GOOD_NOT_ONESELF);
        }

        List<CartGoods> cartGoodsList = null;

        try {

            // 先验证商品是否存在
            CartGoods cartGoods = assortmentSdkService.getCartGoodsBySdk(partnerId, crateUserId, storeId, cartGoodsUid, "", collageCartBaseService,null);
            if (cartGoods == null) {
                return ResponseUtil.error(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
//                throw new ServiceException(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
            }

            // 检查购物车商品库存数量
            checkUpdateStock(updateShoppingCartGoodsQtyRequestVo, cartGoods);

            // 更新购物车中数量
            cartGoodsList = assortmentSdkService.updateGoodsQtyBySdk(partnerId, crateUserId, storeId, cartGoodsUid, qty<0?0:qty, "", collageCartBaseService,null);

            // check购物车中所有商品
            CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, updateShoppingCartGoodsQtyRequestVo.getOrderType(), "", updateShoppingCartGoodsQtyRequestVo.getMenuType(), shoppingCartBaseService);
            if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
                shoppingCartGoodsResponseVo.setChanged(checkCartRequest.getShoppingCartGoodsResponseVo().getChanged());
                shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
            }
            cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

            // 重新存储最新购物车
            List<CartGoods> cartGoodsRedisList = assortmentSdkService.setShoppingCart(partnerId, storeId, crateUserId, cartGoodsList, currentUserId, "", collageCartBaseService,null);

            // 更新拼单购物车人员缓存中的的购物车行id集合
            List<String> cartGoodsUids = new ArrayList<>();
            if(null != cartGoodsRedisList){
                cartGoodsUids = cartGoodsRedisList.stream().filter(cartGoods1 -> currentUserId.equals(cartGoods1.getUserId())).map(CartGoods::getCartGoodsUid).collect(Collectors.toList());
            }
            collageCartBaseService.updateCollageCartGoodsUids(cartGoodsUids,partnerId, storeId, crateUserId,currentUserId);

        } catch (Exception e) {
            ShoppingSdkLogUtil.errorConvertJson(SDKCommonBaseContextWare.getAppName(), LogThreadLocal.getTrackingNo(), getClass(), "shoppingCartCollageServiceImpl updateGoodsQty:" + e.getMessage(), e);
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_VERSION_ERROR, "购物车商品有变动，请手动刷新再修改");
        }


        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo);
        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
                =getCalculationDiscountResult(menuType,partnerId,storeId,crateUserId,appId,userLoginInfoDto.getWxAppid(),orderType,currentUserInfoVo.isMemberPaid(),cartGoodsList,new ArrayList(),new ArrayList<>(),null,deliveryAmount);
        if (calculationDiscountResult == null) {
            shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        }

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, crateUserId, appId, updateShoppingCartGoodsQtyRequestVo.getOrderType());

        // 促销活动的优惠金额计算
        updateShoppingCartGoodsDiscount(null, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto, updateShoppingCartGoodsQtyRequestVo.getMenuType(), deliveryAmount);

        clearMsg(shoppingCartGoodsResponseVo, cartGoodsUid);
        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, crateUserId, ShoppingCartConstant.ADD_AND_UPDATE, null);
        // 设置购物车版本号
        shoppingCartGoodsResponseVo.setCarVer(collageCartBaseService.incrementCartVersion(partnerId, storeId, crateUserId));

        // 根据人员分类购物车
        ShoppingCartCollageResponseVo shoppingCartCollageResponseVo = splitByUser(shoppingCartGoodsResponseVo,crateUserId,partnerId,storeId,currentUserId);

        return ResponseUtil.success(shoppingCartCollageResponseVo);
    }

    @Override
    public BaseResponse getGoodsList(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {

        if (StringUtils.isEmpty(shoppingCartInfoRequestVo.getShopId())){
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }

        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        CustomerInfoVo currentUserInfoVo = getCustomerInfoVo(shoppingCartInfoRequestVo.getSessionId());
        // 当前用户必须登陆
        if (null == currentUserInfoVo || StringUtils.isEmpty(currentUserInfoVo.getMemberId())) {
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
//            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(currentUserInfoVo);
        String currentUserId = userLoginInfoDto.getMemberId();
        //String currentSessionId = shoppingCartInfoRequestVo.getSessionId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        String appId = shoppingCartInfoRequestVo.getAppId();
        String couponCode = shoppingCartInfoRequestVo.getCouponCode();
        String activityCode = shoppingCartInfoRequestVo.getActivityCode();
        List<ChooseCouponVo> couponCodes = shoppingCartInfoRequestVo.getCouponCodes();
        // 兼容老版本
        if (CollectionUtils.isNotEmpty(couponCodes) && StringUtils.isEmpty(couponCode)) {
            ChooseCouponVo otherCouponCode = couponCodes.stream()
                    .filter(couponCode1 -> couponCode1.getCouponType()!=null && couponCode1.getCouponType().compareTo(CouponTypeEnum.TYPE_5.getCode()) != 0)
                    .findFirst().orElse(null);
            if (otherCouponCode != null) {
                // 由于对下面逻辑 不是很清楚 并且修改了 优惠券传参规则 所以直接设置一遍 防止出错
                shoppingCartInfoRequestVo.setCouponCode(otherCouponCode.getCouponCode());
                shoppingCartInfoRequestVo.setActivityCode(otherCouponCode.getActivityCode());
            }
        }

        String menuType = shoppingCartInfoRequestVo.getMenuType();
        Integer orderType = shoppingCartInfoRequestVo.getOrderType();
        String receiveId = shoppingCartInfoRequestVo.getReceiveId();

        // 获取拼单发起人id
        String crateUserId = shoppingCartInfoRequestVo.getCreateCollageUserId();

        // 拼单发起人id不能为空
        // 拼单购物相关的redis的key都需要拼单发起人id，所以这个值是不能为空的
        if (StringUtils.isEmpty(crateUserId)){
            return ResponseUtil.error(ResponseResult.COLLAGE_NOT_EXIST);
//            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        // 获取不到拼单的基础信息，抛出异常
        // 拼单的有效时间为1小时，当获取不到拼单的基础信息时，认为这个拼单没有发起、已经失效、已经结束
        Map<String, String> collageBase = collageCartBaseService.getCollageBase(partnerId,storeId,crateUserId);
        if(collageBase == null || collageBase.isEmpty()){
            return ResponseUtil.error(ResponseResult.COLLAGE_NOT_EXIST);
//            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        List<CartGoods> cartGoodsList = null;

        try {
            // 获取购物车商品
            cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, crateUserId, null, "", collageCartBaseService,null);
            // 如果购物车商品不为空， 则check购物车中所有商品
            if (CollectionUtils.isNotEmpty(cartGoodsList)){
                CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getOrderType(), "", shoppingCartInfoRequestVo.getMenuType() ,shoppingCartBaseService);
                if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
                    shoppingCartGoodsResponseVo.setChanged(checkCartRequest.getShoppingCartGoodsResponseVo().getChanged());
                    shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
                }
                cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);
                // 重新存储最新购物车
                List<CartGoods> cartGoodsRedisList = assortmentSdkService.setShoppingCart(partnerId, storeId, crateUserId, cartGoodsList, currentUserInfoVo.getSessionId(), "", this.collageCartBaseService,null);

                // 更新拼单购物车人员缓存中的的购物车行id集合
                List<String> cartGoodsUids = new ArrayList<>();
                if(null != cartGoodsRedisList){
                    cartGoodsUids = cartGoodsRedisList.stream().filter(cartGoods1 -> currentUserId.equals(cartGoods1.getUserId())).map(CartGoods::getCartGoodsUid).collect(Collectors.toList());
                }
                collageCartBaseService.updateCollageCartGoodsUids(cartGoodsUids,partnerId, storeId, crateUserId,currentUserId);
            }
        } catch (Exception e) {
            ShoppingSdkLogUtil.errorConvertJson(SDKCommonBaseContextWare.getAppName(), LogThreadLocal.getTrackingNo(), getClass(), "shoppingCartCollageServiceImpl getGoodsList:" + e.getMessage(), e);
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_VERSION_ERROR, "购物车商品有变动，请手动刷新再修改");
        }

        // 下面代码 由于接口改动 已经不适用 begin
        List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
        // 当couponCode不为空时，需参与价格计算
        if (StringUtils.isNotEmpty(couponCode)) {
            ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
            coupon.setCode(couponCode);
            coupon.setActivityCode(activityCode);
            coupons.add(coupon);
        }
        // 上面代码 由于接口改动 已经不适用 end
        if (!CollectionUtils.isEmpty(couponCodes)) {
            couponCodes.forEach(shoppingCouponCode -> {
                if (!shoppingCouponCode.getCouponCode().equals(couponCode)) {
                    ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                    coupon.setCode(shoppingCouponCode.getCouponCode());
                    coupon.setActivityCode(shoppingCouponCode.getActivityCode());
                    coupon.setCouponType(shoppingCouponCode.getCouponType());
                    coupons.add(coupon);
                }
            });
        }

        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo);

        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType,partnerId,storeId,crateUserId,appId,userLoginInfoDto.getWxAppid(),orderType,currentUserInfoVo.isMemberPaid(),cartGoodsList,coupons,null,shoppingCartInfoRequestVo.getReceiveId(),deliveryAmount);

        if (calculationDiscountResult == null) {
            shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        }

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, crateUserId, appId, shoppingCartInfoRequestVo.getOrderType());

        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);
        // 促销活动的优惠金额计算
        this.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto,shoppingCartInfoRequestVo.getMenuType(),deliveryAmount);
        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, crateUserId, ShoppingCartConstant.QUERY_INFO, shoppingCartInfoRequestVo);
        // 在原价、现价、折扣价上增加第一次使用会员卡的费用
        this.addNeedCardAmount(shoppingCartInfoRequestVo, shoppingCartGoodsResponseVo);
        // 设置购物车版本号
        String collageCartVerKey = collageCartBaseService.genCollageCarVerKey(partnerId, storeId, crateUserId);
        Integer cartVersion = collageCartBaseService.getCartVersion(collageCartVerKey);
        shoppingCartGoodsResponseVo.setCarVer(cartVersion);

        ShoppingCartCollageResponseVo shoppingCartCollageResponseVo;
        if(shoppingCartInfoRequestVo.getType() != null && shoppingCartInfoRequestVo.getType().intValue() == 1){
            // 根据人员分类购物车 全员购物车
            shoppingCartCollageResponseVo = splitByUser(shoppingCartGoodsResponseVo,crateUserId,partnerId,storeId,null);
        }else if(shoppingCartInfoRequestVo.getType() != null && shoppingCartInfoRequestVo.getType().intValue() == 0){
            // 根据人员分类购物车 个人购物车
            shoppingCartCollageResponseVo = splitByUser(shoppingCartGoodsResponseVo,crateUserId,partnerId,storeId,currentUserId);
        }else{
            // 整合购物车
            shoppingCartCollageResponseVo = new ShoppingCartCollageResponseVo();
            BeanUtils.copyProperties(shoppingCartGoodsResponseVo,shoppingCartCollageResponseVo);
            List<CartGoods> cartGoods = shoppingCartGoodsResponseVo.getProducts();
            List<ShoppingCartCollageGoodsResponseVo> userProducts = new ArrayList<>();
            ShoppingCartCollageGoodsResponseVo shoppingCartCollageGoodsResponseVo = new ShoppingCartCollageGoodsResponseVo();
            shoppingCartCollageGoodsResponseVo.setProducts(cartGoods);
            shoppingCartCollageGoodsResponseVo.setUid(currentUserId);
            shoppingCartCollageGoodsResponseVo.setOpenId(currentUserInfoVo.getOpenId());
            shoppingCartCollageGoodsResponseVo.setUserName(currentUserInfoVo.getNickName());
            shoppingCartCollageGoodsResponseVo.setPhotoUrl(currentUserInfoVo.getPhotoUrl());
            shoppingCartCollageGoodsResponseVo.setPackPrice(shoppingCartGoodsResponseVo.getNewPackAmount());
            shoppingCartCollageGoodsResponseVo.setProductsCount(shoppingCartGoodsResponseVo.getProductsCount());
            shoppingCartCollageGoodsResponseVo.setTotalAmount(shoppingCartGoodsResponseVo.getTotalAmount());
            shoppingCartCollageGoodsResponseVo.setOriginalTotalAmount(shoppingCartGoodsResponseVo.getOriginalTotalAmount());
            userProducts.add(shoppingCartCollageGoodsResponseVo);
            shoppingCartCollageResponseVo.setUserProducts(userProducts);
        }

        return ResponseUtil.success(shoppingCartCollageResponseVo);
    }

    @Override
    public BaseResponse getGoodsListCheck(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        if (StringUtils.isBlank(shoppingCartInfoRequestVo.getCardCode())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING);
        }
        //打包带走外卖
        if (StringUtils.isNotBlank(shoppingCartInfoRequestVo.getCardCode()) && shoppingCartInfoRequestVo.getOrderType() == 2
                && StringUtils.isBlank(shoppingCartInfoRequestVo.getReceiveId())) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING);
        }
        BaseResponse<ShoppingCartCollageResponseVo> goodsList = getGoodsList(shoppingCartInfoRequestVo);
        if (goodsList == null || !ResponseResult.SUCCESS.getCode().equals(goodsList.getCode())) {
            return goodsList;
        }
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        ShoppingCartCollageResponseVo shoppingCartCollageResponseVo = goodsList.getResult();
        //ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = goodsList.getResult();
        //SVC卡支付
        SVCCardPay(shoppingCartInfoRequestVo.getCardCode(), shoppingCartInfoRequestVo.getReceiveId(), partnerId, storeId, shoppingCartCollageResponseVo);
        return ResponseUtil.success(shoppingCartCollageResponseVo);
    }

    @Override
    public BaseResponse clear(ShoppingCartClearRequestVo request) {

        // 拼单发起人
        String createCollageUserId = request.getCreateCollageUserId();
        if (StringUtils.isBlank(createCollageUserId)) {
            return ResponseUtil.error(ResponseResult.COLLAGE_NOT_EXIST);
//            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }
        String partnerId = request.getPartnerId();
        String storeId = request.getShopId();
        if(StringUtils.isEmpty(partnerId) || StringUtils.isEmpty(storeId)){
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING);
//            throw new ServiceException(ResponseResult.PARAMETER_MISSING);
        }

        CustomerInfoVo userLoginInfoDto = getCustomerInfoVo(request.getSessionId());
        if(null == userLoginInfoDto || StringUtils.isEmpty(userLoginInfoDto.getMemberId())){
            return ResponseUtil.error(ResponseResult.NOT_LOGIN);
//            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto cartParamDto = new com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto();
        cartParamDto.setPartnerId(partnerId);
        cartParamDto.setStoreId(storeId);
        cartParamDto.setUserId(createCollageUserId);
        collageCartBaseService.clear(cartParamDto, LogThreadLocal.getTrackingNo());

        // 更新拼单购物车人员缓存中的的购物车行id集合
        // 获取点餐位的购物车行
        Set<String> member = collageCartBaseService.getCollageMember(partnerId,storeId,createCollageUserId);
        for(String mem : member){
            collageCartBaseService.updateCollageCartGoodsUids(new ArrayList<>(),partnerId, storeId, createCollageUserId,mem);
        }
        return ResponseUtil.success();
    }

    @Override
    public BaseResponse<ShoppingCartGoodsDto> getShoppingCartGoods(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity) {

        ShoppingCartGoodsDto shoppingCartGoodsDto = new ShoppingCartGoodsDto();
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息，只有创单发起人才会进行创单，所以当前登陆的用户为拼单的发起人
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(shoppingCartInfoRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        String appId = StringUtils.isEmpty(shoppingCartInfoRequestVo.getAppId())?userLoginInfoDto.getWxAppid():shoppingCartInfoRequestVo.getAppId();
        String couponCode = shoppingCartInfoRequestVo.getCouponCode();
        String activityCode = shoppingCartInfoRequestVo.getActivityCode();
        // 兼容老购物车
        List<ChooseCouponVo> couponCodes = shoppingCartInfoRequestVo.getCouponCodes();
        if (Objects.isNull(couponCode) && CollectionUtils.isNotEmpty(couponCodes)) {
            ChooseCouponVo otherCouponCode = couponCodes.stream()
                    .filter(couponCode1 -> couponCode1.getCouponType()!=null && couponCode1.getCouponType().compareTo(CouponTypeEnum.TYPE_5.getCode())!=0)
                    .findFirst().orElse(null);
            if (otherCouponCode !=null) {
                // 由于对下面逻辑 不是很清楚 并且修改了 优惠券传参规则 所以直接设置一遍 防止出错
                shoppingCartInfoRequestVo.setCouponCode(otherCouponCode.getCouponCode());
                shoppingCartInfoRequestVo.setActivityCode(otherCouponCode.getActivityCode());
            }
        }
        String tableNumber = assortmentCustomerInfoVo.getTableNumber();
        String menuType = shoppingCartInfoRequestVo.getMenuType();
        Integer orderType = shoppingCartInfoRequestVo.getOrderType();
        String receiveId = shoppingCartInfoRequestVo.getReceiveId();

        // 加价购商品
        List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList = shoppingCartInfoRequestVo.getSendGoods();

        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, tableNumber, collageCartBaseService,null);
        if (cartGoodsList == null) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        /**
         *  校验该门店是否有必选商品
         *  1. 调用商品服务拿到该门店是否有必选商品
         *  2. 如果有，则和购物车的商品对比
         */
        if (productService.hasRequiredProducts(partnerId, storeId, cartGoodsList, BusinessTypeEnum.getByType(shoppingCartInfoRequestVo.getMenuType()).getCode())) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_REQUIRED_PRODUCT_NOT_EXIST);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_REQUIRED_PRODUCT_NOT_EXIST);
        }

        // check购物车中所有商品(商品是否存在，价格变动，券是否支持当前点餐方式)
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo,
                shoppingCartInfoRequestVo.getOrderType(), tableNumber, shoppingCartInfoRequestVo.getMenuType() ,shoppingCartBaseService);

        com.freemud.sdk.api.assortment.shoppingcart.domain.ShoppingCartGoodsResponseVo cartGoodsResponseVo = checkCartRequest.getShoppingCartGoodsResponseVo();
        //商品不再售卖状态或价格变动，直接返回报错
        if (cartGoodsResponseVo != null) {
            if (cartGoodsResponseVo.getCartGoodsStates() != null && cartGoodsResponseVo.getCartGoodsStates().isHasInvalidGoods()) {
                return ResponseUtil.error(ResponseResult.STORE_ITEM_CHECK_INVAILD);
            }
            if (cartGoodsResponseVo.getCartGoodsStates() != null && cartGoodsResponseVo.getCartGoodsStates().isPriceChanged()) {
                return ResponseUtil.error(ResponseResult.SHOPPING_CART_ACTIVITY_CHANGE);
            }
            shoppingCartGoodsResponseVo.setToastMsg(cartGoodsResponseVo.getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), tableNumber, this.shoppingCartBaseService,null);

        List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
        // 当couponCode不为空时，需参与价格计算
        if (StringUtils.isNotEmpty(couponCode)) {
            ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
            coupon.setCode(couponCode);
            coupon.setActivityCode(activityCode);
            coupons.add(coupon);
        }
        // 配送券也加入
        if (!CollectionUtils.isEmpty(couponCodes)) {
            // 包含 couponCode 就重新设置
            couponCodes.forEach(shoppingCouponCode -> {
                if (!shoppingCouponCode.getCouponCode().equals(couponCode)) {
                    ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                    coupon.setCode(shoppingCouponCode.getCouponCode());
                    coupon.setActivityCode(shoppingCouponCode.getActivityCode());
                    coupon.setCouponType(shoppingCouponCode.getCouponType());
                    coupons.add(coupon);
                }
            });
        }

        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            processSendGoods(sendGoodsList, partnerId, storeId , shoppingCartInfoRequestVo.getMenuType() , shoppingCartBaseService);
        } else {
            //组装加价购商品
            if (null != premiumExchangeActivity && CollectionUtils.isNotEmpty(premiumExchangeActivity.getProducts())) {
                List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = premiumExchangeActivity.getProducts().stream().map(product -> {
                    ShoppingCartInfoRequestVo.SendGoods sendGood = new ShoppingCartInfoRequestVo.SendGoods();
                    sendGood.setGoodsId(product.getSkuId());
                    sendGood.setQty(product.getQty());
                    return sendGood;
                }).collect(toList());
                shoppingCartInfoRequestVo.setSendGoods(sendGoods);
            }
        }

        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo);
        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType,partnerId,storeId,userId,appId,userLoginInfoDto.getWxAppid(),orderType,assortmentCustomerInfoVo.isMemberPaid(),cartGoodsList,coupons,sendGoodsList,shoppingCartInfoRequestVo.getReceiveId(),deliveryAmount);

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartInfoRequestVo.getOrderType());

        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);
        // 临时方案
        packgeAdditional(shoppingCartInfoRequestVo, premiumExchangeActivity);
        // 促销活动的优惠金额计算
        updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo, userLoginInfoDto,shoppingCartInfoRequestVo.getMenuType(),deliveryAmount);

        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, userId, ShoppingCartConstant.QUERY_INFO, shoppingCartInfoRequestVo);
        //设置均摊信息
        updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);
        // 计算第一次使用会员卡需多支付的金额  单位:分
        getNeedCardAmount(shoppingCartInfoRequestVo, shoppingCartGoodsDto);

        shoppingCartGoodsDto.setDeliveryAmount(shoppingCartGoodsResponseVo.getDeliveryAmount());
        shoppingCartGoodsDto.setDiscountDeliveryAmount(shoppingCartGoodsResponseVo.getDiscountDeliveryAmount());
        shoppingCartGoodsDto.setThresholdAmount(shoppingCartGoodsResponseVo.getThresholdAmount());
        shoppingCartGoodsDto.setIsDiscountDelivery(shoppingCartGoodsResponseVo.getIsDiscountDelivery());
        shoppingCartGoodsDto.setDiscountDeliveryActivityCode(shoppingCartGoodsResponseVo.getDiscountDeliveryActivityCode());
        if (calculationDiscountResult != null){
            shoppingCartGoodsDto.setSendPoint(calculationDiscountResult.getSendPointVo());
        }

        // 购物车购买人包装费计算
        updatePackPrice(shoppingCartGoodsResponseVo, shoppingCartGoodsDto);

        return ResponseUtil.success(shoppingCartGoodsDto);
    }

    /**
     * 拼单订单商品绑定包装费透传
     * @param shoppingCartGoodsResponseVo
     * @param shoppingCartGoodsDto
     */
    private void updatePackPrice(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ShoppingCartGoodsDto shoppingCartGoodsDto) {
        if (shoppingCartGoodsResponseVo != null && shoppingCartGoodsResponseVo.getProducts() != null && shoppingCartGoodsDto != null && shoppingCartGoodsDto.getProducts() != null) {
            if (shoppingCartGoodsResponseVo.getNewPackAmount() == null || shoppingCartGoodsResponseVo.getNewPackAmount() == 0) {
                // 当整单包装费为0时，不计算购物车行包装费
                return;
            }
            shoppingCartGoodsResponseVo.getProducts().stream().forEach(product -> {
                shoppingCartGoodsDto.getProducts().stream().forEach(goods -> {
                    if (goods.getCartGoodsUid().equals(product.getCartGoodsUid())) {
                        goods.setPackPrice(product.getPackPrice());
                    }
                });
            });
        }
    }

    @Override
    public ActivityCalculationDiscountResponseDto.CalculationDiscountResult getActivityCalculationDiscountResponse(String partnerId, String storeId, String userId, String appId, Integer orderType, boolean isMember, List<CartGoods> cartGoodsList, List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons, List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList, String menuType, Long distributionFee,Integer bizType, Integer accoutFlag) {
        ActivityCalculationDiscountRequestDto activityCalculationDiscountRequestDto = getActivityCalculationDiscountRequestDto(partnerId, storeId, userId, appId, orderType);
        List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList = new ArrayList<>();
        // 校验后有效的商品券map
        Map<String, CheckSpqInfoResponseDto> validCouponMap = new HashMap<>(16);
        for (int i = cartGoodsList.size() - 1; i >= 0; i--) {
            CartGoods cartGoods = cartGoodsList.get(i);
            String cartGoodsUid = cartGoods.getCartGoodsUid();
            // 商品不是商品券
            if (!cartGoodsUid.startsWith(CommonsConstant.COUPON_PREFIX)) {
                //this.addCalculationDiscountGoods(calculationDiscountGoodsList, cartGoods.getGoodsId(), cartGoods.getQty(), cartGoods.getFinalPrice(), cartGoods.getMemberDiscount(), cartGoodsUid);
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, cartGoods);
            }
            // 商品是商品券
            else {
                // 商品券ID换取商品
                String spqId = cartGoods.getCartGoodsUid().substring(CommonsConstant.COUPON_PREFIX.length());
                CheckSpqInfoRequestDto checkSpqInfoRequestDto = new CheckSpqInfoRequestDto(partnerId, storeId, spqId,menuType);
                CheckSpqInfoResponseDto checkSpqInfoResponseDto = couponService.checkSpqInfo(checkSpqInfoRequestDto);
                // 商品券不存在时，将商品券从购物车移除
                if (checkSpqInfoResponseDto == null) {
                    cartGoodsList.remove(i);
                    assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, null, null, this.shoppingCartBaseService,null);
                    throw new ServiceException(ResponseResult.SHOPPING_CART_COUPON_NOT_EXIST);
                }
                validCouponMap.put(spqId, checkSpqInfoResponseDto);
                cartGoods.setName(checkSpqInfoResponseDto.getCouponName());
                cartGoods.setSpuName(checkSpqInfoResponseDto.getCouponName());
                // 添加请求的优惠券信息
                ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(checkSpqInfoResponseDto.getCouponCode());
                coupon.setActivityCode(checkSpqInfoResponseDto.getActiveCode());
                coupons.add(coupon);
                // 添加商品券代表的商品
                String goodsId = StringUtils.isEmpty(checkSpqInfoResponseDto.getSkuId()) ? checkSpqInfoResponseDto.getSpuId() : checkSpqInfoResponseDto.getSkuId();
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, goodsId, 1, checkSpqInfoResponseDto.getPrice(), 100, cartGoodsUid);
            }
        }
        // 当加价购商品不为空时
        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, sendGoods.getGoodsId(), sendGoods.getQty(), sendGoods.getOriginalPrice(), 100, "");
            }
        }
        calculationDiscountGoodsList.removeIf(calculationDiscountGoods -> (calculationDiscountGoods.getGoodsQuantity().equals(0)));
        if (CollectionUtils.isEmpty(calculationDiscountGoodsList)) {
            return null;
        }
        // 调用促销前先对购物车行id进行排序
        calculationDiscountGoodsList.sort((o1, o2) -> {
            if (o1.getAddCartTime() == null || o2.getAddCartTime() == null) {
                return 0;
            } else {
                return (int) (o1.getAddCartTime() - o2.getAddCartTime());
            }
        });
        List<String> cartGoodsUidList = calculationDiscountGoodsList.stream().map(ActivityCalculationDiscountRequestDto.CalculationDiscountGoods::getCartGoodsUid).collect(toList());
        activityCalculationDiscountRequestDto.setGoods(calculationDiscountGoodsList);
        activityCalculationDiscountRequestDto.setCoupons(coupons);
        activityCalculationDiscountRequestDto.setOrgIds(commonService.getOrgIdsForCoupon(partnerId, storeId));
        activityCalculationDiscountRequestDto.setDistributionFee(distributionFee);
        activityCalculationDiscountRequestDto.setIsMember(isMember);
        ActivityCalculationDiscountResponseDto activityCalculationDiscountResponseDto;
//        try {
            // 调用老促销接口
            activityCalculationDiscountResponseDto = activityClient.calculationDiscount(activityCalculationDiscountRequestDto);
//        } catch (Exception ex) {
//            ShoppingSdkLogUtil.errorConvertJson(SDKCommonBaseContextWare.getAppName(), LogThreadLocal.getTrackingNo(), getClass(), "shoppingCartCollageServiceImpl getActivityCalculationDiscountResponse:" + ex.getMessage(), ex);
//            throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
//        }
        // 返回成功
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), ResponseCodeConstant.RESPONSE_SUCCESS_STR)) {
            ActivityCalculationDiscountResponseDto.CalculationDiscountResult result = activityCalculationDiscountResponseDto.getResult();
            result.setValidCouponMap(validCouponMap);
            result.setDeliveryAmount(distributionFee);
            result.setDistributionFee(result.getDistributionFee());

            // 返回之前根据购物车行进行排序
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.ApportionGoods> apportionGoodsList = new ArrayList<>();
            List<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Goods> goodList = new ArrayList<>();
            cartGoodsUidList.stream().forEach(cartGoodsUid -> {
                apportionGoodsList.add(result.getApportionGoods().stream().filter(apportionGoods -> cartGoodsUid.equals(apportionGoods.getCartGoodsUid())).findFirst().get());
                goodList.add(result.getGoods().stream().filter(goods -> cartGoodsUid.equals(goods.getCartGoodsUid())).findFirst().get());
            });
            result.setApportionGoods(apportionGoodsList);
            result.setGoods(goodList);

            return result;
        }
        // 支付宝华莱士紧急修改代码，当促销返回103错误码时，需要报券不适用于该门店，且清空购物车
        ShoppingCartClearRequestVo shoppingCartClearRequestVo = new ShoppingCartClearRequestVo();
        shoppingCartClearRequestVo.setAppId(appId);
        shoppingCartClearRequestVo.setPartnerId(partnerId);
        shoppingCartClearRequestVo.setUserId(userId);
        shoppingCartClearRequestVo.setShopId(storeId);
        shoppingCartClearRequestVo.setOperationType(1);
        clear(shoppingCartClearRequestVo);
        if (activityCalculationDiscountResponseDto != null && StringUtils.equals(activityCalculationDiscountResponseDto.getStatusCode(), "103")){
            throw new ServiceException(ResponseResult.SHOPPING_CART_COUPON_CAN_NOT_USE_THIS_SHOP);
        }
        throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
    }

    @Override
    public List<CartGoods> updateCartGoodsLegal(CartGoods cartGoods, String userId, ShoppingCartGoodsBaseResponseVo shoppingCartGoodsResponseVo, AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<CartGoods> oldAllCartGoodsList) {
        //存储新添加的购物车信息
        List<CartGoods> nowCartGoodsList = new ArrayList<>();
        oldAllCartGoodsList.add(cartGoods);

        //当商品全部添加完毕,校验购物车商品(是否合法,上下架,点餐方式,是否在当前菜单中...),并移除非法商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(oldAllCartGoodsList, addShoppingCartGoodsRequestVo.getPartnerId(),
                addShoppingCartGoodsRequestVo.getShopId(), shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo.getOrderType(),
                "", addShoppingCartGoodsRequestVo.getMenuType(),shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
            shoppingCartGoodsResponseVo.setChanged(checkCartRequest.getShoppingCartGoodsResponseVo().getChanged());
        }
        List<CartGoods> allCartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

        //判断当前商品在购物车是否已存在,存在则数量＋1,不存在商品行 + 1
        allCartGoodsList.forEach(oldCartGoods -> {
            int index;
            if ((index = nowCartGoodsList.indexOf(oldCartGoods)) >= 0) {
                nowCartGoodsList.get(index).setQty(nowCartGoodsList.get(index).getQty() + cartGoods.getQty());
            } else {
                nowCartGoodsList.add(oldCartGoods);
            }
        });
        // 重新set购物车信息到缓存中
        assortmentSdkService.setShoppingCart(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(),
                userId, nowCartGoodsList, addShoppingCartGoodsRequestVo.getSessionId(), addShoppingCartGoodsRequestVo.getTableNumber(), this.collageCartBaseService,null);
        oldAllCartGoodsList.clear();
        oldAllCartGoodsList.addAll(nowCartGoodsList);
        return nowCartGoodsList;
    }

    public List<CartGoods> getShoppingCart(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo) {
        return null;
    }


    /**
     * 添加非商品券商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @param cartGoods
     * @param goodsId
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param allCartGoodsList
     */
    public List<CartGoods> addNotProductCouponGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, CartGoods cartGoods
            , String goodsId, String userId, ShoppingCartGoodsBaseResponseVo shoppingCartGoodsResponseVo, List<CartGoods> allCartGoodsList) {

        // 校验合法性,更新缓存中购物车信息
        List<CartGoods> cartGoodsList = updateCartGoodsLegal(cartGoods, userId, shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo, allCartGoodsList);

        // 如果购物车中有商品券，则当前添加的商品是特价商品时，需要提示“已选商品券，与其他优惠商品不同享，商品将恢复原价”
        // 拼单没有商品券、换购券
        return cartGoodsList;
    }

    /**
     * 拼单相关校验<br/>
     * 1、店铺id不能为空<br/>
     * 2、拼单不支持用商品券、换购券<br/>
     * 3、拼单发起人id不能为空<br/>
     * 4、拼单的基础信息不能为空<br/>
     * 5、判断拼单的锁定状态<br/>
     * 6、判单拼单的点餐位是否存在<br/>
     * 7、校验用户选好了状态
     * @param partnerId
     * @param storeId
     * @param crateUserId
     * @param spuId
     * @param currentUserId
     */
    public void check(String partnerId,String storeId,String crateUserId,String spuId,String currentUserId){

        //店铺id不能为空
        if (StringUtils.isEmpty(storeId)){
            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }

        //拼单不支持用商品券、换购券
        if (null != spuId && spuId.startsWith(CommonsConstant.COUPON_PREFIX)){
            throw new ServiceException(ResponseResult.COUPON_SHOP_NOTSUPPORT);
        }
        // 拼单发起人id不能为空
        // 拼单购物相关的redis的key都需要拼单发起人id，所以这个值是不能为空的
        if (StringUtils.isEmpty(crateUserId)){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        // 获取不到拼单的基础信息，抛出异常
        // 拼单的有效时间为1小时，当获取不到拼单的基础信息时，认为这个拼单没有发起、已经失效、已经结束
        Map<String, String> collageBase = collageCartBaseService.getCollageBase(partnerId,storeId,crateUserId);
        if(collageBase == null || collageBase.isEmpty()){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        // 获取拼单的锁定状态，锁定，抛出异常
        // 发起人支付的时候需要对拼单进行锁定，当已锁定的时候，不能操作购物车
        Boolean collageLock = collageCartBaseService.getCollageLock(partnerId,storeId,crateUserId);
        if(collageLock != null && collageLock){
            throw new ServiceException(ResponseResult.COLLAGE_LOCK);
        }

        // 判单拼单的点餐位是否存在
        // 发起拼单、加入拼单，都会给用户创建点餐位，用来存储用户的购物车行id
        // 并设置其相应的购物车行id为空集合，没有点餐位，则认为该用户是没有加入拼单
        List<String> cartGoodsUids = collageCartBaseService.getCollageMemberHashKey(partnerId, storeId,crateUserId ,currentUserId);
        if(cartGoodsUids == null){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_ADD);
        }

        // 校验用户选好了状态
        // 只有用户不是选好了状态的时候才能更改购物车
        CollageOrderDto collageOrderDto = CollageOrderDto.builder()
                    .sessionId("")
                    .createCollageUserId(crateUserId)
                    .currentUserId(currentUserId)
                    .partnerId(partnerId)
                    .storeId(storeId)
                    .build();

        BaseResponse<CollageMemberState> response = collageOrderBaseService.getOneCollageMemberState(collageOrderDto);
        if(response == null || response.getResult() == null){
            throw new ServiceException(ResponseResult.COLLAGE_STATES_CHOOSE);
        }

        CollageMemberState collageMemberState = collageOrderBaseService.getOneCollageMemberState(collageOrderDto).getResult();
        if(collageMemberState.getState()){
            throw new ServiceException(ResponseResult.COLLAGE_ALREADY_CHOOSE);
        }

    }

    /**
     * 购物车版本锁检查和加锁
     * @param partnerId
     * @param storeId
     * @param crateUserId
     * @param carVer
     * @param flag
     */
    private void dolock(String partnerId,String storeId,String crateUserId,Integer carVer,Boolean flag) {
        if(flag){
            // 设置版本锁控制购物车只能一个人进行操作
            if (carVer == null || carVer < 1) {
                throw new ServiceException(ResponseResult.SHOPPING_CART_VERSION_ERROR);
            }
            // 构建拼单购物车版本号缓存key
            String collageCartVerKey = collageCartBaseService.genCollageCarVerKey(partnerId, storeId, crateUserId);
            Integer cartVersion = collageCartBaseService.getCartVersion(collageCartVerKey);
            if (!carVer.equals(cartVersion)) {
                throw new ServiceException(ResponseResult.SHOPPING_CART_VERSION_ERROR);
            }
        }

        boolean lock = RedisLock.getInstance(redisCache.getRedisTemplate()).lock(collageCartBaseService.genCollageCarLockKey(partnerId, storeId, crateUserId));
        if (!lock) {
            //加锁失败
            throw new ServiceException(ResponseResult.SHOPPING_CART_VERSION_ERROR);
        }
    }

    /**
     * 购物车版本解锁
     * @param partnerId
     * @param storeId
     * @param crateUserId
     */
    private void doUnlock(String partnerId,String storeId,String crateUserId) {
        try {
            String collageCartLockKey = collageCartBaseService.genCollageCarLockKey(partnerId, storeId, crateUserId);
            RedisLock.getInstance(redisCache.getRedisTemplate()).unlock(collageCartLockKey);
        } catch (Exception e) {
            ShoppingSdkLogUtil.errorConvertJson(SDKCommonBaseContextWare.getAppName(), LogThreadLocal.getTrackingNo(), getClass(), "购物车版本解锁解锁失败" , e);
        }
    }


    /**
     * 构建 ActivityCalculationDiscountRequestDto
     *
     * @param partnerId
     * @param storeId
     * @param userId
     * @param appId
     * @param orderType
     * @return
     */
    private ActivityCalculationDiscountRequestDto getActivityCalculationDiscountRequestDto(String partnerId, String storeId, String userId, String appId, Integer orderType) {
        ActivityCalculationDiscountRequestDto activityCalculationDiscountRequestDto = new ActivityCalculationDiscountRequestDto();
        activityCalculationDiscountRequestDto.setPartnerCode(partnerId);
        activityCalculationDiscountRequestDto.setStoreId(storeId);
        activityCalculationDiscountRequestDto.setIsShowGoodsActivity(1);
        activityCalculationDiscountRequestDto.setUserId(userId);
        activityCalculationDiscountRequestDto.setVer(1);
        activityCalculationDiscountRequestDto.setAppId(appId);
        ActivityChannelEnum activityChannelEnum = PropertyConvertUtil.orderTypeConvert2ActivityChannel(orderType);
        if (!Objects.isNull(activityChannelEnum)) {
            activityCalculationDiscountRequestDto.setChannel(activityChannelEnum.getCode());
        }
        return activityCalculationDiscountRequestDto;
    }

    /**
     * 促销增加
     *
     * @param calculationDiscountGoodsList
     * @param cartGoods
     */
    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList, CartGoods cartGoods) {
        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods();

        calculationDiscountGoods.setGoodsId(cartGoods.getGoodsId());
        calculationDiscountGoods.setCartGoodsUid(cartGoods.getCartGoodsUid());
        calculationDiscountGoods.setGoodsQuantity(cartGoods.getQty());
        calculationDiscountGoods.setOriginalPrice(cartGoods.getFinalPrice());
        calculationDiscountGoods.setMemberDiscount(cartGoods.getMemberDiscount());
        calculationDiscountGoods.setSpuId(cartGoods.getSpuId());
        calculationDiscountGoods.setAddCartTime(cartGoods.getAddCartTime());

        //加料
        if (CollectionUtils.isNotEmpty(cartGoods.getProductMaterialList())) {
            new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material();
            ArrayList<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material> materials = new ArrayList<>();
            for (CartGoods.MaterialGoods materialGoods : cartGoods.getProductMaterialList()) {
                ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material material = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods.Material();
                material.setType(1);
                material.setGoodsId(materialGoods.getSpuId());
                material.setGoodsQuantity(1);
                material.setOriginalPrice(materialGoods.getFinalPrice());
                materials.add(material);
            }
            calculationDiscountGoods.setSmallMaterial(materials);
        }
        this.addCalculationDiscountGoods(calculationDiscountGoodsList, calculationDiscountGoods);
    }


    /**
     * 将calculationDiscountGoods 封装后加入 calculationDiscountGoodsList
     *
     * @param calculationDiscountGoodsList
     * @param goodsId
     * @param goodsQuantity
     * @param originalPrice
     */
    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList,
                                             String goodsId, Integer goodsQuantity, Long originalPrice, Integer memberDiscount, String cartGoodsUid) {
        ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods = new ActivityCalculationDiscountRequestDto.CalculationDiscountGoods();
        calculationDiscountGoods.setGoodsId(goodsId);
        calculationDiscountGoods.setCartGoodsUid(cartGoodsUid);
        calculationDiscountGoods.setGoodsQuantity(goodsQuantity);
        calculationDiscountGoods.setOriginalPrice(originalPrice);
        calculationDiscountGoods.setMemberDiscount(memberDiscount);
        calculationDiscountGoods.setAddCartTime(System.currentTimeMillis());
        this.addCalculationDiscountGoods(calculationDiscountGoodsList, calculationDiscountGoods);
    }

    /**
     * 累加需加入计算的商品
     *
     * @param calculationDiscountGoodsList
     * @param calculationDiscountGoods
     */
    private void addCalculationDiscountGoods(List<ActivityCalculationDiscountRequestDto.CalculationDiscountGoods> calculationDiscountGoodsList,
                                             ActivityCalculationDiscountRequestDto.CalculationDiscountGoods calculationDiscountGoods) {
        int index;
        // 当商品已存在时,需累加数量
        if ((index = calculationDiscountGoodsList.indexOf(calculationDiscountGoods)) >= 0) {
            ActivityCalculationDiscountRequestDto.CalculationDiscountGoods oldCalculationDiscountGoods = calculationDiscountGoodsList.get(index);
            oldCalculationDiscountGoods.setGoodsQuantity(oldCalculationDiscountGoods.getGoodsQuantity() + calculationDiscountGoods.getGoodsQuantity());
        } else {
            calculationDiscountGoodsList.add(calculationDiscountGoods);
        }
    }

    @Override
    public BaseResponse clearPartCarGoods(ShoppingCartCollageClearRequestVo shoppingCartCollageClearRequestVo) {

        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        CustomerInfoVo currentUserInfoVo = getCustomerInfoVo(shoppingCartCollageClearRequestVo.getSessionId());
        // 当前用户必须登陆
        if (null == currentUserInfoVo || StringUtils.isEmpty(currentUserInfoVo.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(currentUserInfoVo);
        String currentUserId = userLoginInfoDto.getMemberId();
        //String currentSessionId = shoppingCartCollageClearRequestVo.getSessionId();
        String partnerId = shoppingCartCollageClearRequestVo.getPartnerId();
        String storeId = shoppingCartCollageClearRequestVo.getShopId();
        String appId = shoppingCartCollageClearRequestVo.getAppId();
        String menuType = shoppingCartCollageClearRequestVo.getMenuType();
        Integer orderType=shoppingCartCollageClearRequestVo.getOrderType();
        String receiveId = shoppingCartCollageClearRequestVo.getReceiveId();

        // 获取拼单发起人id
        String crateUserId = shoppingCartCollageClearRequestVo.getCreateCollageUserId();
        // 拼单发起人id不能为空
        // 拼单购物相关的redis的key都需要拼单发起人id，所以这个值是不能为空的
        if (StringUtils.isEmpty(crateUserId)){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        // 获取不到拼单的基础信息，抛出异常
        // 拼单的有效时间为1小时，当获取不到拼单的基础信息时，认为这个拼单没有发起、已经失效、已经结束
        Map<String, String> collageBase = collageCartBaseService.getCollageBase(partnerId,storeId,crateUserId);
        if(collageBase == null || collageBase.isEmpty()){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        // 校验用户是否在拼单内
        CollageOrderDto collageOrderDto = CollageOrderDto.builder()
                .sessionId("")
                .createCollageUserId(crateUserId)
                .partnerId(partnerId)
                .storeId(storeId)
                .currentUserId(currentUserId)
                .build();
        Boolean flag = collageOrderBaseService.isInCollagePartnerMemberList(collageOrderDto);
        if(!flag){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_ADD);
        }

        List<CartGoods> cartGoodsList = new ArrayList<>();

        try {

            // 获取用户的购物车行id
            List<String> goodsUids = collageCartBaseService.getCollageCartGoodsUids(partnerId, storeId, crateUserId,currentUserId);
            // 清除购物车中的购物车行信息
            List<com.freemud.sdk.api.assortment.shoppingcart.domain.CartGoods> nowCartGoodsList = collageCartBaseService.removeGoodsUids(partnerId, storeId, crateUserId,goodsUids);

            if(null != nowCartGoodsList && !nowCartGoodsList.isEmpty()){
                cartGoodsList =  JSONArray.parseArray(JSONObject.toJSONString(nowCartGoodsList), CartGoods.class);
            }

            // check购物车中所有商品
            CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, shoppingCartCollageClearRequestVo.getOrderType(), "", shoppingCartCollageClearRequestVo.getMenuType(), shoppingCartBaseService);
            if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
                shoppingCartGoodsResponseVo.setChanged(checkCartRequest.getShoppingCartGoodsResponseVo().getChanged());
                shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
            }
            cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

            // 重新存储最新购物车
            List<CartGoods> cartGoodsRedisList = assortmentSdkService.setShoppingCart(partnerId, storeId, crateUserId, cartGoodsList, shoppingCartCollageClearRequestVo.getSessionId(), "", collageCartBaseService,null);

            // 更新拼单购物车人员缓存中的的购物车行id集合
            List<String> cartGoodsUids = new ArrayList<>();
            if(null != cartGoodsRedisList){
                cartGoodsUids = cartGoodsRedisList.stream().filter(cartGoods1 -> currentUserId.equals(cartGoods1.getUserId())).map(CartGoods::getCartGoodsUid).collect(Collectors.toList());
            }
            collageCartBaseService.updateCollageCartGoodsUids(cartGoodsUids,partnerId, storeId, crateUserId,currentUserId);

        } catch (Exception e) {
            ShoppingSdkLogUtil.errorConvertJson(SDKCommonBaseContextWare.getAppName(), LogThreadLocal.getTrackingNo(), getClass(), "shoppingCartCollageServiceImpl updateGoodsQty:" + e.getMessage(), e);
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_VERSION_ERROR, "购物车商品有变动，请手动刷新再修改");
        }

        Long deliveryAmount = calculateDeliveryAmount(receiveId, partnerId, storeId, userLoginInfoDto.getWxAppid(), shoppingCartGoodsResponseVo);
        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
                =getCalculationDiscountResult(menuType,partnerId,storeId,crateUserId,appId,userLoginInfoDto.getWxAppid(),orderType,currentUserInfoVo.isMemberPaid(),cartGoodsList,new ArrayList(),new ArrayList<>(),null,deliveryAmount);
        if (calculationDiscountResult == null) {
            shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        }

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, crateUserId, appId, shoppingCartCollageClearRequestVo.getOrderType());

        // 促销活动的优惠金额计算
        updateShoppingCartGoodsDiscount(null, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, null, userLoginInfoDto, shoppingCartCollageClearRequestVo.getMenuType(), deliveryAmount);

        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, crateUserId, ShoppingCartConstant.ADD_AND_UPDATE, null);
        // 设置购物车版本号
        shoppingCartGoodsResponseVo.setCarVer(collageCartBaseService.incrementCartVersion(partnerId, storeId, crateUserId));
        // 根据人员分类购物车
        ShoppingCartCollageResponseVo shoppingCartCollageResponseVo = splitByUser(shoppingCartGoodsResponseVo,crateUserId,partnerId,storeId,currentUserId);

        return ResponseUtil.success(shoppingCartCollageResponseVo);
    }

    @Override
    public BaseResponse queryCarVer(CollageShoppingCartVerRequestVo request) {

        if (StringUtils.isEmpty(request.getShopId())){
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_SHOP_ID_NOT_EMPTY);
        }

        // 获取用户信息
        CustomerInfoVo currentUserInfoVo = getCustomerInfoVo(request.getSessionId());
        // 当前用户必须登陆
        if (null == currentUserInfoVo || StringUtils.isEmpty(currentUserInfoVo.getMemberId())) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        String partnerId = request.getPartnerId();
        String storeId = request.getShopId();

        // 获取拼单发起人id
        String crateUserId = request.getCreateCollageUserId();

        // 拼单发起人id不能为空
        // 拼单购物相关的redis的key都需要拼单发起人id，所以这个值是不能为空的
        if (StringUtils.isEmpty(crateUserId)){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        // 获取不到拼单的基础信息，抛出异常
        // 拼单的有效时间为1小时，当获取不到拼单的基础信息时，认为这个拼单没有发起、已经失效、已经结束
        Map<String, String> collageBase = collageCartBaseService.getCollageBase(partnerId,storeId,crateUserId);
        if(collageBase == null || collageBase.isEmpty()){
            throw new ServiceException(ResponseResult.COLLAGE_NOT_EXIST);
        }

        // 构建拼单购物车版本号缓存key
        String collageCartVerKey = collageCartBaseService.genCollageCarVerKey(partnerId, storeId, crateUserId);
        Integer cartVersion = collageCartBaseService.getCartVersion(collageCartVerKey);

        return ResponseUtil.success(cartVersion);
    }

    /**
     * 储值卡支付余额校验
     * 校验订单商品金额与外卖配送费
     */
    private void SVCCardPay(String cardCode, String receiveId, String partnerId, String storeId,
                            ShoppingCartCollageResponseVo shoppingCartGoodsResponseVo) {
        if (StringUtils.isBlank(cardCode)) {
            return;
        }
        Integer orderAmount = shoppingCartGoodsResponseVo.getTotalAmount().intValue();
        String trackingNo = LogThreadLocal.getTrackingNo();
        SVCCardAmountRequest request = new SVCCardAmountRequest();
        request.setPartnerId(partnerId);
        request.setCardCodes(Arrays.asList(cardCode));
        //查询svc卡金额
        BaseResponse<SVCCardAmountResponse> response = svcAppClient.batchQueryCardAmount(request);
        if (response == null) {
            throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR);
        }
        if (response.getResult() == null || CollectionUtils.isEmpty(response.getResult().getCardSimpleInfos())) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        //获取实际配送费
        if (StringUtils.isNotBlank(receiveId) && shoppingCartGoodsResponseVo.getDiscountDeliveryAmount() != null) {
            Integer deliveryAmount = shoppingCartGoodsResponseVo.getDiscountDeliveryAmount().intValue();
            orderAmount += deliveryAmount;
        }
        Integer amount1 = response.getResult().getCardSimpleInfos().get(0).getAmount();
        Integer vamount = response.getResult().getCardSimpleInfos().get(0).getVamount();
        Integer applyType = response.getResult().getCardSimpleInfos().get(0).getApplyType();
        applyType = applyType == null ? 3 : applyType;
        String svcDesc = applyType == 3 ? "储值卡支付￥" : "礼品卡支付￥";
        if (orderAmount > amount1 + vamount) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_AMOUNT_DEFICIENCY);
        }
        BigDecimal bigDecimal = new BigDecimal(orderAmount);
        String amountStr = bigDecimal.divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
        shoppingCartGoodsResponseVo.setTotalAmount(0L);
        shoppingCartGoodsResponseVo.setSvcDiscountDesc(svcDesc + amountStr);
    }

    /**
     * 获取混合支付是否开启
     * @param partnerId
     * @return
     */
    private boolean checkSvcComPay(String partnerId,String storeId) {
        SvcComPayRequestDto requestDto = new SvcComPayRequestDto();
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        SvcComPayResponseDto query = null;
        for (int i=0;i<3;i++) {
            query = svcComPayClient.query(requestDto);
            if (query!=null) break;
        }
        if (query==null || !ResponseResult.SUCCESS.getCode().equals(query.getCode())) {
            return false;
        }
        if (query.getResult()!=null && query.getResult().getValue()) {
            return true;
        }
        else {
            return false;
        }
    }
}
