/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title:
 * @Package cn.freemud.service.impl
 * @Description:
 * @author: ping.wu
 * @date: 2018/5/18 19:46
 * @version V1.0
 * @Copyright: 2018 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */
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.base.util.DateUtil;
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.activity.ActivityQueryResponseDto;
import cn.freemud.entities.dto.activity.ShareDiscountActivityDto;
import cn.freemud.entities.dto.openplatform.WeixinProductRequestDto;
import cn.freemud.entities.dto.openplatform.WeixinProductResponseDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.*;
import cn.freemud.service.thirdparty.*;
import cn.freemud.utils.PromotionFactory;
import cn.freemud.utils.PropertyConvertUtil;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformPartnerStoreDeliveryConfig;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerStoreDeliveryConfigManager;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.membercenter.request.QueryReceiveAddressRequest;
import com.freemud.application.sdk.api.membercenter.response.QueryReceiveAddressResponse;
import com.freemud.application.sdk.api.membercenter.service.MemberCenterService;
import com.freemud.application.sdk.api.paymentcenter.client.request.SVCCardAmountRequest;
import com.freemud.application.sdk.api.paymentcenter.client.response.SVCCardAmountResponse;
import com.freemud.application.sdk.api.paymentcenter.client.service.PaymentNewService;
import com.freemud.application.sdk.api.productcenter.domain.ProductBeanDTO;
import com.freemud.application.sdk.api.storecenter.request.StoreInfoRequest;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.application.sdk.api.storecenter.service.StoreCenterService;
import com.freemud.sdk.api.assortment.shoppingcart.constant.CommonsConstant;
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.ShoppingCartBaseService;
import com.freemud.sdk.api.assortment.shoppingcart.service.impl.ShoppingCartBaseServiceImpl;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.awt.geom.Point2D;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.freemud.constant.ApplicationConstant.DELIVERY_DISCOUNT_DESC1;
import static cn.freemud.constant.ApplicationConstant.DELIVERY_DISCOUNT_DESC2;
import static cn.freemud.constant.ApplicationConstant.DELIVERY_DISCOUNT_DESC3;
import static cn.freemud.constant.ShoppingCartConstant.SHOPPING_CART_EMPTY_GOODS_LIST;
import static cn.freemud.constant.ShoppingCartConstant.SHOPPING_CART_INVALIAD_GOODS;
import static java.util.stream.Collectors.toList;

@Slf4j
@Service
public class ShoppingCartNewServiceImpl implements ShoppingCartNewService {

    @Autowired
    private ActivityAdapter activityAdapter;
    @Autowired
    private StoreItemClient storeItemClient;
    @Autowired
    private ActivityClient activityClient;

    @Autowired
    private ItemService itemService;

    @Autowired
    private ShoppingCartNewBaseService shoppingCartNewBaseService;
    @Autowired
    private ShoppingCartBaseServiceImpl shoppingCartBaseService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private ShoppingCartConvertAdapter shoppingCartConvertAdapter;
    @Autowired
    private FullSubtractionActivityServiceImpl fullSubtractionActivityService;
    @Autowired
    private BuriedPointService buriedPointService;
    @Autowired
    private OpenPlatformClient openPlatformClient;
    @Autowired
    private StockClient stockClient;
    @Value("${goods.cache.second}")
    private long goodsCacheSeconds;
    @Autowired
    private AssortmentSdkService assortmentSdkService;
    @Autowired
    private CouponAdapter couponAdapter;
    @Autowired
    private CustomerApplicationClient customerApplicationClient;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    @Autowired
    private PaymentNewService paymentNewService;
    //会员SDK
    @Autowired
    private MemberCenterService memberCenterService;
    @Autowired
    private AssortmentOpenPlatformPartnerStoreDeliveryConfigManager deliveryConfigManager;
    @Autowired
    private StoreServiceImpl storeService;
    @Autowired
    private StoreCenterService storeCenterService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private ProductService productService;
    @Autowired
    private ActivityService activityService;

    /**
     * 从微信卡券向购物车中添加商品
     */
    @Override
    public BaseResponse addGoodsByCard(AddGoodsByWeixinCardRequestVo request) {
        if (CouponTypeEnum.TYPE_0.getCode().equals(request.getCouponType())) {
            // 调用B端接口，获得商品券对应商品skuId并且解码code
            WeixinProductRequestDto requestDto = shoppingCartConvertAdapter.convent2WeixinProductRequestDto(request);
            WeixinProductResponseDto productRequestDto = openPlatformClient.getWeixinProductRequestDto(requestDto);
            if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(productRequestDto.getCode())) {
                return ResponseUtil.error(productRequestDto.getCode(), productRequestDto.getMessage());
            }
            WeixinProductResponseDto.WxProductResponse result = productRequestDto.getResult();
            request.setSkuId(result.getSkuId());
            request.setEncryptCode(CommonsConstant.COUPON_PREFIX + result.getCode());

            // 根据skuId获取详情
            Map<String, GetProductsVo> products = itemService.getProducts(Arrays.asList(request.getSkuId()), request.getPartnerId(), request.getShopId(),BusinessTypeEnum.getByType(request.getMenuType()).getCode());
            if (products == null || products.size() == 0) {
                return ResponseUtil.error(ResponseResult.WEICHAT_PRODUCT_NOEXIST);
            }
            GetProductsVo getProductsVo = products.get(request.getSkuId());

            // 根据spu查询菜单（必须在当前菜单下才可以加入购物车）
            GetMenuCategoryByIdsDto getMenuCategoryByIdsDto = GetMenuCategoryByIdsDto.builder()
                    .businessDate(DateUtil.convert2String(new Date(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS))
                    .channelType(BusinessTypeEnum.getByType(request.getMenuType()).getCode())
                    .partnerId(request.getPartnerId())
                    .shopId(request.getShopId())
                    .productIds(Arrays.asList(getProductsVo.getSpuId())).build();
            GetMenuByIdsResponseDto getMenuByIdsResponseDto = storeItemClient.getMenuCategoryByIds(getMenuCategoryByIdsDto);
            List<GetMenuByIdsResponseDto.DataBean.MenuDetailDto> menuDetailDtos = null;
            if (Objects.equals(getMenuByIdsResponseDto.getErrcode(), Integer.valueOf(ResponseResult.SUCCESS.getCode()))) {
                if (Objects.equals(getMenuByIdsResponseDto.getData(), null)) {
                    return ResponseUtil.error(ResponseResult.WEICHAT_SHOP_NOTSUPPORT.getCode(), "您当前" + result.getTitle() + "商品券在本门店不支持");
                }
                menuDetailDtos = getMenuByIdsResponseDto.getData().getMenuDetailDtos();
            }
            if (CollectionUtils.isEmpty(menuDetailDtos)) {
                return ResponseUtil.error(ResponseResult.WEICHAT_SHOP_NOTSUPPORT.getCode(), "您当前" + result.getTitle() + "商品券在本门店不支持");
            }

            // 判断商品状态是否可以加入购物车
            List<ProductBeanDTO> productInfos = assortmentSdkService.getProductsInfoSdk(request.getPartnerId(), request.getShopId(), Arrays.asList(getProductsVo.getSpuId()),request.getMenuType(),this.shoppingCartBaseService);
            if (CollectionUtils.isNotEmpty(productInfos)) {
                ProductBeanDTO productBean = productInfos.get(0);
                Integer status = productBean.getStatus();
                if (status == 1) {
                    return ResponseUtil.error(ResponseResult.WEICHAT_SHOP_NOTSUPPORT.getCode(), "您当前" + result.getTitle() + "商品券在本门店不支持");
                }
            }

            AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo = shoppingCartConvertAdapter.convent2AddshoppingCartGoods(request, getProductsVo);
            //LogUtil.info("addGoodsByCard shoppingCartAdapter.convent2AddshoppingCartGoods****", JSONObject.toJSONString(addShoppingCartGoodsRequestVo), null);
            BaseResponse baseResponse = addGoods(addShoppingCartGoodsRequestVo);

            return baseResponse;
        } else {
            return ResponseUtil.success(ResponseResult.WEICHAT_NOT_PRODUCTCARD);
        }
    }

    /**
     * 添加商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @return
     */
    @Override
    public BaseResponse addGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo) {
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(addShoppingCartGoodsRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.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();

        CartGoods cartGoods = ShoppingCartConvertAdapter.convent2CartGoods(addShoppingCartGoodsRequestVo);
        List<Long> productIds = new ArrayList<>();
        //商品skuId或者商品券的商品id
        String spuId2 = spuId;
        if (!spuId.startsWith(CommonsConstant.COUPON_PREFIX)) {
            productIds.add(Long.parseLong(goodsId));
        } else {
            //校验券是否有效
            spuId2 = validCoupon(partnerId, storeId, spuId, productIds,BusinessTypeEnum.getByType(addShoppingCartGoodsRequestVo.getMenuType()).getCode());
        }
        // 获取商品详细信息
        List<ProductBeanDTO> productBeanListSpuClass = assortmentSdkService.getProductsInfoSdk(partnerId, storeId
                , Collections.singletonList(spuId2),addShoppingCartGoodsRequestVo.getMenuType(), this.shoppingCartBaseService);

        //缓存中获取购物车商品信息
        // 注意，围餐和点餐redis数据结构不一样
        List<CartGoods> allCartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, addShoppingCartGoodsRequestVo.getSessionId(), null, shoppingCartBaseService);
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            allCartGoodsList = new ArrayList<>();
        }
        Integer checkQty = allCartGoodsList.indexOf(cartGoods) != -1 ?
                allCartGoodsList.get(allCartGoodsList.indexOf(cartGoods)).getQty() + cartGoods.getQty() : cartGoods.getQty();

        //查询多个商品库存信息
        queryManyGoodsStocks(addShoppingCartGoodsRequestVo, productIds, productBeanListSpuClass, skuId, checkQty);

        String productName = null;
        // 当添加的商品不是商品券时
        if (!spuId.startsWith(CommonsConstant.COUPON_PREFIX)) {
            //添加非商品券商品
             addNotProductGoods(addShoppingCartGoodsRequestVo, cartGoods, goodsId, userId, shoppingCartGoodsResponseVo, allCartGoodsList);
        } else {
            // 当商品是商品券，里面会判断如果购物车中已有商品券，会将cartGoods的CartGoodsUid设为null
            this.addProductGoods(addShoppingCartGoodsRequestVo, cartGoods, spuId2, userId, shoppingCartGoodsResponseVo,
                    spuId, allCartGoodsList, productBeanListSpuClass);
        }

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

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


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

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

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

        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, allCartGoodsList, null, partnerId, storeId, userId, ShoppingCartConstant.ADD_AND_UPDATE, null);

        //埋点添加购物车行为
        this.buriedPointShoppingCart(addShoppingCartGoodsRequestVo, spuId, productName);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }


    /**
     * 埋点添加购物车行为
     *
     * @param addShoppingCartGoodsRequestVo
     * @param spuId
     * @param productName
     */
    private void buriedPointShoppingCart(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, String spuId, String productName) {
        if (StringUtils.isEmpty(productName)) {
            return;
        }

        List<ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo> productVos = Lists.newArrayList();
        ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo productVo = new ShoppingCartSkuAddRequestVo.ShoppingCartSkuProductVo();
        productVo.setProductName(productName);
        productVo.setProductId(spuId);
        productVo.setSpuId(spuId);
        productVos.add(productVo);
        BuriedPointShoppingCartRequestDto shoppingCartRequestDto = BuriedPointShoppingCartRequestDto.builder()
                .sessionId(addShoppingCartGoodsRequestVo.getSessionId()).partnerId(addShoppingCartGoodsRequestVo.getPartnerId())
                .storeId(addShoppingCartGoodsRequestVo.getShopId()).build();
        buriedPointService.buriedPointAddShoppingCart(productVos, shoppingCartRequestDto);
    }

    /**
     * 更新商品数量
     *
     * @param updateShoppingCartGoodsQtyRequestVo
     * @return
     */
    @Override
    public BaseResponse updateGoodsQty(UpdateShoppingCartGoodsQtyRequestVo updateShoppingCartGoodsQtyRequestVo) {
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(updateShoppingCartGoodsQtyRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = 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();

        // 先验证商品是否存在
        CartGoods cartGoods = assortmentSdkService.getCartGoodsBySdk(partnerId, userId, storeId, cartGoodsUid, "", shoppingCartBaseService);
        if (cartGoods == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
        }
        // 检查购物车商品库存数量
        checkUpdateStock(updateShoppingCartGoodsQtyRequestVo, cartGoods);

        // 更新购物车中数量
        List<CartGoods> cartGoodsList = assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoodsUid, qty, "", shoppingCartBaseService);

        // 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);
        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, updateShoppingCartGoodsQtyRequestVo.getSessionId(), "", shoppingCartBaseService);


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

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

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

        //设置更新响应信息
        setAddAndUpdateResponse(shoppingCartGoodsResponseVo, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo.getToastMsg(), partnerId, storeId, userId, ShoppingCartConstant.ADD_AND_UPDATE, null);

        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * 检查购物车商品库存数量
     *
     * @param updateShoppingCartGoodsQtyRequestVo
     * @param cartGoods
     */
    private void checkUpdateStock(UpdateShoppingCartGoodsQtyRequestVo updateShoppingCartGoodsQtyRequestVo, CartGoods cartGoods) {
        Integer qty = updateShoppingCartGoodsQtyRequestVo.getQty();
        // 购物车商品数量减少
        if (cartGoods.getQty() > qty) {
            return;
        }
        String partnerId = updateShoppingCartGoodsQtyRequestVo.getPartnerId();
        String storeId = updateShoppingCartGoodsQtyRequestVo.getShopId();
        //查询商品信息
        List<String> pids = new ArrayList<>();
        pids.add(cartGoods.getGoodsId());
        Map<String, GetProductsVo> products = itemService.getProducts(pids, partnerId, storeId,BusinessTypeEnum.getByType(updateShoppingCartGoodsQtyRequestVo.getMenuType()).getCode());

        GetProductsVo getProductsVo = products.get(cartGoods.getGoodsId());
        // 商品没有库存限制
        if ((getProductsVo == null) || (getProductsVo.getStockLimit() != 1)) {
            return;
        }
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(BusinessTypeEnum.getByType(updateShoppingCartGoodsQtyRequestVo.getMenuType()).getCode());
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        requestDto.setProductIds(Collections.singletonList(Long.parseLong(cartGoods.getGoodsId())));
        GetProductStockResponseDto availableStocks = stockClient.getAvailableStocks(requestDto);
        if ((availableStocks != null) && (ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode()))) {
            if ((CollectionUtils.isEmpty(availableStocks.getResult())) || (qty > availableStocks.getResult().get(0).getQty())) {
                throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
            }
        }
    }


    /**
     * 购物车商品详情接口
     *
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @Override
    public BaseResponse getGoodsList(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(shoppingCartInfoRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        String appId = shoppingCartInfoRequestVo.getAppId();
        String couponCode = shoppingCartInfoRequestVo.getCouponCode();
        String activityCode = shoppingCartInfoRequestVo.getActivityCode();
        String menuType = shoppingCartInfoRequestVo.getMenuType();
        Integer orderType = shoppingCartInfoRequestVo.getOrderType();
        String receiveId = shoppingCartInfoRequestVo.getReceiveId();

        // 获取购物车商品
        List<CartGoods> cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, "", shoppingCartBaseService);
        // 如果购物车商品不为空， 则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);
            // 重新存储最新购物车
            assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService);
        }
        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);
        }
        Long deliveryAmount = calculateDeliveryAmount(receiveId,partnerId,storeId,userLoginInfoDto.getWxAppid());

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

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

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, 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, userId, ShoppingCartConstant.QUERY_INFO, shoppingCartInfoRequestVo);
        // 在原价、现价、折扣价上增加第一次使用会员卡的费用
        this.addNeedCardAmount(shoppingCartInfoRequestVo, shoppingCartGoodsResponseVo);

        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * svc 卡支付使用
     *
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @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<ShoppingCartGoodsResponseVo> goodsList = getGoodsList(shoppingCartInfoRequestVo);
        if (goodsList == null || !ResponseResult.SUCCESS.getCode().equals(goodsList.getCode())) {
            return goodsList;
        }
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = goodsList.getResult();
        //SVC卡支付
        SVCCardPay(shoppingCartInfoRequestVo.getCardCode(), shoppingCartInfoRequestVo.getReceiveId(), partnerId, storeId, shoppingCartGoodsResponseVo);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * 清空购物车
     *
     * @param shoppingCartClearRequestVo
     * @return
     */
    @Override
    public BaseResponse clear(ShoppingCartClearRequestVo shoppingCartClearRequestVo) {
        AssortmentCustomerInfoVo userLoginInfoDto = customerInfoManager.getCustomerInfoByObject(shoppingCartClearRequestVo.getSessionId());
        String appId = shoppingCartClearRequestVo.getAppId();
        if (StringUtils.isBlank(appId)) {
            return ResponseUtil.error(ResponseResult.PARAMETER_MISSING, "appId不能为空");
        }
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartClearRequestVo.getPartnerId();
        String storeId = shoppingCartClearRequestVo.getShopId();
        shoppingCartNewBaseService.clear(partnerId, storeId, userId);
        if (ObjectUtils.equals(shoppingCartClearRequestVo.getOperationType(), OperationTypeEnum.PAY_SUCCESS.getOperationType())) {
            return ResponseUtil.success();
        }

        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartClearRequestVo.getOrderType());
        PromotionMessageDto promotionMessageDto = fullSubtractionActivityService.getFullPromotionActivityInfo(activityQueryDto, null);

        ActivityTip activityTip = new ActivityTip();
        if (promotionMessageDto != null) {
            activityTip.setActivityCode(promotionMessageDto.getActivityId());
            activityTip.setActivityType(promotionMessageDto.getActivityType());
            activityTip.setActivityName(promotionMessageDto.getPromotionMessage());
        }
        shoppingCartGoodsResponseVo.setActivityTip(activityTip);
        shoppingCartGoodsResponseVo.setProducts(new ArrayList<>());
        shoppingCartGoodsResponseVo.setProductsCount(0);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    @Override
    public BaseResponse<ShoppingCartGoodsDto> getShoppingCartGoods(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo,
                                                                   CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity) {
        ShoppingCartGoodsDto shoppingCartGoodsDto = new ShoppingCartGoodsDto();
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        AssortmentCustomerInfoVo assortmentCustomerInfoVo = customerInfoManager.getCustomerInfoByObject(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();
        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, shoppingCartBaseService);
        if (cartGoodsList == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_GETINFO_INVAILD);
        }
        /**
         *  校验该名店是否有必选商品
         *  1. 调用商品服务拿到该门店是否有必选商品
         *  2. 如果有，则和购物车的商品对比
         */
        if (productService.hasRequiredProducts(partnerId, storeId, cartGoodsList,BusinessTypeEnum.getByType(shoppingCartInfoRequestVo.getMenuType()).getCode())) {
            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);

        // 多规格的sku商品计算包装费
        //this.checkSkuOnVersion(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo);
        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), tableNumber, this.shoppingCartBaseService);

        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.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());
        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult = getCalculationDiscountResult(menuType,partnerId,storeId,userId,appId,userLoginInfoDto.getWxAppid(),orderType,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());
        return ResponseUtil.success(shoppingCartGoodsDto);
    }

    private void packgeAdditional(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity) {

        ArrayList<ShoppingCartInfoRequestVo.SendGoods> senGoods = new ArrayList<>();
        if (premiumExchangeActivity != null && CollectionUtils.isNotEmpty(premiumExchangeActivity.getProducts())) {

            for (CreateOrderVo.PremiumExchangeActivity.Product product : premiumExchangeActivity.getProducts()) {
                ShoppingCartInfoRequestVo.SendGoods sendGoods = new ShoppingCartInfoRequestVo.SendGoods();
                sendGoods.setQty(product.getQty());
                sendGoods.setGoodsId(StringUtils.isEmpty(product.getSkuId()) ? product.getSpuId() : product.getSkuId());
                senGoods.add(sendGoods);
            }
        }
        shoppingCartInfoRequestVo.setSendGoods(senGoods);
    }


    /**
     * 计算第一次使用会员卡需多支付的金额  单位:分
     *
     * @param shoppingCartInfoRequestVo
     * @param shoppingCartGoodsDto
     * @return
     */
    private void getNeedCardAmount(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, ShoppingCartGoodsDto shoppingCartGoodsDto) {
        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = shoppingCartInfoRequestVo.getBuyMemberCard();
        if (buyMemberCard != null && StringUtils.isNotEmpty(buyMemberCard.getPaidId()) && StringUtils.isNotEmpty(buyMemberCard.getRuleId())) {
            GetPaidRuleRequestDto getPaidRuleRequestDto = new GetPaidRuleRequestDto();
            getPaidRuleRequestDto.setPartnerId(shoppingCartInfoRequestVo.getPartnerId());
            getPaidRuleRequestDto.setPaidId(buyMemberCard.getPaidId());
            getPaidRuleRequestDto.setRuleId(buyMemberCard.getRuleId());
            BaseResponse<GetPaidRuleResponseDto> baseResponse = customerApplicationClient.getPaidRule(getPaidRuleRequestDto);
            if (baseResponse == null || baseResponse.getResult() == null || !ResponseResult.SUCCESS.getCode().equals(baseResponse.getCode())
                    || baseResponse.getResult().getActivityPrice() == null) {
                return;
            }
            Integer activityPrice = baseResponse.getResult().getActivityPrice();
            Integer firstCouponAmount = baseResponse.getResult().getFirstCouponAmount()==null?0: baseResponse.getResult().getFirstCouponAmount();
            Integer needCardAmount = activityPrice - firstCouponAmount;
            shoppingCartGoodsDto.setMemberCardAmount(needCardAmount);
            shoppingCartGoodsDto.setCardOriginalAmount(baseResponse.getResult().getActivityPrice());
            shoppingCartGoodsDto.setCardDiscountAmount(firstCouponAmount);
            shoppingCartGoodsDto.setOriginalTotalAmount(shoppingCartGoodsDto.getOriginalTotalAmount() + activityPrice);
            shoppingCartGoodsDto.setTotalAmount(shoppingCartGoodsDto.getTotalAmount() + needCardAmount);
            shoppingCartGoodsDto.setTotalDiscountAmount(shoppingCartGoodsDto.getTotalDiscountAmount() + firstCouponAmount);
        }
    }


    /**
     * 获取优惠信息
     *
     * @param partnerId
     * @param storeId
     * @param cartGoodsList
     * @return
     */
    public ActivityCalculationDiscountResponseDto.CalculationDiscountResult getActivityCalculationDiscountResponse(
            String partnerId, String storeId, String userId, String wxAppid, Integer orderType, List<CartGoods> cartGoodsList,String menuType, Long distributionFee) {
        return getActivityCalculationDiscountResponse(partnerId, storeId, userId, wxAppid, orderType, cartGoodsList, new ArrayList<>(), new ArrayList<>(),menuType,distributionFee);
    }

    /**
     * 获取优惠信息
     *
     * @param partnerId
     * @param storeId
     * @param cartGoodsList
     * @return
     */
    @Override
    public ActivityCalculationDiscountResponseDto.CalculationDiscountResult getActivityCalculationDiscountResponse(
            String partnerId, String storeId, String userId, String appId, Integer orderType, List<CartGoods> cartGoodsList,
            List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons,
            List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList,String menuType,Long distributionFee) {

        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());
            }
            // 商品是商品券
            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);
                    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());
            }
        }
        // 当加价购商品不为空时
        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
                this.addCalculationDiscountGoods(calculationDiscountGoodsList, sendGoods.getGoodsId(), sendGoods.getQty(), sendGoods.getOriginalPrice());
            }
        }
        calculationDiscountGoodsList.removeIf(calculationDiscountGoods -> (calculationDiscountGoods.getGoodsQuantity().equals(0)));
        if (CollectionUtils.isEmpty(calculationDiscountGoodsList)) {
            return null;
        }

        activityCalculationDiscountRequestDto.setGoods(calculationDiscountGoodsList);
        activityCalculationDiscountRequestDto.setCoupons(coupons);
        activityCalculationDiscountRequestDto.setOrgIds(commonService.getOrgIds(partnerId, storeId));
        activityCalculationDiscountRequestDto.setDistributionFee(distributionFee);
        ActivityCalculationDiscountResponseDto activityCalculationDiscountResponseDto;
        try {
            activityCalculationDiscountResponseDto = activityClient.calculationDiscount(activityCalculationDiscountRequestDto);
        } catch (Exception ex) {
            ErrorLog.printErrorLog("calculation_discount_error", "/calculation/discount", activityCalculationDiscountRequestDto, 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());
            return result;
        }
        throw new ServiceException(ResponseResult.OPERATE_TOO_OFTEN);
    }

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

    /**
     * 构建 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;
    }

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


    /**
     * 累加需加入计算的商品
     *
     * @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);
        }
    }

    /**
     * 处理加价购商品
     *
     * @param sendGoodsList
     * @param partnerId
     * @param storeId
     */
    private void processSendGoods(List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList
            , String partnerId, String storeId,String menuType, ShoppingCartBaseService shoppingCartService) {
        List<String> goodsIds = sendGoodsList.parallelStream().map(ShoppingCartInfoRequestVo.SendGoods::getGoodsId).collect(Collectors.toList());
        List<ProductBeanDTO> productBeanList =
                assortmentSdkService.getProductsInfoSdk(partnerId, storeId, goodsIds, menuType, shoppingCartService);
        // 将productBeanList转换为Map，key为pid，即goodsId
        Map<String, ProductBeanDTO> productBeanMap = productBeanList.parallelStream()
                .collect(Collectors.toMap(ProductBeanDTO::getPid, Function.identity(), (k1, k2) -> k1));
        // 遍历购物车进行加个更新
        for (ShoppingCartInfoRequestVo.SendGoods sendGoods : sendGoodsList) {
            ProductBeanDTO productBean;
            if ((productBean = productBeanMap.get(sendGoods.getGoodsId())) != null) {
                // 设置加价购商品原价
                sendGoods.setOriginalPrice(productBean.getOriginalPrice());
            } else {
                throw new ServiceException(ResponseResult.SHOPPING_CART_SENDGOODS_NOT_EXIST);
            }
        }

    }


    /**
     * 当ToastMsg为空时才赋值
     *
     * @param shoppingCartGoodsResponseVo
     * @param message
     */
    private void setToastMsgIfNotExist(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String message) {
        if (StringUtils.isEmpty(shoppingCartGoodsResponseVo.getToastMsg())) {
            shoppingCartGoodsResponseVo.setToastMsg(message);
        }
    }

    /**
     * 促销活动的优惠金额计算
     *
     * @param calculationDiscountResult
     * @param cartGoodsList
     * @param shoppingCartGoodsResponseVo
     */
    private void updateShoppingCartGoodsDiscount(CouponPromotionVO couponPromotionVO, ActivityQueryDto activityQueryDto, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, List<CartGoods> cartGoodsList
            , ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, UserLoginInfoDto userLoginInfoDto,String menuType,Long deliveryAmount) {
        //默认计算优惠
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        // 优惠券
        CouponPromotionService couponPromotionService = (CouponPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.COUPON_DISCOUNT);
        couponPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        // 满减
        FullPromotionService fullPromotionService = (FullPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.FULL_REDUCTION);
        fullPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getSendGoods())) {
            if (calculationDiscountResult.getSendGoods().stream()
                    .anyMatch(sendActivity -> Objects.equals(sendActivity.getActivityType(), ActivityTypeEnum.TYPE_6.getCode())
                            || Objects.equals(sendActivity.getActivityType(), ActivityTypeEnum.TYPE_61.getCode()))) {
                // 买赠
                BuySendPromotionService buySendPromotionService = (BuySendPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_ONE_SEND);
                buySendPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
            if (calculationDiscountResult.getSendGoods().stream()
                    .anyMatch(sendActivity -> Objects.equals(sendActivity.getActivityType(), ActivityTypeEnum.TYPE_81.getCode()))) {
                // 加价购
                AdditionalPromotionService additionalPromotionService = (AdditionalPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.ADDITIONAL_BUY);
                additionalPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
        }

        /**
         * 第x件y折活动计算方式：
         * 1. 从calculationDiscountResult.discounts中，type=104&discount>0则走下面的代码逻辑
         * 2. calculationDiscountResult.apportionGoods中，找到商品的所有的活动，然后把apportionAmount相加，把均摊放到当前的购物车商品里
         * 3. 限时特价和第x件y折活动冲突，故在第x件y折活动中去掉这个104type的活动
         *
         */
        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
            if (calculationDiscountResult.getDiscounts().stream()
                    .anyMatch(discount -> Objects.equals(discount.getType(), ActivityTypeEnum.TYPE_104.getCode())
                            && discount.getDiscount() > 0)) {
                XyDiscountServiceImpl xyDiscountService = (XyDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.XY_DISCOUNT);
                xyDiscountService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
        }

        // 限时特价
        TimeSalePromotionService timeSalePromotionService = (TimeSalePromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.TIME_SALE);
        timeSalePromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        //套餐
        SetMealServiceImpl setMealService = (SetMealServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.SET_MEAL);
        setMealService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        //积分兑换
        CustomerScoreService customerScoreService = (CustomerScoreService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.CUSTOMER_SCORE);
        customerScoreService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        /**
         * 第2件N折计算划线价
         */
        if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
            if (calculationDiscountResult.getDiscounts().stream()
                    .anyMatch(discount -> Objects.equals(discount.getType(), ActivityTypeEnum.TYPE_53.getCode())
                            && discount.getDiscount() > 0)) {
                TwoNDiscountServiceImpl twoNDiscountService = (TwoNDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.TwoN_DISCOUNT);
                twoNDiscountService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);
            }
        }
        // 买赠活动
        BuyAndGiftsPromotionService buyAndGiftsPromotionService =(BuyAndGiftsPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_GIFTS);
        buyAndGiftsPromotionService.updateShoppingCartGoodsDiscount(couponPromotionVO, activityQueryDto, calculationDiscountResult, cartGoodsList, shoppingCartGoodsResponseVo, userLoginInfoDto, shoppingCartInfoRequestVo);

        /**
         * 满额减配送费
         */

        if(BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(menuType)) {
            DecimalFormat df = new DecimalFormat("###.##");
            List<ActivityTypeEnum> activityTypeEnums = new LinkedList<>();
            activityTypeEnums.add(ActivityTypeEnum.TYPE_14);

            ActivityQueryResponseDto activityQueryResponseDto = activityService.queryActivityByType(activityQueryDto, activityTypeEnums, null);
            ActivityResponseDto activityResponse =null;
            BenefitBeanDto beanDto=null;
            if (activityQueryResponseDto != null &&activityQueryResponseDto.getResult()!=null && activityQueryResponseDto.getResult().size()>0) {
                activityResponse = activityQueryResponseDto.getResult().get(0);
                shoppingCartGoodsResponseVo.setDiscountDeliveryActivityCode(activityResponse.getActivityCode());
                beanDto=activityResponse.getBenefits().get(0);
            }

            ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount discount=null;
            if (calculationDiscountResult != null && CollectionUtils.isNotEmpty(calculationDiscountResult.getDiscounts())) {
                Optional<ActivityCalculationDiscountResponseDto.CalculationDiscountResult.Discount> discountop
                        = calculationDiscountResult.getDiscounts().stream()
                        .filter(discount1 -> {
                            return ActivityTypeEnum.TYPE_14.getCode().equals(discount1.getType());
                        })
                        .findFirst();
                discount=discountop.orElseGet(() -> {return null ;});
            }
            if(discount!=null){
                if(beanDto.getBenefitType() == 1){
                    String desc = DELIVERY_DISCOUNT_DESC2;
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ));
                }else{
                    String desc = DELIVERY_DISCOUNT_DESC1;
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ,df.format(beanDto.getDiscountAmount().doubleValue() / 100)));
                }
                shoppingCartGoodsResponseVo.setDeliveryAmount(calculationDiscountResult.getDeliveryAmount());
                shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(calculationDiscountResult.getDistributionFee());
                shoppingCartGoodsResponseVo.setThresholdAmount(discount.getThresholdAmount());
                shoppingCartGoodsResponseVo.setIsDiscountDelivery(true);
            }else{

                if (activityResponse!=null) {

                    if(beanDto.getBenefitType() == 1){
                        String desc = DELIVERY_DISCOUNT_DESC2;
                        shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100) ));
                    }else{
                        String desc = DELIVERY_DISCOUNT_DESC1;
                        shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(beanDto.getThresholdAmount().doubleValue() /100 ),df.format(beanDto.getDiscountAmount().doubleValue() / 100)));
                    }

                    shoppingCartGoodsResponseVo.setDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setIsDiscountDelivery(false);

                }else{
                    String desc = DELIVERY_DISCOUNT_DESC3;
                    shoppingCartGoodsResponseVo.setDeliveryDiscountDesc(String.format(desc, df.format(deliveryAmount.doubleValue() / 100)));
                    shoppingCartGoodsResponseVo.setDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setDiscountDeliveryAmount(deliveryAmount);
                    shoppingCartGoodsResponseVo.setIsDiscountDelivery(false);
                }
            }
        }

    }

    /**
     * 促销均摊计算
     *
     * @param shoppingCartGoodsResponseVo
     * @param calculationDiscountResult
     * @param shoppingCartGoodsDto
     * @param premiumExchangeActivity
     * @param shoppingCartInfoRequestVo
     */
    private void updateShoppingCartGoodsApportion(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult, ShoppingCartGoodsDto shoppingCartGoodsDto, CreateOrderVo.PremiumExchangeActivity premiumExchangeActivity, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 优惠券
        CouponPromotionService couponPromotionService = (CouponPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.COUPON_DISCOUNT);
        couponPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 买赠
        BuySendPromotionService buySendPromotionService = (BuySendPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_ONE_SEND);
        buySendPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 加价购
        AdditionalPromotionService additionalPromotionService = (AdditionalPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.ADDITIONAL_BUY);
        additionalPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        // 限时特价
        TimeSalePromotionService timeSalePromotionService = (TimeSalePromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.TIME_SALE);
        timeSalePromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //套餐
        SetMealServiceImpl setMealService = (SetMealServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.SET_MEAL);
        setMealService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //积分兑换
        CustomerScoreService customerScoreService = (CustomerScoreService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.CUSTOMER_SCORE);
        customerScoreService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //xy折
        XyDiscountServiceImpl xyDiscountService = (XyDiscountServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.XY_DISCOUNT);
        xyDiscountService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);

        //xy折
        BuyAndGiftsPromotionService buyAndGiftsPromotionService = (BuyAndGiftsPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.BUY_GIFTS);
        buyAndGiftsPromotionService.updateShoppingCartGoodsApportion(shoppingCartGoodsResponseVo, calculationDiscountResult, shoppingCartGoodsDto, premiumExchangeActivity, shoppingCartInfoRequestVo);
    }


    /**
     * 获取购物车商品,添加商品,校验商品合法性,合并商品行,重新set购物车信息到缓存中
     *
     * @param cartGoods
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param addShoppingCartGoodsRequestVo
     */
    @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.shoppingCartBaseService);
        oldAllCartGoodsList.clear();
        oldAllCartGoodsList.addAll(nowCartGoodsList);
        return nowCartGoodsList;
    }

    /**
     * 添加非商品券商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @param cartGoods
     * @param goodsId
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param allCartGoodsList
     * @param productBeanListSpuClass
     */
    private Map<String, List<CartGoods>> addNotProductGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, CartGoods cartGoods
            , String goodsId, String userId, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, List<CartGoods> allCartGoodsList
            , List<ProductBeanDTO> productBeanListSpuClass) {

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

        // 如果购物车中有商品券，则当前添加的商品是特价商品时，需要提示“已选商品券，与其他优惠商品不同享，商品将恢复原价”
        boolean haveCouponProduct = allCartGoodsList.parallelStream().anyMatch(k -> k.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX));
        if (haveCouponProduct && isSpecialGoods(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(), userId, addShoppingCartGoodsRequestVo.getAppId(), goodsId, addShoppingCartGoodsRequestVo.getOrderType())) {
            // 如果购物车先加入商品券，再加入促销商品，toast提示“已选商品券，与其他优惠商品不同享，商品将恢复原价”
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, ShoppingCartConstant.HAS_GOODS_COUPON_WHEN_ADD_SPECIAL_GOODS);
        }

        Map<String, List<CartGoods>> map = new HashMap<>();
        map.put(productBeanListSpuClass.get(0).getName(), allCartGoodsList);
        return map;
    }

    /**
     * 添加商品券商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @param cartGoods
     * @param userId
     * @param shoppingCartGoodsResponseVo
     * @param spuId
     * @param spuId2
     * @param allCartGoodsList
     * @param productBeanListSpuClass
     */
    private void addProductGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo
            , CartGoods cartGoods, String spuId2, String userId, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, String spuId
            , List<CartGoods> allCartGoodsList, List<ProductBeanDTO> productBeanListSpuClass) {
        // 商品券商品list
        List<CartGoods> tmpCartGoods = allCartGoodsList.parallelStream().filter(k -> k.getCartGoodsUid().startsWith(CommonsConstant.COUPON_PREFIX)).collect(Collectors.toList());
        // 当已有商品券时，不得添加(暂时的限制)
        if (CollectionUtils.isNotEmpty(tmpCartGoods)) {
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, ShoppingCartConstant.ONE_TRADE_CAN_ONLY_USE_ONE_GOODS_COUPON);
            cartGoods.setCartGoodsUid(null);
        } else {
            cartGoods.setCartGoodsUid(spuId);
            // 设置商品类型为商品券
            cartGoods.setGoodsType(GoodsTypeEnum.COUPON_GOODS.getGoodsType());
            // 商品券Id
            String spqId = spuId.substring(CommonsConstant.COUPON_PREFIX.length());
            cartGoods.setSpuId(spqId);
            cartGoods.setSkuId(spuId2);
            cartGoods.setOriginalPrice(0L);
            cartGoods.setOriginalAmount(0L);
            cartGoods.setAmount(0L);
            cartGoods.setPackPrice(productBeanListSpuClass.get(0).getPackPrice());
            cartGoods.setPic(productBeanListSpuClass.get(0).getPicture());

            List<String> goodsIds = allCartGoodsList.parallelStream().map(CartGoods::getGoodsId).collect(Collectors.toList());
            boolean hasSpecialGoods = hasSpecialGoods(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(), userId, addShoppingCartGoodsRequestVo.getAppId(), goodsIds, addShoppingCartGoodsRequestVo.getOrderType());
            // 如果购物车先加入促销活动的商品，再加入商品券时，toast提示“该商品券与其他活动不同享，购物车中已优惠的商品将恢复原价”
            if (hasSpecialGoods) {
                setToastMsgIfNotExist(shoppingCartGoodsResponseVo, ShoppingCartConstant.HAS_OTHER_ACTIVITY_WHEN_ADD_GOODS_COUPON);
            }
            //校验合法性,更新缓存中购物车信息
            allCartGoodsList = updateCartGoodsLegal(cartGoods, userId, shoppingCartGoodsResponseVo, addShoppingCartGoodsRequestVo, allCartGoodsList);
        }
    }

    /**
     * 查询多个商品库存信息
     *
     * @param addShoppingCartGoodsRequestVo
     * @param productIds
     * @param productBeanListSpuClass
     * @param skuId
     */
    private void queryManyGoodsStocks(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<Long> productIds
            , List<ProductBeanDTO> productBeanListSpuClass, String skuId, Integer qty) {
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(BusinessTypeEnum.getByType(addShoppingCartGoodsRequestVo.getMenuType()).getCode());
        requestDto.setPartnerId(addShoppingCartGoodsRequestVo.getPartnerId());
        requestDto.setStoreId(addShoppingCartGoodsRequestVo.getShopId());
        requestDto.setProductIds(productIds);
        GetProductStockResponseDto availableStocks = null;
        if (productBeanListSpuClass.get(0).getType() == ProductType.NOSPEC.getCode()
                && productBeanListSpuClass.get(0).getStockLimit() == 1) {
            availableStocks = stockClient.getAvailableStocks(requestDto);
        } else {
            for (ProductBeanDTO.SkuProductBean skuProductBean : productBeanListSpuClass.get(0).getSkuList()) {
                if (skuId.equals(skuProductBean.getSkuId()) && skuProductBean.getStockLimit() == 1) {
                    availableStocks = stockClient.getAvailableStocks(requestDto);
                    break;
                }
            }
        }
        if (availableStocks != null && !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode())) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
        if (availableStocks != null && ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(availableStocks.getCode()) &&
                (CollectionUtils.isEmpty(availableStocks.getResult()) || availableStocks.getResult().get(0).getQty() == null
                        || availableStocks.getResult().get(0).getQty() <= qty)) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
    }

    /**
     * 组装添加商品和更新商品和查询的响应信息
     * <p>
     * 查询购物车计算包装费
     *
     * @param shoppingCartGoodsResponseVo
     * @param calculationDiscountResult
     * @param cartGoodsList
     * @param toastMsg
     * @param userId
     * @param opt
     * @param shoppingCartInfoRequestVo
     */
    private void setAddAndUpdateResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult
            , List<CartGoods> cartGoodsList, String toastMsg, String partnerId, String storeId, String userId, String opt, ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        //updateCartGoodsResponse(shoppingCartGoodsResponseVo, calculationDiscountResult);
        shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        shoppingCartGoodsResponseVo.setProductsCount(cartGoodsList.size());
        if (StringUtils.isNotEmpty(toastMsg)) {
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, toastMsg);
        }
        // 更新和添加商品时不需要包装费
        if (ShoppingCartConstant.ADD_AND_UPDATE.equals(opt)) {
            shoppingCartGoodsResponseVo.setNewPackAmount(null);
            return;
        }
        //==========================  购物车查询特有逻辑  =================================
        // 到店自取包装费设为null,外卖要计算包装费，flag为1表示去结算
        // 兼容老版本判断null
        if (Objects.equals(shoppingCartInfoRequestVo.getOrderType(), CreateOrderType.COLLECT_GOODS.getCode())
                && (Objects.equals(shoppingCartInfoRequestVo.getReachStoreType(), null)
                || Objects.equals(shoppingCartInfoRequestVo.getReachStoreType(), OrderType.EAT_IN.getCode()))) {
            shoppingCartGoodsResponseVo.setNewPackAmount(null);
        } else if ((Objects.equals(shoppingCartInfoRequestVo.getOrderType(), CreateOrderType.TAKE_OUT.getCode())
                || Objects.equals(shoppingCartInfoRequestVo.getReachStoreType(), OrderType.COLLECT_GOODS.getCode()))
                && Objects.equals(shoppingCartInfoRequestVo.getFlag(), CouponFlag.YES.getCode())) {
            Long packAmount = shoppingCartGoodsResponseVo.getNewPackAmount() == null ? 0 : shoppingCartGoodsResponseVo.getNewPackAmount();
            Long originalTotalAmount = shoppingCartGoodsResponseVo.getOriginalTotalAmount() + packAmount;
            Long totalAmount = shoppingCartGoodsResponseVo.getTotalAmount() + packAmount;
            shoppingCartGoodsResponseVo.setOriginalTotalAmount(originalTotalAmount);
            shoppingCartGoodsResponseVo.setTotalAmount(totalAmount);
        }
        shoppingCartGoodsResponseVo.setChanged(false);
    }

    /**
     * 在原价、现价、折扣价上增加第一次使用会员卡的费用
     *
     * @param shoppingCartInfoRequestVo
     * @param shoppingCartGoodsResponseVo
     */
    private void addNeedCardAmount(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo, ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo) {
        ShoppingCartInfoRequestVo.BuyMemberCard buyMemberCard = shoppingCartInfoRequestVo.getBuyMemberCard();
        if (shoppingCartInfoRequestVo.getBuyMemberCard() == null || StringUtils.isEmpty(buyMemberCard.getPaidId()) || StringUtils.isEmpty(buyMemberCard.getRuleId())) {
            return;
        }
        GetPaidRuleRequestDto getPaidRuleRequestDto = new GetPaidRuleRequestDto();
        getPaidRuleRequestDto.setPartnerId(shoppingCartInfoRequestVo.getPartnerId());
        getPaidRuleRequestDto.setPaidId(buyMemberCard.getPaidId());
        getPaidRuleRequestDto.setRuleId(buyMemberCard.getRuleId());
        BaseResponse<GetPaidRuleResponseDto> baseResponse = customerApplicationClient.getPaidRule(getPaidRuleRequestDto);
        if (baseResponse == null || !ResponseResult.SUCCESS.getCode().equals(baseResponse.getCode()) || baseResponse.getResult() == null
                || baseResponse.getResult().getActivityPrice() == null) {
            return;
        }
        // 购买会员卡的金额
        Integer activityPrice = baseResponse.getResult().getActivityPrice();
        // 首次使用会员卡享受的折扣金额
        Integer firstCouponAmount = baseResponse.getResult().getFirstCouponAmount() == null ? 0 : baseResponse.getResult().getFirstCouponAmount();
        Long originalTotalAmount = shoppingCartGoodsResponseVo.getOriginalTotalAmount() + activityPrice;
        Long totalAmount = shoppingCartGoodsResponseVo.getTotalAmount() + (activityPrice - firstCouponAmount);
        Long totalDiscountAmount = shoppingCartGoodsResponseVo.getTotalDiscountAmount() + firstCouponAmount;
        shoppingCartGoodsResponseVo.setOriginalTotalAmount(originalTotalAmount);
        shoppingCartGoodsResponseVo.setTotalAmount(totalAmount);
        shoppingCartGoodsResponseVo.setTotalDiscountAmount(totalDiscountAmount);
        shoppingCartGoodsResponseVo.setCardOriginalAmount(activityPrice);
        shoppingCartGoodsResponseVo.setCardDiscountAmount(firstCouponAmount);
    }

    private UserLoginInfoDto convert2UserLoginInfoDto(AssortmentCustomerInfoVo assortmentCustomerInfoVo) {
        if (assortmentCustomerInfoVo == null || assortmentCustomerInfoVo.getMemberId() == null) {
            throw new ServiceException(ResponseResult.NOT_LOGIN);
        }

        UserLoginInfoDto userLoginInfoDto = new UserLoginInfoDto();
        userLoginInfoDto.setMemberId(assortmentCustomerInfoVo.getMemberId());
        userLoginInfoDto.setOpenId(assortmentCustomerInfoVo.getOpenId());
        userLoginInfoDto.setWxAppid(assortmentCustomerInfoVo.getWxAppId());
        userLoginInfoDto.setSessionKey(assortmentCustomerInfoVo.getSessionKey());
        userLoginInfoDto.setMobile(assortmentCustomerInfoVo.getMobile());
        userLoginInfoDto.setAppsecret(assortmentCustomerInfoVo.getAppSecret());
        userLoginInfoDto.setPartnerId(assortmentCustomerInfoVo.getPartnerId());
        userLoginInfoDto.setNewMemeber(assortmentCustomerInfoVo.getNewMember());
        userLoginInfoDto.setUnionId(assortmentCustomerInfoVo.getUnionId());

        return userLoginInfoDto;
    }

    /**
     * 储值卡支付余额校验
     * 校验订单商品金额与外卖配送费
     */
    private void SVCCardPay(String cardCode, String receiveId, String partnerId, String storeId,
                            ShoppingCartGoodsResponseVo 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卡金额
        com.freemud.application.sdk.api.base.BaseResponse<SVCCardAmountResponse> response = paymentNewService.querySVCCardAmount(request, trackingNo);
        if (response == null) {
            throw new ServiceException(ResponseResult.SYSTEM_BUSINESS_ERROR);
        }
        if (response.getData() == null || response.getData().getData() == null || response.getData().getData().getCardSimpleInfos().size() > 1) {
            throw new ServiceException(ResponseResult.USER_SVC_CARD_ERROR);
        }
        //获取实际配送费
        if (StringUtils.isNotBlank(receiveId)) {
//            Integer deliveryAmount = getDeliveryAmount(receiveId, partnerId, storeId);
            Integer deliveryAmount = shoppingCartGoodsResponseVo.getDiscountDeliveryAmount().intValue();
            orderAmount += deliveryAmount;
        }
        Integer amount1 = response.getData().getData().getCardSimpleInfos().get(0).getAmount();
        Integer vamount = response.getData().getData().getCardSimpleInfos().get(0).getVamount();
        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("储值卡支付￥" + amountStr);
    }

    /**
     * 储值卡支付查询配送费
     *
     * @return
     */
    private Integer getDeliveryAmount(String receiveId, String partnerId, String storeId) {
        String trackingNo = LogThreadLocal.getTrackingNo();
        Integer amount = 0;
        if (StringUtils.isBlank(receiveId)) {
            return amount;
        }
        QueryReceiveAddressRequest queryReceive = new QueryReceiveAddressRequest(receiveId, partnerId);
        //查询会员后货地址经纬度
        com.freemud.application.sdk.api.base.BaseResponse<QueryReceiveAddressResponse> queryReceiveAddressResponse = memberCenterService.queryReceiveAddressById(queryReceive, trackingNo);
        if (!ResponseResult.SUCCESS.getCode().equals(queryReceiveAddressResponse.getCode()) || queryReceiveAddressResponse.getData() == null) {
            throw new ServiceException(ResponseResult.USER_GETRECEIVEADDRESS_ERROR);
        }
        StoreInfoRequest request = new StoreInfoRequest();
        request.setPartnerId(partnerId);
        request.setStoreCode(storeId);
        //查询门店信息，获取门店经纬度
        StoreResponse storeResponse = storeCenterService.getStoreInfo(request, trackingNo);
        if (storeResponse == null || storeResponse.getStatusCode() != 100 || storeResponse.getBizVO() == null) {
            throw new ServiceException(ResponseResult.STORE_NOT_FOUND);
        }
        //查询门店外卖配送配置
        AssortmentOpenPlatformPartnerStoreDeliveryConfig deliveryConfig = deliveryConfigManager.findByPartnerIdAndStoreCode(partnerId, storeId);
        if (deliveryConfig == null) {
            throw new ServiceException(ResponseResult.STORE_ITEM_NOT_DELIVERY);
        }
        StoreDeliveryInfoDto storeDeliveryInfoDto = new StoreDeliveryInfoDto();
        storeDeliveryInfoDto.setPartnerId(partnerId);
        storeDeliveryInfoDto.setStoreId(storeId);
        storeDeliveryInfoDto.setStoreName(storeResponse.getBizVO().getStoreName());
        storeDeliveryInfoDto.setDeliveryLimitAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryLimitAmount());
        storeDeliveryInfoDto.setDeliveryAmount(deliveryConfig == null ? 0 : deliveryConfig.getDeliveryAmount());
        storeDeliveryInfoDto.setDefaultDeliveryRange(deliveryConfig == null ? 0L : deliveryConfig.getDefaultDeliveryRange());
        storeDeliveryInfoDto.setAddRangeAmount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeAmount());
        storeDeliveryInfoDto.setAddRangeCount(deliveryConfig == null ? 0L : deliveryConfig.getAddRangeCount());
        storeDeliveryInfoDto.setPoint2DList(getDeliveryPoint2DList(storeResponse.getBizVO().getDistributionScope()));
        storeDeliveryInfoDto.setDeliveryHoursDay(storeResponse.getBizVO().getDeliveryHoursDay());
        storeDeliveryInfoDto.setLongitude(storeResponse.getBizVO().getLongitude());
        storeDeliveryInfoDto.setLatitude(storeResponse.getBizVO().getLatitude());
        storeDeliveryInfoDto.setScopeConfig(storeResponse.getBizVO().getScopeConfig());
        if (StringUtils.isNotEmpty(storeResponse.getBizVO().getDeliveryRadius())) {
            storeDeliveryInfoDto.setDeliveryRadius(Integer.valueOf(storeResponse.getBizVO().getDeliveryRadius()));
        } else {
            storeDeliveryInfoDto.setDeliveryRadius(0);
        }
        storeDeliveryInfoDto.setEnableTakeaway(true);
        String userLongitude = queryReceiveAddressResponse.getData().getLongitude();
        String userLatitude = queryReceiveAddressResponse.getData().getLatitude();
        amount = storeService.getUserRealDeliveryAmount(storeDeliveryInfoDto, userLongitude, userLatitude).intValue();
        return amount;
    }

    /**
     * 获取配送范围内集合
     */
    public List<Point2D.Double> getDeliveryPoint2DList(String distributionScope) {
        if (StringUtils.isBlank(distributionScope)) {
            return Collections.emptyList();
        }
        /**
         * 如果点不为整数，返回空
         */
        String[] points = distributionScope.split(",");
        if (points.length % 2 != 0) {
            return Collections.emptyList();
        }
        List<String> pointList = Arrays.asList(points);
        List<Point2D.Double> point2DList = Lists.newArrayList();
        for (int i = 0; i < pointList.size(); i++) {
            Double pointX = Double.parseDouble(pointList.get(i));
            Double pointY = Double.parseDouble(pointList.get(++i));
            point2DList.add(new Point2D.Double(pointX, pointY));
        }
        return point2DList;
    }

    /**
     * 获取优惠
     */
    private ActivityCalculationDiscountResponseDto.CalculationDiscountResult getCalculationDiscountResult(String menuType
            ,String partnerId,String storeId,String userId,String appId,String wxappid,Integer orderType
            ,List<CartGoods> cartGoodsList,List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons
            ,List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList,String receiveId,Long deliveryAmount){
        // 获取优惠信息
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationDiscountResult=null;
        //外卖场景下 查询门店配送信息
        if(BusinessTypeEnum.SAAS_DELIVERY.getCode().equals(menuType)){

            calculationDiscountResult = this.getActivityCalculationDiscountResponse(partnerId, storeId, userId, appId, orderType, cartGoodsList, coupons, sendGoodsList,BusinessTypeEnum.getByType(menuType).getCode(),deliveryAmount);
        }else{
            calculationDiscountResult = this.getActivityCalculationDiscountResponse(partnerId, storeId, userId, appId, orderType, cartGoodsList, coupons, sendGoodsList,BusinessTypeEnum.getByType(menuType).getCode(),null);
        }

        return calculationDiscountResult;
    }

    private Long calculateDeliveryAmount(String receiveId,String partnerId,String storeId,String wxappid){
        Long deliveryAmount = 0l;
        if(receiveId==null) {
        }else{
            deliveryAmount = Long.parseLong(getDeliveryAmount(receiveId,partnerId,storeId).toString());
        }
        return deliveryAmount;
    }

}
