package com.fs.store.service.impl;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.api.param.OrderListParam;
import com.fs.api.vo.OrderListVO;
import com.fs.api.vo.ProductListVO;
import com.fs.common.config.FSSysConfig;
import com.fs.common.core.domain.R;
import com.fs.common.core.redis.RedisCache;
import com.fs.common.event.TemplateBean;
import com.fs.common.event.TemplateEvent;
import com.fs.common.event.TemplateListenEnum;
import com.fs.common.exception.CustomException;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.StringUtils;
import com.fs.company.domain.Company;
import com.fs.company.domain.CompanyDept;
import com.fs.company.domain.CompanyMoneyLogs;
import com.fs.company.domain.CompanyUser;
import com.fs.company.mapper.CompanyMoneyLogsMapper;
import com.fs.company.service.ICompanyDeptService;
import com.fs.company.service.ICompanyService;
import com.fs.company.service.ICompanyUserService;
import com.fs.erp.domain.*;
import com.fs.erp.dto.*;
import com.fs.erp.service.IErpOrderService;
import com.fs.huifuPay.domain.HuiFuRefundResult;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.pay.pay.domain.RefundResult;
import com.fs.pay.pay.service.PayService;
import com.fs.store.config.StoreConfig;
import com.fs.store.config.StoreIntegralConfig;
import com.fs.store.constants.StoreConstants;
import com.fs.store.domain.*;
import com.fs.store.dto.*;
import com.fs.store.enums.*;
import com.fs.store.mapper.FsStoreCartMapper;
import com.fs.store.mapper.FsStoreOrderItemMapper;
import com.fs.store.mapper.FsUserAddressMapper;
import com.fs.store.param.*;
import com.fs.store.service.*;
import com.fs.store.vo.*;
import com.fs.pay.service.IPayService;
import com.fs.system.service.ISysConfigService;
import com.fs.wx.pay.config.WxPayProperties;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.Synchronized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import com.fs.store.mapper.FsStoreOrderMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import static com.fs.store.constants.StoreConstants.DELIVERY;

/**
 * 订单Service业务层处理
 *
 * @author fs
 * @date 2022-03-15
 */
@Service
public class FsStoreOrderServiceImpl implements IFsStoreOrderService
{

    Logger logger= LoggerFactory.getLogger(getClass());
    @Autowired
    private CompanyMoneyLogsMapper moneyLogsMapper;
    @Autowired
    private IFsStoreOrderStatusService orderStatusService;
    @Autowired
    private FsStoreCartMapper cartMapper;

    @Autowired
    private FsUserAddressMapper userAddressMapper;

    @Autowired
    private FsStoreOrderMapper fsStoreOrderMapper;

    @Autowired
    private IFsStoreProductService productService;

    @Autowired
    private IFsUserService userService;

    @Autowired
    private IFsUserBillService billService;

    @Autowired
    RedisCache redisCache;

    @Autowired
    private IFsStoreCartService cartService;

    @Autowired
    private ApplicationEventPublisher publisher;

    @Autowired
    private IFsShippingTemplatesService shippingTemplatesService;

    @Autowired
    private IFsShippingTemplatesRegionService shippingTemplatesRegionService;

    @Autowired
    private IFsShippingTemplatesFreeService shippingTemplatesFreeService;
    @Autowired
    private IFsExpressService expressService;

    @Autowired
    private IPayService payService;
    @Autowired
    private FSSysConfig sysConfig;
    @Autowired
    IErpOrderService erpOrderService;
    @Autowired
    IFsStorePaymentService paymentService;

    @Autowired
    IFsStoreProductPackageService productPackageService;

    @Autowired
    ICompanyUserService companyUserService;
    @Autowired
    private IFsStoreProductAttrValueService attrValueService;
    @Autowired
    private IFsStoreProductService storeProductService;

    @Autowired
    private IFsStoreCouponUserService couponUserService;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    private IFsStoreOrderItemService storeOrderItemService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IFsStoreProductGroupService storeProductGroupService;

    @Autowired
    private FsStoreOrderItemMapper fsStoreOrderItemMapper;
    @Autowired
    ICompanyDeptService companyDeptService;
    @Autowired
    IFsPrescribeService prescribeService;

    @Autowired
    PayService ybPayService;

    @Autowired
    HuiFuService huiFuService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private WxPayProperties wxPayProperties;
    @Value("${fsConfig.erpWarehouseCode}")
    private String wareHouseCode;
    /**
     * 查询订单
     *
     * @param id 订单ID
     * @return 订单
     */
    @Override
    public FsStoreOrder selectFsStoreOrderById(Long id)
    {
        return fsStoreOrderMapper.selectFsStoreOrderById(id);
    }

    /**
     * 查询订单列表
     *
     * @param fsStoreOrder 订单
     * @return 订单
     */
    @Override
    public List<FsStoreOrder> selectFsStoreOrderList(FsStoreOrder fsStoreOrder)
    {
        return fsStoreOrderMapper.selectFsStoreOrderList(fsStoreOrder);
    }

    /**
     * 新增订单
     *
     * @param fsStoreOrder 订单
     * @return 结果
     */
    @Override
    public int insertFsStoreOrder(FsStoreOrder fsStoreOrder)
    {
        fsStoreOrder.setCreateTime(DateUtils.getNowDate());
        return fsStoreOrderMapper.insertFsStoreOrder(fsStoreOrder);
    }

    /**
     * 修改订单
     *
     * @param fsStoreOrder 订单
     * @return 结果
     */
    @Override
    public int updateFsStoreOrder(FsStoreOrder fsStoreOrder)
    {
        fsStoreOrder.setUpdateTime(DateUtils.getNowDate());
        return fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder);
    }

    /**
     * 批量删除订单
     *
     * @param ids 需要删除的订单ID
     * @return 结果
     */
    @Override
    public int deleteFsStoreOrderByIds(Long[] ids)
    {
        return fsStoreOrderMapper.deleteFsStoreOrderByIds(ids);
    }

    /**
     * 删除订单信息
     *
     * @param id 订单ID
     * @return 结果
     */
    @Override
    public int deleteFsStoreOrderById(Long id)
    {
        return fsStoreOrderMapper.deleteFsStoreOrderById(id);
    }

    @Override
    public List<FsStoreOrderVO> selectFsStoreOrderListVO(FsStoreOrderParam param) {
        List<FsStoreOrderVO> list= fsStoreOrderMapper.selectFsStoreOrderListVO(param);
        for(FsStoreOrderVO vo:list){
            String nickName = vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
            vo.setNickname(nickName);
            if(StringUtils.isNotEmpty(vo.getItemJson())){
                JSONArray jsonArray=JSONUtil.parseArray(vo.getItemJson());
                List<FsStoreOrderItemVO> items=JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
                if(items.size()>0){
                    vo.setItems(items);
                }
            }
            //List<FsStoreOrderItemVO> items=storeOrderItemService.selectFsStoreOrderItemListByOrderId(vo.getId());
            //vo.setItems(items);
        }
        return list;
    }

    @Override
    public List<FsStoreOrderVO> selectFsStoreOrderAllListVO(FsStoreOrderParam param) {
        List<FsStoreOrderVO> list= fsStoreOrderMapper.selectFsStoreOrderAllListVO(param);
        for(FsStoreOrderVO vo:list){
            String nickName = vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
            vo.setNickname(nickName);
            if(StringUtils.isNotEmpty(vo.getItemJson())){
                JSONArray jsonArray=JSONUtil.parseArray(vo.getItemJson());
                List<FsStoreOrderItemVO> items=JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
                if(items.size()>0){
                    vo.setItems(items);
                }
            }
        }
        return list;
    }

    @Override
    public List<FsStoreOrderVO> selectPayRemainListVO(FsStoreOrderParam param) {
        List<FsStoreOrderVO> list= fsStoreOrderMapper.selectFsPayRemainListVO(param);
        for(FsStoreOrderVO vo:list){
            String nickName = vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
            vo.setNickname(nickName);
            if(StringUtils.isNotEmpty(vo.getItemJson())){
                JSONArray jsonArray=JSONUtil.parseArray(vo.getItemJson());
                List<FsStoreOrderItemVO> items=JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
                if(items.size()>0){
                    vo.setItems(items);
                }
            }

        }
        return list;
    }


    @Override
    public List<FsPromotionOrderVO> selectFsPromotionOrderListVO(FsStoreOrderParam param) {
        List<FsPromotionOrderVO> list = fsStoreOrderMapper.selectFsPromotionOrderListVO(param);
        for(FsPromotionOrderVO vo:list){
            String nickName = vo.getUserPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
            String tuiNickName = vo.getTuiNickName().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
            vo.setNickname(nickName);
            vo.setTuiNickName(tuiNickName);
            if(StringUtils.isNotEmpty(vo.getItemJson())){
                JSONArray jsonArray=JSONUtil.parseArray(vo.getItemJson());
                List<FsStoreOrderItemVO> items=JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
                if(items.size()>0){
                    vo.setItems(items);
                }
            }

        }
        return list;
    }

    @Override
    public R confirmOrder(long uid, FsStoreConfirmOrderParam cartParam) {
        //获取地址信息和购物车信息
        FsUserAddress address= userAddressMapper.selectFsUserAddressByDefaultAddress(uid);
        List<FsStoreCartQueryVO>  carts=cartMapper.selectFsStoreCartListByIds(cartParam.getCartIds());
        String uuid = IdUtil.randomUUID();
        redisCache.setCacheObject("orderKey:"+uuid, cartParam.getCartIds(), 300, TimeUnit.SECONDS);
        redisCache.setCacheObject("orderCarts:"+uuid, carts, 300, TimeUnit.SECONDS);
        return R.ok().put("orderKey",uuid).put("address",address).put("carts",carts);

    }

    @Override
    public FsStoreOrderComputeDTO computedOrder(long uid, FsStoreOrderComputedParam param) {
        String cartIds = redisCache.getCacheObject("orderKey:" + param.getOrderKey());
        if (ObjectUtil.isNull(cartIds)) {
            throw new CustomException("订单已过期",501);
        }
        List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + param.getOrderKey());
        BigDecimal payPrice=getOrderSumPrice(carts,"truePrice");
        if(StringUtils.isNotEmpty(param.getCreateOrderKey()))
        {
            BigDecimal money=redisCache.getCacheObject("createOrderMoney:"+param.getCreateOrderKey());
            if(money!=null){
                payPrice=money;
            }
        }
        BigDecimal serviceFee=BigDecimal.ZERO;
        String configJson=configService.selectConfigByKey("store.config");
        StoreConfig config=JSONUtil.toBean(configJson,StoreConfig.class);
        if(config.getServiceFee()!=null){
            serviceFee=config.getServiceFee();
        }
        payPrice = payPrice.add(serviceFee);
        FsUserAddress userAddress = null;
        if (param.getAddressId()!=null) {
            userAddress = userAddressMapper.selectFsUserAddressById(param.getAddressId());
        }
        FsStoreOrderPriceDTO priceGroup = this.getOrderPriceGroup(carts, userAddress);
        BigDecimal payPostage = priceGroup.getStorePostage();
        payPrice = NumberUtil.add(payPrice, payPostage);

        FsUser user=userService.selectFsUserById(uid);
        // 积分抵扣
        BigDecimal deductionPrice = BigDecimal.ZERO; //积分抵扣金额
        double usedIntegral = 0; //使用了多少积分
        if (param.getUseIntegral()!=null&&param.getUseIntegral()==1 && user.getIntegral().intValue() > 0) {
            //如果积分总和小于用户积分 抵扣比例 计算抵扣价格
            //默认配置
            Double integralMax = Double.valueOf(100);
            BigDecimal integralFull = new BigDecimal(100);
            Double integralRatio = Double.valueOf(1);
            String json=configService.selectConfigByKey("store.integral");
            if(StringUtils.isEmpty(json)) {

            }
            else{
                StoreIntegralConfig integralConfig=JSONUtil.toBean(json,StoreIntegralConfig.class);
                integralMax = integralConfig.getIntegralMax();
                integralFull = integralConfig.getIntegralFull();
                integralRatio =integralConfig.getIntegralRatio();

            }
            if (priceGroup.getTotalPrice().compareTo(integralFull) >= 0) {
                Double userIntegral = user.getIntegral().doubleValue();
                if (integralMax.intValue() > 0 && Double.compare(userIntegral, integralMax) >= 0) {
                    userIntegral = integralMax;
                }
                deductionPrice = BigDecimal.valueOf(NumberUtil.mul(userIntegral, integralRatio));
                if (deductionPrice.compareTo(payPrice) < 0) {
                    payPrice = NumberUtil.sub(payPrice, deductionPrice);
                    usedIntegral = userIntegral;
                } else {
                    deductionPrice = payPrice;
                    payPrice = BigDecimal.ZERO;
                    usedIntegral = NumberUtil.round(NumberUtil.div(deductionPrice,
                            BigDecimal.valueOf(integralRatio)), 2).doubleValue();
                }
            }
        }

        if (payPrice.compareTo(BigDecimal.ZERO) <= 0) {
            payPrice = BigDecimal.ZERO;
        }
        //优惠券
        if(param.getCouponUserId()!=null){
            FsStoreCouponUser couponUser=couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
            if(couponUser!=null&&couponUser.getStatus()==0){
                if(couponUser.getUseMinPrice().compareTo(priceGroup.getTotalPrice())==-1){
                    payPrice=payPrice.subtract(couponUser.getCouponPrice());
                }
            }
        }

        return FsStoreOrderComputeDTO.builder()
                .totalPrice(priceGroup.getTotalPrice())
                .payPrice(payPrice)
                .payPostage(payPostage)
                .deductionPrice(deductionPrice)
                .usedIntegral(usedIntegral)
                .payIntegral(priceGroup.getPayIntegral())
                .serviceFee(serviceFee)
                .build();
    }


    @Override
    @Transactional
    public R createOrder(long userId, FsStoreOrderCreateParam param) {
        FsStoreOrderComputedParam computedParam=new FsStoreOrderComputedParam();
        BeanUtils.copyProperties(param, computedParam);
        //计算金额
        FsStoreOrderComputeDTO dto=this.computedOrder(userId, computedParam);
        String cartIds = redisCache.getCacheObject("orderKey:" + param.getOrderKey());
        Integer totalNum = 0;
        BigDecimal integral = BigDecimal.ZERO;
        if(cartIds!=null){
            //获取购物车列表
            List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + param.getOrderKey());
            //获取地址
            FsUserAddress address=userAddressMapper.selectFsUserAddressById(param.getAddressId());
            //检测库存
            //三种特定产品发YDSP001
            int ydspHouse = 0;
            //如果是美乳产品，发武汉仓库
            Integer meiruCount=0;
            for (FsStoreCartQueryVO cart : carts) {
//                cartService.checkProductStock( cart.getProductId(),cart.getProductAttrValueId());
                totalNum += cart.getCartNum();
                integral = NumberUtil.add(integral,
                        NumberUtil.mul(cart.getCartNum(), cart.getIntegral()));
//                if(cart.getCateId()!=null&&cart.getCateId().equals(176L)){
//                    meiruCount++;
//                }
                //判断是否是三种特定产品
                if(cart.getProductId()!=null&&(cart.getProductId().equals(3168L)||cart.getProductId().equals(3184L)||cart.getProductId().equals(3185L))){
                    ydspHouse++;
                }
            }
            //生成分布式唯一值
            String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
            //是否使用积分
            Boolean isIntegral=false;
            //组合数据
            FsStoreOrder storeOrder = new FsStoreOrder();

            //修改默认仓库
            if(ydspHouse>0){
//                storeOrder.setStoreHouseCode("WHSP001");
                storeOrder.setStoreHouseCode("YDSP001");
            }
            else{
                storeOrder.setStoreHouseCode("CQDS001");
            }
            storeOrder.setCompanyId(param.getCompanyId());
            storeOrder.setCompanyUserId(param.getCompanyUserId());
            if(param.getCompanyUserId()!=null){
                CompanyUser companyUser=companyUserService.selectCompanyUserById(param.getCompanyUserId());
                if(companyUser!=null){
                    storeOrder.setDeptId(companyUser.getDeptId());
                }
            }
            storeOrder.setUserId(userId);
            storeOrder.setOrderCode(orderSn);
            storeOrder.setRealName(address.getRealName());
            storeOrder.setUserPhone(address.getPhone());
            storeOrder.setUserAddress(address.getProvince() + " " + address.getCity() +
                    " " + address.getDistrict() + " " + address.getDetail().trim());
            storeOrder.setCartId(cartIds);
            storeOrder.setTotalNum(Long.parseLong(String.valueOf(carts.size())));
            storeOrder.setTotalPrice(dto.getTotalPrice());
            storeOrder.setTotalPostage(dto.getPayPostage());

            //优惠券处理
            if(param.getCouponUserId()!=null){
                FsStoreCouponUser couponUser=couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
                if(couponUser!=null&&couponUser.getStatus()==0){
                    storeOrder.setCouponId(couponUser.getId());
                    storeOrder.setCouponPrice(couponUser.getCouponPrice());
                    //更新优惠券状态
                    couponUser.setStatus(1);
                    couponUser.setUseTime(new Date());
                    couponUserService.updateFsStoreCouponUser(couponUser);
                }
            }
            //处理推荐人
            FsUser user= userService.selectFsUserById(storeOrder.getUserId());
            if(user.getSpreadUserId()!=null&&user.getSpreadUserId()>0){
                storeOrder.setTuiUserId(user.getSpreadUserId());
            }
            else{
                if(param.getTuiUserId()!=null){
                    FsUser tuiUser= userService.selectFsUserById(param.getTuiUserId());
                    if(tuiUser!=null&&tuiUser.getIsPromoter()==1){
                        storeOrder.setTuiUserId(param.getTuiUserId());
                    }
                }
            }
            storeOrder.setPayPostage(dto.getPayPostage());
            storeOrder.setDeductionPrice(dto.getDeductionPrice());
            storeOrder.setPaid(0);
            storeOrder.setPayType(param.getPayType());
            if (isIntegral) {
                storeOrder.setPayIntegral(integral);
            }
            storeOrder.setUseIntegral(BigDecimal.valueOf(dto.getUsedIntegral()));
            storeOrder.setBackIntegral(BigDecimal.ZERO);
            storeOrder.setGainIntegral(BigDecimal.ZERO);
            storeOrder.setMark(param.getMark());
            //todo 获取成本价
            BigDecimal costPrice = this.getOrderSumPrice(carts, "costPrice");
            storeOrder.setCost(costPrice);
            storeOrder.setIsChannel(1);
            storeOrder.setShippingType(1);
            storeOrder.setCreateTime(new Date());

            String json=configService.selectConfigByKey("store.config");
            StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
            if(config.getServiceFee()!=null){
                storeOrder.setServiceFee(config.getServiceFee());
            }


            if(param.getPayType().equals("1")){
                //全款支付
                storeOrder.setStatus(0);
            }
            else if(param.getPayType().equals("2")){
                //货到付款
                storeOrder.setStatus(1);
            }
            //后台制单处理
            if(param.getPayPrice()!=null&&param.getPayPrice().compareTo(BigDecimal.ZERO)>0){
                storeOrder.setPayPrice(param.getPayPrice());
            }
            else{
                storeOrder.setPayPrice(dto.getPayPrice());
            }
            storeOrder.setOrderCreateType(param.getOrderCreateType());
            Long prescribe = carts.stream().filter(item -> item.getProductType()!=null&&item.getProductType()==2).count();
            if(prescribe>0){
                storeOrder.setIsPrescribe(1);
            }
            Integer flag=fsStoreOrderMapper.insertFsStoreOrder(storeOrder);
            if (flag==0) {
                return R.error("订单创建失败");
            }
            //收款单更新
//            if(param.getPaymentId()!=null&&param.getPaymentId()>0){
//                FsStorePayment payment=new FsStorePayment();
//                payment.setOrderId(storeOrder.getId());
//                payment.setPaymentId(param.getPaymentId());
//                paymentService.updateFsStorePayment(payment);
//            }
            //使用了积分扣积分
            if (dto.getUsedIntegral() > 0) {
                this.decIntegral(userId, dto.getUsedIntegral(), dto.getDeductionPrice().doubleValue(),storeOrder.getId().toString());
            }
            //减库存加销量
            this.deStockIncSale(carts);
            //保存OrderItem
            List<FsStoreOrderItem> listOrderItem=new ArrayList<>();
            //保存购物车商品信息
            for(FsStoreCartQueryVO vo:carts){
                FsStoreCartDTO fsStoreCartDTO=new FsStoreCartDTO();
                fsStoreCartDTO.setProductId(vo.getProductId());
                fsStoreCartDTO.setPrice(vo.getPrice());
                fsStoreCartDTO.setSku(vo.getProductAttrName());
                fsStoreCartDTO.setProductName(vo.getProductName());
                fsStoreCartDTO.setNum(vo.getCartNum());
                fsStoreCartDTO.setBarCode(vo.getBarCode());
                fsStoreCartDTO.setGroupBarCode(vo.getGroupBarCode());
                fsStoreCartDTO.setBrokerage(vo.getBrokerage());
                fsStoreCartDTO.setBrokerageTwo(vo.getBrokerageTwo());
                fsStoreCartDTO.setBrokerageThree(vo.getBrokerageThree());
                if(StringUtils.isEmpty(vo.getProductAttrImage())){
                    fsStoreCartDTO.setImage(vo.getProductImage());
                }
                else{
                    fsStoreCartDTO.setImage(vo.getProductAttrImage());
                }

                FsStoreOrderItem item=new FsStoreOrderItem();
                item.setOrderId(storeOrder.getId());
                item.setOrderCode(orderSn);
                item.setCartId(vo.getId());
                item.setProductId(vo.getProductId());
                item.setJsonInfo(JSONUtil.toJsonStr(fsStoreCartDTO));
                item.setNum(vo.getCartNum());
                item.setIsAfterSales(0);
                //处方药
                if(vo.getProductType().equals(2)){
                    item.setIsPrescribe(1);
                }
                fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
                listOrderItem.add(item);
            }
            if(listOrderItem.size()>0){
                String itemJson=JSONUtil.toJsonStr(listOrderItem);
                storeOrder.setItemJson(itemJson);
                fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
            }
            //购物车状态修改
            cartMapper.updateIsPay(cartIds);

            //删除缓存
            redisCache.deleteObject("orderKey:" + param.getOrderKey());
            redisCache.deleteObject("orderCarts:" + param.getOrderKey());

            //添加记录
            orderStatusService.create(storeOrder.getId(), OrderLogEnum.CREATE_ORDER.getValue(),
                    OrderLogEnum.CREATE_ORDER.getDesc());

            //加入redis，24小时自动取消
            String redisKey = String.valueOf(StrUtil.format("{}{}",
                    StoreConstants.REDIS_ORDER_OUTTIME_UNPAY, storeOrder.getId()));

            if(config.getUnPayTime()!=null&&config.getUnPayTime()>0){
                redisCache.setCacheObject(redisKey,storeOrder.getId(),config.getUnPayTime(), TimeUnit.MINUTES);
            }
            else{
                redisCache.setCacheObject(redisKey,storeOrder.getId(),30, TimeUnit.MINUTES);
            }
            //添加支付到期时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(storeOrder.getCreateTime());
            calendar.add(Calendar.MINUTE,config.getUnPayTime());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String payLimitTime = format.format(calendar.getTime() );
            //删除推荐订单KEY
            if(StringUtils.isNotEmpty(param.getCreateOrderKey())){
                redisCache.deleteObject("createOrderKey:"+param.getCreateOrderKey());
                redisCache.deleteObject("orderCarts:" +param.getCreateOrderKey());
                redisCache.deleteObject("createOrderMoney:" +param.getCreateOrderKey());
            }
            return R.ok().put("order", storeOrder).put("payLimitTime",payLimitTime);
        }
        else{
            return R.error("订单已过期");
        }
    }

    /**
     * 积分抵扣
     */
    private void decIntegral(Long uid, double usedIntegral, double deductionPrice,String busId) {
        userService.decIntegral(uid, usedIntegral);
        FsUser user=userService.selectFsUserById(uid);
        //积分记录
        billService.addBill(uid, BillDetailEnum.CATEGORY_2.getValue(),0, BillDetailEnum.TYPE_1.getDesc(),  usedIntegral, user.getIntegral().doubleValue(),
                "购买商品使用" + usedIntegral + "积分抵扣" + deductionPrice + "元",busId,0l);

    }

    public void deStockIncSale(List<FsStoreCartQueryVO> cartInfo) {
        for (FsStoreCartQueryVO storeCartVO : cartInfo) {
            productService.decProductStock(storeCartVO.getProductId(),
                    storeCartVO.getProductAttrValueId(),storeCartVO.getCartNum());
        }
    }

    //未支付取消订单
    @Override
    public void cancelOrder(Long orderId) {
        FsStoreOrder order= fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if(order.getStatus()==OrderInfoEnum.STATUS_0.getValue()){
            if(!StringUtils.isEmpty(order.getExtendOrderId())){
                redisCache.deleteObject(DELIVERY+":"+order.getExtendOrderId());
            }
            //退回积分
            this.refundIntegral(order);
            //退回优惠券
            this.refundCoupon(order);
            //退回库存
            this.refundStock(order);
            fsStoreOrderMapper.cancelOrder(orderId);
            //添加记录
            orderStatusService.create(order.getId(), OrderLogEnum.CANCEL_ORDER.getValue(),
                    OrderLogEnum.CANCEL_ORDER.getDesc());
//            if(order.getPaid()==1){
//                //更新OMS
//                ErpRefundUpdateRequest request=new ErpRefundUpdateRequest();
//                request.setTid(order.getOrderCode());
//                request.setOid(order.getOrderCode());
//                request.setRefund_state(1);
//                erpOrderService.refundUpdate(request);
//            }
            TemplateBean templateBean = TemplateBean.builder()
                    .orderId(order.getId().toString())
                    .orderCode(order.getOrderCode().toString())
                    .remark("您的订单已取消")
                    .userId(order.getUserId())
                    .templateType(TemplateListenEnum.TYPE_1.getValue())
                    .build();
            publisher.publishEvent(new TemplateEvent(this, templateBean));
        }
    }

    @Override
    @Transactional
    public void refundPrescribeOrder(Long orderId) {
        FsStoreOrder order= fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if(order!=null&&order.getStatus()==OrderInfoEnum.STATUS_1.getValue()&&order.getRefundStatus()==0){
            //退回积分
            this.refundIntegral(order);
            //退回库存
            this.refundStock(order);
            fsStoreOrderMapper.cancelOrder(orderId);
            //退佣金
            if(order.getTuiUserId()!=null&&order.getTuiUserId()>0){
                userService.subTuiMoney(order);
            }
            if(order.getPayType().equals(3)){
                //货到付款
            }
            else{
                FsStoreOrder orderMap=new FsStoreOrder();
                orderMap.setId(order.getId());
                orderMap.setRefundPrice(order.getPayMoney());
                orderMap.setRefundReason("拒绝开方自动退款");
                orderMap.setRefundReasonTime(new Date());
                fsStoreOrderMapper.updateFsStoreOrder(orderMap);
                //将钱退还给用户
                List<FsStorePayment> payments=paymentService.selectFsStorePaymentByOrderId(order.getId());
                if(payments!=null){
                    for(FsStorePayment payment:payments){
                        //易宝退款
                        com.fs.pay.pay.dto.RefundDTO refundDTO = new com.fs.pay.pay.dto.RefundDTO();
                        refundDTO.setRefundMoney(payment.getPayMoney().toString());
                        refundDTO.setLowRefundNo("refund-"+payment.getPayCode());
                        refundDTO.setUpOrderId(payment.getTradeNo());
                        RefundResult result=ybPayService.refund(refundDTO);
                        if(result.getState().equals("5")||result.getState().equals("6")){
                            payment.setRefundMoney(payment.getPayMoney());
                            payment.setStatus(-1);
                            payment.setRefundTime(new Date());
                            paymentService.updateFsStorePayment(payment);
                        }
                        else{
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            return;
                        }

                        //小雨点退款
//                        RefundDTO refundDTO=new RefundDTO();
//                        refundDTO.setMerchOrderNo(Ids.oid());
//                        refundDTO.setAmount(payment.getPayMoney().toString());
//                        if(payment.getIsPayRemain()!=null&&payment.getIsPayRemain().equals(1)){
//                            refundDTO.setOrigMerchOrderNo("store_remain-"+payment.getPayCode());
//                        }
//                        else{
//                            refundDTO.setOrigMerchOrderNo("store-"+payment.getPayCode());
//                        }
//                        payService.refundOrder(refundDTO);
                    }
                }
            }
        }
    }


    private void refundCoupon(FsStoreOrder order) {
        if(order.getCouponId()!=null){
            FsStoreCouponUser couponUser=couponUserService.selectFsStoreCouponUserById(order.getCouponId());
            if(couponUser!=null){
                couponUser.setStatus(0);
                couponUser.setUseTime(null);
                couponUserService.updateFsStoreCouponUser(couponUser);
            }
        }
    }

    //已支付退款
    @Override
    public void refundOrder(Long orderId) {

        FsStoreOrder order= fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if(order!=null&&order.getStatus()==OrderInfoEnum.STATUS_1.getValue()&&order.getRefundStatus()==0){
            //退回积分
            this.refundIntegral(order);
            //退回库存
            this.refundStock(order);
            fsStoreOrderMapper.cancelOrder(orderId);
        }
    }

    @Override
    public void deliveryOrder(String orderCode,String deliveryId,String deliverCode,String deliverName) {
        FsStoreOrder order= fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderCode);
        if(order!=null&&order.getStatus()==OrderInfoEnum.STATUS_1.getValue()){
            FsExpress express=expressService.selectFsExpressByOmsCode(deliverCode);
            if(express!=null){
                order.setDeliveryName(deliverName);
                order.setDeliverySn(express.getCode());
            }
            order.setStatus(OrderInfoEnum.STATUS_2.getValue());
            order.setDeliveryId(deliveryId);
            order.setDeliverySendTime(new Date());

            fsStoreOrderMapper.updateFsStoreOrder(order);
            orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
                    OrderLogEnum.DELIVERY_GOODS.getDesc());
            //订阅物流回调
            String lastFourNumber = "";
            if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
                lastFourNumber = order.getUserPhone();
                if (lastFourNumber.length() == 11) {
                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                }
            }
            expressService.subscribeEspress(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);

            TemplateBean templateBean = TemplateBean.builder()
                    .orderId(order.getId().toString())
                    .orderCode(order.getOrderCode().toString())
                    .deliveryId(order.getDeliveryId())
                    .deliveryName(order.getDeliveryName())
                    .userId(order.getUserId())
                    .templateType(TemplateListenEnum.TYPE_2.getValue())
                    .build();
            publisher.publishEvent(new TemplateEvent(this, templateBean));
        }
    }

    @Override
    public void updateDeliveryOrder(Long id,String deliveryId,String deliverCode,String deliverName) {
        FsStoreOrder order= fsStoreOrderMapper.selectFsStoreOrderById(id);
        if(order!=null){
            FsExpress express=expressService.selectFsExpressByOmsCode(deliverCode);
            if(express!=null){
            order.setDeliveryName(deliverName);
            order.setDeliverySn(express.getCode());
            order.setDeliveryId(deliveryId);
            order.setDeliverySendTime(new Date());
            fsStoreOrderMapper.updateFsStoreOrder(order);
            orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
                    OrderLogEnum.DELIVERY_GOODS.getDesc());
            //订阅物流回调
            String lastFourNumber = "";
            if (express.getCode().equals(ShipperCodeEnum.SF.getValue())) {
                lastFourNumber = order.getUserPhone();
                if (lastFourNumber.length() == 11) {
                    lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                }
            }
            expressService.subscribeEspress(order.getOrderCode(),express.getCode(),deliveryId,lastFourNumber);
            }
        }
    }


    @Override
    public List<FsMyStoreOrderListQueryVO> selectFsMyStoreOrderListVO(FsMyStoreOrderQueryParam param) {
        List<FsMyStoreOrderListQueryVO> list= fsStoreOrderMapper.selectFsMyStoreOrderListVO(param);
        for(FsMyStoreOrderListQueryVO vo:list){
//          List<FsStoreOrderItemVO> items=fsStoreOrderItemMapper.selectMyFsStoreOrderItemListByOrderId(vo.getId());
//          vo.setItems(items);
            if(StringUtils.isNotEmpty(vo.getItemJson())){
                JSONArray jsonArray=JSONUtil.parseArray(vo.getItemJson());
                List<FsStoreOrderItemVO> items=JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
                if(items.size()>0){
                    vo.setItems(items);
                }
            }
            //处理是否可以申请售后
            vo.setIsAfterSales(0);
            if(vo.getStatus().equals(OrderInfoEnum.STATUS_3.getValue())){
                //已完成订单
                vo.setIsAfterSales(1);
                if(vo.getFinishTime()!=null){
                    String json=configService.selectConfigByKey("store.config");
                    StoreConfig storeConfig=JSONUtil.toBean(json,StoreConfig.class);
                    if(storeConfig.getStoreAfterSalesDay()!=null&&storeConfig.getStoreAfterSalesDay()>0){
                        //判断完成时间是否超过指定时间
                        Calendar calendar = new GregorianCalendar();
                        calendar.setTime(vo.getFinishTime());
                        calendar.add(calendar.DATE,storeConfig.getStoreAfterSalesDay()); //把日期往后增加一天,整数  往后推,负数往前移动
                        if(calendar.getTime().getTime()<new Date().getTime()){
                            vo.setIsAfterSales(0);
                        }
                    }
                }
            }
            else if(vo.getStatus()==1||vo.getStatus()==2){
                vo.setIsAfterSales(1);
            }
        }
        return list;
    }

    @Override
    public FsStoreOrder selectFsStoreOrderByOrderCode(String orderCode) {
        return fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderCode);
    }

    @Override
    public R getExpress(FsStoreOrder order) {
        //顺丰轨迹查询处理
        String lastFourNumber = "";
        if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
            lastFourNumber = order.getUserPhone();
            if (lastFourNumber.length() == 11) {
                lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
            }
        }
        ExpressInfoDTO dto=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
        dto.setShipperName(order.getDeliveryName());
        FsExpress express=expressService.selectFsExpressByName(order.getDeliveryName());
        return R.ok().put("data", dto).put("express",express).put("deliveryId",order.getDeliveryId());
    }

    @Override
    @Transactional
    public R createUserOrder(FsStoreOrderCreateUserParam param) {

        List<String> cartIds=new ArrayList<>();
        for(FsStoreProductAttrValueVO productAttrValue:param.getProducts()){
            FsStoreCart storeCart = FsStoreCart.builder()
                    .cartNum(productAttrValue.getCount())
                    .productAttrValueId(productAttrValue.getId())
                    .productId(productAttrValue.getProductId())
                    .userId(param.getUserId())
                    .isPay(0)
                    .isDel(0)
                    .isBuy(0)
                    .build();
            storeCart.setCreateTime(new Date());
//            cartService.checkProductStock(productAttrValue.getProductId(),storeCart.getProductAttrValueId());
            cartService.insertFsStoreCart(storeCart);
            cartIds.add(storeCart.getId().toString());
        }
        FsStoreConfirmOrderParam confirmOrderParam=new FsStoreConfirmOrderParam();
        confirmOrderParam.setCartIds(StringUtils.join(cartIds.toArray(), ","));
        confirmOrderParam.setType("buy");
        R confirmResult=this.confirmOrder(param.getUserId(),confirmOrderParam);
        if(confirmResult.get("code").equals(200)){
            FsStoreOrderCreateParam createParam=new FsStoreOrderCreateParam();
            createParam.setUserId(param.getUserId());
            createParam.setAddressId(param.getAddressId());
            createParam.setOrderKey(confirmResult.get("orderKey").toString());
            createParam.setMark(param.getMark());
            createParam.setUseIntegral(0);
            createParam.setPayType(param.getPayType().toString());
            createParam.setCompanyId(param.getCompanyId());
            createParam.setCompanyUserId(param.getCompanyUserId());
            createParam.setPaymentId(param.getPaymentId());
            createParam.setPayPrice(param.getPayPrice());
            return this.createOrder(param.getUserId(),createParam);
        }
        else{
            throw new CustomException("创建失败");
        }
    }

    @Override
    public List<FsMyStoreOrderListQueryVO> selectFsCompanyStoreOrderListVO(FsMyStoreOrderQueryParam param) {
        List<FsMyStoreOrderListQueryVO> list=fsStoreOrderMapper.selectFsCompanyStoreOrderListVO(param);
        for(FsMyStoreOrderListQueryVO vo:list){
//          List<FsStoreOrderItemVO> items=fsStoreOrderItemMapper.selectMyFsStoreOrderItemListByOrderId(vo.getId());
//          vo.setItems(items);
            if(StringUtils.isNotEmpty(vo.getItemJson())){
                JSONArray jsonArray=JSONUtil.parseArray(vo.getItemJson());
                List<FsStoreOrderItemVO> items=JSONUtil.toList(jsonArray, FsStoreOrderItemVO.class);
                if(items.size()>0){
                    vo.setItems(items);
                }
            }
        }
        return list;
    }

    @Override
    public FsStoreOrder selectFsStoreOrderByExtendOrderId(String extendOrderId) {
        return fsStoreOrderMapper.selectFsStoreOrderByExtendOrderId(extendOrderId);
    }

    @Override
    public List<FsStoreOrderTuiVO> selectFsStoreOrderTuiListVO(String userId) {
        return fsStoreOrderMapper.selectFsStoreOrderTuiListVO(userId);
    }

    @Override
    public R confirmPackageOrder(long uid, FsStoreConfirmPackageIdOrderParam param) {
        FsUserAddress address= userAddressMapper.selectFsUserAddressByDefaultAddress(uid);
        FsStoreProductPackage storeProductPackage=productPackageService.selectFsStoreProductPackageById(param.getPackageId());
        String uuid = IdUtil.randomUUID();
        BigDecimal totalMoney=storeProductPackage.getPayMoney();
        if(param.getCouponUserId()!=null){
            FsStoreCouponUser couponUser=couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
            if(couponUser!=null&&couponUser.getStatus()==0){
                if(couponUser.getUseMinPrice().compareTo(storeProductPackage.getPayMoney())==-1){
                    //
                    totalMoney=totalMoney.subtract(couponUser.getCouponPrice());
                }
            }
        }

        redisCache.setCacheObject("orderKey:"+uuid, storeProductPackage.getPackageId().toString(), 300, TimeUnit.SECONDS);
        return R.ok().put("orderKey",uuid).put("address",address).put("package",storeProductPackage).put("totalMoney",totalMoney);
    }

    @Override
    @Transactional
    public R createPackageOrder(long uid, FsStorePackageOrderCreateParam param) {
        //计算金额
        String packageId = redisCache.getCacheObject("orderKey:" + param.getOrderKey());
        if(packageId!=null){
            FsStoreProductPackage storeProductPackage=productPackageService.selectFsStoreProductPackageById(param.getPackageId());
            if(storeProductPackage.getStatus().equals(0)){
                return R.error("此套餐已下架" );
            }
            //限购处理
            if(storeProductPackage.getLimitCount()!=null&&storeProductPackage.getLimitCount()>0){
                //查看是否已购买
                FsUser user=userService.selectFsUserById(uid);
                if(!user.getLevel().equals(1)){
                    if(fsStoreOrderMapper.checkPackageOrderCount(uid,packageId)>=storeProductPackage.getLimitCount()){
                        return R.error("此套餐限购:"+storeProductPackage.getLimitCount()+"次");
                    }
                }
            }
            //获取地址
            FsUserAddress address=userAddressMapper.selectFsUserAddressById(param.getAddressId());
            //获取套餐数据
            JSONArray jsonArray=JSONUtil.parseArray(storeProductPackage.getProducts());
            List<StorePackageProductDTO> goodsList=JSONUtil.toList(jsonArray,StorePackageProductDTO.class);
            //检测库存
            Integer totalNum=0;
            //如果是美乳产品，发武汉仓库
            Integer meiruCount=0;
            //指定三个产品发ydsp
            int ydspHouse = 0;
            List<FsStoreCartQueryVO> carts=new ArrayList<>();
            for (StorePackageProductDTO goods : goodsList) {
                FsStoreProductAttrValue attrValue=attrValueService.selectFsStoreProductAttrValueById(goods.getId());
                if(attrValue!=null&&attrValue.getProductId()!=null){
                    FsStoreProduct product=storeProductService.selectFsStoreProductById(attrValue.getProductId());
                    if(product!=null){
                        totalNum += goods.getCount();
                        FsStoreCartQueryVO vo=new FsStoreCartQueryVO();
                        vo.setProductId(attrValue.getProductId());
                        vo.setProductAttrValueId(goods.getId());
                        vo.setCartNum(goods.getCount());
                        vo.setProductName(product.getProductName());
                        vo.setProductAttrName(attrValue.getSku());
                        vo.setProductImage(product.getImage());
                        vo.setBarCode(attrValue.getBarCode());
                        vo.setGroupBarCode(attrValue.getGroupBarCode());
                        vo.setPrice(product.getPrice());
                        vo.setProductType(product.getProductType());
                        carts.add(vo);
//                        if(product.getCateId()!=null&&product.getCateId().equals(176L)){
//                            meiruCount++;
//                        }
                        //判断是否是三种特定产品
                        if(product.getProductId()!=null&&(product.getProductId().equals(3168L)||product.getProductId().equals(3184L)||product.getProductId().equals(3185L))){
                            ydspHouse++;
                        }

                    }
                }
                //cartService.checkProductStock(attrValue.getProductId(),attrValue.getId(), goods.getCount() );
            }
            //生成分布式唯一值
            String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
            //是否使用积分
            Boolean isIntegral=false;
            //组合数据
            CompanyUser user= companyUserService.selectCompanyUserById(param.getCompanyUserId());
            FsStoreOrder storeOrder = new FsStoreOrder();
            //修改默认仓库
            if(ydspHouse>0){
                storeOrder.setStoreHouseCode("YDSP001");
            }
            else{
                storeOrder.setStoreHouseCode("CQDS001");
            }
            if(user!=null){
                storeOrder.setCompanyId(user.getCompanyId());
                storeOrder.setDeptId(user.getDeptId());
            }
            BigDecimal totalMoney=storeProductPackage.getPayMoney();
            //优惠券处理
            if(param.getCouponUserId()!=null){
                FsStoreCouponUser couponUser=couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
                if(couponUser!=null&&couponUser.getStatus()==0){
                    if(couponUser.getUseMinPrice().compareTo(storeProductPackage.getPayMoney())==-1){
                        //
                        totalMoney=totalMoney.subtract(couponUser.getCouponPrice());
                        storeOrder.setCouponId(couponUser.getId());
                        storeOrder.setCouponPrice(couponUser.getCouponPrice());
                        //更新优惠券状态
                        couponUser.setStatus(1);
                        couponUser.setUseTime(new Date());
                        couponUserService.updateFsStoreCouponUser(couponUser);
                    }
                }
            }
            storeOrder.setCompanyUserId(param.getCompanyUserId());
            storeOrder.setUserId(uid);
            storeOrder.setOrderCode(orderSn);
            storeOrder.setRealName(address.getRealName());
            storeOrder.setUserPhone(address.getPhone());
            storeOrder.setUserAddress(address.getProvince() + " " + address.getCity() +
                    " " + address.getDistrict() + " " + address.getDetail());

            storeOrder.setTotalNum(Long.parseLong(String.valueOf(goodsList.size())));
            storeOrder.setTotalPrice(storeProductPackage.getPayMoney());
            storeOrder.setTotalPostage(BigDecimal.ZERO);

            storeOrder.setPayPostage(BigDecimal.ZERO);
            storeOrder.setDeductionPrice(BigDecimal.ZERO);
            storeOrder.setPaid(0);
            storeOrder.setUseIntegral(BigDecimal.ZERO);
            storeOrder.setBackIntegral(BigDecimal.ZERO);
            storeOrder.setGainIntegral(BigDecimal.ZERO);
            storeOrder.setMark(param.getMark());
            storeOrder.setIsChannel(1);
            storeOrder.setShippingType(1);
            storeOrder.setCreateTime(new Date());
            storeOrder.setStatus(0);
            storeOrder.setOrderCreateType(2);
            storeOrder.setPayType(storeProductPackage.getPayType().toString());
            storeOrder.setPayPrice(totalMoney);
            storeOrder.setIsPackage(1);
            FsStoreProductPackage productPackage=new FsStoreProductPackage();
            productPackage.setTitle(storeProductPackage.getTitle());
            productPackage.setImgUrl(storeProductPackage.getImgUrl());
            productPackage.setDescs(storeProductPackage.getDescs());
            productPackage.setPayMoney(storeOrder.getPayMoney());
            productPackage.setPackageId(storeProductPackage.getPackageId());
            storeOrder.setPackageJson(JSONUtil.toJsonStr(productPackage));
            storeOrder.setPackageId(storeProductPackage.getPackageId());
            Long prescribe = carts.stream().filter(item -> item.getProductType()!=null&&item.getProductType()==2).count();
            if(prescribe>0){
                storeOrder.setIsPrescribe(1);
            }
            Integer flag=fsStoreOrderMapper.insertFsStoreOrder(storeOrder);
            if (flag==0) {
                return R.error("订单创建失败");
            }
            //减库存加销量
            this.deStockIncSale(carts);
            //保存购物车商品信息
            for(FsStoreCartQueryVO vo:carts){
                FsStoreCartDTO fsStoreCartDTO=new FsStoreCartDTO();
                fsStoreCartDTO.setProductId(vo.getProductId());
                fsStoreCartDTO.setPrice(vo.getPrice());
                fsStoreCartDTO.setSku(vo.getProductAttrName());
                fsStoreCartDTO.setProductName(vo.getProductName());
                fsStoreCartDTO.setNum(vo.getCartNum());
                fsStoreCartDTO.setBarCode(vo.getBarCode());
                fsStoreCartDTO.setGroupBarCode(vo.getGroupBarCode());
                if(StringUtils.isEmpty(vo.getProductAttrImage())){
                    fsStoreCartDTO.setImage(vo.getProductImage());
                }
                else{
                    fsStoreCartDTO.setImage(vo.getProductAttrImage());
                }
                FsStoreOrderItem item=new FsStoreOrderItem();
                item.setOrderId(storeOrder.getId());
                item.setOrderCode(orderSn);
                item.setCartId(vo.getId());
                item.setProductId(vo.getProductId());
                item.setJsonInfo(JSONUtil.toJsonStr(fsStoreCartDTO));
                item.setNum(vo.getCartNum());
                item.setIsAfterSales(0);
                //处方药
                if(vo.getProductType().equals(2)){
                    item.setIsPrescribe(1);
                }
                fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
            }
            //删除缓存
            redisCache.deleteObject("orderKey:" + param.getOrderKey());
            //添加记录
            orderStatusService.create(storeOrder.getId(), OrderLogEnum.CREATE_ORDER.getValue(),
                    OrderLogEnum.CREATE_ORDER.getDesc());

            //加入redis，30分钟自动取消
            String redisKey = String.valueOf(StrUtil.format("{}{}",
                    StoreConstants.REDIS_ORDER_OUTTIME_UNPAY, storeOrder.getId()));

            //添加支付到期时间
            String json=configService.selectConfigByKey("store.config");
            StoreConfig config=JSONUtil.toBean(json,StoreConfig.class);
            if(config.getUnPayTime()!=null&&config.getUnPayTime()>0){
                redisCache.setCacheObject(redisKey,storeOrder.getId(),config.getUnPayTime(), TimeUnit.MINUTES);
            }
            else{
                redisCache.setCacheObject(redisKey,storeOrder.getId(),30, TimeUnit.MINUTES);
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(storeOrder.getCreateTime());
            calendar.add(Calendar.MINUTE,config.getUnPayTime());
            SimpleDateFormat format = new   SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String payLimitTime = format.format(calendar.getTime() );
            return R.ok().put("order", storeOrder).put("payLimitTime",payLimitTime);
        }
        else{
            return R.error("订单已过期");
        }
    }

    @Override
    public synchronized  R finishOrder(Long orderId) {
        return finishStoreOrder(orderId);
    }

    @Transactional
    R finishStoreOrder(Long orderId){
        FsStoreOrder order= fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if(order.getStatus()==OrderInfoEnum.STATUS_2.getValue()){
            order.setFinishTime(new Date());
            order.setStatus(3);
            fsStoreOrderMapper.updateFsStoreOrder(order);
            orderStatusService.create(order.getId(), OrderLogEnum.FINISH_ORDER.getValue(),
                    OrderLogEnum.FINISH_ORDER.getDesc());
            //写入公司余额 条件是只有全款订单才分，非全款后台导入
            if(order.getCompanyId()!=null&&order.getCompanyId()>0&&order.getPayDelivery().compareTo(new BigDecimal(0))==0){
                if(order.getTuiMoneyStatus()==null||order.getTuiMoneyStatus()!=1){
                    companyService.addCompanyMoney(order);
                }
            }
            //模板消息支付成功发布事件
            TemplateBean templateBean = TemplateBean.builder()
                    .orderId(order.getId().toString())
                    .orderCode(order.getOrderCode().toString())
                    .remark("您的订单已签收成功")
                    .finishTime(order.getFinishTime())
                    .userId(order.getUserId())
                    .templateType(TemplateListenEnum.TYPE_3.getValue())
                    .build();
            publisher.publishEvent(new TemplateEvent(this, templateBean));
            return R.ok("操作成功");
        }
        else {
            return R.error("非法操作");
        }
    }

    @Override
    @Transactional
    //类型1支付回调 类型2货到付款
    public String payConfirm(Integer type,Long orderId,String payCode,String tradeNo,String bankTransactionId,String bankSerialNo) {
        //支付订单
        try {
            FsStoreOrder order=null;
            if(type.equals(1)){
                FsStorePayment storePayment=paymentService.selectFsStorePaymentByCode(payCode);
                if(storePayment==null||!storePayment.getStatus().equals(0)){
                    return "";
                }
                FsStorePayment storePaymentMap=new FsStorePayment();
                storePaymentMap.setPaymentId(storePayment.getPaymentId());
                storePaymentMap.setStatus(1);
                storePaymentMap.setPayTime(new Date());
                storePaymentMap.setTradeNo(tradeNo);
                storePaymentMap.setBankSerialNo(bankSerialNo);
                storePaymentMap.setBankTransactionId(bankTransactionId);
                paymentService.updateFsStorePayment(storePaymentMap);
                order=fsStoreOrderMapper.selectFsStoreOrderById(storePayment.getOrderId());
//                if(order!=null&&!order.getStatus().equals(OrderInfoEnum.STATUS_0.getValue())){
//                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return "";
//                }
                if(order!=null&&!order.getPaid().equals(0)){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return "";
                }
            }
            else if(type.equals(2)){
                //货到付款
                order=fsStoreOrderMapper.selectFsStoreOrderById(orderId);
                if(!order.getStatus().equals(OrderInfoEnum.STATUS_0.getValue())){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return "";
                }
            }
            //写入公司佣金 当有归属公司时只进行公司分佣
            if(order.getCompanyId()!=null&&order.getCompanyId()>0){
                companyService.addCompanyTuiMoney(order);
                //没有归属公司对个人分佣
            }
            else if (order.getIsPackage()!=1&&order.getTuiUserId()!=null&&order.getTuiUserId()>0){
                //处理佣金 套餐不分佣金
                FsStoreOrderItem orderItemMap=new FsStoreOrderItem();
                orderItemMap.setOrderId(order.getId());
                List<FsStoreOrderItem> items= storeOrderItemService.selectFsStoreOrderItemList(orderItemMap);
                userService.addTuiMoney(order,items);
            }
            //增加用户购买次数
            userService.incPayCount(order.getUserId());
            //增加状态
            orderStatusService.create(order.getId(), OrderLogEnum.PAY_ORDER_SUCCESS.getValue(),
                    OrderLogEnum.PAY_ORDER_SUCCESS.getDesc());
//        FsUser user=userService.selectFsUserById(order.getUserId());
//        //增加流水
//        String payTypeMsg = PayTypeEnum.WEIXIN.getDesc();
//        billService.addBill(user.getUserId(),
//                BillDetailEnum.CATEGORY_1.getValue(),
//                0,
//                BillDetailEnum.TYPE_1.getDesc(),
//                order.getPayPrice().doubleValue(), user.getNowMoney().doubleValue(),
//                payTypeMsg + order.getPayPrice() + "元购买商品",order.getId().toString());
            FsStoreOrder storeOrder = new FsStoreOrder();
            storeOrder.setId(order.getId());
            storeOrder.setPaid(OrderInfoEnum.PAY_STATUS_1.getValue());
            storeOrder.setStatus(OrderInfoEnum.STATUS_1.getValue());
            storeOrder.setPayTime(new Date());
            fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
            //非处方直接提交OMS
//            if(order.getIsPrescribe().equals(0)){
//                createOmsOrder(order.getId());
//            }
//            else if(order.getIsPrescribe().equals(1)){
//                //是否已开方
//                FsPrescribe prescribe=prescribeService.selectFsPrescribeByOrderId(order.getId());
//                if(prescribe!=null&&prescribe.getStatus()==1){
//                    createOmsOrder(order.getId());
//                }
//            }
        }
        catch (Exception e){
            logger.info("payConfirm:"+e.getMessage());
            logger.info("payConfirm:"+e.getLocalizedMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return "";
        }
        return "SUCCESS";
    }


    public  boolean containsAddress(String companyName) {
        String[] items= {"新疆","西藏","内蒙古","海南"};
        boolean found = false;
        for (String item : items) {
            if (companyName.contains(item)) {
                found = true;
                break;
            }
        }
        return found;
    }


    @Override
    public void createOmsOrder(Long orderId) throws ParseException {
        FsStoreOrder order=fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if(!StringUtils.isEmpty(order.getExtendOrderId())&&order.getStatus()!=1){
            return;
        }
        ErpOrder erpOrder = getErpOrder(order);
        ErpOrderResponse response= erpOrderService.addOrder(erpOrder);
        //写入日志
        logger.info("ErpCreate:"+order.getOrderCode()+":"+JSONUtil.toJsonStr(response));
        //支付成功后 将订单号写入待发货的REDIS中
        redisCache.setCacheObject(DELIVERY+":"+response.getCode(),order.getOrderCode());
        //写入外部订单号
        order.setExtendOrderId(response.getCode());
        fsStoreOrderMapper.updateFsStoreOrder(order);

    }

    @Override
    public ErpOrder getErpOrder(FsStoreOrder order) throws ParseException {
        ErpOrder erpOrder=new ErpOrder();
        if (order.getCompanyId()!=null){
            erpOrder.setVip_code(order.getUserId().toString()+ order.getCompanyId().toString());
        }else {
            erpOrder.setVip_code(order.getUserId().toString());
        }
        erpOrder.setPlatform_code(order.getOrderCode());
//        if(order.getStoreHouseCode()==null){
//            erpOrder.setWarehouse_code("CQDS001");
//        }
//        else{
            erpOrder.setWarehouse_code(wareHouseCode);
//        }
//        if(order.getStoreHouseCode().equals("YDSP001")){
//            erpOrder.setShop_code("RunDayWuHan");
//        }
//        else{
            erpOrder.setShop_code(sysConfig.getErpShopCode());
//        }
//      erpOrder.setPost_fee(order.getTotalPostage().doubleValue());
        erpOrder.setSeller_memo(order.getMark());
        // order.setCurrency_code("JCZD");
        List<ErpOrderPayment> payments=new ArrayList<>();
        ErpOrderPayment payment=new ErpOrderPayment();
        payment.setPay_type_code("weixin");
        payment.setPayment(order.getPayMoney().doubleValue());
        //payment.setPaytime(new Timestamp(System.currentTimeMillis()));
        if(order.getPayTime()!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String timeString = sdf.format(order.getPayTime());
            Date date = sdf.parse(timeString); // 时间格式转为时间戳
            long timeLong = date.getTime();
            payment.setPaytime(new Timestamp(timeLong));
        }
        payments.add(payment);
        //1.新疆、西藏、内蒙古、海南的订单(代收+非代收）全部发EMS
        //2.全款订单选择中通，快递ID 452  ZTO 中通商城标快 ZTBK.17782167502
        //3.新疆  西藏 内蒙古 海南  全款订单走顺丰丰云配  【非全款】的就根据公司配置那来 配的哪个走哪个快递
        //4.把现在发中通的规则改成发顺丰风云配 SF.0235402855
        //5.全款支付且应付金额小于等于100元，快递方式默认中通小件455 ZTO 中通小件 ZTPDD
        if(order.getCompanyId()!=null&& order.getStoreHouseCode()!=null&& order.getStoreHouseCode().equals("WHSP001")){
            //杭州家有仙妻实业有限公司 全部订单快递方式设置为商城德邦快递
            FsExpress express=expressService.selectFsExpressByOmsCode("SF-WHC");
            erpOrder.setExpress_code(express.getOmsCode());
            order.setDeliveryName(express.getName());
            order.setDeliverySn(express.getCode());
            if(order.getPayDelivery().compareTo(new BigDecimal(0))==0){

            }
            else{
                //物流代收金额
                ErpOrderPayment codPayment=new ErpOrderPayment();
                codPayment.setPay_type_code("cod");
                codPayment.setPayment(order.getPayDelivery().doubleValue());
                payments.add(codPayment);
                erpOrder.setCod(true);
            }
        }
        else if(order.getCompanyId()!=null){
            Company company = companyService.selectCompanyById(order.getCompanyId());
            if (order.getPayDelivery().compareTo(new BigDecimal(0)) == 0) {  //没有物流代收(全款订单)
                FsExpress express = new FsExpress();
                //express=expressService.selectFsExpressByOmsCode("SF.0235402855");
                if(order.getPayPrice().compareTo(new BigDecimal(100))<=0){
                    express=expressService.selectFsExpressByOmsCode("ZTPDD");
                }
                else{
                    boolean found = containsAddress(order.getUserAddress());
                    if(found){
                        express=expressService.selectFsExpressByOmsCode("SF.0235402855");
                    }
                    else{
                        express=expressService.selectFsExpressByOmsCode("SF.0235402855");
                    }
                }
                erpOrder.setExpress_code(express.getOmsCode());
                order.setDeliveryName(express.getName());
                order.setDeliverySn(express.getCode());
            }
            else {
                FsExpress express = new FsExpress();
                boolean found = containsAddress(order.getUserAddress());
                if(found){
                    if(StringUtils.isNotEmpty(company.getOmsCode())){
                        express = expressService.selectFsExpressByOmsCode(company.getOmsCode());
                    }else{
                        express=expressService.selectFsExpressByOmsCode("EMS.1");
                    }
                }
                else{
                    if(StringUtils.isNotEmpty(company.getOmsCode())){
                        express = expressService.selectFsExpressByOmsCode(company.getOmsCode());
                    }else{
                        express = expressService.selectFsExpressByOmsCode("SF.0235402855");
                    }
                }
                erpOrder.setExpress_code(express.getOmsCode());
                order.setDeliveryName(express.getName());
                order.setDeliverySn(express.getCode());
                //物流代收金额
                ErpOrderPayment codPayment = new ErpOrderPayment();
                codPayment.setPay_type_code("cod");
                codPayment.setPayment(order.getPayDelivery().doubleValue());
                payments.add(codPayment);
                erpOrder.setCod(true);
            }
        }
        else{
            if(order.getPayDelivery().compareTo(new BigDecimal(0))==0){  //没有物流代收(全款订单)
                FsExpress express=new FsExpress();
                if(order.getPayPrice().compareTo(new BigDecimal(100))<=0){
                    express=expressService.selectFsExpressByOmsCode("ZTPDD");
                }else{
                    boolean found = containsAddress(order.getUserAddress());
                    if(found){
                        express=expressService.selectFsExpressByOmsCode("SF.0235402855");
                    }
                    else{
                        express=expressService.selectFsExpressByOmsCode("SF.0235402855");
                    }
                }
                erpOrder.setExpress_code(express.getOmsCode());
                order.setDeliveryName(express.getName());
                order.setDeliverySn(express.getCode());
            }
            else{
                ErpOrderPayment codPayment=new ErpOrderPayment();
                codPayment.setPay_type_code("cod");
                codPayment.setPayment(order.getPayDelivery().doubleValue());
                payments.add(codPayment);
                erpOrder.setCod(true);
                FsExpress express=new FsExpress();
                boolean found = containsAddress(order.getUserAddress());
                if(found){
                    express=expressService.selectFsExpressByOmsCode("EMS.1");
                }
                else {
                    express=expressService.selectFsExpressByOmsCode("SF.0235402855");
                }
                erpOrder.setExpress_code(express.getOmsCode());
                order.setDeliveryName(express.getName());
                order.setDeliverySn(express.getCode());
            }
        }
        erpOrder.setPayments(payments);
        if(order.getCompanyId()!=null){
            Company company=companyService.selectCompanyById(order.getCompanyId());
            if(company!=null){
                erpOrder.setSeller_memo(company.getCompanyName());
            }
        }
        if(order.getCompanyUserId()!=null){
            CompanyUser companyUser=companyUserService.selectCompanyUserById(order.getCompanyUserId());
            if(companyUser!=null){
                CompanyDept dept=companyDeptService.selectCompanyDeptById(companyUser.getDeptId());
                if(dept!=null){
                    List<String> names=companyDeptService.selectCompanyDeptNamesByIds(dept.getAncestors());
                    if(names!=null&&names.size()>0){
                        //写备注
                        erpOrder.setSeller_memo(erpOrder.getSeller_memo()+"-"+StringUtils.join(names, ",")+","+dept.getDeptName() );
                    }
                }
                erpOrder.setSeller_memo(erpOrder.getSeller_memo()+"-"+companyUser.getNickName());
            }
        }

        if(order.getStoreHouseCode().equals("WHSP001")){
            //武汉不备注快递史
            //erpOrder.setSeller_memo(erpOrder.getSeller_memo()+"-"+order.getDeliveryName());
        }
        else{
            erpOrder.setSeller_memo(erpOrder.getSeller_memo()+"-"+ order.getDeliveryName());
        }
        ErpRemarkDTO remarkDTO=new ErpRemarkDTO();
        remarkDTO.setTotalPrice(order.getTotalPrice());
        remarkDTO.setPayPrice(order.getPayPrice());
        remarkDTO.setDeliveryMoney(order.getPayDelivery());
        remarkDTO.setPayMoney(order.getPayMoney());
        remarkDTO.setCouponMoney(order.getCouponPrice());
        remarkDTO.setOrderId(order.getOrderCode());
        remarkDTO.setYdMoney(order.getPayPrice().subtract(order.getPayMoney().subtract(order.getPayDelivery())));
//        //套餐标题也传过去
//        if (order.getOrderCreateType() == 2){
//            JSONObject jsonStr = JSONObject.parseObject(order.getPackageJson());
//            remarkDTO.setPackageTitle(jsonStr.getString("title"));
//        }

        if(order.getPayTime()!=null){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = sdf.format(order.getPayTime());
            remarkDTO.setPayTime(format);
        }
        erpOrder.setSeller_memo(erpOrder.getSeller_memo()+JSONUtil.toJsonStr(remarkDTO));

        erpOrder.setOrder_type_code("order");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        erpOrder.setDeal_datetime(sdf.format(new Date()));
        FsStoreOrderItem itemMap=new FsStoreOrderItem();
        itemMap.setOrderId(order.getId());
        List<FsStoreOrderItem> orderItems=storeOrderItemService.selectFsStoreOrderItemList(itemMap);
        List<ErpOrderItem> details=new ArrayList<>();
        for(FsStoreOrderItem orderItem: orderItems){
            FsStoreCartDTO cartDTO= JSONUtil.toBean(orderItem.getJsonInfo(),FsStoreCartDTO.class);
            //如果是组合码，查询出真实的商品数据 然后写入
            if(StringUtils.isNotEmpty(cartDTO.getGroupBarCode())){
                FsStoreProductGroup group=storeProductGroupService.selectFsStoreProductGroupByBarCode(cartDTO.getGroupBarCode().trim());
                if(group!=null){
                    JSONArray jsonArray=JSONUtil.parseArray(group.getProducts());
                    List<StoreProductGroupDTO> productGroupDTOS=JSONUtil.toList(jsonArray, StoreProductGroupDTO.class);
                    if(productGroupDTOS!=null){
                        for(StoreProductGroupDTO dto:productGroupDTOS){
                            FsStoreProductAttrValue attrValue=attrValueService.selectFsStoreProductAttrValueById(dto.getId());
                            ErpOrderItem item=new ErpOrderItem();
                            item.setItem_code(attrValue.getBarCode());
                            item.setPrice(attrValue.getPrice().toString());
                            item.setQty(dto.getCount()*cartDTO.getNum());
                            item.setRefund(0);
                            details.add(item);
                        }
                    }
                }
            }
            else{
                ErpOrderItem item=new ErpOrderItem();
                item.setItem_code(cartDTO.getBarCode().trim());
                item.setPrice(cartDTO.getPrice().toString());
                item.setQty(cartDTO.getNum());
                item.setRefund(0);
                details.add(item);
            }
        }
        erpOrder.setDetails(details);
        erpOrder.setReceiver_name(order.getRealName());
        if(order.getUserPhone().length()>11){
            erpOrder.setReceiver_phone(order.getUserPhone());
        }
        else{
            erpOrder.setReceiver_mobile(order.getUserPhone());
        }
        String[] address= order.getUserAddress().split(" ");
        erpOrder.setReceiver_province(address[0]);
        erpOrder.setReceiver_city(address[1]);
        erpOrder.setReceiver_district(address[2]);
        //处理地址多空隔问题
        if(address.length>3){
            StringBuffer addrs=new StringBuffer();
            for(int i=3;i<address.length;i++){
                addrs.append(address[i]);
            }
            erpOrder.setReceiver_address(addrs.toString());
        }
        else if(address.length==3){
            erpOrder.setReceiver_address(address[2]);
        }
        //处理地址字符问题
        erpOrder.setReceiver_address(erpOrder.getReceiver_address().replace("+","加"));
        erpOrder.setReceiver_address(erpOrder.getReceiver_address().replace("\n",""));
        return erpOrder;
    }

    @Override
    public FsStoreOrderVO selectFsStoreOrderVOByOrderCode(String orderCode) {
        return fsStoreOrderMapper.selectFsStoreOrderVOByOrderCode(orderCode);
    }

    @Override
    public Long selectFsStoreOrderTotalCount(int type,Long companyId) {
        return fsStoreOrderMapper.selectFsStoreOrderTotalCount(type,companyId);
    }

    @Override
    @Transactional
    public R editTuiMoney(FsStoreOrderEditTuiMoneyParam param) {
        FsStoreOrder order= fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
        if(order.getTuiMoney()!=null&&order.getTuiMoney().compareTo(new BigDecimal(0))==1){
            if(order.getTuiMoneyStatus().equals(0)){
                order.setTuiMoneyStatus(1);
                orderStatusService.create(order.getId(), OrderLogEnum.UNLOCK_TUI_MONEY.getValue(),
                        OrderLogEnum.UNLOCK_TUI_MONEY.getDesc());
                //写入公司余额
                Company company=companyService.selectCompanyById(order.getCompanyId());
                company.setMoney(company.getMoney().add(order.getTuiMoney()));
                companyService.updateCompany(company);
                //写入日志
                CompanyMoneyLogs log=new CompanyMoneyLogs();
                log.setCompanyId(order.getCompanyId());
                log.setRemark("订单佣金解冻");
                log.setMoney(order.getTuiMoney());
                log.setLogsType(4);
                log.setBalance(company.getMoney());
                log.setCreateTime(new Date());
                log.setBusinessId(order.getId().toString());
                moneyLogsMapper.insertCompanyMoneyLogs(log);
                fsStoreOrderMapper.updateFsStoreOrder(order);
                return R.ok("解冻成功");
            }
            else{
                order.setTuiMoneyStatus(0);
                //写入公司余额
                Company company=companyService.selectCompanyById(order.getCompanyId());
                company.setMoney(company.getMoney().subtract(order.getTuiMoney()));
                companyService.updateCompany(company);
                //写入日志
                CompanyMoneyLogs log=new CompanyMoneyLogs();
                log.setCompanyId(order.getCompanyId());
                log.setRemark("订单佣金冻结");
                log.setMoney(order.getTuiMoney().multiply(new BigDecimal(-1)));
                log.setLogsType(5);
                log.setBalance(company.getMoney());
                log.setCreateTime(new Date());
                log.setBusinessId(order.getId().toString());
                moneyLogsMapper.insertCompanyMoneyLogs(log);
                fsStoreOrderMapper.updateFsStoreOrder(order);
                return R.ok("冻结成功");
            }

        }
        else {
            return R.error("推广佣金不存在");
        }
    }

    @Override
    public List<OrderListVO> selectCompanyStoreOrderListAPI(OrderListParam param) {
        List<OrderListVO> list=fsStoreOrderMapper.selectCompanyStoreOrderListAPI(param);
        if(list!=null){
            for(OrderListVO vo:list){
                List<ProductListVO> productList=new ArrayList<>();
                FsStoreOrderItem map=new FsStoreOrderItem();
                map.setOrderId(vo.getOrderid());
                List<FsStoreOrderItem> items=fsStoreOrderItemMapper.selectFsStoreOrderItemList(map);
                if(items!=null){
                    for(FsStoreOrderItem item:items){
                        FsStoreCartDTO cartDTO= JSONUtil.toBean(item.getJsonInfo(),FsStoreCartDTO.class);
                        ProductListVO productListVO=new ProductListVO();
                        productListVO.setProductid(cartDTO.getProductId());
                        productListVO.setProductname(cartDTO.getProductName());
                        productListVO.setProductprice(cartDTO.getPrice());
                        productListVO.setProductqty(cartDTO.getNum());
                        productList.add(productListVO);
                    }
                }
                vo.setProductList(productList);
            }

        }
        return list;
    }

    @Override
    public List<FsStoreOrder> selectFsStoreOrderByCompanyId(Long companyId) {
        return fsStoreOrderMapper.selectFsStoreOrderByCompanyId(companyId);
    }

    @Override
    public List<FsStoreOrder> selectFsStoreOrderListByDeliveryId(String logisticCode) {
        return fsStoreOrderMapper.selectFsStoreOrderListByDeliveryId(logisticCode);
    }

    @Override
    @Transactional
    public R refundOrderMoney(Long orderId) {
        FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if(order.getStatus()==-2){
            return R.error("已退款");
        }
        if(order.getStatus()!=1&&order.getStatus()!=2){
            return R.error("非法操作");
        }
        if(StringUtils.isNotEmpty(order.getExtendOrderId())){
            ErpRefundUpdateRequest request=new ErpRefundUpdateRequest();
            request.setTid(order.getOrderCode());
            request.setOid(order.getOrderCode());
            request.setRefund_state(1);
            BaseResponse response=erpOrderService.refundUpdate(request);
//            if(response.getSuccess()){
//            }
//            else{
//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                return R.error(response.getErrorDesc());
//            }
        }
        order.setStatus(-2);
        order.setRefundPrice(order.getPayMoney());
        order.setRefundStatus(OrderInfoEnum.REFUND_STATUS_2.getValue());
        fsStoreOrderMapper.updateFsStoreOrder(order);

        //退库存
        //获取订单下的商品
        List<FsStoreOrderItemVO> orderItemVOS=fsStoreOrderItemMapper.selectFsStoreOrderItemListByOrderId(order.getId());
        for(FsStoreOrderItemVO vo:orderItemVOS){
            if(vo.getIsAfterSales()==1){
                productService.incProductStock(vo.getNum(), vo.getProductId(), vo.getProductAttrValueId());
            }

        }
        if(order.getPayType().equals(3)){
            //货到付款
        }
        else{
            //将钱退还给用户
            List<FsStorePayment> payments=paymentService.selectFsStorePaymentByOrderId(order.getId());
            if(payments!=null){
                for(FsStorePayment payment:payments){
                    if (payment.getPayMode()==null||payment.getPayMode().equals("wx")){
                        WxPayConfig payConfig = new WxPayConfig();
                        String json = configService.selectConfigByKey("store.pay");
                        FsPayConfig fsPayConfig = JSON.parseObject(json, FsPayConfig.class);
                        payConfig.setAppId(fsPayConfig.getAppId());
                        payConfig.setMchId(fsPayConfig.getWxMchId());
                        payConfig.setMchKey(fsPayConfig.getWxMchKey());
                        payConfig.setKeyPath(wxPayProperties.getKeyPath());
                        payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                        payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                        wxPayService.setConfig(payConfig);
                        WxPayRefundRequest refundRequest = new WxPayRefundRequest();
                        refundRequest.setOutTradeNo("store-"+payment.getPayCode());
                        refundRequest.setOutRefundNo("store-"+payment.getPayCode());
                        refundRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
                        refundRequest.setRefundFee(WxPayUnifiedOrderRequest.yuanToFen(payment.getPayMoney().toString()));
                        try {
                            WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
                            WxPayRefundQueryResult refundQueryResult = wxPayService.refundQuery("", refundResult.getOutTradeNo(), refundResult.getOutRefundNo(), refundResult.getRefundId());
                            if(refundQueryResult!=null&&refundQueryResult.getResultCode().equals("SUCCESS")){
                                FsStorePayment paymentMap=new FsStorePayment();
                                paymentMap.setPaymentId(payment.getPaymentId());
                                paymentMap.setStatus(-1);
                                paymentMap.setRefundTime(DateUtils.getNowDate());
                                paymentMap.setRefundMoney(payment.getPayMoney());
                                paymentService.updateFsStorePayment(paymentMap);
                            }
                            else {
                                return R.error("退款请求失败"+refundQueryResult.getErrCodeDes());
                            }
                        } catch (WxPayException e) {
                            return R.error("退款请求失败"+e.getErrCodeDes());
                        }
                    }else if (payment.getPayMode()!=null&&payment.getPayMode().equals("hf")){
                        V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
                        request.setOrdAmt(payment.getPayMoney().toString());
                        request.setOrgReqDate(new SimpleDateFormat("yyyyMMdd").format(payment.getCreateTime()));
                        request.setReqSeqId("refund-"+payment.getPayCode());
                        Map<String, Object> extendInfoMap = new HashMap<>();
                        extendInfoMap.put("org_party_order_id", payment.getBankSerialNo());
                        request.setExtendInfo(extendInfoMap);
                        HuiFuRefundResult refund = huiFuService.refund(request);
                        logger.info("退款："+refund);
                        if((refund.getResp_code().equals("00000000")||refund.getResp_code().equals("00000100"))&&(refund.getTrans_stat().equals("S")||refund.getTrans_stat().equals("P"))){
                            payment.setRefundMoney(payment.getPayMoney());
                            payment.setStatus(-1);
                            payment.setRefundTime(new Date());
                            paymentService.updateFsStorePayment(payment);
                        }else {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            return R.error(refund.getResp_desc());
                        }

                    }else {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return R.error("支付类型异常");
                    }


                }
            }
        }
        orderStatusService.create(order.getId(), OrderLogEnum.REFUND_ORDER_SUCCESS.getValue(),
                OrderLogEnum.REFUND_ORDER_SUCCESS.getDesc());
        if(order.getTuiUserId()!=null&&order.getTuiUserId()>0){
            userService.subTuiMoney(order);
        }
        return R.ok();

    }

    @Override
    public R updateExpress(FsStoreOrderExpressEditParam param) {
        FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
        if(order.getStatus()!=1){
            return R.error("只有待发货状态可以同步");
        }
        if(order.getExtendOrderId()==null){
            return R.error("未生成管易云订单");
        }
        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
        request.setCode(order.getExtendOrderId());
        ErpOrderQueryResponse response = erpOrderService.getOrder(request);
        if(response.getOrders()!=null&&response.getOrders().size()>0){
            for(ErpOrderQuery orderQuery : response.getOrders()){
                if(orderQuery.getDeliverys()!=null&&orderQuery.getDeliverys().size()>0){
                    for(ErpDeliverys delivery:orderQuery.getDeliverys()){
                        if(delivery.getDelivery()&& StringUtils.isNotEmpty(delivery.getMail_no())){
                            FsStoreOrder map=new FsStoreOrder();
                            map.setStatus(OrderInfoEnum.STATUS_2.getValue());
                            map.setId(order.getId());
                            map.setDeliverySn(response.getOrders().get(0).getDeliverys().get(0).getExpress_code());
                            map.setDeliveryName(response.getOrders().get(0).getDeliverys().get(0).getExpress_name());
                            map.setDeliveryId(response.getOrders().get(0).getDeliverys().get(0).getMail_no());
                            fsStoreOrderMapper.updateFsStoreOrder(map);
                            orderStatusService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(),
                                    OrderLogEnum.DELIVERY_GOODS.getDesc());
                            TemplateBean templateBean = TemplateBean.builder()
                                    .orderId(order.getId().toString())
                                    .orderCode(order.getOrderCode().toString())
                                    .deliveryId(order.getDeliveryId())
                                    .deliveryName(order.getDeliveryName())
                                    .userId(order.getUserId())
                                    .templateType(TemplateListenEnum.TYPE_2.getValue())
                                    .build();
                            publisher.publishEvent(new TemplateEvent(this, templateBean));
                            return R.ok();
                        }
                    }

                }
            }
        }
        return R.error("未生成运单信息");
    }

    @Override
    @Transactional
    public R syncExpress(FsStoreOrderExpressEditParam param) {
        FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
        String lastFourNumber = "";
        if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
            lastFourNumber = order.getUserPhone();
            if (lastFourNumber.length() == 11) {
                lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
            }
        }
        ExpressInfoDTO dto=expressService.getExpressInfo(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
        FsStoreOrder map=new FsStoreOrder();
        map.setDeliveryStatus(Integer.parseInt(dto.getState()));
        map.setId(order.getId());
        map.setDeliveryType(dto.getStateEx());
        fsStoreOrderMapper.updateFsStoreOrder(map);
        //如果是正常签收，更新订单状态
        if(dto.getState().equals("3")&&(dto.getStateEx().equals("301")||dto.getStateEx().equals("302")||dto.getStateEx().equals("304")||dto.getStateEx().equals("311"))){
            finishOrder(order.getId());
        }
        return null;
    }

    @Override
    @Synchronized
    public R addTuiMoney(FsStoreOrderAddTuiMoneyParam param) {
        FsStoreOrder order = fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
        if(order.getStatus()!=OrderInfoEnum.STATUS_3.getValue()) {
            return R.error("订单未完成，不能分佣金");
        }
        if (order.getCompanyId() != null && order.getCompanyId() > 0 && order.getPayDelivery().compareTo(new BigDecimal(0)) == 0) {
            if (order.getTuiMoneyStatus() == null || order.getTuiMoneyStatus() != 1) {
                companyService.addCompanyMoney(order);
                return R.ok();
            }
            else{
                return R.error("此订单已分佣，不能重复分佣");
            }
        }
        else{
            return R.error("此订单不能手动分佣");
        }
    }

    @Override
    public R createSalesOrder(CompanyUser companyUser, String cateIds) {
        List<FsStoreCartQueryVO>  carts=cartMapper.selectFsStoreCartListByIds(cateIds);
        String uuid = IdUtil.randomUUID();
        redisCache.setCacheObject("createOrderKey:"+uuid, companyUser.getCompanyId()+"-"+companyUser.getUserId(), 24, TimeUnit.HOURS);
        redisCache.setCacheObject("orderCarts:"+uuid, carts, 24, TimeUnit.HOURS);
        //计算总价
        BigDecimal totalMoney= BigDecimal.ZERO;
        for(FsStoreCartQueryVO vo:carts){
            totalMoney=totalMoney.add(vo.getPrice().multiply(new BigDecimal(vo.getCartNum().toString())));
        }
        redisCache.setCacheObject("createOrderMoney:"+uuid, totalMoney, 24, TimeUnit.HOURS);
        return R.ok().put("orderKey",uuid).put("carts",carts);
    }

    @Override
    public R getSalesOrder(String createOrderKey) {
        String key=redisCache.getCacheObject("createOrderKey:"+createOrderKey);
        List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + createOrderKey);
        BigDecimal money=redisCache.getCacheObject("createOrderMoney:"+createOrderKey);
        if (StringUtils.isEmpty(key)) {
            throw new CustomException("订单已过期",501);
        }
        return R.ok().put("carts",carts).put("totalMoney",money);
    }

    @Override
    @Transactional
    public R addUserCart(long userId, String createOrderKey) {
        String key=redisCache.getCacheObject("createOrderKey:"+createOrderKey);
        List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + createOrderKey);
        if (StringUtils.isEmpty(key)) {
            throw new CustomException("订单已过期",501);
        }
        List<Long> ids=new ArrayList<>();
        for(FsStoreCartQueryVO vo : carts){
            FsStoreCart storeCart = FsStoreCart.builder()
                    .cartNum(vo.getCartNum())
                    .productAttrValueId(vo.getProductAttrValueId())
                    .productId(vo.getProductId())
                    .userId(userId)
                    .isPay(0)
                    .isDel(0)
                    .isBuy(1)
                    .build();
            storeCart.setCreateTime(new Date());
            cartMapper.insertFsStoreCart(storeCart);
            ids.add(storeCart.getId());
        }
        //删除REDIS
//        redisCache.deleteObject("createOrderKey:"+createOrderKey);
//        redisCache.deleteObject("orderCarts:" + createOrderKey);
        String[] idArr=key.split("-");
        return R.ok().put("cartIds",ids).put("companyId",idArr[0]).put("companyUserId",idArr[1]);

    }

    @Override
    public R updateSalseOrderMoney(String createOrderKey, BigDecimal money) {
        if(money==null){
            return R.error("请输入价格");
        }
        if(money.compareTo(BigDecimal.ZERO)<=0){
            return R.error("价格应大于0");
        }
        String key=redisCache.getCacheObject("createOrderKey:"+createOrderKey);
        if (StringUtils.isEmpty(key)) {
            throw new CustomException("订单已过期",501);
        }
        List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + createOrderKey);
        BigDecimal totalMoney= BigDecimal.ZERO;
        for(FsStoreCartQueryVO vo:carts){
            totalMoney=totalMoney.add(vo.getPrice().multiply(new BigDecimal(vo.getCartNum().toString())));
        }
        if(money.compareTo(totalMoney)==1){
            throw new CustomException("价格不能大于商品总价",501);
        }
        String json=configService.selectConfigByKey("store.config");
        StoreConfig config= JSONUtil.toBean(json,StoreConfig.class);
        if(config.getCreateMoneyRate()!=null){
            totalMoney=totalMoney.multiply(new BigDecimal(config.getCreateMoneyRate())).divide(new BigDecimal(100));
            if(money.compareTo(totalMoney)==-1){
                throw new CustomException("价格必须大于商品总价"+config.getCreateMoneyRate()+"%",501);
            }
        }
        redisCache.setCacheObject("createOrderMoney:"+createOrderKey, money, 24, TimeUnit.HOURS);
        return R.ok();
    }

    @Override
    public Integer selectFsStoreOrderCountByType(Long companyId, long userId, int type) {
        return fsStoreOrderMapper.selectFsStoreOrderCountByType(companyId,userId,type);
    }

    @Override
    public List<FsCustomerStoreOrderListQueryVO> selectFsCustomerStoreOrderListQuery(FsCustomerStoreOrderListQueryParam param) {
        List<FsCustomerStoreOrderListQueryVO> list= fsStoreOrderMapper.selectFsCustomerStoreOrderListQuery(param);
        for(FsCustomerStoreOrderListQueryVO vo:list){
            List<FsStoreOrderItemVO> items=fsStoreOrderItemMapper.selectMyFsStoreOrderItemListByOrderId(vo.getId());
            vo.setItems(items);
        }
        return list;
    }

    @Override
    public List<JSONObject> selectFsStoreOrderCounts(Map<String, Object> toMap) {
        return fsStoreOrderMapper.selectFsStoreOrderCounts(toMap);
    }

    @Override
    public List<FsStoreOrderStatisticsVO> selectFsStoreOrderStatisticsList(FsStoreStatisticsParam param) {
        return fsStoreOrderMapper.selectFsStoreOrderStatisticsList(param);
    }

    @Override
    public List<FsStoreOrderExportVO> selectFsStoreOrderListVOByExport(FsStoreOrderParam param) {
        return fsStoreOrderMapper.selectFsStoreOrderListVOByExport(param);
    }

    @Override
    public List<FsStoreOrderPromotionExportVO> selectFsPromotionOrderListVOByExport(FsStoreOrderParam param) {
        List<FsStoreOrderPromotionExportVO> list = fsStoreOrderMapper.selectFsPromotionOrderListVOByExport(param);
        for (FsStoreOrderPromotionExportVO vo : list){
           FsStoreOrderBrokerageVO brokerageVO = fsStoreOrderMapper.selectBrokerage(vo.getId());
           vo.setBrokerage(brokerageVO.getBrokerage());
           vo.setBrokerageTwo(brokerageVO.getBrokerageTwo());
           vo.setBrokerageThree(brokerageVO.getBrokerageThree());
        }
        return list;
    }

    @Override
    public List<FsStorePayRemainOrderExportVO> selectFsStorePayRemainOrderListVOByExport(FsStoreOrderParam param) {
        return fsStoreOrderMapper.selectFsStorePayRemainOrderListVOByExport(param);
    }

    @Override
    public List<FsStoreOrder> selectFsStoreOrderListByFinish7Day() {
        return fsStoreOrderMapper.selectFsStoreOrderListByFinish7Day();
    }

    @Override
    public List<FsStoreOrderVO> selectFsCustomerStoreOrderListVO(FsStoreOrderParam param) {
        return fsStoreOrderMapper.selectFsCustomerStoreOrderListVO(param);
    }

    @Override
    @Transactional
    @Synchronized
    public String payRemainConfirm( String payCode, String tradeNo, String bankTransactionId, String bankSerialNo) {
        //支付订单
        FsStoreOrder order=null;
        FsStorePayment storePayment=paymentService.selectFsStorePaymentByCode(payCode);
        if(storePayment==null||!storePayment.getStatus().equals(0)){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return "";
        }
        storePayment.setStatus(1);
        storePayment.setPayTime(new Date());
        storePayment.setTradeNo(tradeNo);
        storePayment.setBankSerialNo(bankSerialNo);
        storePayment.setBankTransactionId(bankTransactionId);
        storePayment.setIsPayRemain(1);
        paymentService.updateFsStorePayment(storePayment);
        order=fsStoreOrderMapper.selectFsStoreOrderById(storePayment.getOrderId());
        //增加状态
        orderStatusService.create(order.getId(), OrderLogEnum.PAY_REMAIN_ORDER_SUCCESS.getValue(),
                OrderLogEnum.PAY_REMAIN_ORDER_SUCCESS.getDesc());

        FsStoreOrder storeOrder = new FsStoreOrder();
        storeOrder.setId(order.getId());
        storeOrder.setIsPayRemain(1);
        fsStoreOrderMapper.updateFsStoreOrder(storeOrder);

        return "SUCCESS";
    }

    @Override
    public R auditPayRemain(Long orderId) {
        FsStoreOrder order=fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if(order.getIsPayRemain()==1){
            FsStoreOrder storeOrder = new FsStoreOrder();
            storeOrder.setId(order.getId());
            storeOrder.setIsPayRemain(2);
            storeOrder.setPayType("1");
            storeOrder.setPayMoney(order.getPayPrice());
            storeOrder.setPayDelivery(new BigDecimal(0));
            fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
            return R.ok("操作成功");
        }
        else{
            return R.error("非法操作");
        }
    }

    @Override
    public Integer selectFsStoreOrderCount(long userId, int status) {
        return fsStoreOrderMapper.selectFsStoreOrderCount(userId,status);
    }

    @Override
    public R computedPackageOrder(long userId, FsStoreComputedPackageIdOrderParam param) {
        FsStoreProductPackage storeProductPackage=productPackageService.selectFsStoreProductPackageById(param.getPackageId());
        BigDecimal totalMoney=storeProductPackage.getPayMoney();
        if(param.getCouponUserId()!=null){
            FsStoreCouponUser couponUser=couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
            if(couponUser!=null&&couponUser.getStatus()==0){
                if(couponUser.getUseMinPrice().compareTo(storeProductPackage.getPayMoney())==-1){
                    totalMoney=totalMoney.subtract(couponUser.getCouponPrice());
                }
            }
        }
        return R.ok().put("totalMoney",totalMoney);
    }

    @Override
    public FsStoreOrder selectFsStoreOrderByDeliveryId(String logisticCode) {
        return fsStoreOrderMapper.selectFsStoreOrderByDeliveryId(logisticCode);
    }




    @Synchronized
    @Override
    //@Async
    public String importExpress(List<StoreOrderExpressExportDTO> list, boolean updateSupport) {
        if (StringUtils.isNull(list) || list.size() == 0)
        {
            throw new CustomException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder importSuccessMsg = new StringBuilder();
        StringBuilder importErrorMsg = new StringBuilder();
        StringBuilder importMsg = new StringBuilder();
        for (StoreOrderExpressExportDTO dto : list)
        {
            try
            {
//                Thread.sleep(1000);
                FsStoreOrder order=fsStoreOrderMapper.selectFsStoreOrderByDeliveryId(dto.getDeliveryId());
                if (StringUtils.isNull(order))
                {
                    String msg = "<br/>" + failureNum + "、快递单号 " + dto.getDeliveryId() + "不存在";
                    importErrorMsg.append(msg);
                    failureNum++;
                }
                else
                {
                    //订单状态为已签收并且未导入过
                    if(order.getDeliveryStatus().equals(3)&& order.getDeliveryImportTime()==null&&(order.getPayType().equals("2")||order.getPayType().equals("3"))){
                        FsStoreOrder orderMap=new FsStoreOrder();
                        orderMap.setId(order.getId());
                        orderMap.setDeliveryTime(dto.getDeliveryTime());
                        orderMap.setDeliveryPayStatus(Integer.parseInt(dto.getDeliveryPayStatus()));
                        orderMap.setDeliveryPayMoney(dto.getDeliveryPayMoney());
                        orderMap.setDeliveryPayTime(dto.getDeliveryPayTime());
                        orderMap.setDeliveryImportTime(new Date());
                        this.updateFsStoreOrder(orderMap);
                        //未分佣写入分佣
                        if(order.getCompanyId()!=null&&order.getCompanyId()>0){
                            companyService.addCompanyMoney(order);
                        }
                        successNum++;
                        importSuccessMsg.append("<br/>" + successNum + "、快递单号 " +dto.getDeliveryId() + " 导入成功");
                    }
                    else{
                        String msg = "<br/>" + failureNum + "、快递单号 " + dto.getDeliveryId() + " 未签收或已导入,不能导入";
                        importErrorMsg.append(msg);
                        failureNum++;
                    }
                }
            }
            catch (Exception e)
            {
                String msg = "<br/>" + failureNum + "、快递单号 " + dto.getDeliveryId() + " 导入异常：";
                importErrorMsg.append(msg+e.getMessage());
                failureNum++;
            }
        }
        importMsg.insert(0, "导入完成！成功" + successNum + " 条，失败"+failureNum+"条。");
        importMsg.append(importErrorMsg.toString());
        importMsg.append(importSuccessMsg.toString());
        return importMsg.toString();
    }


    /**
     * 退回积分
     */
    private void refundIntegral(FsStoreOrder order) {

        if (order.getPayIntegral().compareTo(BigDecimal.ZERO) > 0) {
            order.setUseIntegral(order.getPayIntegral());
        }
        if (order.getUseIntegral().compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        if ( order.getBackIntegral().compareTo(BigDecimal.ZERO) > 0) {
            return;
        }
        FsUser user = userService.selectFsUserById(order.getUserId());
        //增加积分
        BigDecimal newIntegral = NumberUtil.add(order.getUseIntegral(), user.getIntegral());
        user.setIntegral(newIntegral);
        userService.updateFsUser(user);
        //增加流水
        billService.addBill(user.getUserId(),BillDetailEnum.CATEGORY_2.getValue(),1, BillDetailEnum.TYPE_5.getDesc(),
                order.getUseIntegral().doubleValue(),
                newIntegral.doubleValue(),
                "购买商品失败,回退积分" + order.getUseIntegral(), order.getId().toString(),0l);
        //更新订单回退积分
        FsStoreOrder storeOrder = new FsStoreOrder();
        storeOrder.setBackIntegral(order.getUseIntegral());
        storeOrder.setId(order.getId());
        fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
    }


    /**
     * 退回库存
     */
    private void refundStock(FsStoreOrder order) {
        //获取订单下的商品
        List<FsStoreOrderItemVO> orderItemVOS=fsStoreOrderItemMapper.selectFsStoreOrderItemListByOrderId(order.getId());
        for(FsStoreOrderItemVO vo:orderItemVOS){
            productService.incProductStock(vo.getNum(), vo.getProductId()
                    , vo.getProductAttrValueId());
        }

    }



    /**
     * 获取订单价格
     */
    private FsStoreOrderPriceDTO getOrderPriceGroup(List<FsStoreCartQueryVO> cartInfo, FsUserAddress userAddress) {
        BigDecimal storePostage = BigDecimal.ZERO;
        //免运费设置
        BigDecimal storeFreePostage = BigDecimal.ZERO;

        BigDecimal totalPrice = this.getOrderSumPrice(cartInfo, "truePrice");//获取订单总金额
        BigDecimal costPrice = this.getOrderSumPrice(cartInfo, "costPrice");//获取订单成本价
        BigDecimal payIntegral = this.getOrderSumPrice(cartInfo, "payIntegral");//获取订单需要的积分

        //如果设置满包邮0 表示全局包邮，如果设置大于0表示满这价格包邮，否则走运费模板算法
        if (storeFreePostage.compareTo(BigDecimal.ZERO) != 0 && totalPrice.compareTo(storeFreePostage) <= 0) {
            storePostage = this.handlePostage(cartInfo, userAddress);
        }

        FsStoreOrderPriceDTO priceGroupDTO = new FsStoreOrderPriceDTO();
        priceGroupDTO.setStorePostage(storePostage);
//        priceGroupDTO.setStoreFreePostage(storeFreePostage);
        priceGroupDTO.setTotalPrice(totalPrice);
        priceGroupDTO.setCostPrice(costPrice);
        priceGroupDTO.setPayIntegral(payIntegral);
        return priceGroupDTO;
    }

    /**
     * 根据运费模板算法返回邮费
     *
     * @param cartInfo    购物车
     * @param userAddress 地址
     * @return double
     */
    private BigDecimal handlePostage(List<FsStoreCartQueryVO> cartInfo, FsUserAddress userAddress) {
        BigDecimal storePostage = BigDecimal.ZERO;
        if (userAddress != null) {
            if (userAddress.getCityId() == null) {
                return storePostage;
            }
            Long cityId = userAddress.getCityId();
            List<Long> citys = new ArrayList<>();
            citys.add(cityId);
            citys.add(0l);//城市包括默认
            List<Long> tempIds = cartInfo
                    .stream()
                    .map(FsStoreCartQueryVO::getTempId)
                    .collect(Collectors.toList());

            //获取商品用到的运费模板
            List<FsShippingTemplates> shippingTemplatesList =shippingTemplatesService.selectFsShippingTemplatesByIds(StringUtils.join(tempIds,","));

            //获取运费模板区域列表按照城市排序
            List<FsShippingTemplatesRegion> shippingTemplatesRegionList = shippingTemplatesRegionService.selectFsShippingTemplatesRegionListByTempIdsAndCityIds(StringUtils.join(tempIds,","),StringUtils.join(citys,","));

            //提取运费模板类型
            Map<Long, Integer> shippingTemplatesMap = shippingTemplatesList
                    .stream()
                    .collect(Collectors.toMap(FsShippingTemplates::getId,
                            FsShippingTemplates::getType));
            //提取运费模板有相同值覆盖
            Map<Long, FsShippingTemplatesRegion> shippingTemplatesRegionMap =
                    shippingTemplatesRegionList.stream()
                            .collect(Collectors.toMap(FsShippingTemplatesRegion::getTempId,
                                    YxShippingTemplatesRegion -> YxShippingTemplatesRegion,
                                    (key1, key2) -> key2));


            Map<Long, TemplateDTO> templateDTOMap = new HashMap<>();
            for (FsStoreCartQueryVO storeCartVO : cartInfo) {
                Long tempId = storeCartVO.getTempId();
                //根据模板类型获取相应的数量
                double num = 0d;
                if (ShippingTempEnum.TYPE_1.getValue().equals(shippingTemplatesMap.get(tempId))) {
                    num = storeCartVO.getCartNum().doubleValue();
                } else if (ShippingTempEnum.TYPE_2.getValue().equals(shippingTemplatesMap.get(tempId))) {
                    num = NumberUtil.mul(storeCartVO.getCartNum(),
                            storeCartVO.getWeight()).doubleValue();
                } else if (ShippingTempEnum.TYPE_3.getValue().equals(shippingTemplatesMap.get(tempId))) {
                    num = NumberUtil.mul(storeCartVO.getCartNum(),
                            storeCartVO.getVolume()).doubleValue();
                }

                FsShippingTemplatesRegion shippingTemplatesRegion = shippingTemplatesRegionMap.get(tempId);
                BigDecimal price = NumberUtil.round(NumberUtil.mul(storeCartVO.getCartNum(),
                        storeCartVO.getPrice()), 2);
                if (!templateDTOMap.containsKey(tempId)) {
                    TemplateDTO templateDTO = TemplateDTO.builder()
                            .number(num)
                            .price(price)
                            .first(shippingTemplatesRegion.getFirst().doubleValue())
                            .firstPrice(shippingTemplatesRegion.getFirstPrice())
                            .continues(shippingTemplatesRegion.getContinues().doubleValue())
                            .continuePrice(shippingTemplatesRegion.getContinuePrice())
                            .tempId(tempId)
                            .cityId(cityId)
                            .build();
                    templateDTOMap.put(tempId, templateDTO);
                } else {
                    TemplateDTO templateDTO = templateDTOMap.get(tempId);
                    templateDTO.setNumber(templateDTO.getNumber() + num);
                    templateDTO.setPrice(NumberUtil.add(templateDTO.getPrice().doubleValue(), price));
                }
            }

            //处理区域邮费
            boolean isFirst = true; //用来是否多个产品的标识 false表示数量大于1
            for (TemplateDTO templateDTO : templateDTOMap.values()) {
                if (isFirst) {//首件
                    //只满足首件
                    if (Double.compare(templateDTO.getNumber(), templateDTO.getFirst()) <= 0) {
                        storePostage = NumberUtil.round(NumberUtil.add(storePostage,
                                templateDTO.getFirstPrice()), 2);
                    } else {
                        BigDecimal firstPrice = NumberUtil.add(storePostage, templateDTO.getFirstPrice());

                        if (templateDTO.getContinues() <= 0) {
                            storePostage = firstPrice;
                        } else {
                            //续件平均值且向上取整数
                            double average = Math.ceil(NumberUtil.div(NumberUtil.sub(templateDTO.getNumber(),
                                    templateDTO.getFirst()),
                                    templateDTO.getContinues().doubleValue()));
                            //最终邮费
                            storePostage = NumberUtil.add(firstPrice, NumberUtil.mul(average,
                                    templateDTO.getContinuePrice()));
                        }

                    }
                    isFirst = false;
                } else {
                    //多件直接在以前的基数继续续建
                    if (templateDTO.getContinues() > 0) {
                        //续件平均值且向上取整数
                        double average = Math.ceil(
                                NumberUtil.div(
                                        templateDTO.getNumber(),
                                        templateDTO.getContinues()
                                )
                        );
                        //最终邮费
                        storePostage = NumberUtil.add(storePostage.doubleValue(), NumberUtil.mul(average,
                                templateDTO.getContinuePrice()));
                    }
                }
            }
        }
        return storePostage;
    }

    /**
     * 获取某字段价格
     *
     * @param cartInfo 购物车
     * @param key      key值
     * @return Double
     */
    private BigDecimal getOrderSumPrice(List<FsStoreCartQueryVO> cartInfo, String key) {
        BigDecimal sumPrice = BigDecimal.ZERO;

        if ("truePrice".equals(key)) {
            for (FsStoreCartQueryVO storeCart : cartInfo) {
                sumPrice = NumberUtil.add(sumPrice, NumberUtil.mul(storeCart.getCartNum(), storeCart.getPrice()));
            }
        }
        else if ("costPrice".equals(key)) {
            for (FsStoreCartQueryVO storeCart : cartInfo) {
                sumPrice = NumberUtil.add(sumPrice,
                        NumberUtil.mul(storeCart.getCartNum(), storeCart.getCost()));
            }
        }else if ("payIntegral".equals(key)) {
            for (FsStoreCartQueryVO storeCart : cartInfo) {
                if (storeCart.getIntegral() != null) {
                    sumPrice = NumberUtil.add(sumPrice,
                            NumberUtil.mul(storeCart.getCartNum(), storeCart.getIntegral()));
                }

            }
        }
        return sumPrice;
    }

    @Override
    public Boolean isEntityNull(FsStoreOrderParam param) {
        if (param == null) {
            return true; // 整个实体对象为null
        }

        Class<? extends FsStoreOrderParam> entityClass = param.getClass();
        Field[] fields = entityClass.getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(param);
                if (value != null) {
                    return false; // 实体对象中有字段不为null
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return true; // 实体对象内所有字段为null
    }

    @Override
    public int uploadCredentials(FsStoreOrder order) {
        order.setUploadTime(new Date());
        return fsStoreOrderMapper.uploadCredentials(order);
    }

    @Override
    public String getCredentialsById(Long id) {

        return fsStoreOrderMapper.getCredentialsById(id);
    }

    @Override
    public List<Long> selectFsStoreOrderToPushByIds(String startTime) {
        return fsStoreOrderMapper.selectFsStoreOrderToPushByIds(startTime);
    }

    @Override
    public List<FsStoreOrder> selectFsStoreOrderItemJson() {
        return fsStoreOrderMapper.selectFsStoreOrderItemJson();
    }

    @Override
    public int uploadItemJson(FsStoreOrder order) {
        return fsStoreOrderMapper.uploadItemJson(order);
    }

    @Override
    public void updateDeliveryItem(ExpressNotifyDTO notifyDTO) {
        //RequestData={"PushTime":"2022-09-06 09:59:26","EBusinessID":"1762981","Data":[{"StateEx":"0","LogisticCode":"SF1650775430012","ShipperCode":"SF","State":"0","OrderCode":"XCRTZH22090500435","EBusinessID":"1762981","Success":false}],"Count":"1"}&DataSign=YTEwMzAxMTAzNGI4ZjQ0OTU5MWE1Y2U0NzMzYTczNWM=&RequestType=102
        //RequestData={"PushTime":"2022-09-06 10:28:41","EBusinessID":"1762981","Data":[{"StateEx":"301","LogisticCode":"SF1372196615474","ShipperCode":"SF","Traces":[{"Action":"1","AcceptStation":"顺丰速运 已收取快件","AcceptTime":"2022-09-04 15:27:25","Remark":"","Location":"重庆"},{"Action":"1","AcceptStation":"顺丰速运 已收取快件","AcceptTime":"2022-09-04 15:34:27","Remark":"","Location":"重庆市"},{"Action":"2","AcceptStation":"快件在【重庆南岸区时代都汇营业点】完成分拣,准备发往 【重庆渝北中转场】","AcceptTime":"2022-09-04 17:17:16","Remark":"","Location":"重庆市"},{"Action":"2","AcceptStation":"快件已发车","AcceptTime":"2022-09-04 17:44:37","Remark":"","Location":"重庆市"},{"Action":"2","AcceptStation":"快件到达 【重庆渝北中转场】","AcceptTime":"2022-09-04 22:13:11","Remark":"","Location":"重庆市"},{"Action":"2","AcceptStation":"快件在【重庆渝北中转场】完成分拣,准备发往 【郑州港区中转场】","AcceptTime":"2022-09-05 00:04:51","Remark":"","Location":"重庆市"},{"Action":"2","AcceptStation":"快件已发车","AcceptTime":"2022-09-05 04:45:47","Remark":"","Location":"重庆市"},{"Action":"2","AcceptStation":"车辆当前所在位置道路管控，等待通行中，请您耐心等待\n","AcceptTime":"2022-09-05 19:35:55","Remark":"","Location":"重庆市"},{"Action":"2","AcceptStation":"快件到达 【郑州港区中转场】","AcceptTime":"2022-09-05 22:43:06","Remark":"","Location":"郑州市"},{"Action":"2","AcceptStation":"快件在【郑州港区中转场】完成分拣,准备发往 【焦作丰收集散点】","AcceptTime":"2022-09-05 23:16:24","Remark":"","Location":"郑州市"},{"Action":"2","AcceptStation":"快件已发车","AcceptTime":"2022-09-06 00:43:25","Remark":"","Location":"郑州市"},{"Action":"2","AcceptStation":"车辆当前所在位置道路管控，等待通行中，请您耐心等待\n","AcceptTime":"2022-09-06 01:03:39","Remark":"","Location":"郑州市"},{"Action":"2","AcceptStation":"快件到达 【焦作丰收集散点】","AcceptTime":"2022-09-06 03:03:35","Remark":"","Location":"焦作市"},{"Action":"2","AcceptStation":"快件在【焦作丰收集散点】完成分拣,准备发往 【济源市济源市汤帝路营业点】","AcceptTime":"2022-09-06 06:41:58","Remark":"","Location":"焦作市"},{"Action":"2","AcceptStation":"快件已发车","AcceptTime":"2022-09-06 06:42:17","Remark":"","Location":"焦作市"},{"Action":"2","AcceptStation":"车辆当前所在位置道路管控，等待通行中，请您耐心等待\n","AcceptTime":"2022-09-06 07:58:17","Remark":"","Location":"济源市"},{"Action":"2","AcceptStation":"快件到达 【济源市济源市汤帝路营业点】","AcceptTime":"2022-09-06 08:27:59","Remark":"","Location":"济源市"},{"Action":"202","AcceptStation":"正在派送途中,请您准备签收(派件人：刘亚飞，电话：18439188789)","AcceptTime":"2022-09-06 08:28:00","Remark":"","Location":"济源市"},{"Action":"202","AcceptStation":"快件交给刘亚飞，正在派送途中（联系电话：18439188789，顺丰已开启“安全呼叫”保护您的电话隐私,请放心接听！）（主单总件数：1件）","AcceptTime":"2022-09-06 08:38:03","Remark":"","Location":"济源市"},{"Action":"301","AcceptStation":"您的快件已签收，如有疑问请电联快递员【刘亚飞，电话：18439188789】。疫情期间顺丰每日对网点消毒、快递员每日测温、配戴口罩，感谢您使用顺丰，期待再次为您服务。（主单总件数：1件）","AcceptTime":"2022-09-06 08:54:05","Remark":"","Location":"济源市"}],"State":"3","OrderCode":"SKP012000681762","EBusinessID":"1762981","Success":true,"Location":"济源市"}],"Count":"1"}&DataSign=MTNlYTA5OTJmMjgxYjhiY2FjMTZjNTYyOGYxYjVhODA=&RequestType=102
        //https://api.hospital.ifeiyu100.com/app/common/expressNotify
        String data= URLDecoder.decode(notifyDTO.getRequestData(), Charset.forName("UTF-8"));
        //ExpressInfoDTO
        logger.info("快递根踪回调:"+data);
        ExpressDataDTO expressDataDTO=JSONUtil.toBean(data,ExpressDataDTO.class);
        if(expressDataDTO!=null&&expressDataDTO.getData()!=null){
            for(ExpressInfoDTO dto:expressDataDTO.getData()){
                List<FsStoreOrder> orders=this.selectFsStoreOrderListByDeliveryId(dto.getLogisticCode());
                if(orders!=null){
                    for(FsStoreOrder order:orders){
                        logger.info("订单信息:"+JSONUtil.toJsonStr(order));
                        logger.info("运单号:"+dto.getLogisticCode());
                        if(order!=null && (order.getDeliveryStatus()==null||order.getDeliveryStatus()!=3)){
                            if (dto.getState()!=null&&dto.getStateEx()!=null) {
                                FsStoreOrder map = new FsStoreOrder();
                                map.setDeliveryStatus(Integer.parseInt(dto.getState()));
                                map.setId(order.getId());
                                map.setDeliveryType(dto.getStateEx());
                                this.updateFsStoreOrder(map);
                                //如果是正常签收，更新订单状态
                                if (dto.getState().equals("3") && (dto.getStateEx().equals("301") || dto.getStateEx().equals("302") || dto.getStateEx().equals("304") || dto.getStateEx().equals("311"))) {
                                    this.finishOrder(order.getId());
                                }
                            }
                            //如果无轨迹重新订阅
                            if ((!dto.isSuccess()&&dto.getReason().equals("三天无轨迹"))||(!dto.isSuccess()&&dto.getReason().equals("七天内无轨迹变化"))){
                                //订阅物流回调
                                String lastFourNumber = "";
                                if (order.getDeliverySn().equals(ShipperCodeEnum.SF.getValue())) {
                                    lastFourNumber = order.getUserPhone();
                                    if (lastFourNumber.length() == 11) {
                                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                                    }
                                }
                                logger.info("物流重新订阅：{}",order.getDeliveryId());
                                expressService.subscribeEspress(order.getOrderCode(),order.getDeliverySn(),order.getDeliveryId(),lastFourNumber);
                            }

                        }
                    }
                }

            }
        }
    }

    @Override
    public FsStoreOrder selectOrderByUserIdLimit1(Long userId) {
        return fsStoreOrderMapper.selectOrderByUserIdLimit1(userId);
    }


    @Override
    public List<FsStoreOrder> selectFsStoreOrderStatisticsByUserId(List<Long> fsUserIdList) {
        return fsStoreOrderMapper.selectFsStoreOrderStatisticsByUserId(fsUserIdList);
    }
}
