/**
 * 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.constant.ResponseCodeConstant;
import cn.freemud.constant.ShoppingCartConstant;
import cn.freemud.entities.dto.BuriedPointShoppingCartRequestDto;
import cn.freemud.entities.dto.GetProductStockRequestDto;
import cn.freemud.entities.dto.GetProductStockResponseDto;
import cn.freemud.entities.dto.UserLoginInfoDto;
import cn.freemud.entities.dto.activity.ActivityQueryDto;
import cn.freemud.entities.dto.activity.DiscountSharingDto;
import cn.freemud.entities.dto.calculate.ActivityCalculationDiscountRequestDto;
import cn.freemud.entities.dto.calculate.ActivityCalculationDiscountResponseDto;
import cn.freemud.entities.dto.delivery.DeliveryFeeInfo;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.ecology.VirtualBindStoreResponse;
import cn.freemud.entities.ecology.VirtualStoreRequest;
import cn.freemud.entities.vo.*;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.service.BuriedPointService;
import cn.freemud.service.ItemService;
import cn.freemud.service.ShoppingCartNewService;
import cn.freemud.service.impl.calculate.*;
import cn.freemud.service.shoppingCart.ShoppingCartRelationFactory;
import cn.freemud.service.shoppingCart.ShoppingCartRelationService;
import cn.freemud.service.thirdparty.CustomerApplicationClient;
import cn.freemud.service.thirdparty.DeliveryFeiginClient;
import cn.freemud.service.thirdparty.EcologyAdminApplicationClient;
import cn.freemud.service.thirdparty.StockClient;
import cn.freemud.utils.PromotionFactory;
import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.customer.AssortmentCustomerInfoManager;
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.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.ShoppingCartMallBaseServiceImpl;
import com.google.common.collect.Lists;
import lombok.Data;
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.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

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

@Service
public class ShoppingCartMallServiceImpl implements ShoppingCartNewService {


    @Autowired
    private ItemService itemService;

    @Autowired
    private ShoppingCartMallBaseServiceImpl shoppingCartBaseService;
    @Autowired
    private BuriedPointService buriedPointService;
    @Autowired
    private StockClient stockClient;
    @Autowired
    private AssortmentSdkService assortmentSdkService;
    @Autowired
    private AssortmentCustomerInfoManager customerInfoManager;
    @Autowired
    private EcologyAdminApplicationClient ecologyAdminApplicationClient;
    @Autowired
    private CalculationSharingCartService sharingCartService;
    @Autowired
    private CalculationSharingDiscountService sharingDiscountService;
    @Autowired
    private ShoppingCartRelationFactory shoppingCartRelationFactory;
    @Autowired
    private CustomerApplicationClient customerApplicationClient;
    @Autowired
    private ActivityAdapter activityAdapter;
    @Autowired
    private CouponAdapter couponAdapter;
    @Autowired
    private DeliveryFeiginClient deliveryFeiginClient;
    @Autowired
    private CalculationSharingValidatorService calculationSharingValidatorService;
    @Autowired
    private CalculationSharingEquallyService sharingEquallyService;
    @Value("${saas.cart.sharing}")
    private String sharing;
    /**
     * 从微信卡券向购物车中添加商品
     */
    @Override
    public BaseResponse addGoodsByCard(AddGoodsByWeixinCardRequestVo request) {
        throw new UnsupportedOperationException("暂不支持此操作");
    }

    /**
     * 添加商品
     *
     * @param addShoppingCartGoodsRequestVo
     * @return
     */
    @Override
    public BaseResponse addGoods(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo) {
        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        // 获取用户信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(addShoppingCartGoodsRequestVo.getSessionId());

        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = addShoppingCartGoodsRequestVo.getPartnerId();
        String appId = addShoppingCartGoodsRequestVo.getAppId();
        String spuId = addShoppingCartGoodsRequestVo.getSpuId();
        String skuId = addShoppingCartGoodsRequestVo.getSkuId();
        String goodsId = StringUtils.isEmpty(skuId) ? spuId : skuId;
        String storeId = this.getBindMallShopId(appId);
        String menuType = addShoppingCartGoodsRequestVo.getMenuType();
        Integer orderType = addShoppingCartGoodsRequestVo.getOrderType();
        addShoppingCartGoodsRequestVo.setShopId(storeId);
        Integer accountType = 0; //非结算页
        //清空临时购物车
        // 构造请求参数，进行清空购物车
        if(ShoppingCartConstant.NOW_BUY_TYPE == addShoppingCartGoodsRequestVo.getBuyType()) {
            com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto cartParamDto = assortmentSdkService.getNowBuyCartParamDto(addShoppingCartGoodsRequestVo.getBuyType(), partnerId, storeId, userId);
            shoppingCartBaseService.clear(cartParamDto, LogThreadLocal.getTrackingNo());
        }
        /**
         * 不支持优惠券
         */
        if(spuId.startsWith(CommonsConstant.COUPON_PREFIX)) {
            return ResponseUtil.error(ResponseResult.COUPON_SHOP_NOTSUPPORT);
        }
        CartGoods cartGoods = ShoppingCartConvertAdapter.convent2CartGoods(addShoppingCartGoodsRequestVo);
        List<Long> productIds = Lists.newArrayList(Long.parseLong(goodsId));
        //商品skuId或者商品券的商品id
        String spuId2 = spuId;
        // 获取商品详细信息
        List<ProductBeanDTO> productBeanListSpuClass = assortmentSdkService.getProductsInfoSdk(partnerId, storeId, Collections.singletonList(spuId2), BusinessTypeEnum.SAAS_MALL.getName(), this.shoppingCartBaseService);
        //查询多个商品库存信息
        queryManyGoodsStocks(addShoppingCartGoodsRequestVo, productIds, productBeanListSpuClass, skuId);

        //缓存中获取购物车商品信息
        // 注意，围餐和点餐redis数据结构不一样
        List<CartGoods> allCartGoodsList =  new ArrayList<>() ;
        if(ShoppingCartConstant.NOW_BUY_TYPE == addShoppingCartGoodsRequestVo.getBuyType()) {
            allCartGoodsList = assortmentSdkService.getNowBuyShoppingCart(ShoppingCartConstant.NOW_BUY_TYPE ,partnerId, storeId, userId, addShoppingCartGoodsRequestVo.getSessionId(), null, shoppingCartBaseService,null);
        }else{
            allCartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, addShoppingCartGoodsRequestVo.getSessionId(), null, shoppingCartBaseService,null);
        }
        if (CollectionUtils.isEmpty(allCartGoodsList)) {
            allCartGoodsList = new ArrayList<>();
        }

        String productName = null;
        //添加非商品券商品
        Map<String, List<CartGoods>> map = addNotProductGoods(addShoppingCartGoodsRequestVo, cartGoods, goodsId, userId, shoppingCartGoodsResponseVo, allCartGoodsList, productBeanListSpuClass);
        for (Map.Entry<String, List<CartGoods>> entry : map.entrySet()) {
            productName = entry.getKey();
            allCartGoodsList = entry.getValue();
        }

        // 当商品数量被设为0时
        if (Objects.equals(cartGoods.getQty(), 0)) {
            assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoods.getCartGoodsUid(), 0, "", shoppingCartBaseService,null);
        }
        //todo 配送费用计算
        Long deliveryAmount = 0L;

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

        ActivityCalculationDiscountResponseDto.CalculationDiscountResult discountResult = null;
        discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType, partnerId, storeId, userId, appId, orderType, assortmentCustomerInfoVo.isMemberPaid(), allCartGoodsList, new ArrayList<>(), null, deliveryAmount, null,null, accountType,new DiscountSharingDto());
        sharingCartService.distribute(discountResult, allCartGoodsList, shoppingCartGoodsResponseVo, null, null, null, activityQueryDto, menuType, deliveryAmount, ShoppingCartConstant.ADD_AND_UPDATE, partnerId, null, userId, storeId);

        buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,discountResult,null,partnerId);

        //埋点添加购物车行为
        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();
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(updateShoppingCartGoodsQtyRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = updateShoppingCartGoodsQtyRequestVo.getPartnerId();
        String appId = updateShoppingCartGoodsQtyRequestVo.getAppId();
        String storeId = this.getBindMallShopId(appId);
        updateShoppingCartGoodsQtyRequestVo.setShopId(storeId);
        String cartGoodsUid = updateShoppingCartGoodsQtyRequestVo.getCartGoodsUid();
        Integer qty = updateShoppingCartGoodsQtyRequestVo.getQty();
        String receiveId = updateShoppingCartGoodsQtyRequestVo.getReceiveId();
        String menuType = updateShoppingCartGoodsQtyRequestVo.getMenuType();
        Integer orderType=updateShoppingCartGoodsQtyRequestVo.getOrderType();
        Integer accountFlag = 0;// 非结算页

        // 先验证商品是否存在
        CartGoods cartGoods = assortmentSdkService.getCartGoodsBySdk(partnerId, userId, storeId, cartGoodsUid, "", shoppingCartBaseService,null);
        if (cartGoods == null) {
            return ResponseUtil.error(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
//            throw new ServiceException(ResponseResult.SHOPPING_CART_UPDATE_ERROR);
        }
        // 检查购物车商品库存数量
        checkUpdateStock(updateShoppingCartGoodsQtyRequestVo, cartGoods);
        Integer oldQty = cartGoods.getQty();
        // 更新购物车中数量
        List<CartGoods> cartGoodsList = assortmentSdkService.updateGoodsQtyBySdk(partnerId, userId, storeId, cartGoodsUid, qty<0?0:qty, "", shoppingCartBaseService,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);

        // 重新存储最新购物车
        assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, updateShoppingCartGoodsQtyRequestVo.getSessionId(), "", shoppingCartBaseService,null);
        Long deliveryAmount = 0L;

        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, updateShoppingCartGoodsQtyRequestVo.getOrderType());
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult discountResult = null;
        discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                , partnerId
                , storeId
                , userId
                , appId
                , orderType
                , assortmentCustomerInfoVo.isMemberPaid()
                , cartGoodsList
                , new ArrayList() //券
                , null //加价购商品
                , deliveryAmount
                , null,null, accountFlag,new DiscountSharingDto());

        sharingCartService.distribute(discountResult
                , cartGoodsList
                , shoppingCartGoodsResponseVo
                , null //入参
                , userLoginInfoDto
                , null //券信息
                , activityQueryDto
                , menuType
                , deliveryAmount
                , ShoppingCartConstant.ADD_AND_UPDATE
                , partnerId
                , null
                , userId
                , storeId);

        buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,discountResult,null,partnerId);

        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.SAAS_MALL.getCode());

        GetProductsVo getProductsVo = products.get(cartGoods.getGoodsId());
        // 商品没有库存限制
        if ((getProductsVo == null) || (getProductsVo.getStockLimit() != 1)) {
            return;
        }
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(BusinessTypeEnum.SAAS_MALL.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();
        // 获取用户信息
        CustomerInfoVo assortmentCustomerInfoVo = getCustomerInfoVo(shoppingCartInfoRequestVo.getSessionId());
        UserLoginInfoDto userLoginInfoDto = convert2UserLoginInfoDto(assortmentCustomerInfoVo);
        String userId = userLoginInfoDto.getMemberId();
        String partnerId = shoppingCartInfoRequestVo.getPartnerId();
        String appId = shoppingCartInfoRequestVo.getAppId();
        String storeId = this.getBindMallShopId(appId);
        shoppingCartInfoRequestVo.setShopId(storeId);
        List<CartGoods> cartGoodsList = new ArrayList<>();
        String couponCode = shoppingCartInfoRequestVo.getCouponCode();
        String activityCode = shoppingCartInfoRequestVo.getActivityCode();
        List<ChooseCouponVo> couponCodes = shoppingCartInfoRequestVo.getCouponCodes();
        Integer accountFlag = shoppingCartInfoRequestVo.getFlag();
        // 兼容老版本
        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();
        // 获取购物车商品
        if(ShoppingCartConstant.NOW_BUY_TYPE == shoppingCartInfoRequestVo.getBuyType()) {
            cartGoodsList = assortmentSdkService.getNowBuyShoppingCart(ShoppingCartConstant.NOW_BUY_TYPE,partnerId, storeId, userId, null, "", shoppingCartBaseService,null);
        }else{
            cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, "", shoppingCartBaseService,null);
        }
        if (cartGoodsList == null) {
            cartGoodsList = new ArrayList<>();
        }
        // check购物车中所有商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getOrderType(), "", BusinessTypeEnum.SAAS_MALL.getName() ,shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);
        //1.5.4 多规格的sku商品计算包装费
        //checkSkuOnVersion(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo);
        // 重新存储最新购物车
        if(ShoppingCartConstant.NOW_BUY_TYPE == shoppingCartInfoRequestVo.getBuyType()) {
            assortmentSdkService.setNowBuyShoppingCart(shoppingCartInfoRequestVo.getBuyType(),partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService,null);
        }else {
            assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService,null);
        }
        ArrayList<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
        if (StringUtils.isNotEmpty(couponCode)) {
            ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
            coupon.setCode(couponCode);
            coupon.setActivityCode(activityCode);
            coupons.add(coupon);
        }

        buildCoupons(coupons,shoppingCartInfoRequestVo.getCouponCodes());

        DeliveryFeeInfo deliveryFeeInfo = calculateDeliveryAmount(partnerId, shoppingCartInfoRequestVo.getProvince(), cartGoodsList);
        Long deliveryAmount = deliveryFeeInfo.getDeliveryAmount();
        shoppingCartGoodsResponseVo.setCostType(deliveryFeeInfo.getCostType());

                ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartInfoRequestVo.getOrderType());
        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);
        List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList = shoppingCartInfoRequestVo.getSendGoods();
        List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(sendGoodsList)) {
            for (ShoppingCartInfoRequestVo.SendGoods sds : sendGoodsList) {
                ShoppingCartInfoRequestVo.SendGoods sd = new ShoppingCartInfoRequestVo.SendGoods();
                sd.setGoodsId(sds.getGoodsId());
                if (StringUtils.isBlank(sds.getActivityCode())) continue;
                sd.setQty(sds.getQty());
                sd.setOriginalPrice(0L);
                sd.setActivityCode(sds.getActivityCode());
                sendGoods.add(sd);
            }
        }
        ActivityCalculationDiscountResponseDto.CalculationDiscountResult calculationSharingDiscountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                , partnerId
                , storeId
                , userId
                , appId
                , orderType
                , assortmentCustomerInfoVo.isMemberPaid()
                , cartGoodsList
                , coupons
                , sendGoods
                , deliveryAmount
                , null,null, accountFlag,new DiscountSharingDto());
        sharingCartService.distribute(calculationSharingDiscountResult
                , cartGoodsList
                , shoppingCartGoodsResponseVo
                , shoppingCartInfoRequestVo
                , userLoginInfoDto
                , couponPromotionVO
                , activityQueryDto
                , menuType
                , deliveryAmount
                , ShoppingCartConstant.QUERY_INFO
                , partnerId
                ,shoppingCartInfoRequestVo.getFlag()
                , userId
                , storeId);

        buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,calculationSharingDiscountResult,shoppingCartInfoRequestVo.getFlag(),partnerId);


        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * svc 卡支付使用
     * @param shoppingCartInfoRequestVo
     * @return
     */
    @Override
    public BaseResponse getGoodsListCheck(ShoppingCartInfoRequestVo shoppingCartInfoRequestVo) {
        throw new UnsupportedOperationException("暂不支持此操作");
    }

    /**
     * 清空购物车
     *
     * @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();
        if(Objects.equals(shoppingCartClearRequestVo.getOperationType(), OperationTypeEnum.PAY_SUCCESS.getOperationType())) {
            storeId = this.getBindMallShopId(appId);
            shoppingCartClearRequestVo.setShopId(storeId);
        }

        // 构造请求参数，进行清空购物车
        com.freemud.sdk.api.assortment.shoppingcart.domain.CartParamDto cartParamDto = assortmentSdkService.getCartParamDto(partnerId, storeId, userId);
        shoppingCartBaseService.clear(cartParamDto, LogThreadLocal.getTrackingNo());

        // 支付成功回调不查询任何数据，直接返回成功结果
        if (ObjectUtils.equals(shoppingCartClearRequestVo.getOperationType(), OperationTypeEnum.PAY_SUCCESS.getOperationType())) {
            return ResponseUtil.success();
        }

        ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo = new ShoppingCartGoodsResponseVo();
        ActivityTip activityTip = new ActivityTip();
        shoppingCartGoodsResponseVo.setActivityTip(activityTip);
        shoppingCartGoodsResponseVo.setProducts(new ArrayList<>());
        shoppingCartGoodsResponseVo.setProductsCount(0);
        return ResponseUtil.success(shoppingCartGoodsResponseVo);
    }

    /**
     * 供点单获取优惠均摊调用，传入的shopId为绑定商城的shopId
     */
    @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 appId = StringUtils.isEmpty(shoppingCartInfoRequestVo.getAppId())?userLoginInfoDto.getWxAppid():shoppingCartInfoRequestVo.getAppId();
        String storeId = shoppingCartInfoRequestVo.getShopId();
        String couponCode = shoppingCartInfoRequestVo.getCouponCode();
        String activityCode = shoppingCartInfoRequestVo.getActivityCode();
        Integer accountFlag = shoppingCartInfoRequestVo.getFlag();
        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 menuType = shoppingCartInfoRequestVo.getMenuType();
        Integer orderType = shoppingCartInfoRequestVo.getOrderType();
        List<ShoppingCartInfoRequestVo.SendGoods> sendGoodsList = shoppingCartInfoRequestVo.getSendGoods();
        List<CartGoods> cartGoodsList = new ArrayList<>();
        // 获取购物车商品
        if(ShoppingCartConstant.NOW_BUY_TYPE == shoppingCartInfoRequestVo.getBuyType()) {
            cartGoodsList = assortmentSdkService.getNowBuyShoppingCart(ShoppingCartConstant.NOW_BUY_TYPE,partnerId, storeId, userId, null, "", shoppingCartBaseService,null);
        }else{
            cartGoodsList = assortmentSdkService.getShoppingCart(partnerId, storeId, userId, null, "", shoppingCartBaseService,null);
        }
        if (cartGoodsList == null) {
            cartGoodsList = new ArrayList<>();
        }
        // check购物车中所有商品
        CheckCartRequest checkCartRequest = assortmentSdkService.checkShoppingCartSdk(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo, shoppingCartInfoRequestVo.getOrderType(), "", BusinessTypeEnum.SAAS_MALL.getName() ,shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
        }
        cartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);
        //1.5.4 多规格的sku商品计算包装费
        //checkSkuOnVersion(cartGoodsList, partnerId, storeId, shoppingCartGoodsResponseVo);
        // 重新存储最新购物车
        if(ShoppingCartConstant.NOW_BUY_TYPE == shoppingCartInfoRequestVo.getBuyType()) {
            assortmentSdkService.setNowBuyShoppingCart(shoppingCartInfoRequestVo.getBuyType(),partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService,null);
        }else {
            assortmentSdkService.setShoppingCart(partnerId, storeId, userId, cartGoodsList, assortmentCustomerInfoVo.getSessionId(), "", this.shoppingCartBaseService,null);
        }
        ArrayList<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> coupons = new ArrayList<>();
        if (StringUtils.isNotEmpty(couponCode)) {
            ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
            coupon.setCode(couponCode);
            coupon.setActivityCode(activityCode);
            coupons.add(coupon);
        }
        buildCoupons(coupons,shoppingCartInfoRequestVo.getCouponCodes());


        DeliveryFeeInfo deliveryFeeInfo = calculateDeliveryAmount(partnerId, shoppingCartInfoRequestVo.getProvince(), cartGoodsList);
        Long deliveryAmount = deliveryFeeInfo.getDeliveryAmount();


        ActivityQueryDto activityQueryDto = activityAdapter.getActivityQueryDto(partnerId, storeId, userId, appId, shoppingCartInfoRequestVo.getOrderType());
        CouponPromotionVO couponPromotionVO = couponAdapter.getCouponPromotionVO(shoppingCartInfoRequestVo, userLoginInfoDto);
        List<ShoppingCartInfoRequestVo.SendGoods> sendGoods = new ArrayList<>();
        // 当couponCodes不为空时，需参与价格计算,同时排除单券入参
        buildCoupons(coupons,shoppingCartInfoRequestVo.getCouponCodes());

        ActivityCalculationDiscountResponseDto.CalculationDiscountResult discountResult = sharingDiscountService.getCalculationSharingDiscountResult(menuType
                , partnerId
                , storeId
                , userId
                , appId
                , orderType
                , assortmentCustomerInfoVo.isMemberPaid()
                , cartGoodsList
                , coupons
                , shoppingCartInfoRequestVo.getSendGoods()
                , deliveryAmount
                , shoppingCartInfoRequestVo,null, accountFlag,new DiscountSharingDto());

        // 活动校验
        calculationSharingValidatorService.validator(discountResult
                , cartGoodsList
                , shoppingCartGoodsResponseVo
                , shoppingCartInfoRequestVo
                , userLoginInfoDto
                , couponPromotionVO
                , activityQueryDto
                , menuType
                , deliveryAmount
                , ShoppingCartConstant.QUERY_INFO);

        //直接利用促销返回做均摊
        sharingEquallyService.equally(discountResult
                , cartGoodsList
                , shoppingCartGoodsResponseVo
                , shoppingCartInfoRequestVo
                , userLoginInfoDto
                , couponPromotionVO
                , activityQueryDto
                , menuType
                , deliveryAmount
                , shoppingCartGoodsDto
                , premiumExchangeActivity);

        return ResponseUtil.success(shoppingCartGoodsDto);
    }

    @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 accountFlag) {
        return null;
    }


    /**
     * 处理加价购商品
     *
     * @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);
        }
    }

    @Data
    static class CartGoodsStates {
        /**
         * 价格变化
         */
        boolean priceChanged;
        /**
         * 非法商品
         */
        boolean hasInvalidGoods;
        /**
         * 点餐方式
         */
        boolean orderWayFlag;

    }

    /**
     * 促销活动的优惠金额计算
     *
     * @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) {

        //默认计算优惠
        DefaultPromotionService defaultPromotionService = (DefaultPromotionService) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.DEFAULT_PROMOTION);
        defaultPromotionService.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);

    }

    /**
     * 促销均摊计算
     *
     * @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);

        //套餐
        SetMealServiceImpl setMealService = (SetMealServiceImpl) PromotionFactory.getPromotionService(ShoppingCartPromotionEnum.SET_MEAL);
        setMealService.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(), "",BusinessTypeEnum.SAAS_MALL.getName(), shoppingCartBaseService);
        if (checkCartRequest.getShoppingCartGoodsResponseVo() != null) {
            shoppingCartGoodsResponseVo.setToastMsg(checkCartRequest.getShoppingCartGoodsResponseVo().getToastMsg());
        }
        List<CartGoods> allCartGoodsList = JSONArray.parseArray(JSONObject.toJSONString(checkCartRequest.getCartGoodsList()), CartGoods.class);

        //判断当前商品在购物车是否已存在,存在则数量＋添加的数量,不存在商品行 + 添加的数量
        allCartGoodsList.forEach(oldCartGoods -> {
            int index;
            if ((index = nowCartGoodsList.indexOf(oldCartGoods)) >= 0) {
                nowCartGoodsList.get(index).setQty(nowCartGoodsList.get(index).getQty() + oldCartGoods.getQty());
            } else {
                nowCartGoodsList.add(oldCartGoods);
            }
        });
        // 重新set购物车信息到缓存中
        if(addShoppingCartGoodsRequestVo.getBuyType() == ShoppingCartConstant.NOW_BUY_TYPE){
            assortmentSdkService.setNowBuyShoppingCart(ShoppingCartConstant.NOW_BUY_TYPE,addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(),
                    userId, nowCartGoodsList, addShoppingCartGoodsRequestVo.getSessionId(), addShoppingCartGoodsRequestVo.getTableNumber(), this.shoppingCartBaseService,null);
        }else {
            assortmentSdkService.setShoppingCart(addShoppingCartGoodsRequestVo.getPartnerId(), addShoppingCartGoodsRequestVo.getShopId(),
                    userId, nowCartGoodsList, addShoppingCartGoodsRequestVo.getSessionId(), addShoppingCartGoodsRequestVo.getTableNumber(), this.shoppingCartBaseService,null);
        }
        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 productIds
     * @param productBeanListSpuClass
     * @param skuId
     */
    private void queryManyGoodsStocks(AddShoppingCartGoodsRequestVo addShoppingCartGoodsRequestVo, List<Long> productIds
            , List<ProductBeanDTO> productBeanListSpuClass, String skuId) {
        GetProductStockRequestDto requestDto = new GetProductStockRequestDto();
        requestDto.setChannel(BusinessTypeEnum.SAAS_MALL.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() <= 0)) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_STOCK_NOT_HAVE);
        }
    }

    /**
     * 组装添加商品和更新商品和查询的响应信息
     * <p>
     * 查询购物车计算包装费
     *
     * @param shoppingCartGoodsResponseVo
     * @param cartGoodsList
     * @param toastMsg
     */
    private void setAddAndUpdateResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo, List<CartGoods> cartGoodsList, String toastMsg) {
        shoppingCartGoodsResponseVo.setProducts(cartGoodsList);
        shoppingCartGoodsResponseVo.setProductsCount(cartGoodsList.size());
        if (StringUtils.isNotEmpty(toastMsg)) {
            setToastMsgIfNotExist(shoppingCartGoodsResponseVo, toastMsg);
        }
        shoppingCartGoodsResponseVo.setChanged(false);
    }


    private UserLoginInfoDto convert2UserLoginInfoDto(CustomerInfoVo 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;
    }

    /**
     * 获取商城门店id
     */
    private String getBindMallShopId(String wxAppId) {
        VirtualStoreRequest virtualStoreRequest = new VirtualStoreRequest();
        virtualStoreRequest.setPlatformAppId(wxAppId);
        virtualStoreRequest.setType("microMall");
        BaseResponse<VirtualBindStoreResponse> virtualBindStoreResponse = ecologyAdminApplicationClient.getBuyBindVirtualStore(virtualStoreRequest);
        if(virtualBindStoreResponse == null || virtualBindStoreResponse.getResult() == null || StringUtils.isBlank(virtualBindStoreResponse.getResult().getStoreId())) {
            throw new ServiceException(ResponseResult.STORE_MALL_NOT_FOUND);
        }
        return virtualBindStoreResponse.getResult().getStoreId();
    }

    /**
     * 设置总的优惠信息和商品优惠信息
     * @param shoppingCartGoodsResponseVo
     * @param discountResult
     */
    private void buildShoppingCartGoodsResponse(ShoppingCartGoodsResponseVo shoppingCartGoodsResponseVo,
                                                ActivityCalculationDiscountResponseDto.CalculationDiscountResult discountResult,
                                                Integer flag,
                                                String partnerId) {

        ShoppingCartRelationService shoppingCartRelationService = shoppingCartRelationFactory.getBuildShoppingCartGoodsResponseService(partnerId);
        shoppingCartRelationService.buildShoppingCartGoodsResponse(shoppingCartGoodsResponseVo,discountResult,flag);

    }

    private CustomerInfoVo getCustomerInfoVo(String sessionId) {
//        GetSessionUserInfoDto getSessionUserInfoDto = new GetSessionUserInfoDto();
//        getSessionUserInfoDto.setIsGetPaid(true);
//        getSessionUserInfoDto.setSessionId(sessionId);
//        BaseResponse<CustomerInfoVo> sessionUserInfo = customerApplicationClient.getSessionUserInfo(getSessionUserInfoDto);
//        if (!ResponseResult.SUCCESS.getCode().equals(sessionUserInfo.getCode()) || sessionUserInfo.getResult() == null) {
//            throw new ServiceException(ResponseResult.NOT_LOGIN);
//        }
//        return sessionUserInfo.getResult();
        AssortmentCustomerInfoVo customerInfoVo = customerInfoManager.getCustomerInfoByObject(sessionId);
        if(customerInfoVo == null) throw new ServiceException(ResponseResult.NOT_LOGIN);;
        String jsonObject = JSON.toJSONString(customerInfoVo);
        CustomerInfoVo customerInfoVo1 = JSON.parseObject(jsonObject,CustomerInfoVo.class);
//        BeanUtil.convertBean(customerInfoVo,customerInfoVo1);
        return customerInfoVo1;
    }

    private List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> buildCoupons(List<ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon> oldCoupons, List<ChooseCouponVo> coupons){

        for(int i = 0 ; i < oldCoupons.size() ; i++){
            ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon oldCoupon = oldCoupons.get(i);
            oldCoupon.setUseIndex(i);
        }

        List<String> codes = oldCoupons.stream().map(ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon::getCode).collect(toList());

        if (coupons != null) {
            for(int x = 0 ; x < coupons.size() ; x++){
                ChooseCouponVo cp  = coupons.get(x);
                if(codes.contains(cp.getCouponCode())){
                    continue;
                }
                ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon coupon = new ActivityCalculationDiscountRequestDto.CalculationDiscountCoupon();
                coupon.setCode(cp.getCouponCode());
                coupon.setActivityCode(cp.getActivityCode());
                coupon.setUseIndex(cp.getIndex() == null ? x + oldCoupons.size():  cp.getIndex() + oldCoupons.size());
                coupon.setCouponType(cp.getCouponType());
                oldCoupons.add(coupon);
            }
        }

        return oldCoupons;
    }

    public DeliveryFeeInfo calculateDeliveryAmount(String partnerId, String province, List<CartGoods> cartGoodsList) {
        DeliveryFeeInfo deliveryFeeInfo = new DeliveryFeeInfo();
        Long deliveryAmount = 0L;
        //区code 为空则运费为0
        if (StringUtils.isBlank(province)) {
            deliveryFeeInfo.setDeliveryAmount(deliveryAmount);
            return deliveryFeeInfo;
        }
        Long orderAmount = 0L ;
        Integer orderCount = 0;
        if(null != cartGoodsList && cartGoodsList.size()>0){
            orderAmount = cartGoodsList.stream().mapToLong(CartGoods::getAmount).sum();
            orderCount = cartGoodsList.stream().mapToInt(CartGoods::getQty).sum();
        }
        QueryDeliveryTemplateRequestVo requestVo = new QueryDeliveryTemplateRequestVo(partnerId, province,Integer.valueOf(orderAmount.toString()),orderCount);
        QueryDeliveryTemplateResponseVo queryDeliveryTemplateResponseVo = deliveryFeiginClient.queryDeliveryTemplate(requestVo);
        if (!ResponseResult.SUCCESS.getCode().equals(queryDeliveryTemplateResponseVo.getCode().toString()) || queryDeliveryTemplateResponseVo.getData() == null) {
            throw new ServiceException(ResponseResult.SHOPPING_CART_QUERY_DELIVERY_TEMPLATE_ERR);
        }
        Boolean isDispatchFree = queryDeliveryTemplateResponseVo.getData().getIsDispatchFree();
        if(isDispatchFree != null && !isDispatchFree) {
            deliveryAmount = Long.valueOf(null == queryDeliveryTemplateResponseVo.getData().getFreight() ? 0 : queryDeliveryTemplateResponseVo.getData().getFreight() );
        }
        //邮费付款方式 DeliveryTemplateCostTypeEnum
        if(queryDeliveryTemplateResponseVo.getData() != null){
            deliveryFeeInfo.setCostType(queryDeliveryTemplateResponseVo.getData().getCostType());
        }
        deliveryFeeInfo.setDeliveryAmount(deliveryAmount);
        return deliveryFeeInfo;
    }

    /**
     * @param partnerId
     * @param storeId
     * @return
     */
    public boolean grayPush(String partnerId, String storeId, String version) {

        if (StringUtils.isBlank(sharing)) return false;
        CalculateCenter center = JSON.parseObject(sharing, CalculateCenter.class);
        Boolean enable = false;
        if (!center.getEnable()) return false;
        switch (center.getType()) {
            case 2:
                enable = true;
                break;
            case 1: {
                //商户+门店级别
                String real = partnerId.concat(storeId);
                if (Arrays.asList(center.getGrayList().split(",")).contains(real)) {
                    enable = true;
                }
                //商户级别
                else if (Arrays.asList(center.getGrayList().split(",")).contains(partnerId)) {
                    enable = true;
                }
            }
        }
        if (center.getEnable() && enable) {
            enable = true;
        }
        return enable;
    }

}
