package com.gree.mall.miniapp.logic.order;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.miniapp.bean.PayDetail;
import com.gree.mall.miniapp.bean.coupon.UserCouponBean;
import com.gree.mall.miniapp.bean.goods.AckGoodsBean;
import com.gree.mall.miniapp.bean.order.*;
import com.gree.mall.miniapp.bean.user.CurrentCompanyWechat;
import com.gree.mall.miniapp.bean.workorder.PgOrderSettleNormBean;
import com.gree.mall.miniapp.commonmapper.*;
import com.gree.mall.miniapp.constant.Constant;
import com.gree.mall.miniapp.enums.*;
import com.gree.mall.miniapp.enums.base.BaseEnum;
import com.gree.mall.miniapp.enums.material.GoodsMaterialTypeEnum;
import com.gree.mall.miniapp.enums.workorder.SettleNormTypeEnum;
import com.gree.mall.miniapp.exception.RemoteServiceException;
import com.gree.mall.miniapp.logic.ExpressLogic;
import com.gree.mall.miniapp.logic.FreightLogic;
import com.gree.mall.miniapp.logic.common.CommonLogic;
import com.gree.mall.miniapp.logic.common.WxPubNoticeLogic;
import com.gree.mall.miniapp.logic.common.outside.WechatLogic;
import com.gree.mall.miniapp.logic.coupon.CouponLogic;
import com.gree.mall.miniapp.logic.goods.GoodsCategoryLogic;
import com.gree.mall.miniapp.logic.goods.GoodsLogic;
import com.gree.mall.miniapp.logic.promotion.PromotionFullPieceLogic;
import com.gree.mall.miniapp.logic.promotion.PromotionGroupLogic;
import com.gree.mall.miniapp.logic.seckill.SecKillLogic;
import com.gree.mall.miniapp.logic.user.PayLogic;
import com.gree.mall.miniapp.logic.user.UserLogic;
import com.gree.mall.miniapp.plus.entity.*;
import com.gree.mall.miniapp.plus.service.*;
import com.gree.mall.miniapp.utils.ArithUtils;
import com.gree.mall.miniapp.utils.CommonUtils;
import com.gree.mall.miniapp.utils.DateUtils;
import com.gree.mall.miniapp.utils.IpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderLogic {

    @Autowired
    GoodsLogic goodsLogic;
    @Autowired
    CouponLogic couponLogic;
    @Autowired
    WechatLogic wechatLogic;
    @Autowired
    RedisLockRegistry redisLockRegistry;
    @Autowired
    CommonLogic commonLogic;
    @Autowired
    PromotionGroupLogic promotionGroupLogic;
    @Autowired
    private GoodsCategoryLogic goodsCategoryLogic;
    @Autowired
    private SecKillLogic secKillLogic;
    @Autowired
    private FreightLogic freightLogic;
//    @Autowired
//    GongdanLogic gongdanLogic;
    @Autowired
    PayLogic payLogic;
    @Autowired
    ExpressLogic expressLogic;
    @Autowired
    UserLogic userLogic;
    @Autowired
    PromotionFullPieceLogic promotionFullPieceLogic;
    @Autowired
    SecActivityStageMapper secActivityStageMapper;
    @Autowired
    GiftExchangeCodeService giftExchangeCodeService;
    @Autowired
    OrderInfoService orderInfoService;
    @Autowired
    OrderRefundService orderRefundService;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    UserService userService;
    @Autowired
    UserAddressService userAddressService;
    @Autowired
    ShoppingCartService shoppingCartService;
    @Autowired
    FreightTemplateDetailService freightTemplateDetailService;
    @Autowired
    OrderShareService orderShareService;
    @Autowired
    AppMapper appMapper;
    @Autowired
    SecKillActivityService secKillActivityService;
    @Autowired
    SecKillActivitySpecService secKillActivitySpecService;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    CouponGoodsService couponGoodsService;
    @Autowired
    private SoldNumMapper soldNumMapper;
    @Autowired
    OrderRequestService orderRequestService;
    @Autowired
    PromotionGroupSpecUserService promotionGroupSpecUserService;
    @Autowired
    AdminWebsitService adminWebsitService;
//    @Autowired
//    EnterpriseWechatWorkerService enterpriseWechatWorkerService;
    @Autowired
    PromotionDiscountService promotionDiscountService;
    @Autowired
    CategoryMapper categoryMapper;
    @Autowired
    GoodsPackagePopService goodsPackagePopService;
    @Autowired
    GoodsPackageUserRelaService goodsPackageUserRelaService;
    @Autowired
    ExternalUserService externalUserService;
    @Autowired
    PgOrderSettleNormService pgOrderSettleNormService;
    @Autowired
    WxPubNoticeLogic wxPubNoticeLogic;
    @Autowired
    PgOrderWorkerService pgOrderWorkerService;
    @Autowired
    PgOrderSettleWorkerService pgOrderSettleWorkerService;

    @Autowired
    AdminUserService adminUserService;

    @Autowired
    AdminUserWebsitRelaService adminUserWebsitRelaService;
    @Autowired
    GoodsMaterialService goodsMaterialService;
    @Autowired
    GoodsMaterialItemService goodsMaterialItemService;
    @Autowired
    OrderOfflineRefundService orderOfflineRefundService;

    @Autowired
    OrderOldProductService orderOldProductService;

    @Autowired
    OrderOldProductItemService  orderOldProductItemService;

    @Autowired
    GoodsCategoryItemService goodsCategoryItemService;

    @Autowired
    GoodsCategoryService goodsCategoryService;


    /**
     * 立即购买
     */
    @Transactional
    public PayDetail buy(OrderBuyBean orderBuyBean,HttpServletRequest request) throws Exception {
        String ip = IpUtil.getIpAddr(request);
        if(StringUtils.isBlank(orderBuyBean.getUserAddressId())){
            throw new RemoteServiceException(1100,"请选择收货地址");
        }
        CurrentCompanyWechat currentCompanyWechat = commonLogic.getCurrentCompanyWechat(request);
        //订单
        OrderInfo orderInfo = new OrderInfo();
        String orderId = currentCompanyWechat.getOrderPrefix() + IdWorker.getIdStr();
        orderInfo.setOrderId(orderId);
        orderInfo.setIsOld(orderBuyBean.getIsOld());
        //购买人
        String userId = currentCompanyWechat.getUserId();
        User user = currentCompanyWechat.getUser();
        //分销员
        String serviceId = user.getServiceId();
        if(user.getType().equals(UserTypeEnum.SERVICE.toString())) {
            serviceId = user.getUserId();
        }
        User service = userService.getById(serviceId);
        //商品总金额(不包含运费，优惠金额，非实际支付金额)
        BigDecimal totalPrice = BigDecimal.valueOf(0);
        //商品实际支付总金额
        BigDecimal totalPayAmount = BigDecimal.valueOf(0);
        //运费总额
        BigDecimal totalFreight = BigDecimal.valueOf(0);
        //订单标题
        String orderTitle = "";
        //分账金额
        BigDecimal shareAmount = BigDecimal.valueOf(0);
        //非团购商品的分账金额
        BigDecimal notPromotionShareAmount = BigDecimal.valueOf(0);
        //总数量
        Integer totalNum = 0;
        //兑换码
        String exchangeCode = orderBuyBean.getExchangeCode();
        //是否有使用了礼品码的商品
        Boolean hasGiftCode = false;
        //收获地址
        UserAddress userAddress = userAddressService.getById(orderBuyBean.getUserAddressId());
        //团长id
        String promotionGroupUserId = "";
        String orderPromotionGroupId = "";
        List<String> goodsIds = orderBuyBean.getBuyGoods().stream().map(BuyGood::getGoodsId).collect(Collectors.toList());
        //满件折扣活动
        Boolean promotionFullPiece = false;
        String promotionFullPieceId = "";
        String promotionFullPieceRemark = "";
        List<PromotionFullPieceItem> promotionFullPieceItems = promotionFullPieceLogic.getItems();

        //购物车ids
        List<String> shoppingCartIds = orderBuyBean.getBuyGoods().stream().map(BuyGood::getShoppingCartId).collect(Collectors.toList());
        //如果用户存在，则判断是否为业务员，并更新相关信息
        if (!user.getStatus()) {
            throw new RemoteServiceException(1100,"用户已被冻结");
        }

        //这里面会处理各个活动对单价以及佣金金额的处理
        List<BuyGood> buyGoods = this.supplyBuyBoods(orderBuyBean, user);

        //以旧换新
        OrderOldProduct orderOldProduct = handleOldProduct(orderBuyBean, orderId, currentCompanyWechat.getYjhxDkFlag());

        //订单详情
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (BuyGood buyGood : buyGoods) {
            String promotionGroupId = buyGood.getPromotionGroupId();
            if(StringUtils.isBlank(orderPromotionGroupId)) {
                orderPromotionGroupId = buyGood.getPromotionGroupId();
            }
            String secKillId = buyGood.getSecKillId();
            //商品
            Goods goods = buyGood.getGoods();
            if(!goods.getStatus()){
               throw new RemoteServiceException("存在已下架商品:"+goods.getGoodsName());
            }
            //处理库存并返回商品规格
            GoodsSpec goodsSpec = this.stock(buyGood.getGoodsSpecId(), goods.getGoodsName(), buyGood.getNum());
            //礼品卡商品(此处会重置规格的价格)
            Boolean isGift = this.giftGoods(userId,exchangeCode,true,goods, goodsSpec,buyGood.getNum());
            if(!hasGiftCode)
                hasGiftCode = isGift;

            String goodsId = goodsSpec.getGoodsId();
            String goodsSpecId = goodsSpec.getGoodsSpecId();
            String goodsSpecName = goodsSpec.getName();
            String goodsSpecValue = goodsSpec.getSpecValue();
            String goodsName = goods.getGoodsName();
            //BigDecimal goodsShareAmount = goodsSpec.getShareAmount();
            //BigDecimal goodsSecPrice = goodsSpec.getPrice();
            BigDecimal goodsShareAmount = buyGood.getShareAmount();
            BigDecimal goodsSecPrice = buyGood.getPrice();
            String catagoryId = goods.getCategoryId();
            String userCouponId = orderBuyBean.getUserCouponId();
            BigDecimal cutAmount = new BigDecimal("0");

            //内部价格处理
            if(service != null
                    && service.getType().equals(UserTypeEnum.SERVICE.toString())
                    && service.getInnerr()
                    && !buyGood.getIsPromotionGroup()
                    && !buyGood.getIsSecKill()
                    && !buyGood.getIsGoodsPackage()){
                goodsShareAmount = goodsSpec.getInnerShareAmount();
            }

            GoodsMaterial gm = goodsMaterialService.getById(goodsSpec.getGoodsCode());
//            if(gm == null){
//                throw new RemoteServiceException("商品物料不存在，请联系相关人员");
//            }
            List<GoodsMaterialItem> list = goodsMaterialItemService.lambdaQuery().eq(GoodsMaterialItem::getGoodsMaterialId, goodsSpec.getGoodsCode()).list();
            Integer insideQty = list.stream().filter(v -> v.getType().equals(GoodsMaterialTypeEnum.INSIDE.getKey())).map(GoodsMaterialItem::getQty).reduce(Integer::sum).orElse(0);
            Integer outQty = list.stream().filter(v -> v.getType().equals(GoodsMaterialTypeEnum.OUT.getKey())).map(GoodsMaterialItem::getQty).reduce(Integer::sum).orElse(0);
            Integer partsQty = list.stream().filter(v -> v.getType().equals(GoodsMaterialTypeEnum.PARTS.getKey())).map(GoodsMaterialItem::getQty).reduce(Integer::sum).orElse(0);

            log.info("是否为礼品卡商品：{},金额:{}",isGift,goodsSecPrice);

            //活动和优惠券不能一起使用
            if(StringUtils.isNotBlank(userCouponId)
     //               && (StringUtils.isNotBlank(promotionGroupId) || StringUtils.isNotBlank(secKillId) || isGift || StringUtils.isNotBlank(exchangeCode))){
                    && ( isGift || StringUtils.isNotBlank(exchangeCode) || buyGood.getIsPromotionGroup())){
                throw new RemoteServiceException(1100,"活动商品不可使用优惠券");
            }

            OrderDetail orderDetail = new OrderDetail();
            //默认的分佣人是分销员
            orderDetail.setShareUserId(serviceId);
            //秒杀活动
            if (buyGood.getIsSecKill()) {
                SecKillActivitySpec kill = secKillLogic.getStock(secKillId,buyGood.getGoodsSpecId(),buyGood.getNum());

                orderDetail.setSecKill(true);
                orderDetail.setSecKillId(secKillId);
                orderDetail.setSecKillSpecId(kill.getSecKillSpecId());
            }
            //团购活动
            if(buyGood.getIsPromotionGroup()) {
                PromotionGroupSpecUser promotionGroupSpecUser = promotionGroupLogic.getStock(user.getPromotionGroupUserId(), buyGood.getGoodsSpecId(),buyGood.getNum());
                promotionGroupUserId = promotionGroupSpecUser.getUserId();

                orderDetail.setPromotionGroupId(promotionGroupId);
                orderDetail.setShareUserId(promotionGroupUserId);
            }
            orderDetail.setPayAmount(goodsSecPrice.multiply(new BigDecimal(buyGood.getNum())));
            //满件打折
            PromotionFullPieceItem promotionFullPieceItem = this.getPromotionFullPieceItem(buyGoods, promotionFullPieceItems, goods);
            if (promotionFullPiece != null && promotionFullPieceItem != null) {
                BigDecimal sub = BigDecimal.valueOf(1).subtract(promotionFullPieceItem.getDiscountRate());
                BigDecimal fullDiscountAmount = goodsSecPrice.multiply(BigDecimal.valueOf(buyGood.getNum()))
                        .multiply(sub).setScale(2, BigDecimal.ROUND_HALF_UP);
                //记录id
                promotionFullPieceId = promotionFullPieceItem.getPromotionFullPieceId();
                //打折说明
                promotionFullPieceRemark = this.getPromotionFullPieceRemark(promotionFullPieceItem);
                //标记为满件打折活动
                promotionFullPiece = true;

                orderDetail.setPromotionFullPieceId(promotionFullPieceItem.getPromotionFullPieceId());
                orderDetail.setPromotionFullPieceDiscountRate(promotionFullPieceItem.getDiscountRate());
                orderDetail.setPromotionFullPieceShareRate(promotionFullPieceItem.getShareRate());
                orderDetail.setDiscountAmount(fullDiscountAmount);
                orderDetail.setFullDiscountAmount(fullDiscountAmount.divide(BigDecimal.valueOf(buyGood.getNum())).setScale(2, BigDecimal.ROUND_HALF_UP));
                orderDetail.setFullTotalDiscountAmount(fullDiscountAmount);
                orderDetail.setPayAmount(goodsSecPrice.multiply(BigDecimal.valueOf(buyGood.getNum()))
                        .subtract(fullDiscountAmount));
            }


            orderDetail.setOrderId(orderId);
            orderDetail.setPromotionGroupId(promotionGroupId);
            orderDetail.setGoodsId(goodsId);
            orderDetail.setGoodsName(goodsName);
            orderDetail.setGoodsSpecId(goodsSpecId);
            orderDetail.setGoodsSpecName(goodsSpecName);
            orderDetail.setGoodsSpecValue(goodsSpecValue);
            orderDetail.setIsGift(isGift);

            if (StringUtils.isNotBlank(catagoryId)) {
                GoodsCategory goodsCategory = goodsCategoryLogic.queryById(catagoryId);
                if(goodsCategory != null) {
                    orderDetail.setMainNumber(goodsCategory.getMainNumber());
                    orderDetail.setMainName(goodsCategory.getMainName());
                    orderDetail.setSmallNumber(goodsCategory.getSmallNumber());
                    orderDetail.setSmallName(goodsCategory.getSmallName());
                    orderDetail.setGoodsCategoryId(goodsCategory.getCategoryId());
                    orderDetail.setGoodsCategoryName(goodsCategory.getName());
                    orderDetail.setWorkOrderType(goodsCategory.getWorkOrderType());
                }
            }
            orderDetail.setPrice(goodsSecPrice);
            orderDetail.setNeedPayAmount(goodsSecPrice);
            orderDetail.setNum(buyGood.getNum());
            orderDetail.setTotalPrice(goodsSecPrice.multiply(new BigDecimal(buyGood.getNum())));
            orderDetail.setShareAmount(goodsShareAmount.multiply(new BigDecimal(buyGood.getNum())));
            orderDetail.setCutAmount(cutAmount);
            orderDetail.setTotalCutAmount(cutAmount.multiply(new BigDecimal(buyGood.getNum())));
            orderDetail.setProfitAmount(orderDetail.getTotalPrice().subtract(orderDetail.getShareAmount()));
            orderDetail.setImgUrl(goodsSpec.getImgUrl());
            orderDetail.setCreateTime(new Date());
            orderDetail.setMarketingId(goods.getMarketingId());
            orderDetail.setMarketingName(goods.getMarketingName());
            orderDetail.setIsVr(goods.getIsVr());
            orderDetail.setOrderSmallType(goods.getOrderSmallType());
            orderDetail.setBrandId(goods.getBrandId());
            orderDetail.setBrandName(goods.getBrandName());
            orderDetail.setInsideNum(insideQty * orderDetail.getNum());
            orderDetail.setOutNum(outQty * orderDetail.getNum());
            orderDetail.setPartNum(partsQty * orderDetail.getNum());
            if(gm != null) {
                orderDetail.setGoodsMaterialId(gm.getId());
                orderDetail.setGoodsMaterialName(gm.getGoodsName());
                orderDetail.setGoodsMaterialSpecsName(gm.getSpecsName());
                orderDetail.setGoodsMaterialUnit(gm.getUnit());
            }
            orderDetail.setMainNumber(goodsSpec.getMainId());
            orderDetail.setMainName(goodsSpec.getMainName());
            orderDetail.setSmallNumber(goodsSpec.getSmallId());
            orderDetail.setSmallName(goodsSpec.getSmallName());
            orderDetail.setFlag(1);

            //以旧换新
            if(orderOldProduct != null && orderOldProduct.getYjhxDkFlag() == 1) {
                BigDecimal yjhxDiscountAmount = orderOldProduct.getPayAmount();
                orderDetail.setPayAmount(orderDetail.getPayAmount().subtract(yjhxDiscountAmount));
                orderDetail.setYjhxDiscountAmount(yjhxDiscountAmount);
            }

            BigDecimal freightAmountItem = this.getFreightAmountItem(userAddress.getProvince(), userAddress.getCity(), userAddress.getArea(), buyGood,currentCompanyWechat);
            orderDetail.setFreight(freightAmountItem);

            orderDetails.add(orderDetail);

            totalPrice = totalPrice.add(orderDetail.getTotalPrice());
            totalPayAmount = totalPayAmount.add(orderDetail.getPayAmount());
            totalFreight = totalFreight.add(freightAmountItem);
            orderTitle += goods.getGoodsName() + ",";
            totalNum += buyGood.getNum();
            //orderTitle += goods.getGoodsName() + ",";
            shareAmount = orderDetail.getShareAmount().add(shareAmount);
            if(StringUtils.isBlank(orderDetail.getPromotionGroupId())){
                notPromotionShareAmount = notPromotionShareAmount.add(orderDetail.getShareAmount());
            }
        }
        //补充网点师傅相关信息
        this.supplyWorkUser(orderInfo, user);

        //实际需要支付的金额(包含运费)
        BigDecimal payAmount = totalPayAmount.add(totalFreight);

        //生成订单
        orderInfo.setIsAllVr(orderDetails.stream().filter(v -> !v.getIsVr()).count() == 0);
        //orderInfo.setIsAddCorp(yrzqw > 0);
        orderInfo.setBuyerMsg(orderBuyBean.getBuyerMsg());
        orderInfo.setOrderStatus(OrderStatusEnum.NOPAY.toString());
        orderInfo.setUserId(user.getUserId());
        orderInfo.setUserName(user.getNickName());
        orderInfo.setPhone(user.getMobile());
        orderInfo.setExchangeCode(exchangeCode);
        //orderInfo.setExchangeSubAmount(subAmount);
        orderInfo.setPromotionGroupId(orderPromotionGroupId);
        orderInfo.setPromotionGroupUserId(promotionGroupUserId);
        orderInfo.setUserAddressId(userAddress.getUserAddressId());
        orderInfo.setReceUserName(userAddress.getName());
        orderInfo.setReceAddress(userAddress.getAddress());
        orderInfo.setRecePhone(userAddress.getPhone());
        orderInfo.setProvince(userAddress.getProvince());
        orderInfo.setCity(userAddress.getCity());
        orderInfo.setArea(userAddress.getArea());
        orderInfo.setStreet(userAddress.getStreet());
        orderInfo.setHouseNo(userAddress.getHouseNo());
        orderInfo.setCreateTime(new Date());
        orderInfo.setFreight(totalFreight);
        orderInfo.setTotalAmount(totalPrice);
        orderInfo.setPayAmount(payAmount);
        orderInfo.setPromotionPackageGoodsId(orderBuyBean.getGoodsPackageId());
        orderInfo.setPayTypeId(orderBuyBean.getPayTypeId());
        orderInfo.setPayType(BaseEnum.keyToEnum(PayTypeEnum.class,orderBuyBean.getPayTypeId()).getRemark());
        //检查优惠券的使用合法性
        //if(!isPromotion && !hasGiftCode) {
            UserCouponBean userCoupon = couponLogic.check(orderBuyBean.getUserCouponId(), totalPrice, goodsIds,true);
//            if(userCoupon == null){
//                throw new RemoteServiceException("优惠券暂不可用，请联系相关人员");
//            }
            if (userCoupon != null && this.checkPackageUseCoupon(orderBuyBean.getGoodsPackageId(),userCoupon)) {
                orderInfo.setDiscountAmount(userCoupon.getCouponValue());
                orderInfo.setCouponId(userCoupon.getCouponId());
                orderInfo.setCouponName(userCoupon.getCouponName());
                orderInfo.setCouponValue(userCoupon.getCouponValue());
                orderInfo.setUserCouponId(userCoupon.getId());

                //检查是否优惠超过50%，如果超过，拒绝下单
                BigDecimal divide = totalPrice.divide(userCoupon.getCouponValue(), 3, RoundingMode.HALF_UP);
                if(divide.doubleValue() < 2){
                    throw new RemoteServiceException("优惠券抵扣额度不可超订单价格50%");
                }

                //扣减优惠券金额
                orderInfo.setPayAmount(orderInfo.getPayAmount().subtract(orderInfo.getDiscountAmount()));
            }
        //}
        orderInfo.setTotalNum(totalNum);
        orderInfo.setTotalShareAmount(shareAmount);
        if(StringUtils.isNotBlank(orderTitle) && orderTitle.length() > 0) {
            orderTitle = orderTitle.substring(0,orderTitle.length() - 1);
            orderInfo.setOrderTitle(orderTitle);
        }
        orderInfo.setTotalProductAmount(totalPrice);
        orderInfo.setCompanyWechatId(currentCompanyWechat.getCompanyWechatId());
        orderInfo.setCompanyWechatName(currentCompanyWechat.getCompanyName());
        orderInfo.setDispatchType(orderBuyBean.getDispatchType());
        orderInfo.setPromotionFullPieceId(promotionFullPieceId);
        orderInfo.setPromotionFullPieceRemark(promotionFullPieceRemark);

        //以旧换新
        if(orderOldProduct != null) {
            //明细已经扣了，这里不需要再扣了
            BigDecimal yjhxDiscountAmount = orderOldProduct.getPayAmount();
            //orderInfo.setPayAmount(orderInfo.getPayAmount().subtract(yjhxDiscountAmount));
            orderInfo.setYjhxDiscountAmount(yjhxDiscountAmount);
            orderInfo.setYjhxDkFlag(orderOldProduct.getYjhxDkFlag());
        }

        //支付金额不可为负数
        if(orderInfo.getPayAmount().doubleValue() < 0){
            throw new RemoteServiceException("优惠金额超出，请联系客服");
        }
//        orderInfo.setPayAmount(
//                orderInfo.getPayAmount().doubleValue()
//                        < 0 ? BigDecimal.valueOf(0)
//                        : orderInfo.getPayAmount());

        //来源
        if(orderBuyBean.getMiniPay() != null && orderBuyBean.getMiniPay()){
            orderInfo.setSource(OrderInfoSourceEnum.A.getRemark());
        }else{
            orderInfo.setSource(OrderInfoSourceEnum.B.getRemark());
        }

        orderInfoService.save(orderInfo);
        //新增订单详情
        orderDetailService.saveBatch(orderDetails);
        //检查清掉购物车
        if (!CollectionUtils.isEmpty(shoppingCartIds)) {
            shoppingCartService.lambdaUpdate().in(ShoppingCart::getShoppingCartId, shoppingCartIds).remove();
        }
        //代客下单
        if (orderBuyBean.getProxyUser()) {
            PayDetail payDetail = new PayDetail();
            payDetail.setIsPay(false);
            payDetail.setId(orderInfo.getOrderId());
            payDetail.setCodeUrl(wechatLogic.getQrcode(QrCodeEnum.ORDER.toString().toLowerCase(Locale.ROOT),
                    orderInfo.getOrderId(), orderInfo.getUserId(),user.getCompanyWechatId()));
            return payDetail;
        }
        //调起支付
        String profitSharingFlag = "N";
        BigDecimal zero = new BigDecimal("0.00");
        if (shareAmount.compareTo(zero) > 0) {
            profitSharingFlag = "Y";
        }

        PayDetail payDetail = new PayDetail();
        payDetail.setId(orderInfo.getOrderId());

        //if(orderBuyBean.getWechatPay()) {
        if(!StringUtils.equals(orderBuyBean.getPayTypeId(),PayTypeEnum.STORE.getKey())) {
            if (orderBuyBean.getH5Pay() != null && orderBuyBean.getH5Pay()) {
                payDetail = wechatLogic.paymentH5(orderInfo.getOrderId(), orderInfo.getPayAmount(), user.getOpenId(),
                        profitSharingFlag, ip, user.getCompanyWechatId());
            } else {
                payDetail = wechatLogic.payment(orderInfo.getOrderId(), orderInfo.getPayAmount(),
                        orderBuyBean.getMiniPay() != null && orderBuyBean.getMiniPay() ? orderBuyBean.getOpenId() : user.getOpenId(),
                        profitSharingFlag, ip, user.getCompanyWechatId(), orderBuyBean.getMiniPay());
            }
        }else{
            payDetail.setIsPay(false);
        }

        //不需要支付
        if (!payDetail.getIsPay()) {
            payLogic.payCall(payDetail.getId(), "", orderInfo.getPayAmount());
        }
        //}
        return payDetail;
    }


    /**
     * 处理旧机
     * @param orderBuyBean
     * @param orderId
     * @param yjhxDkFlag
     * @return
     */
    private OrderOldProduct handleOldProduct(OrderBuyBean orderBuyBean,String orderId,Integer yjhxDkFlag){
        //以旧换新
        if (orderBuyBean.getOrderOldProductAdds() != null) {

            List<OrderOldProductItem> orderOldProductItems = new ArrayList<>();

            GoodsCategoryItem goodsCategoryItemDto = goodsCategoryItemService.getById(orderBuyBean.getOrderOldProductAdds().getId());

            GoodsCategory goodsCategory = goodsCategoryService.getById(goodsCategoryItemDto.getMainId());
            GoodsCategory goodsCategorySmall = goodsCategoryService.getById(goodsCategoryItemDto.getSmallId());

            OrderOldProduct orderOldProduct = new OrderOldProduct();
            this.productCategory(orderOldProduct, goodsCategoryItemDto);
            orderOldProduct.setId(null);
            orderOldProduct.setSaleType(1);
            orderOldProduct.setOrderId(orderId);
            orderOldProduct.setId(IdWorker.getIdStr());
            orderOldProduct.setNum(1);
            orderOldProduct.setYjhxDkFlag(yjhxDkFlag);
            orderOldProduct.setPrice(goodsCategoryItemDto.getPrice());
            orderOldProduct.setPayAmount(goodsCategoryItemDto.getPrice());

            orderOldProduct.setMainImg(goodsCategory.getImgUrl());
            orderOldProduct.setSmallImg(goodsCategorySmall.getImgUrl());

            for (String goodsCategoryItem : orderBuyBean.getOrderOldProductAdds().getItemIds()) {
                GoodsCategoryItem goodsCategoryItems = goodsCategoryItemService.getById(goodsCategoryItem);
                OrderOldProductItem orderOldProductItem = this.productCategoryItem(goodsCategoryItems);
                orderOldProductItem.setId(null);
                orderOldProductItem.setGoodsCategoryItemId(goodsCategoryItems.getId());
                orderOldProductItem.setOrderId(orderOldProduct.getOrderId());
                orderOldProductItem.setOrderOldProductId(orderOldProduct.getId());
                orderOldProduct.setPayAmount(orderOldProduct.getPayAmount().add(goodsCategoryItems.getPrice()));
                orderOldProductItems.add(orderOldProductItem);
            }

            orderOldProductService.lambdaUpdate().eq(OrderOldProduct::getOrderId,orderId).remove();
            orderOldProductItemService.lambdaUpdate().eq(OrderOldProductItem::getOrderId,orderId).remove();
            orderOldProductService.save(orderOldProduct);

            if (!org.springframework.util.CollectionUtils.isEmpty(orderOldProductItems)){
                orderOldProductItemService.saveBatch(orderOldProductItems);
            }

            return orderOldProduct;
        }
        return null;
    }


    private OrderOldProductItem productCategoryItem(GoodsCategoryItem goodsCategoryItem) {
        OrderOldProductItem orderOldProductItem = BeanUtil.toBean(goodsCategoryItem, OrderOldProductItem.class);
        return orderOldProductItem;
    }

    private void productCategory(OrderOldProduct orderOldProduct, GoodsCategoryItem goodsCategoryItem) {
        BeanUtil.copyProperties(goodsCategoryItem,orderOldProduct);
        orderOldProduct.setPrice(goodsCategoryItem.getPrice());
        orderOldProduct.setSpecId(goodsCategoryItem.getId());
        orderOldProduct.setSpecName(goodsCategoryItem.getDictName());
    }



    /**
     * 查询当前可用的满件折扣活动规则
     * @param buyGoods
     * @param items
     * @return
     */
    private PromotionFullPieceItem getPromotionFullPieceItem(List<BuyGood> buyGoods,List<PromotionFullPieceItem> items,Goods goods){
        if(!goods.getPromotionFullPiece()){
            return null;
        }
        //参与活动的总商品数量
        int total = buyGoods.stream().filter(BuyGood::getPromotionFullPiece).mapToInt(BuyGood::getNum).sum();
        //总优惠金额
        for(PromotionFullPieceItem item : items){
            if(total >= item.getSatisfyNum()){
                return item;
            }
        }
        return null;
    }


    private String getPromotionFullPieceRemark(PromotionFullPieceItem item){
        if(item == null)
            return "";
        return "满"+item.getSatisfyNum()+"件打"+item.getDiscountRate().multiply(BigDecimal.valueOf(10))+"折";
    }


    /**
     * 维护兑换码抵扣金额对订单详情商品的影响
     */
    private void supplyOrderDetail(List<OrderDetail> orderDetails,BigDecimal exchangeAmount,BigDecimal notPromotionGroupAmount){

        List<OrderDetail> ods = orderDetails.stream().filter(v -> StringUtils.isBlank(v.getPromotionGroupId())).collect(Collectors.toList());
        if(ods.size() == 0){
            return;
        }
        if(exchangeAmount == null || exchangeAmount.doubleValue() == 0){
            return;
        }
        BigDecimal totalSubAmount = BigDecimal.valueOf(0);
        for(int i = 0; i < ods.size();i++){
            OrderDetail orderDetail = ods.get(i);
            if(i == ods.size() - 1){
                //最后一个，直接用总数减掉
                BigDecimal subtract = exchangeAmount.subtract(totalSubAmount);
                orderDetail.setShareAmount(orderDetail.getShareAmount().subtract(subtract));
                orderDetail.setTotalExchangeAmount(subtract);

                double div = ArithUtils.div(subtract.doubleValue(), orderDetail.getNum(), 2);
                orderDetail.setExchangeAmount(BigDecimal.valueOf(div));
                break;
            }
            //该商品的总抵扣金额
            double div = ArithUtils.div(orderDetail.getShareAmount().doubleValue(), notPromotionGroupAmount.doubleValue(), 4);
            double mul = ArithUtils.mul(div, exchangeAmount.doubleValue());
            BigDecimal subAmount = BigDecimal.valueOf(mul);
            //该商品数量1情况下的抵扣金额
            double div1 = ArithUtils.div(subAmount.doubleValue(), orderDetail.getNum(), 2);

            orderDetail.setShareAmount(orderDetail.getShareAmount().subtract(subAmount));
            orderDetail.setTotalExchangeAmount(subAmount);
            orderDetail.setExchangeAmount(BigDecimal.valueOf(div1));
            //记录已经分配了多少抵扣金额
            totalSubAmount = totalSubAmount.add(subAmount);
        }

    }


    /**
     * 补充网点师傅信息
     * @param orderInfo
     * @param user
     */
    private void supplyWorkUser(OrderInfo orderInfo,User user){
        if (user.getType().equals(UserTypeEnum.SERVICE.toString()) || user.getType().equals(UserTypeEnum.WORKER.getKey())) {
            orderInfo.setWorkerId(user.getUserId());
            orderInfo.setWorkerName(user.getNickName());
            orderInfo.setWorkerPhone(user.getMobile());
            orderInfo.setPosition(user.getPosition());
        } else {
            //非业务员那就找到业务员
            if (StringUtils.isNotBlank(user.getServiceId())) {
                User workUser = userService.getById(user.getServiceId());
                if (workUser != null) {
                    orderInfo.setWorkerId(workUser.getUserId());
                    orderInfo.setWorkerName(workUser.getNickName());
                    orderInfo.setWorkerPhone(workUser.getMobile());
                    orderInfo.setPosition(workUser.getPosition());
                    if (workUser.getCustomerServiceFlag() != null && workUser.getCustomerServiceFlag()) {
                        orderInfo.setSource("svip邀请");
                    }
                }
            }
        }
    }


    /**
     * 支付待支付订单
     */
    @Transactional
    public PayDetail waitPayOrder(String userId, String orderId, String ip,HttpServletRequest request,Boolean miniPay,String openId) throws Exception {
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        //订单
        CurrentCompanyWechat currentCompanyWechat = commonLogic.getCurrentCompanyWechat(request);
        String newOrderId = currentCompanyWechat.getOrderPrefix()+IdWorker.getIdStr();

        if(orderInfo.getPromotionApplyStatus() != null && orderInfo.getPromotionApplyStatus() == 1){
            throw new RemoteServiceException("正在申请优惠中请耐心等待");
        }
        if (StringUtils.isNotBlank(userId) && !userId.equals(orderInfo.getUserId())) {
            User user = userService.getById(userId);
            if (user.getType().equals(UserTypeEnum.SERVICE.toString())) {
                throw new RemoteServiceException("业务员不可替业务员下单");
            }

            //绑定客户关系
            if (StringUtils.isBlank(user.getServiceId())) {
                user.setServiceId(orderInfo.getUserId());
                user.setServiceTime(new Date());
                user.updateById();
            }

            if (!orderInfo.getOrderStatus().equals(OrderStatusEnum.NOPAY.toString())) {
                throw new RemoteServiceException("订单已超时取消或已支付成功");
            }

            //将订单绑定给用户
            orderInfo.setUserId(userId);
            orderInfo.setUserName(user.getNickName());
            orderInfo.setPhone(user.getMobile());
            orderInfo.updateById();

        }

        if ( miniPay != null && miniPay) {
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfo::getOrderId, orderId)
                    .set(OrderInfo::getSource, OrderInfoSourceEnum.A.getRemark())
                    .update();
        }else {
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfo::getOrderId, orderId)
                    .set(OrderInfo::getSource, OrderInfoSourceEnum.B.getRemark())
                    .update();
        }

        orderInfoService.lambdaUpdate().set(OrderInfo::getOrderId,newOrderId).eq(OrderInfo::getOrderId,orderId).update();
        orderDetailService.lambdaUpdate().set(OrderDetail::getOrderId,newOrderId).eq(OrderDetail::getOrderId,orderId).update();

        User user = userService.getById(orderInfo.getUserId());
        String profitSharingFlag = "N";
        BigDecimal zero = new BigDecimal("0.00");
        if (orderInfo.getTotalShareAmount().compareTo(zero) > 0) {
            profitSharingFlag = "Y";
        }
        PayDetail payDetail = wechatLogic.payment(newOrderId, orderInfo.getPayAmount(),miniPay != null && miniPay?openId:user.getOpenId(),
                profitSharingFlag, ip,user.getCompanyWechatId(),miniPay);
        return payDetail;
    }


    /**
     * 订单列表
     *
     * @return
     */
    public IPage<OrderDetailBean> list(String userId, String orderStatus,Integer promotionApplyStatus, Integer pageNum, Integer pageSize) {
        User user = userService.getById(userId);
        List<Integer> promotionApplyStatusList = new ArrayList<>();
        if(promotionApplyStatus != null) {
            if (promotionApplyStatus == 100) {
                promotionApplyStatusList.add(0);
                promotionApplyStatusList.add(1);
                promotionApplyStatusList.add(2);
                promotionApplyStatusList.add(3);
                promotionApplyStatusList.add(4);
            } else if (promotionApplyStatus == 2) {
                promotionApplyStatusList.add(2);
                promotionApplyStatusList.add(4);
            } else {
                promotionApplyStatusList.add(promotionApplyStatus);
            }
            userId = null;
        }
        List<String> orderStatusList = new ArrayList<>();
        if(StringUtils.isNotBlank(orderStatus)) {
            orderStatusList.add(orderStatus);
            if (StringUtils.equals(orderStatus, OrderStatusEnum.CLOSE.toString())) {
                orderStatusList.add(OrderStatusEnum.REFUND.toString());
            }
            if(StringUtils.equals(orderStatus,OrderStatusEnum.YFH.toString())){
                orderStatusList.add(OrderStatusEnum.DFH.toString());
            }
        }

        IPage page = orderInfoService.lambdaQuery()
                .ne(OrderInfo::getOrderStatus,OrderStatusEnum.TIMEOUT.toString())
                .in(CollectionUtils.isNotEmpty(orderStatusList), OrderInfo::getOrderStatus, orderStatusList)
                .eq(StringUtils.equals(orderStatus,OrderStatusEnum.OVER.toString()),OrderInfo::getCommentGoods,0)
                .eq(StringUtils.equals(user.getType(),UserTypeEnum.GENERAL.getKey()),OrderInfo::getUserId, userId)
                .and(!StringUtils.equals(user.getType(),UserTypeEnum.GENERAL.getKey()), v -> v.eq(OrderInfo::getUserId,user.getUserId())
                        .or().eq(OrderInfo::getWorkerId,user.getUserId()))
                .in(!CollectionUtils.isEmpty(promotionApplyStatusList),OrderInfo::getPromotionApplyStatus,promotionApplyStatusList)
                .eq(!CollectionUtils.isEmpty(promotionApplyStatusList),OrderInfo::getWorkerId,user.getUserId())
                .and(promotionApplyStatus != null && promotionApplyStatus == 100,v ->
                        v.eq(OrderInfo::getOrderStatus,OrderStatusEnum.NOPAY.toString())
                                .or().ne(OrderInfo::getOrderStatus,OrderStatusEnum.NOPAY.toString()).ne(OrderInfo::getPromotionApplyStatus,0)
                )
                .orderByDesc(OrderInfo::getCreateTime)
                .page(new Page<>(pageNum, pageSize));

        List<OrderDetailBean> list = new ArrayList<>();
        for (Object o : page.getRecords()) {
            OrderInfo orderInfo = (OrderInfo) o;
            OrderDetailBean orderDetailBean = new OrderDetailBean();
            BeanUtils.copyProperties(orderInfo, orderDetailBean);
            List<OrderShare> list1 = orderShareService
                    .lambdaQuery()
                    .eq(OrderShare::getOrderId, orderInfo.getOrderId())
                    .list();
            if (list1 != null && list1.size() > 0) {
                //此处list1目前最多2条
                for(OrderShare orderShare : list1) {
                    orderDetailBean.setOrderShareStatus(orderShare.getStatus());
                }
            }
            //查询订单详情
            List<OrderDetail> orderDetails = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderInfo.getOrderId()).list();
            orderDetailBean.setOrderDetails(orderDetails);
            orderDetailBean.setIsShareOrder(!StringUtils.equals(orderInfo.getUserId(),user.getUserId()));
            list.add(orderDetailBean);
        }
        page.setRecords(list);
        return page;
    }


    /**
     * 订单超时取消
     */
    @Transactional
    public void timeoutOrder() throws ParseException {
        //todo 该方法订单量大时，需要使用其他方案进行优化
        String timeByMin = DateUtils.getTimeByMin(new Date(), -35);
        //1次至多处理50单
        List<OrderInfo> list = orderInfoService.lambdaQuery()
                .select(OrderInfo::getOrderId, OrderInfo::getUserCouponId,OrderInfo::getExchangeCode)
                .le(OrderInfo::getCreateTime, timeByMin)
                .eq(OrderInfo::getSaleType,1)
                .eq(OrderInfo::getOrderStatus, OrderStatusEnum.NOPAY.toString())
                .page(new Page<>(1, 50, false))
                .getRecords();
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        List<String> orderIds = list.stream().map(OrderInfo::getOrderId).collect(Collectors.toList());
        this.cancel(orderIds);
    }

    /**
     * 订单详情
     */
    public OrderDetailBean detail(String orderId) {
        CurrentCompanyWechat currentCompanyWechat = commonLogic.getCurrentCompanyWechat();
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        //查询订单详情
        List<OrderDetail> orderDetails = orderDetailService.lambdaQuery()
                .eq(OrderDetail::getOrderId, orderInfo.getOrderId())
                .list();
        //组装数据
        OrderDetailBean orderDetailBean = new OrderDetailBean();
        BeanUtils.copyProperties(orderInfo, orderDetailBean);
        List<OrderShare> list = orderShareService
                .lambdaQuery()
                .eq(OrderShare::getOrderId, orderInfo.getOrderId())
                .list();
        if (list.size() > 0) {
            orderDetailBean.setOrderShareStatus(list.get(0).getStatus());
        }else{
            orderDetailBean.setOrderShareStatus(OrderShareStatusEnum.ING.toString());
        }
        orderDetailBean.setOrderDetails(orderDetails);
        orderDetailBean.setIsShareOrder(!StringUtils.equals(orderInfo.getUserId(),currentCompanyWechat.getUserId()));

        List<OrderOldProduct> listProduce = orderOldProductService.lambdaQuery()
                .eq(OrderOldProduct::getOrderId, orderId).list();

        List<OrderOldProductDTO> orderOldProductDTOS = new ArrayList<>();

        for (OrderOldProduct orderOldProduct : listProduce) {
            OrderOldProductDTO orderOldProductDTO = BeanUtil.toBean(orderOldProduct, OrderOldProductDTO.class);
            List<OrderOldProductItem> orderOldProductItemList = orderOldProductItemService.lambdaQuery()
                    .eq(OrderOldProductItem::getOrderOldProductId, orderOldProduct.getId()).list();
            orderOldProductDTO.setItemList(orderOldProductItemList);

            orderOldProductDTOS.add(orderOldProductDTO);
        }

        orderDetailBean.setOrderOldProductDTOList(orderOldProductDTOS);

        return orderDetailBean;
    }

    /**
     * 取消订单
     */
    @Transactional
    public void cancel(List<String> orderIds) throws RemoteServiceException {
        List<OrderInfo> list = orderInfoService.lambdaQuery().in(OrderInfo::getOrderId,orderIds).list();
        List<String> userCouponIds = list.stream().map(OrderInfo::getUserCouponId).collect(Collectors.toList());
        //1.取消订单
        orderInfoService.lambdaUpdate()
                .set(OrderInfo::getOrderStatus, OrderStatusEnum.TIMEOUT.toString())
                .in(OrderInfo::getOrderId, orderIds).update();

        //2.恢复商品规格库存
        List<OrderDetail> orderDetails = orderDetailService.lambdaQuery().in(OrderDetail::getOrderId, orderIds).list();
        for (OrderDetail orderDetail : orderDetails) {
            //非秒杀订单 还原库存
            this.recoveryStock(orderDetail.getGoodsSpecId(), orderDetail.getNum());
            //秒杀订单还原库存
            if (orderDetail.getSecKill()) {
                SecKillActivitySpec secKillActivitySpec = secKillActivitySpecService.getById(orderDetail.getSecKillSpecId());
                if (secKillActivitySpec != null) {
                    try {
                        soldNumMapper.updateSecGoodsSpec(orderDetail);
                    } catch (Exception e) {
                        log.error("订单超时取消，恢复秒杀库存失败。orderId:{}",orderDetail.getOrderId());
                    }
                }
            }
        }
        //3.恢复优惠券的使用状态
        if (!CollectionUtils.isEmpty(userCouponIds)) {
            couponLogic.updateStatus(userCouponIds);
        }
        //4.恢复礼品兑换码
        for(OrderInfo orderInfo:list) {
            String exchangeCode = orderInfo.getExchangeCode();
            if(StringUtils.isNotBlank(orderInfo.getExchangeCode())) {
                Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_GIFT + ":" + orderInfo.getExchangeCode());
                try {
                    if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                        continue;
                    }
                    giftExchangeCodeService.lambdaUpdate()
                            .set(GiftExchangeCode::getStatus, 0)
                            .eq(GiftExchangeCode::getId, exchangeCode)
                            .update();
                } catch (InterruptedException e) {
                    log.error("订单超时取消，恢复兑换码失败。orderId:{}",orderInfo.getOrderId());
                } finally {
                    obtain.unlock();
                }
            }
        }


    }

    /**
     * 确认收货
     */
    //@Transactional
    public void ack(String orderId) throws Exception {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER + ":" + orderId);
        if(!obtain.tryLock(5,TimeUnit.SECONDS)){
            throw new RemoteServiceException("系统繁忙,请勿重复操作");
        }
        try {
            OrderInfo orderInfo = orderInfoService.getById(orderId);
            if (!orderInfo.getOrderStatus().equals(OrderStatusEnum.YFH.toString())) {
                throw new RemoteServiceException("非已发货订单不可确认收货");
            }
            orderInfo.setOrderStatus(OrderStatusEnum.OVER.toString());
            orderInfo.setOverTime(new Date());
            orderInfo.updateById();

            orderShareService.lambdaUpdate()
                    .set(OrderShare::getOrderStatus, orderInfo.getOrderStatus())
                    .eq(OrderShare::getOrderId, orderId)
                    .set(OrderShare::getOrderFinishTime, new Date())
                    .update();

            //调php派单接口
            this.orderToPhp(orderInfo);
        }finally {
            obtain.unlock();
        }
    }

    //生成工单到工单系统
    public void orderToPhp(OrderInfo orderInfo) throws Exception {

        //需要发货的安装单类型 //101=家用空调,103 = 热水器,104=生活电器,106=冰箱,115 = 厨大电
        //冰箱和生活电器经业务沟通，不派单
        List<String> mainNumbers = Arrays.asList("101", "103", "115");

        //生成工单到工单系统
        if (orderInfo.getWorkOrder() != null && orderInfo.getWorkOrder()) {
            List<OrderDetail> list = orderDetailService.lambdaQuery()
                    .eq(OrderDetail::getOrderId, orderInfo.getOrderId())
                    .eq(OrderDetail::getWorkOrderType,WorkOrderTypeEnum.INSTALL.toString())
                    .list();
            //如果是退换货的单，直接全拆
//            if(orderInfo.getExchangeOrder() != null && orderInfo.getExchangeOrder()){
//                for(OrderDetail orderDetail : list){
//                    gongdanLogic.installOrder(orderInfo,Arrays.asList(orderDetail),orderDetail.getMainNumber());
//                }
//            }else {
//                //非退换货的单，按品类拆，里面还会按营销类型拆
//                for (String mainNumber : mainNumbers) {
//                    gongdanLogic.installOrder(orderInfo, list, mainNumber);
//                }
//            }
        }
    }


    /**
     * 申请售后
     */
    @Transactional
    public String applyAfterSale(RefundGoodsBean refundGoodsBean) throws Exception {
        String orderId = refundGoodsBean.getOrderId();
        String refundReason = refundGoodsBean.getRefundReason();
        String refundType = refundGoodsBean.getRefundType();
        String refundExplain = refundGoodsBean.getRefundExplain();
        List<String> imgIds = refundGoodsBean.getImgIds();
        List<RefundGoods> refundGoods = refundGoodsBean.getRefundGoods();

        OrderInfo orderInfo = orderInfoService.getById(orderId);

        if (OrderStatusEnum.NOPAY.toString().equals(orderInfo.getOrderStatus())) {
            throw new RemoteServiceException("未付款,不需要售后");
        }
//        if (OrderStatusEnum.OVER.toString().equals(orderInfo.getOrderStatus())) {
//            throw new RemoteServiceException("订单已完成,不能售后");
//        }

        Integer count = orderOfflineRefundService.lambdaQuery()
                .eq(OrderOfflineRefund::getOrderId, orderId)
                .eq(OrderOfflineRefund::getExamineStatus, ExamineStatusEnum.WAIT.getKey()).count();
        if(count > 0){
            throw new RemoteServiceException("暂不可申请售后，请联系客服查看原因");
        }


        int refundCount = orderRefundService.lambdaQuery()
                .eq(OrderRefund::getOrderId, orderId)
                .in(OrderRefund::getOrderStatus, Arrays.asList(OrderStatusEnum.DSJCL.toString(),
                        OrderStatusEnum.DMJCL.toString(),OrderStatusEnum.DSJSH.toString(),OrderStatusEnum.REFUND.toString(),OrderStatusEnum.OVER.toString()))
                .ne(OrderRefund::getExamineStatus, OrderExamineEnum.FAIL.toString())
                .count();
        if (refundCount > 0) {
            throw new RemoteServiceException("请勿重新申请售后");
        }

        BigDecimal totalRefundAmount = new BigDecimal("0.00");
        BigDecimal totalRefundShareAmount = new BigDecimal("0.00");
        for (RefundGoods bean : refundGoods) {
            OrderDetail orderDetail = orderDetailService.getById(bean.getOrderDetailId());
            if(orderInfo.getPromotionPackageGoods() && orderDetail.getNum().intValue() != bean.getNum().intValue()){
                throw new RemoteServiceException("套购商品只支持全量退");
            }
            if (bean.getNum() > orderDetail.getNum()) {
                throw new RemoteServiceException("申请售后的商品数量错误");
            }
            //商品需要退款的金额
            BigDecimal refundAmount = BigDecimal.valueOf(ArithUtils.mul(ArithUtils.div(orderDetail.getPayAmount().doubleValue(), orderDetail.getNum(), 4), bean.getNum(),2));
            //计算退款的数量占比
            double div = ArithUtils.div(bean.getNum(), orderDetail.getNum(), 4);
            //按比例退运费(这里涉及到运费模板规则问题，暂不明确退款的规则运费怎么处理，目前以不退运费为准)
//            if (orderInfo.getOrderStatus().equals(OrderStatusEnum.DFH.toString()) ||
//                    (orderInfo.getOrderStatus().equals(OrderStatusEnum.REFUND.toString()) &&
//                            org.apache.commons.lang3.StringUtils.isBlank(orderInfo.getLogisticsNo()))) {//待发货状态退运费
//                BigDecimal refundFreight = BigDecimal.valueOf(ArithUtils.mul(orderDetail.getFreight().doubleValue(), div, 2));
//                if (refundFreight == null) {
//                    refundFreight = new BigDecimal("0.00");
//                }
//                refundAmount = refundAmount.add(refundFreight);
//            }
            orderDetail.setUserRefundNum(bean.getNum());
            orderDetail.setUserRefundAmount(refundAmount);
            orderDetail.setRefundNum(orderDetail.getRefundNum() + bean.getNum());
            orderDetail.setRefundAmount(orderDetail.getRefundAmount().add(refundAmount));
            //orderDetail.setRefundTime(new Date());
            //orderDetail.setRefundBy(adminUser.getNickName());
            orderDetail.setRefund(true);
            orderDetail.updateById();
            //总退款金额
            totalRefundAmount = totalRefundAmount.add(refundAmount);
            totalRefundShareAmount = totalRefundShareAmount.add(orderDetail.getShareAmount());
        }
        //扣除运费后的金额
        //totalRefundAmount=totalRefundAmount.subtract(orderInfo.getFreight());
        //绑定附件
        commonLogic.bindFile(orderId, Constant.Img.ORDER_REFUND_TKPZ, imgIds);
        //新增售后申请信息
        OrderRefund orderRefund = orderRefundService.lambdaQuery()
                .eq(OrderRefund::getOrderId, orderId)
                .one();
        if (orderRefund == null) {
            orderRefund = new OrderRefund();
            orderRefund.setCreateTime(new Date());
            BeanUtils.copyProperties(orderInfo, orderRefund);
        }
        orderRefund.setOrderStatus(OrderStatusEnum.DSJCL.toString());
        orderRefund.setRefundType(refundType);
        orderRefund.setRefundReason(refundReason);
        orderRefund.setRefundExplain(refundExplain);
        orderRefund.setRefundAmount(totalRefundAmount);
        orderRefund.setRefundShareAmount(totalRefundShareAmount);
        orderRefund.setWebsitName(orderInfo.getWebsitName());
        orderRefund.setWebsitNumber(orderInfo.getWebsitNumber());
        orderRefund.setCreateTime(new Date());
        orderRefundService.saveOrUpdate(orderRefund);
        orderInfo.setLastOrderStatus(orderInfo.getOrderStatus());
        orderInfo.setOrderStatus(OrderStatusEnum.REFUND.toString());
        orderInfo.setRefundFlag(RefundFlagEnum.ING.toString());
        orderInfoService.updateById(orderInfo);

        //公众号通知
        wxPubNoticeLogic.addAfter(orderInfo.getCompanyWechatId(),orderInfo.getOrderId(),orderInfo.getOrderTitle(),
                orderInfo.getPayAmount(),orderInfo.getReceUserName(),orderRefund.getCreateTime());

        this.sendMaterialExamine(orderInfo.getOrderId(),orderRefund.getOrderRefundId());

        return orderRefund.getOrderRefundId();
    }



    private void sendMaterialExamine(String orderId,String refundId) {

        OrderInfo orderInfo = orderInfoService.getById(orderId);


        List<AdminUserWebsitRela> adminUserWebsitRelas = adminUserWebsitRelaService.lambdaQuery()
                .eq(AdminUserWebsitRela::getAdminWebsitId, orderInfo.getWebsitId()).list();

        for (AdminUserWebsitRela adminUserWebsitRela : adminUserWebsitRelas) {
            AdminUser one = adminUserService.getById(adminUserWebsitRela.getAdminUserId());
            NoticeRecord noticeRecord = new NoticeRecord();
            noticeRecord.setNoticeId(orderInfo.getOrderId());
            String format = DateUtil.format(new Date(), "yyyy-MM-dd");
            noticeRecord.setTitle(orderInfo.getOrderTitle()+"创建时间"+format+",请及时处理");
            noticeRecord.setContent(orderInfo.getOrderTitle()+"创建时间"+format+",请及时处理");
            noticeRecord.setType(NoticeEnum.B.getKey());
            noticeRecord.setAdminNoticeType(NoticeTypeEnum.SYSTEM.getKey());
            noticeRecord.setIsNotice(IsYesNoEnum.YES.getKey());
            noticeRecord.setReadFlag(IsYesNoEnum.NO.getKey());
            noticeRecord.setAdminUserId(adminUserWebsitRela.getAdminUserId());
            noticeRecord.setAdminNickName(one.getNickName());
            noticeRecord.setIssueTime(new Date());
            noticeRecord.setAdminCompanyId(adminUserWebsitRela.getCompanyWechatId());
            noticeRecord.setAdminCompanyName(orderInfo.getCompanyWechatName());
            noticeRecord.setAdminNoticeType(AdminNoticTypeEnum.RP_MALL.getKey());
            noticeRecord.setOrderId(refundId);
            noticeRecord.insert();
        }

        AdminUser one = adminUserService.lambdaQuery().eq(AdminUser::getCompanyWechatId, orderInfo.getCompanyWechatId())
                .eq(AdminUser::getType, 1).last("limit 1").one();

        NoticeRecord noticeRecordCom = new NoticeRecord();
        noticeRecordCom.setNoticeId(orderInfo.getOrderId());
        String format = DateUtil.format(new Date(), "yyyy-MM-dd");
        noticeRecordCom.setTitle(orderInfo.getOrderTitle()+"创建时间"+format+",请及时处理");
        noticeRecordCom.setContent(orderInfo.getOrderTitle()+"创建时间"+format+",请及时处理");
        noticeRecordCom.setType(NoticeEnum.B.getKey());
        noticeRecordCom.setAdminNoticeType(NoticeTypeEnum.SYSTEM.getKey());
        noticeRecordCom.setIsNotice(IsYesNoEnum.YES.getKey());
        noticeRecordCom.setReadFlag(IsYesNoEnum.NO.getKey());
        noticeRecordCom.setAdminUserId(one.getAdminUserId());
        noticeRecordCom.setAdminNickName(one.getNickName());
        noticeRecordCom.setIssueTime(new Date());
        noticeRecordCom.setAdminCompanyId(one.getCompanyWechatId());
        noticeRecordCom.setAdminCompanyName(one.getCompanyName());
        noticeRecordCom.setAdminNoticeType(AdminNoticTypeEnum.RP_MALL.getKey());
        noticeRecordCom.setOrderId(refundId);
        noticeRecordCom.insert();

    }


    /**
     * 撤销申请
     */
    @Transactional
    public String cancelRefund(String refundOrderId) throws RemoteServiceException {
        OrderRefund orderRefund = orderRefundService.getById(refundOrderId);
        if (orderRefund == null || !orderRefund.getOrderStatus().equals(OrderStatusEnum.DSJCL.toString())) {
            throw new RemoteServiceException("已非待商家处理状态不可撤销申请");
        }
        //还原订单为完成状态
        String orderId = orderRefund.getOrderId();
        orderRefund.deleteById();
        return orderId;
    }

    /**
     * 售后订单列表
     */
    public IPage<OrderRefundDetailBean> refundList(String userId, String orderStatus, Integer pageNo, Integer pageSize) {
        IPage page = orderRefundService.lambdaQuery()
                .eq(OrderRefund::getUserId, userId)
                .eq(StringUtils.isNotBlank(orderStatus), OrderRefund::getOrderStatus, orderStatus)
                .orderByDesc(OrderRefund::getCreateTime)
                .page(new Page<>(pageNo, pageSize));

        List<OrderRefundDetailBean> list = new ArrayList<>();
        for (Object o : page.getRecords()) {
            OrderRefund orderRefund = (OrderRefund) o;
            OrderRefundDetailBean orderRefundDetailBean = new OrderRefundDetailBean();
            BeanUtils.copyProperties(orderRefund, orderRefundDetailBean);
            orderRefundDetailBean.setOrderDetails(orderDetailService.lambdaQuery()
                    .eq(OrderDetail::getOrderId, orderRefund.getOrderId()).list());
            list.add(orderRefundDetailBean);
        }
        page.setRecords(list);
        return page;
    }


    /**
     * 售后订单详情
     *
     * @param orderRefundId
     * @return
     */
    public OrderRefundDetailBean orderRefundDetail(String orderRefundId) {
        OrderRefund orderRefund = orderRefundService.getById(orderRefundId);
        List<OrderDetail> list = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderRefund.getOrderId()).list();

        OrderRefundDetailBean orderRefundDetailBean = new OrderRefundDetailBean();
        BeanUtils.copyProperties(orderRefund, orderRefundDetailBean);
        orderRefundDetailBean.setOrderDetails(list);
        //售后凭证
        List<CommonFile> commonFiles = commonLogic.queryFileByObjId(orderRefundId, Constant.Img.ORDER_REFUND_WLPZ);
        orderRefundDetailBean.setFiles(commonFiles);

        return orderRefundDetailBean;
    }


    /**
     * 售后订单-补充退货资料
     */
    @Transactional
    public void supplyData(String orderRefundId, String logisticsNo, String expressCompany, List<String> imgIds) throws RemoteServiceException {
        OrderRefund orderRefund = orderRefundService.getById(orderRefundId);
        if (!orderRefund.getOrderStatus().equals(OrderStatusEnum.DMJCL.toString())) {
            throw new RemoteServiceException("请耐心等待商家审核");
        }
        orderRefund.setLogisticsNo(logisticsNo);
        orderRefund.setExpressCompanyCode(expressCompany);
        orderRefund.setOrderStatus(OrderStatusEnum.DSJSH.toString());
        orderRefund.updateById();
        //订阅物流
        expressLogic.subscribeExpress(logisticsNo, expressCompany);
        //凭证
        commonLogic.bindFile(orderRefundId, Constant.Img.ORDER_REFUND_WLPZ, imgIds);
    }


    /**
     * 根据件数以及地区计算运费
     */
    private BigDecimal getFreightAmount(String province, String city, String area, List<BuyGood> buyGoods,AdminCompanyWechat adminCompanyWechat) throws RemoteServiceException {
        return freightLogic.getFreightAmountV2(province, city, area, buyGoods,adminCompanyWechat);
    }

    /**
     * 根据件数以及地区计算运费
     */
    private BigDecimal getFreightAmountItem(String province, String city, String area, BuyGood buyGood,AdminCompanyWechat adminCompanyWechat) throws RemoteServiceException {
        return freightLogic.computeAmountItem(province, city, area, buyGood,adminCompanyWechat);
    }


    /**
     * 处理商品规格库存
     *
     * @param goodsSpecId
     * @param goodsName
     * @param num
     * @return
     * @throws RemoteServiceException
     * @throws InterruptedException
     */
    private GoodsSpec stock(String goodsSpecId, String goodsName, Integer num) throws RemoteServiceException, InterruptedException {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER_STOCK +":"+ goodsSpecId);
        try {
            if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
                throw new RemoteServiceException("系统繁忙，请稍后再试");
            }
            GoodsSpec goodsSpec = goodsLogic.getGoodsSpecById(goodsSpecId);
            if (goodsSpec.getStockNum() < num) {
                throw new RemoteServiceException(1100,goodsName+"库存不足");
            }
            goodsSpec.setStockNum(goodsSpec.getStockNum() - num);
            goodsSpec.setSoldNum(goodsSpec.getSoldNum() + num);
            goodsSpec.updateById();

            return goodsSpec;
        } finally {
            obtain.unlock();
        }
    }

    /**
     * 还原库存
     */
    private void recoveryStock(String goodsSpecId, Integer num) {
        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_ORDER_STOCK + goodsSpecId);
        try {
            if (!obtain.tryLock(10, TimeUnit.SECONDS)) {
                log.error("还原库存获取锁失败");
                return;
            }
            GoodsSpec goodsSpec = goodsLogic.getGoodsSpecById(goodsSpecId);
            goodsSpec.setStockNum(goodsSpec.getStockNum() + num);
            goodsSpec.updateById();
        } catch (Exception e) {
            log.info("还原库存失败goodsSpecId:" + goodsSpecId, e);
        } finally {
            obtain.unlock();
        }
    }

    /**
     * 订单数量
     */
    public OrderStatusBean count(String orderId) {
        OrderStatusBean orderStatusBean = appMapper.orderStatusCount(orderId);
        return orderStatusBean;
    }

    /**
     * 提醒发货
     */
    public void notice(String orderId) {
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        Notice notice = new Notice();
//        notice.setObjId(orderId);
//        notice.setCreateTime(new Date());
//        notice.setContent("客户催促您发货了，订单号：" + orderId);
//        notice.setType(1);
//        notice.setTitle("订单发货");
//        notice.setWebsitName(orderInfo.getWebsitName());
//        notice.setWebsitNumber(orderInfo.getWebsitNumber());
        notice.insert();
    }


    /**
     * 确认订单内容
     */
    public OrderAckBean ackOrder(OrderBuyBean orderBuyBean, HttpServletRequest request) throws InterruptedException {
        OrderAckBean orderAckBean = this.ackOrder2(orderBuyBean,request);

        //运费
        BigDecimal freightAmountV2 = freightLogic.getFreightAmountV2(orderBuyBean,request);

        orderAckBean.setFreight(freightAmountV2);
        orderAckBean.setTotalAmount(orderAckBean.getTotalAmount());
        //实际支付金额
        BigDecimal payAmount = orderAckBean.getTotalAmount()
                .subtract(orderAckBean.getExchangeAmount())
                .subtract(orderAckBean.getDiscountAmount())
                .subtract(orderAckBean.getPromotionFullPieceDiscountAmount())
                .add(orderAckBean.getFreight());
        if(payAmount.doubleValue() <= 0){
            payAmount = BigDecimal.valueOf(0);
        }
        orderAckBean.setPayAmount(payAmount);
        return orderAckBean;
    }

    /**
     * 确认订单内容
     */
    public OrderAckBean ackOrder2(OrderBuyBean orderBuyBean, HttpServletRequest request) throws RemoteServiceException, InterruptedException {

        //是否有礼品卡兑换码
        Boolean hasGiftCode = false;
        //是否为团购活动
        Boolean isPromotionGroup = false;
        //是否为秒杀活动
        Boolean isSecKill = false;
        //是否为套购商品
        Boolean isGoodsPackage = StringUtils.isNotBlank(orderBuyBean.getGoodsPackageId());

        //购买人
        String userId = CommonUtils.getUserId(request);
        User user = userService.getById(userId);
        //兑换码
        String exchangeCode = orderBuyBean.getExchangeCode();
        //非团购商品的分佣金额
        BigDecimal notPromotionShareAmount = BigDecimal.valueOf(0);
        //总的商品金额
        BigDecimal totalAmount = new BigDecimal(0);
        //总的商品数量
        Integer totalNum = 0;
        //满件打折金额
        BigDecimal promotionFullPieceDiscountAmount = BigDecimal.valueOf(0);
        //满件打折活动规则
        List<PromotionFullPieceItem> promotionFullPieceItems = promotionFullPieceLogic.getItems();

        OrderAckBean orderAckBean = new OrderAckBean();
        orderAckBean.setDiscountAmount(BigDecimal.valueOf(0));
        orderAckBean.setOpenId(user.getOpenId());
        List<AckGoodsBean> list = new ArrayList<>();
        //业务员
        User service = user.getType().equals(UserTypeEnum.SERVICE.toString()) ? user : null;
        if(service == null){
            service = userService.getById(user.getServiceId());
        }
        //填充必要参数
        List<BuyGood> buyGoods = this.supplyBuyBoods(orderBuyBean,user);

        for (BuyGood buyGood : buyGoods) {

            Goods goods = buyGood.getGoods();
            GoodsSpec goodsSpec = buyGood.getGoodsSpec();

            //礼品卡商品处理
            //Boolean isGift = this.giftGoods(user.getUserId(), orderBuyBean.getExchangeCode(), false, goods, goodsSpec, buyGood.getNum());

            //总购买数量
            totalNum += buyGood.getNum();

            AckGoodsBean ackGoodsBean = new AckGoodsBean();
            BeanUtils.copyProperties(goods, ackGoodsBean);
            ackGoodsBean.setSpecImgUrl(goodsSpec.getImgUrl());
            ackGoodsBean.setSpecValue(goodsSpec.getSpecValue());
            ackGoodsBean.setNum(buyGood.getNum());
            ackGoodsBean.setPrice(buyGood.getPrice());
            ackGoodsBean.setOrgPrice(goods.getOrgGoodsPrice());
            ackGoodsBean.setSecKillId(buyGood.getSecKillId());
            ackGoodsBean.setPromotionGroupId(buyGood.getPromotionGroupId());
            //if (isGift) {
                //ackGoodsBean.setPrice(goodsSpec.getPrice());
            //    ackGoodsBean.setIsGift(true);
           //     hasGiftCode = true;

                //商品需要支付的金额（累加小计金额）
            //    totalAmount = totalAmount.add(this.getChildTotalPrice(ackGoodsBean,goodsSpec.getPrice()));
            //}else {
                //商品需要支付的金额（累加小计金额）
                totalAmount = totalAmount.add(this.getChildTotalPrice(ackGoodsBean));
            //}

            //普通商品佣金
//            BigDecimal shareAmount = buyGood.getShareAmount();
//            //内部人员佣金
//            if(service != null && service.getType().equals(UserTypeEnum.SERVICE.toString()) && service.getInnerr()) {
//                shareAmount = goodsSpec.getInnerShareAmount();
//            }
            //非团购商品的分佣金额
//            if(!buyGood.getIsPromotionGroup()) {
//                notPromotionShareAmount = notPromotionShareAmount.add(shareAmount.multiply(BigDecimal.valueOf(ackGoodsBean.getNum())));
//            }
//            if(buyGood.getIsPromotionGroup() && !isGoodsPackage)
//                isPromotionGroup = true;
//            if(buyGood.getIsSecKill() && !isGoodsPackage)
//                isSecKill = true;

            //满件打折金额(改变打折后的佣金，并返回打折优惠的金额)
            BigDecimal fullPieceDiscAmount = this.promotionFullPiece(orderAckBean, buyGoods, promotionFullPieceItems, goods, ackGoodsBean);
            promotionFullPieceDiscountAmount = promotionFullPieceDiscountAmount.add(fullPieceDiscAmount);

            list.add(ackGoodsBean);
        }
        //检查优惠券的使用合法性(团购和礼品卡和兑换码不可使用)
        //if(!isPromotionGroup && !hasGiftCode) {
            List<String> goodsIds = buyGoods.stream().map(BuyGood::getGoodsId).collect(Collectors.toList());
            UserCouponBean userCoupon = couponLogic.check(orderBuyBean.getUserCouponId(), totalAmount, goodsIds,false);
            if (userCoupon != null && this.checkPackageUseCoupon(orderBuyBean.getGoodsPackageId(),userCoupon)) {
                orderAckBean.setExchangeAmount(userCoupon.getCouponValue());
            }
        //}
        //优惠码的金额
//        if(!hasGiftCode && !isGoodsPackage){
//            //兑换码商品(此处会重置规格的价格)
//            BigDecimal subAmount = this.subGoods(userId, exchangeCode, false, notPromotionShareAmount,null);
//            if(subAmount != null && subAmount.doubleValue() > 0) {
//                orderAckBean.setExchangeAmount(subAmount);
//            }
//        }
        if(orderAckBean.getExchangeAmount() == null){
            orderAckBean.setExchangeAmount(BigDecimal.valueOf(0));
        }
        //计算折扣活动的金额（任何活动商品都可以参与,允许与优惠券/兑换码同用）-------------start
        //1.订单商品的实际支付金额
//        BigDecimal payAmount = totalAmount.subtract(orderAckBean.getExchangeAmount());
//        //2.折扣活动 需要扣减的金额
//        if(!isGoodsPackage) {
//            PromotionDiscountBean promotionDiscountBean = this.discountPromotion(buyGoods, payAmount);
//            if (promotionDiscountBean != null) {
//                orderAckBean.setDiscountAmount(promotionDiscountBean.getSubDiscountAmount());
//                orderAckBean.setPromotionDiscountRate(promotionDiscountBean.getDiscountRate());
//            } else {
//                if (orderAckBean.getDiscountAmount() == null) {
//                    orderAckBean.setDiscountAmount(BigDecimal.valueOf(0));
//                }
//                orderAckBean.setPromotionDiscountRate(BigDecimal.valueOf(0));
//            }
//        }
        orderAckBean.setPromotionFullPieceDiscountAmount(promotionFullPieceDiscountAmount);
        //计算折扣活动的金额（任何活动商品都可以参与,允许与优惠券/兑换码同用）-------------end
        orderAckBean.setGoods(list);
        orderAckBean.setTotalAmount(totalAmount);
        orderAckBean.setTotalNum(totalNum);
        return orderAckBean;
    }


    /**
     * 处理满件折扣活动
     * @return 可减免的金额
     */
    private BigDecimal promotionFullPiece(OrderAckBean orderAckBean,List<BuyGood> buyGoods,List<PromotionFullPieceItem> items,Goods goods,AckGoodsBean ackGoodsBean){
        PromotionFullPieceItem item = this.getPromotionFullPieceItem(buyGoods, items,goods);
        if(item == null || !goods.getPromotionFullPiece()){
            return BigDecimal.valueOf(0);
        }
        orderAckBean.setPromotionFullPriceRemark(this.getPromotionFullPieceRemark(item));
        BigDecimal subRate = BigDecimal.valueOf(1).subtract(item.getDiscountRate());
        return ackGoodsBean.getPrice().multiply(BigDecimal.valueOf(ackGoodsBean.getNum())).multiply(subRate).setScale(2,BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 整理 购买商品 的必要参数
     * @param orderBuyBean
     * @param user
     * @return
     */
    public List<BuyGood> supplyBuyBoods(OrderBuyBean orderBuyBean,User user) throws InterruptedException {
        String goodsPackageId = orderBuyBean.getGoodsPackageId();

        List<BuyGood> buyGoods = orderBuyBean.getBuyGoods();
        //套购商品
        Boolean isGoodsPackage = false;
        if(StringUtils.isNotBlank(goodsPackageId)){
            Goods goodsPackage = goodsLogic.getGoodsById(goodsPackageId);
            if(goodsPackage != null) {
                //套购商品检查
                this.checkPackageGoods(buyGoods, user, goodsPackage);
                //是否为套购商品
                isGoodsPackage = StringUtils.equals(goodsPackage.getGoodsType(), GoodsTypeEnum.PACKAGE.toString());
            }
        }

        for(BuyGood buyGood : buyGoods){
            //String promotionGroupId = buyGood.getPromotionGroupId();
            Goods goods = goodsLogic.getGoodsById(buyGood.getGoodsId());
            GoodsSpec goodsSpec = goodsLogic.getGoodsSpecById(buyGood.getGoodsSpecId());
            if (goods == null || goodsSpec == null) {
                throw new RemoteServiceException("商品不存在，请重新添加");
            }
            buyGood.setGoods(goods);
            buyGood.setGoodsSpec(goodsSpec);

            buyGood.setPromotionFullPiece(goods.getPromotionFullPiece());

            //非套购商品
            if(!isGoodsPackage) {

                buyGood.setOrgPrice(goodsSpec.getOrgPrice());
                buyGood.setPrice(goodsSpec.getPrice());
                buyGood.setShareAmount(goodsSpec.getShareAmount());
                //秒杀活动
                this.secKillPromotion(buyGood, goodsSpec.getGoodsSpecId());
                //团购活动
                this.groupPromotion(buyGood, goodsSpec,user);

            }else{
                //套购商品
                GoodsPackagePop goodsPackagePop = goodsPackagePopService.lambdaQuery()
                        .eq(GoodsPackagePop::getGoodsPackageId, goodsPackageId)
                        .eq(GoodsPackagePop::getGoodsSpecId, buyGood.getGoodsSpecId()).one();
                buyGood.setOrgPrice(goodsSpec.getOrgPrice());
                buyGood.setPrice(goodsPackagePop.getPrice());
                buyGood.setShareAmount(goodsPackagePop.getShareRate().multiply(buyGood.getPrice()));
                buyGood.setIsGoodsPackage(true);
            }

        }
        return buyGoods;
    }



    //获取商品小计金额
    private BigDecimal getChildTotalPrice(AckGoodsBean ackGoodsBean){
        return  ackGoodsBean.getPrice().multiply(new BigDecimal(ackGoodsBean.getNum()));
    }

    private BigDecimal getChildTotalPrice(AckGoodsBean ackGoodsBean,BigDecimal price){
        return  price.multiply(new BigDecimal(ackGoodsBean.getNum()));
    }

    /**
     * 套购商品
     */
    public void checkPackageGoods(List<BuyGood> buyGoods,User user,Goods goodsPackage){
        List<GoodsPackagePop> list = goodsPackagePopService.lambdaQuery()
                .eq(GoodsPackagePop::getGoodsPackageId, goodsPackage.getGoodsId())
                .orderByAsc(GoodsPackagePop::getType).list();
        //判断是否都为套购内商品
        Map<String, GoodsPackagePop> goodsSpecMap = list.stream().collect(Collectors.toMap(GoodsPackagePop::getGoodsSpecId, v -> v));
        for(BuyGood buyGood : buyGoods){
            Goods goods = goodsLogic.getGoodsById(buyGood.getGoodsId());
            GoodsSpec goodsSpec = goodsLogic.getGoodsSpecById(buyGood.getGoodsSpecId());
            GoodsPackagePop goodsPackagePop = goodsSpecMap.get(buyGood.getGoodsSpecId());
            if(goodsPackagePop == null){
                throw new RemoteServiceException("存在不包含当前套购的商品");
            }
            //检查是否超出了购买上限
            if(buyGood.getNum() > goodsPackagePop.getLimitNum()){
                throw new RemoteServiceException(goods.getGoodsName()+"-"+goodsSpec.getSpecValue()+"最大支持购买"+goodsPackagePop.getLimitNum()+"个");
            }
        }
        //检查配比是否正确
        String[] splitPop = goodsPackage.getPackagePop().split(":");
        this.checkPackagePop(buyGoods,splitPop);
        //检查是否有权限购买
        this.checkPackagePower(user,goodsPackage);
    }


    /**
     * 套购--检查配比是否正确
     * @param list
     * @param splitPop 配比比例
     */
    private void checkPackagePop(List<BuyGood> list,String[] splitPop){
        //检查配提购买的机型是否大于等于限定机型购买的倍数，
        //倍数 num = 购买的数量 / 所属比例
        double num = -1;
        for(int i = 1;i <= splitPop.length;i++){
            int a = i;
            int rate = Integer.parseInt(splitPop[i-1]);
            int sum = list.stream().filter(v -> v.getPopType() == a).mapToInt(BuyGood::getNum).sum();
            double div = sum / rate;
            if(div == 0)
                throw new RemoteServiceException("检查到配比不正确");

            if(sum % rate != 0)
                throw new RemoteServiceException("购买数量必须是套餐对应比例的整倍数");

            if(num != -1 && num != div)
                throw new RemoteServiceException("检查到配比不正确");

            if(i == 1)
                num = div;
        }
    }

    /**
     * 套购--检查是否有权限购买
     */
    private void checkPackagePower(User user,Goods goods){
        if(!StringUtils.equals(goods.getGoodsType(),GoodsTypeEnum.PACKAGE.toString())){
            return;
        }
        // 0=指定人员 1=所有人 2=普通用户 3=业务员
        if(goods.getPackageUserType() == null){
            return ;
        }
        //指定人员
        if(goods.getPackageUserType() == 0){
            Integer count = goodsPackageUserRelaService.lambdaQuery()
                    .eq(GoodsPackageUserRela::getGoodsId, goods.getGoodsId()).eq(GoodsPackageUserRela::getUserId, user.getUserId()).count();
            if(count > 0){
                return;
            }
        }
        //所有人
        if(goods.getPackageUserType() == 1){
            return;
        }
        //普通用户
        if(goods.getPackageUserType() == 2 && StringUtils.equals(user.getType(),UserTypeEnum.GENERAL.toString())){
            return;
        }
        //业务员
        if(goods.getPackageUserType() == 3 && StringUtils.equals(user.getType(),UserTypeEnum.SERVICE.toString())){
            return;
        }
        throw new RemoteServiceException("暂不可购买该商品");
    }

    /**
     * 套购--检查是否可使用优惠券
     */
    private Boolean checkPackageUseCoupon(String goodsPackageId,UserCoupon userCoupon){
        if(StringUtils.isBlank(goodsPackageId)){
            return true;
        }
        //使用优惠券   0=不可使用 1=所有优惠券 2=满减券 3=商品券
        Goods goods = goodsLogic.getGoodsById(goodsPackageId);
        if(!StringUtils.equals(goods.getGoodsType(),GoodsTypeEnum.PACKAGE.toString())){
            return true;
        }
        Integer useCoupon = goods.getUseCoupon();
        if(useCoupon == 0){
            throw new RemoteServiceException("当前套购商品不可使用优惠券");
        }
        if(useCoupon == 2 && !userCoupon.getCouponType().equals(CouponTypeEnum.SATISFY.toString())){
            throw new RemoteServiceException("当前套购商品不可使用满减券");
        }
        if(useCoupon == 3 && !userCoupon.getCouponType().equals(CouponTypeEnum.GOODS.toString())){
            throw new RemoteServiceException("当前套购商品不可使用商品券");
        }
        return true;
    }

    /**
     * 折扣活动处理
     * @param buyGoods 购买的商品
     * @param payAmount 实际支付的金额
     */
    private PromotionDiscountBean discountPromotion(List<BuyGood> buyGoods,BigDecimal payAmount){

        List<String> promotionIds = buyGoods.stream().filter(v -> StringUtils.isNotBlank(v.getPromotionGroupId()))
                .map(BuyGood::getPromotionGroupId)
                .collect(Collectors.toList());

        //全团购商品
        Boolean allPromotionGroup = !CollectionUtils.isEmpty(promotionIds) && promotionIds.size() == buyGoods.size();

        BigDecimal discountAmount = BigDecimal.valueOf(0);
        //1.判断是否达到折扣条件
        List<PromotionDiscount> list = promotionDiscountService.lambdaQuery()
                .ge(PromotionDiscount::getLimitUpperAmount, payAmount)
                .le(PromotionDiscount::getLimitLowerAmount,payAmount)
                .eq(PromotionDiscount::getStatus,true)
                .in(allPromotionGroup,PromotionDiscount::getPromotionGroupId,promotionIds)
                .eq(allPromotionGroup,PromotionDiscount::getType,2)
                .eq(!allPromotionGroup,PromotionDiscount::getType,1)
                .orderByAsc(PromotionDiscount::getDiscountRate)
                .list();
        if(CollectionUtils.isEmpty(list)){
            return null;
        }
        PromotionDiscount promotionDiscount = list.get(0);
        //2.判断是否有非该团购活动之外的商品
        long count = buyGoods.stream().filter(v -> !StringUtils.equals(v.getPromotionGroupId(), promotionDiscount.getPromotionGroupId())).count();
        if(count > 0){
            throw new RemoteServiceException("检测到有非折扣商品，请联系相关人员");
        }
        BigDecimal subRate = BigDecimal.valueOf(1).subtract(promotionDiscount.getDiscountRate());
        //实际折扣扣减的金额
        discountAmount = payAmount.multiply(subRate).setScale(2,BigDecimal.ROUND_HALF_UP);

        PromotionDiscountBean bean = new PromotionDiscountBean();
        BeanUtils.copyProperties(promotionDiscount,bean);
        bean.setSubDiscountAmount(discountAmount);
        return bean;
    }


    /**
     * 秒杀活动
     * @param buyGood
     * @param goodsSpecId
     */
    private void secKillPromotion(BuyGood buyGood,String goodsSpecId){
        //判断是否为秒杀商品
        SecKillActivitySpec secKill = secActivityStageMapper.getSecKillSpecByGoodsSpecId(goodsSpecId);
        if (secKill != null) {
            if (StringUtils.isNotBlank(secKill.getSecKillId()) && secKillLogic.isSecing(secKill.getSecKillId())) {
                buyGood.setPrice(secKill.getPrice());
                buyGood.setShareAmount(secKill.getAmount());
                buyGood.setOrgPrice(secKill.getGoodsPrice());
                buyGood.setPromotionImgUrl(secKill.getImgUrl());
                buyGood.setIsSecKill(true);
            }
        }
    }

    /**
     * 团购活动
     * @param buyGood
     * @param goodsSpec
     */
    private void groupPromotion(BuyGood buyGood,GoodsSpec goodsSpec,User user){
        String promotionGroupUserId = user.getPromotionGroupUserId();
        if(user.getPromotionGroupLeader()){
            promotionGroupUserId = user.getUserId();
        }

        PromotionGroupSpecUser promotionGroupSpecUser = promotionGroupSpecUserService.lambdaQuery()
                .eq(PromotionGroupSpecUser::getGoodsSpecId, goodsSpec.getGoodsSpecId())
                .eq(PromotionGroupSpecUser::getUserId, promotionGroupUserId)
                .ge(PromotionGroupSpecUser::getEndTime,new Date())
                .le(PromotionGroupSpecUser::getStartTime,new Date())
                .one();
        if(promotionGroupSpecUser == null){
            return ;
        }
        if(promotionGroupLogic.checkPromotionGroup(promotionGroupSpecUser.getPromotionGroupId())){
            buyGood.setPrice(promotionGroupSpecUser.getGroupPrice());
            buyGood.setShareAmount(promotionGroupSpecUser.getShareAmount());
            buyGood.setOrgPrice(promotionGroupSpecUser.getOrgGoodsPrice());
            buyGood.setPromotionImgUrl(promotionGroupSpecUser.getGoodsImgSrc());
            buyGood.setIsPromotionGroup(true);
        }
    }


    /**
     * 礼品卡商品
     */
    private Boolean giftGoods(String userId,String exchangeCode,Boolean order,Goods goods,GoodsSpec goodsSpec,int num) throws RemoteServiceException, InterruptedException {
        if(StringUtils.isBlank(exchangeCode)){
            return false;
        }

        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_GIFT + ":" + exchangeCode);
        if(!obtain.tryLock(5,TimeUnit.SECONDS)){
            throw new RemoteServiceException("系统繁忙，请稍后再试");
        }
        try {
            GiftExchangeCode giftExchangeCode = giftExchangeCodeService.getById(exchangeCode);
            if(giftExchangeCode == null)
                return false;
            User user = userService.getById(userId);
            if (user.getExchangeNum() > 10) {
                throw new RemoteServiceException(1100,"该用户已被禁用兑换码");
            }
            if(giftExchangeCode.getType().equals(ExchangeCodeTypeEnum.GIFT.toString())){
                //礼品兑换码
                if (goods == null || goodsSpec == null) {
                    throw new RemoteServiceException("商品不存在");
                }
                BigDecimal amount = this.giftExchangeCodeGoods(giftExchangeCode, goods.getGoodsId(), user, num,order);
                goodsSpec.setPrice(amount);
                return true;
            }
        }finally {
            obtain.unlock();
        }
        return false;
    }


    /**
     * 抵扣兑换码商品
     */
    private BigDecimal subGoods(String userId,String exchangeCode,Boolean order,BigDecimal totalShareAmount,String orderId) throws RemoteServiceException, InterruptedException {
        if(StringUtils.isBlank(exchangeCode)){
            return BigDecimal.valueOf(0);
        }

        Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.LOCK_GIFT + ":" + exchangeCode);
        if(!obtain.tryLock(5,TimeUnit.SECONDS)){
            throw new RemoteServiceException("系统繁忙，请稍后再试");
        }
        try {
            GiftExchangeCode giftExchangeCode = giftExchangeCodeService.getById(exchangeCode);
            if(giftExchangeCode == null)
                return BigDecimal.valueOf(0);
            User user = userService.getById(userId);
            if (user.getExchangeNum() > 10) {
                throw new RemoteServiceException(1100,"该用户已被禁用兑换码");
            }
            if(giftExchangeCode.getType().equals(ExchangeCodeTypeEnum.SUB.toString())  && totalShareAmount != null){
                //金额抵扣码
                return this.subExchangeCodeGoods(giftExchangeCode,user,order,totalShareAmount,orderId);
            }
        }finally {
            obtain.unlock();
        }
        return BigDecimal.valueOf(0);
    }


    /**
     * 礼品卡兑换码
     */
    private BigDecimal giftExchangeCodeGoods(GiftExchangeCode giftExchangeCode,String goodsId,User user,Integer num,Boolean order){
        if(giftExchangeCode == null || giftExchangeCode.getStatus() == 1 || giftExchangeCode.getStartTime().getTime() > new Date().getTime()
                || giftExchangeCode.getEndTime().getTime() < new Date().getTime() || !giftExchangeCode.getGoodsId().equals(goodsId)){
            user.setExchangeNum(user.getExchangeNum() + 1);
            user.updateById();
            throw new RemoteServiceException(1100, "兑换码无效");
        }
        if(num > 1)
            throw new RemoteServiceException(1100,"该兑换码只支持购买1个商品");
        //生成订单需要核销
        if (order) {
            //分享人id
//            String userId = giftExchangeCode.getUserId();
//            User service = userService.getById(userId);
//            if(service != null) {
//                giftExchangeCode.setNickName(service.getWorkName());
//                giftExchangeCode.setAvatar(service.getAvatar());
//                giftExchangeCode.setWebsitId()
//            }
            //使用人
            giftExchangeCode.setUseUserId(user.getUserId());
            giftExchangeCode.setUseNickName(user.getNickName());
            giftExchangeCode.setUseTime(new Date());
            giftExchangeCode.setUseAvatar(user.getAvatar());
            giftExchangeCode.setCompanyWechatId(user.getCompanyWechatId());
            giftExchangeCode.setCompanyName(user.getCompanyName());

            giftExchangeCode.setStatus(1);
            giftExchangeCode.updateById();

            user.setExchangeNum(0);
            user.updateById();
        }
        return giftExchangeCode.getAmount();
    }


    /**
     * 抵扣兑换码
     * @return 可抵扣的金额
     * @throws InterruptedException
     */
    private BigDecimal subExchangeCodeGoods(GiftExchangeCode giftExchangeCode,User user,Boolean order,BigDecimal totalShareAmount,String orderId) throws InterruptedException {
        String serviceId = user.getServiceId();
        if(user.getType().equals(UserTypeEnum.SERVICE.toString())){
            serviceId = user.getUserId();
        }
        if(giftExchangeCode == null || giftExchangeCode.getStatus() == 1 || giftExchangeCode.getStartTime().getTime() > new Date().getTime()
                || giftExchangeCode.getEndTime().getTime() < new Date().getTime() || !giftExchangeCode.getUserId().equals(serviceId)){
            user.setExchangeNum(user.getExchangeNum() + 1);
            user.updateById();
            throw new RemoteServiceException(1100, "兑换码无效");
        }
        if(giftExchangeCode.getAmount().doubleValue() > totalShareAmount.doubleValue()){
            throw new RemoteServiceException(1100,"兑换码不适用目前所购买的商品");
        }
        //生成订单需要核销
        if (order) {

            //使用人
            giftExchangeCode.setUseUserId(user.getUserId());
            giftExchangeCode.setUseNickName(user.getNickName());
            giftExchangeCode.setUseTime(new Date());
            giftExchangeCode.setUseAvatar(user.getAvatar());

            giftExchangeCode.setOrderId(orderId);
            giftExchangeCode.setCompanyWechatId(user.getCompanyWechatId());
            giftExchangeCode.setCompanyName(user.getCompanyName());
            giftExchangeCode.setStatus(1);
            giftExchangeCode.updateById();

            user.setExchangeNum(0);
            user.updateById();
        }
        return giftExchangeCode.getAmount();
    }
    /**
     * 已开发票
     */
    public void tax(String orderId, String orderTaxId) {
        orderInfoService.lambdaUpdate()
                .set(OrderInfo::getTax, true)
                .set(OrderInfo::getOrderTaxId, orderTaxId)
                .eq(OrderInfo::getOrderId, orderId).update();
    }


    /**
     * 根据已发货状态订单
     */
    public List<OrderInfo> listByYFH() {
        return orderInfoService.lambdaQuery().eq(OrderInfo::getOrderStatus, OrderStatusEnum.YFH.toString()).list();
    }


    /**
     * 查询工单列表详情
     */
    public IPage<WorkerOrderInfo> getWorkerOrder(String userId,String workerOrderNo,Integer pageNo,Integer pageSize) throws Exception {
        IPage page = orderRequestService.lambdaQuery()
                .eq(OrderRequest::getUserId, userId)
                .eq(StringUtils.isNotBlank(workerOrderNo),OrderRequest::getWorkerOrderNo,workerOrderNo)
                .orderByDesc(OrderRequest::getCreateTime)
                .page(new Page<>(pageNo, pageSize));

        List<String> installWorkerOrderNos = new ArrayList<>();
        List<String> repairWorkerOrderNos = new ArrayList<>();
        for(Object o : page.getRecords()){
            OrderRequest orderRequest = (OrderRequest) o;
            if(StringUtils.equals(orderRequest.getOrderType(),"INSTALL")) {
                installWorkerOrderNos.add(orderRequest.getWorkerOrderNo());
            }else{
                repairWorkerOrderNos.add(orderRequest.getWorkerOrderNo());
            }
        }
//        List<WorkerOrderInfo> installOrderList = new ArrayList<>();
//        if(!CollectionUtils.isEmpty(installWorkerOrderNos)) {
//            installOrderList.addAll(gongdanLogic.getInstallOrderList(null, workerOrderNo, installWorkerOrderNos));
//        }
//        if(!CollectionUtils.isEmpty(repairWorkerOrderNos)) {
//            installOrderList.addAll(gongdanLogic.getRepairOrderList(null, workerOrderNo, repairWorkerOrderNos));
//        }
//        page.setRecords(installOrderList);

        return page;
    }



    /**
     * 修改收货人信息
     */
    @Transactional
    public void updateReceInfo(OrderInfo orderInfo) throws Exception {
//        if (orderInfo.getOrderStatus().equals(OrderStatusEnum.OVER.toString())
//                || orderInfo.getOrderStatus().equals(OrderStatusEnum.OVER.toString())) {
//            throw new RemoteServiceException("已发货、已完成订单不可修改");
//        }

        OrderInfo oldOrderInfo = orderInfoService.getById(orderInfo.getOrderId());
        if(oldOrderInfo.getIsChangeAddress()){
            throw new RemoteServiceException("收货地址只能修改一次");
        }

        if(com.aliyuncs.utils.StringUtils.isEmpty(orderInfo.getReceUserName()) || com.aliyuncs.utils.StringUtils.isEmpty(orderInfo.getRecePhone()) || com.aliyuncs.utils.StringUtils.isEmpty(orderInfo.getReceAddress())
                || com.aliyuncs.utils.StringUtils.isEmpty(orderInfo.getProvince()) || com.aliyuncs.utils.StringUtils.isEmpty(orderInfo.getCity()) || com.aliyuncs.utils.StringUtils.isEmpty(orderInfo.getArea()) || com.aliyuncs.utils.StringUtils.isEmpty(orderInfo.getStreet())){
            throw new RemoteServiceException("缺少必传的参数");
        }
        orderInfo.setIsChangeAddress(true);
        orderInfo.updateById();
    }

    public List<PgOrderSettleNormBean> settleNormDetail(String orderId, HttpServletRequest request) {
        String workerId = CommonUtils.getUserId(request);
        List<PgOrderSettleNorm> norms = pgOrderSettleNormService.lambdaQuery()
                .eq(PgOrderSettleNorm::getOrderBaseId, orderId)
                .list();

        if (CollectionUtil.isEmpty(norms)) {
            return new ArrayList<>();
        }

        List<PgOrderSettleWorker> settleWorkers = pgOrderSettleWorkerService.lambdaQuery()
                .in(PgOrderSettleWorker::getOrderSettleNormId, norms.stream()
                        .map(PgOrderSettleNorm::getId)
                        .collect(Collectors.toList()))
                .eq(PgOrderSettleWorker::getWorkerId, workerId)
                .list();

        if (CollectionUtil.isEmpty(settleWorkers)) {
            return new ArrayList<>();
        }

        Map<String, PgOrderSettleWorker> decimalMap = settleWorkers.stream()
                .collect(Collectors.toMap(PgOrderSettleWorker::getOrderSettleNormId, Function.identity()));

        List<PgOrderSettleNormBean> beanList = new ArrayList<>();

        for (PgOrderSettleNorm norm : norms) {
            PgOrderSettleNormBean bean = new PgOrderSettleNormBean();
            BeanUtils.copyProperties(norm, bean);
            bean.setWorkerSettleAmount(decimalMap.get(norm.getId()).getSettleAmount());
            beanList.add(bean);
        }

        return beanList;
    }

    /**
     * 完工插入结算费用明细
     * @param orderBase
     * @param orderProductList
     */
    public void insertSettleOrderMethod(PgOrderBase orderBase, List<PgOrderProduct> orderProductList) {
        if (CollectionUtil.isNotEmpty(orderProductList)) {
            List<PgOrderWorker> workers = pgOrderWorkerService.lambdaQuery()
                    .eq(PgOrderWorker::getOrderBaseId, orderBase.getId())
                    .list();

            List<PgOrderSettleWorker> orderWorkerList = new ArrayList<>();

            List<PgOrderSettleNorm> normList = new ArrayList<>();
            for (PgOrderProduct product : orderProductList) {
                PgOrderSettleNorm norm = new PgOrderSettleNorm();
                norm.setId(IdWorker.getIdStr())
                        .setOrderBaseId(orderBase.getId())
                        .setPgOrderProductId(product.getId())
                        .setCompanyWechatId(orderBase.getCompanyWechatId())
                        .setCompanyWechatName(orderBase.getCompanyWechatName())
                        .setWebsitId(orderBase.getWebsitId())
                        .setWebsitName(orderBase.getWebsitName())
                        .setOrderType(orderBase.getOrderType())
                        .setOrderTypeText(orderBase.getOrderTypeText())
                        .setChannelId(orderBase.getOrderChannelId())
                        .setChannelText(orderBase.getOrderChannelText())
                        .setType(orderBase.getOrderSmallType())
                        .setTypeName(orderBase.getOrderSmallTypeText())
                        .setOrderNum(product.getNum())
                        .setSettleNum(product.getNum())
                        .setGoodsId(product.getProductId())
                        .setGoodsName(product.getProductName())
                        .setMainId(product.getMainId())
                        .setMainName(product.getMainName())
                        .setSmallId(product.getSmallId())
                        .setSmallName(product.getSmallName())
                        .setOrderChannelId(orderBase.getOrderChannelId())
                        .setOrderChannelText(orderBase.getOrderChannelText())
//                        .setParentCategoryId(product.getMainId())
//                        .setParentCategoryName(product.getMainName())
//                        .setCategoryId(product.getSmallId())
//                        .setCategoryName(product.getSmallName())
                        .setBrandId(product.getBrandId())
                        .setBrand(product.getBrandName())
                        .setSettleNormType(orderBase.getOrderType());

                PgOrderSettleNorm otherNorm = new PgOrderSettleNorm();
                otherNorm.setId(IdWorker.getIdStr())
                        .setOrderBaseId(orderBase.getId())
                        .setPgOrderProductId(product.getId())
                        .setCompanyWechatId(orderBase.getCompanyWechatId())
                        .setCompanyWechatName(orderBase.getCompanyWechatName())
                        .setWebsitId(orderBase.getWebsitId())
                        .setWebsitName(orderBase.getWebsitName())
                        .setOrderNum(product.getNum())
                        .setSettleNum(product.getNum())
                        .setGoodsId(product.getProductId())
                        .setGoodsName(product.getProductName())
                        .setMainId(product.getMainId())
                        .setMainName(product.getMainName())
                        .setSmallId(product.getSmallId())
                        .setSmallName(product.getSmallName())
                        .setBrandId(product.getBrandId())
                        .setBrand(product.getBrandName())
                        .setSettleNormType(SettleNormTypeEnum.OTHER.getKey());

                normList.add(norm);
                normList.add(otherNorm);

                for (PgOrderWorker worker : workers) {
                    PgOrderSettleWorker settleWorker = new PgOrderSettleWorker();
                    settleWorker.setId(IdWorker.getIdStr())
                            .setOrderBaseId(orderBase.getId())
                            .setOrderSettleNormId(norm.getId())
                            .setWorkerId(worker.getWorkerId())
                            .setWorkerName(worker.getWorkerName())
                            .setWorkerMobile(worker.getWorkerMobile())
                            .setWorkerIdcard(worker.getWorkerIdcard())
                            .setSettleNormType(norm.getSettleNormType());

                    PgOrderSettleWorker settleOtherWorker = new PgOrderSettleWorker();
                    settleOtherWorker.setId(IdWorker.getIdStr())
                            .setOrderBaseId(orderBase.getId())
                            .setOrderSettleNormId(otherNorm.getId())
                            .setWorkerId(worker.getWorkerId())
                            .setWorkerName(worker.getWorkerName())
                            .setWorkerMobile(worker.getWorkerMobile())
                            .setWorkerIdcard(worker.getWorkerIdcard())
                            .setSettleNormType(otherNorm.getSettleNormType());

                    orderWorkerList.add(settleWorker);
                    orderWorkerList.add(settleOtherWorker);
                }
            }

            pgOrderSettleNormService.saveBatch(normList);
            pgOrderSettleWorkerService.saveBatch(orderWorkerList);
        }
    }

    public BigDecimal settleNormDetailCount(String orderId, HttpServletRequest request) {
        List<PgOrderSettleNormBean> beanList = this.settleNormDetail(orderId, request);
        BigDecimal total = BigDecimal.ZERO;
        if (CollectionUtil.isNotEmpty(beanList)) {
            for (PgOrderSettleNormBean bean : beanList) {
                total = total.add(bean.getWorkerSettleAmount());
            }
        }
        return total;
    }
}
