package com.fs.hisStore.service.impl;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
import cn.binarywang.wx.miniapp.bean.shop.response.WxMaOrderShippingInfoGetResponse;
import cn.hutool.core.date.DateTime;
import cn.binarywang.wx.miniapp.api.WxMaService;
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.alibaba.fastjson.TypeReference;
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.AjaxResult;
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.exception.ServiceException;
import com.fs.common.utils.CloudHostUtils;
import com.fs.common.utils.DateUtils;
import com.fs.common.utils.IpUtil;
import com.fs.common.utils.ServletUtils;
import com.fs.common.utils.StringUtils;
import com.fs.common.utils.poi.ExcelUtil;
import com.fs.common.utils.ip.IpUtils;
import com.fs.common.utils.spring.SpringUtils;
import com.fs.company.domain.*;
import com.fs.company.mapper.CompanyDeptMapper;
import com.fs.company.mapper.CompanyMapper;
import com.fs.company.mapper.CompanyMoneyLogsMapper;
import com.fs.company.mapper.CompanyUserUserMapper;
import com.fs.company.service.ICompanyDeptService;
import com.fs.company.service.ICompanyService;
import com.fs.company.service.ICompanyUserService;
import com.fs.config.cloud.CloudHostProper;
import com.fs.core.config.WxMaConfiguration;
import com.fs.core.config.WxPayProperties;
import com.fs.core.utils.OrderCodeUtils;
import com.fs.course.dto.FsOrderDeliveryNoteDTO;
import com.fs.course.dto.OrderOpenIdTransDTO;
import com.fs.erp.domain.*;
import com.fs.erp.dto.*;
import com.fs.erp.dto.df.*;
import com.fs.erp.mapper.FsErpFinishPushMapper;
import com.fs.erp.service.IErpOrderService;
import com.fs.his.config.FsSysConfig;
import com.fs.his.domain.*;
import com.fs.his.dto.FsPrescribeUsageDTO;
import com.fs.his.dto.FsProdItemDTO;
import com.fs.his.dto.FsStoreOrderAmountScrmStatsQueryDto;
import com.fs.his.dto.FsStoreOrderItemDTO;
import com.fs.his.enums.FsStoreOrderLogEnum;
import com.fs.his.enums.FsStoreOrderStatusEnum;
import com.fs.his.mapper.*;
import com.fs.his.param.FsStoreOrderSalesParam;
import com.fs.his.service.IFsPrescribeService;
import com.fs.his.service.IFsUserWatchService;
import com.fs.his.utils.ConfigUtil;
import com.fs.his.vo.FsInquiryOrderVO;
import com.fs.his.vo.FsStoreOrderAmountScrmStatsVo;
import com.fs.his.vo.FsStoreOrderExcelVO;
import com.fs.his.vo.*;
import com.fs.his.vo.FsPrescribeVO;
import com.fs.hisStore.config.FsErpConfig;
import com.fs.hisStore.constants.ErpTypeEnum;
import com.fs.hisStore.dto.*;
import com.fs.hisStore.mapper.*;
import com.fs.hisStore.param.*;
import com.fs.hisStore.vo.*;
import com.fs.hisStore.vo.FsStoreOrderErpExportVO;
import com.fs.hisStore.vo.FsStoreOrderExportVO;
import com.fs.hisStore.vo.FsStoreOrderItemVO;
import com.fs.hisStore.vo.FsStoreOrderVO;
import com.fs.hisStore.vo.FsStoreProductAttrValueVO;
import com.fs.hisStore.vo.FsStoreProductDeliverExcelVO;
import com.fs.hisapi.domain.ApiResponse;
import com.fs.hisapi.param.CreateOrderParam;
import com.fs.hisapi.param.RecipeDetailParam;
import com.fs.hisapi.service.HisApiService;
import com.fs.huifuPay.domain.HuiFuCreateOrder;
import com.fs.huifuPay.domain.HuiFuRefundResult;
import com.fs.huifuPay.domain.HuifuCreateOrderResult;
import com.fs.huifuPay.sdk.opps.core.request.V2TradePaymentScanpayRefundRequest;
import com.fs.huifuPay.sdk.opps.core.utils.HuiFuUtils;
import com.fs.huifuPay.service.HuiFuService;
import com.fs.pay.pay.dto.OrderQueryDTO;
import com.fs.pay.pay.dto.RefundDTO;
import com.fs.pay.service.IPayService;
import com.fs.hisStore.config.StoreConfig;
import com.fs.hisStore.config.StoreIntegralConfig;
import com.fs.hisStore.constants.StoreConstants;
import com.fs.hisStore.domain.*;
import com.fs.hisStore.enums.*;
import com.fs.hisStore.service.*;
import com.fs.system.service.ISysConfigService;
import com.fs.wx.miniapp.config.WxMaProperties;
import com.fs.wx.order.domain.FsWxExpressTask;
import com.fs.wx.order.dto.*;
import com.fs.wx.order.mapper.FsWxExpressTaskMapper;
import com.fs.wx.order.service.ExpressToWxHolder;
import com.fs.wx.order.service.ExpressToWxService;
import com.fs.wx.order.service.ShippingService;
import com.fs.ybPay.domain.OrderResult;
import com.fs.ybPay.domain.RefundResult;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
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 com.google.common.base.Joiner;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.http.util.Asserts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.fs.his.utils.PhoneUtil.decryptPhone;
import static com.fs.his.utils.PhoneUtil.encryptPhone;
import static com.fs.hisStore.constants.StoreConstants.DELIVERY;

/**
 * 订单Service业务层处理
 *
 * @author fs
 * @date 2022-03-15
 */
@Service
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@Slf4j
public class FsStoreOrderScrmServiceImpl implements IFsStoreOrderScrmService {
    private static final String STORE_PAY_CONF = "his.pay";

    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private CompanyMoneyLogsMapper moneyLogsMapper;

    @Autowired
    private CompanyUserUserMapper companyUserUserMapper;
    @Autowired
    private IFsStoreOrderStatusScrmService orderStatusService;
    @Autowired
    private FsStoreCartScrmMapper cartMapper;

    @Autowired
    private FsUserAddressScrmMapper userAddressMapper;

    @Autowired
    private FsStoreOrderScrmMapper fsStoreOrderMapper;

    @Autowired
    private IFsStoreProductScrmService productService;

    @Autowired
    private IFsUserScrmService userService;

    @Autowired
    private IFsUserBillScrmService billService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IFsStoreCartScrmService cartService;

    @Autowired
    private ApplicationEventPublisher publisher;

    @Autowired
    private IFsShippingTemplatesScrmService shippingTemplatesService;

    @Autowired
    private IFsShippingTemplatesRegionScrmService shippingTemplatesRegionService;

    @Autowired
    private IFsShippingTemplatesFreeScrmService shippingTemplatesFreeService;
    @Autowired
    private IFsExpressScrmService expressService;

    @Autowired
    @Lazy
    private IFsPrescribeService fsPrescribeService;

    @Autowired
    private IPayService payService;
    @Autowired
    private FSSysConfig sysConfig;

    @Autowired
    private ConfigUtil configUtil;
    @Autowired
    private IFsStorePaymentScrmService paymentService;

    @Autowired
    private IFsStoreProductPackageScrmService productPackageService;

    @Autowired
    private ICompanyUserService companyUserService;
    @Autowired
    private IFsStoreProductAttrValueScrmService attrValueService;
    @Autowired
    private IFsStoreProductScrmService storeProductService;

    @Autowired
    private IFsStoreCouponUserScrmService couponUserService;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    private IFsStoreOrderItemScrmService storeOrderItemService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IFsStoreProductGroupScrmService storeProductGroupService;

    @Autowired
    private FsStoreOrderItemScrmMapper fsStoreOrderItemMapper;
    @Autowired
    private FsStoreOrderLogsScrmMapper fsStoreOrderLogsMapper;


    @Autowired
    private FsStorePaymentScrmMapper fsStorePaymentMapper;

    @Autowired
    private ICompanyDeptService companyDeptService;
    @Autowired
    private IFsPrescribeScrmService prescribeService;

    @Autowired
    private IPayService ybPayService;

    @Autowired
    private HuiFuService huiFuService;
    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private WxPayProperties wxPayProperties;

    @Autowired
    private FsErpFinishPushMapper fsErpFinishPushMapper;

    @Autowired
    @Qualifier("erpOrderServiceImpl")
    private IErpOrderService gyOrderService;

    @Autowired
    @Qualifier("wdtErpOrderServiceImpl")
    private IErpOrderService wdtOrderService;

    @Autowired
    @Qualifier("k9OrderScrmServiceImpl")
    private IErpOrderService k9OrderService;

    @Autowired
    @Qualifier("hzOMSErpOrderServiceImpl")
    private IErpOrderService hzOMSOrderService;

    @Autowired
    @Qualifier("dfOrderServiceImpl")
    private IErpOrderService dfOrderService;

    @Autowired
    @Qualifier("JSTErpOrderServiceImpl")
    private IErpOrderService jSTOrderService;

    @Autowired
    private IFsStoreOrderAuditScrmService orderAuditService;
    @Autowired
    private IFsStoreOrderAuditLogScrmService orderAuditLogService;
    @Autowired
    private CompanyMapper companyMapper;
    @Autowired
    private CompanyDeptMapper companyDeptMapper;

    @Autowired
    private FsStoreProductScrmMapper fsStoreProductMapper;

    @Autowired
    private FsPrescribeMapper prescribeMapper;

    @Autowired
    private FsPrescribeDrugMapper prescribeDrugMapper;

    @Autowired
    private FsInquiryOrderMapper fsInquiryOrderMapper;

    @Autowired
    private IFsStoreOrderLogsScrmService fsStoreOrderLogsService;//

    @Autowired
    private FsStoreProductAttrValueScrmMapper fsStoreProductAttrValueMapper;
    @Autowired
    private CloudHostProper cloudHostProper;

    @Autowired
    //fsStoreMapper
    private FsStoreScrmMapper fsStoreMapper;

    @Autowired
    private IFsUserWatchService fsUserWatchService;


    @Autowired
    private HisApiService hisApiService;

    @Autowired
    private IFsStoreAfterSalesScrmService fsStoreAfterSalesService;
    @Autowired
    private FsStoreAfterSalesLogsScrmMapper fsStoreAfterSalesLogsMapper;

    @Autowired
    private FsStoreAfterSalesItemScrmMapper fsStoreAfterSalesItemMapper;

    @Autowired
    private FsPackageOrderMapper fsPackageOrderMapper;

    @Autowired
    private WxMaProperties properties;

    //ERP 类型到服务的映射
    private Map<Integer, IErpOrderService> erpServiceMap;
    @Autowired
    private FsStoreOrderLogsScrmMapper fsStoreOrderLogsScrmMapper;

    @Autowired
    private FsStoreOrderDfMapper fsStoreOrderDfMapper;
    @Autowired
    private ShippingService shippingService;
    @Autowired
    private FsWxExpressTaskMapper fsWxExpressTaskMapper;

    @Autowired
    private IFsStoreCartScrmService fsStoreCartScrmService;

    @PostConstruct
    public void initErpServiceMap() {
        erpServiceMap = new HashMap<>();
        erpServiceMap.put(1, gyOrderService);      // 管易
        erpServiceMap.put(2, wdtOrderService);     // 旺店通
        erpServiceMap.put(3, hzOMSOrderService);   // 瀚智OMS
        erpServiceMap.put(4, dfOrderService);      // 代服
        erpServiceMap.put(5, jSTOrderService);     // 聚水潭
        erpServiceMap.put(6, k9OrderService);      // K9
    }
    @Override
    public void syncExpressToWx() {
        List<FsWxExpressTask> fsWxExpressTasks = fsWxExpressTaskMapper.selectPendingData();
        if (CollectionUtils.isEmpty(fsWxExpressTasks)) {
            logger.info("当前没有待同步的数据！已取消");
            return;
        }

        for (FsWxExpressTask fsWxExpressTask : fsWxExpressTasks) {

            try{
                UploadShippingInfoRequest request = new UploadShippingInfoRequest();

                OrderKey orderKey = new OrderKey();
                orderKey.setOrderNumberType(2);


                FsUserScrm fsUser = userService.selectFsUserByUserId(fsWxExpressTask.getUserId());

                ExpressToWxService service = ExpressToWxHolder.findBest(fsWxExpressTask.getType(),fsWxExpressTask.getOrderCode());
                Asserts.notNull(service,"订单类型不被支持！");


                orderKey.setTransactionId(service.getTransactionId());


                String userPhone = service.getUserPhone();
                String orderGoodsInfo = service.getOrderGoodsInfo();


                Payer payer = new Payer();
                if(StringUtils.isNotBlank(fsUser.getMaOpenId())){
                    payer.setOpenid(fsUser.getMaOpenId());
                }
                request.setPayer(payer);
                request.setOrderKey(orderKey);

                request.setLogisticsType(1);
                request.setDeliveryMode(1);

                request.setShippingList(Collections.singletonList(ShippingItem.builder()
                        .itemDesc(orderGoodsInfo)
                        .expressCompany(service.getExpressCompany())
                        .trackingNo(service.getExpressNo())
                        .contact(Contact.builder().consignorContact(userPhone).build())
                        .build()));

                OffsetDateTime now = OffsetDateTime.now();
                DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
                String formattedTimestamp = now.format(formatter);
                request.setUploadTime(formattedTimestamp);


                request.setAppid(fsWxExpressTask.getAppid());
                WeChatApiResponse response = shippingService.uploadShippingInfo(request);
                if(ObjectUtil.equal(response.getErrcode(),0)){
                    fsWxExpressTask.setStatus(2);
                } else {
                    fsWxExpressTask.setRetryCount(fsWxExpressTask.getRetryCount() +1);
                    fsWxExpressTask.setStatus(3);
                    fsWxExpressTask.setData(JSON.toJSONString(request));
                    fsWxExpressTask.setRequestBody(JSON.toJSONString(request));
                    fsWxExpressTask.setResponseBody(JSON.toJSONString(response));
                }
            }catch (Exception e){
                logger.info("该单 {} 推送到物流失败！",fsWxExpressTask);
                fsWxExpressTask.setRetryCount(fsWxExpressTask.getRetryCount() +1);
                fsWxExpressTask.setStatus(3);


            }
        }
        fsWxExpressTaskMapper.batchUpdate(fsWxExpressTasks);

    }
    /**
     * 查询订单
     *
     * @param id 订单ID
     * @return 订单
     */
    @Override
    public FsStoreOrderScrm selectFsStoreOrderById(Long id) {
        return fsStoreOrderMapper.selectFsStoreOrderById(id);
    }

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

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

    /**
     * 修改订单
     *
     * @param fsStoreOrder 订单
     * @return 结果
     */
    @Override
    public int updateFsStoreOrder(FsStoreOrderScrm fsStoreOrder) {
        fsStoreOrder.setUpdateTime(DateUtils.getNowDate());
        //推送修改的商城订单地址到聚水潭ERP
        try {
            pushOrderAddressToErp(fsStoreOrder);
        }catch (Exception e){
            log.error("修改商城订单地址推送到聚水潭ERP失败，orderId: {}", fsStoreOrder.getId(), e);
        }

        return fsStoreOrderMapper.updateFsStoreOrder(fsStoreOrder);
    }

    /**
     * 推送修改订单的最新地址到 ERP
     *
     * @param partialOrder 前端传入的部分订单对象，必须包含 id、userAddress
     */
    public void pushOrderAddressToErp(FsStoreOrderScrm partialOrder) {
        if (partialOrder == null || partialOrder.getId() == null) {
            log.info("传入订单为空或ID缺失，跳过ERP同步");
            return;
        }

        // 1. 检查 ERP 是否开启
        FsSysConfig sysConfig = configUtil.getSysConfig();
        Integer erpOpen = sysConfig.getErpOpen();
        if (erpOpen == null || erpOpen == 0) {
            log.info("ERP未开启，跳过同步");
            return;
        }
        Integer erpType = sysConfig.getErpType();
        if (erpType == null || !erpServiceMap.containsKey(erpType)) {
            log.info("ERP类型配置无效: {}", erpType);
            return;
        }
        //目前只针对聚水潭ERP推送最新的修改地址
        if (erpType != 5){
            return;
        }
        // 2. 从数据库获取完整订单（用于补全必要字段;当前是修改商城订单接口,查询fs_store_order_scrm表)
        FsStoreOrderScrm dbOrder = fsStoreOrderMapper.selectFsStoreOrderById(partialOrder.getId());
        if (dbOrder == null) {
            log.error("数据库表fs_store_order_scrm中订单不存在，orderId: {}", partialOrder.getId());
            return;
        }
        //判断当前是否满足推送条件(erp订单号不为空且订单状态为待发货时可推送)
        if (StringUtils.isBlank(dbOrder.getExtendOrderId()) || dbOrder.getStatus() != 1) {
            log.info("不满足修改订单地址推送到ERP条件: extendOrderId={}, status={}", dbOrder.getExtendOrderId(), dbOrder.getStatus());
            return;
        }
        // 3. 构造用于ERP推送的订单对象：订单地址用传入的新值
        if (StrUtil.isBlank(partialOrder.getUserAddress())){
            log.error("修改商城订单地址为空，orderId: {}", partialOrder.getId());
            return;
        }
        dbOrder.setUserAddress(partialOrder.getUserAddress());
        try {
        // 4. 构建 ERP 订单对象
        ErpOrder erpOrder = getErpOrder(dbOrder);

        // 5. 调用对应 ERP 服务(当前是聚水潭ERP)
        IErpOrderService erpService = erpServiceMap.get(erpType);
        //执行商城订单推送逻辑
        ErpOrderResponse response = erpService.addOrderScrm(erpOrder);
        log.info("ERP地址推送结果 - 商城订单: {}, ERP类型: {}, 成功: {}, 外部单号: {}",
                dbOrder.getOrderCode(), erpType, response.getSuccess(), response.getCode());
        } catch (Exception e) {
            log.error("修改商城订单地址推送到ERP失败，orderId: {}", partialOrder.getId(), e);
        }
    }

    /**
     * 批量删除订单
     *
     * @param ids 需要删除的订单ID
     * @return 结果
     */
    @Override
    public int deleteFsStoreOrderByIds(Long[] ids) {
        //查询订单是否存在
        List<FsStoreOrderScrm> fsStoreOrderList = fsStoreOrderMapper.selectStoreOrderScrmInId(ids);
        if (fsStoreOrderList.isEmpty()) {
            throw new ServiceException("操作失败，数据不存在！");
        }
//        FsStoreOrderScrm checKOrder=fsStoreOrderList.stream().filter(f->f.getPaid() != null &&!f.getPaid().equals(0)).findFirst().orElse(null);
//         if(checKOrder != null){
//            if(!checKOrder.getPaid().equals(0)){
//                throw new ServiceException("操作失败，当前订单号为:"+checKOrder.getOrderCode()+"状态不为待支付，无法删除！");
//            }
//        }

        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) {
        //获取地址信息和购物车信息
        FsUserAddressScrm address = userAddressMapper.selectFsUserAddressByDefaultAddress(uid);
        List<FsStoreCartQueryVO> carts = cartMapper.selectFsStoreCartListByIds(cartParam.getCartIds());
        for (FsStoreCartQueryVO cart : carts) {
            if (cart.getChangePrice() != null && BigDecimal.ZERO.compareTo(cart.getChangePrice()) < 0) {
                cart.setPrice(cart.getChangePrice());
                //删除改价
                FsStoreCartScrm fsStoreCart = new FsStoreCartScrm();
                fsStoreCart.setId(cart.getId());
                fsStoreCart.setChangePrice(BigDecimal.ZERO);
                cartMapper.updateFsStoreCart(fsStoreCart);
            }
        }
        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) {
        logger.info("computedOrder param:{},uid:{}", param,uid);
        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())) {
            Integer payType = redisCache.getCacheObject("createOrderPayType:" + param.getCreateOrderKey());
            if (payType != null && payType == 3) {
                payPrice = redisCache.getCacheObject("createOrderAmount:" + param.getCreateOrderKey());
            } else {
                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);
        FsUserAddressScrm 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);

        FsUserScrm 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) {
            FsStoreCouponUserScrm 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 payType = redisCache.getCacheObject("createOrderPayType:" + param.getCreateOrderKey());
        if (payType != null) {
            param.setPayType(payType.toString());
        }
//        Integer totalNum = 0;
        BigDecimal integral = BigDecimal.ZERO;
        if (cartIds != null) {
            //获取购物车列表
            List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + param.getOrderKey());
            //获取地址
            FsUserAddressScrm address = userAddressMapper.selectFsUserAddressById(param.getAddressId());
            //生成分布式唯一值
            String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
            //是否使用积分
            Boolean isIntegral = false;
            //组合数据
            FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
            storeOrder.setStoreHouseCode("CK01");
            storeOrder.setCompanyId(param.getCompanyId());
            storeOrder.setCompanyUserId(param.getCompanyUserId());

            String json = configService.selectConfigByKey("store.config");
            StoreConfig config= JSONUtil.toBean(json, StoreConfig.class);
            //绑定销售
            FsUserScrm fsuser= userService.selectFsUserById(userId);
            if(ObjectUtil.isEmpty(config.getOrderAttribution())
                    ||!config.getOrderAttribution().equals(1)){
                if(param.getCompanyUserId()!=null){
                    if (ObjectUtil.isNotEmpty(fsuser.getCompanyUserId())&&!fsuser.getCompanyUserId().equals(param.getCompanyUserId())){
                        CompanyUser companyUser=companyUserService.selectCompanyUserById(fsuser.getCompanyUserId());
                        return R.error(String.format("请联系%s销售进行购买商品！",companyUser.getNickName()));
                    }else {
                        fsuser.setCompanyUserId(param.getCompanyUserId());
                        userService.updateFsUser(fsuser);
                    }
                    CompanyUser companyUser=companyUserService.selectCompanyUserById(param.getCompanyUserId());
                    if(companyUser!=null){
                        storeOrder.setDeptId(companyUser.getDeptId());
                    }
                }else {
                    storeOrder.setCompanyUserId(fsuser.getCompanyUserId());
                }
            }

            CompanyUserUser map=new CompanyUserUser();
            map.setCompanyUserId(param.getCompanyUserId());
            map.setUserId(userId);
            List<CompanyUserUser> list= companyUserUserMapper.selectCompanyUserUserList(map);
            if(list==null||list.size()==0){
                CompanyUser companyUser=companyUserService.selectCompanyUserById(param.getCompanyUserId());
                if(companyUser!=null&&companyUser.getStatus().equals("0")){
                    map.setCompanyId(companyUser.getCompanyId());
                    companyUserUserMapper.insertCompanyUserUser(map);
                }
            }

            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) {
                FsStoreCouponUserScrm 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);
                }
            }
            //处理推荐人
            FsUserScrm user = userService.selectFsUserById(storeOrder.getUserId());
            if (user.getSpreadUserId() != null && user.getSpreadUserId() > 0) {
                storeOrder.setTuiUserId(user.getSpreadUserId());
            } else {
                if (param.getTuiUserId() != null) {
                    FsUserScrm 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.getPayPrice() != null && param.getPayPrice().compareTo(BigDecimal.ZERO) > 0) {
                if (param.getPayPrice().compareTo(dto.getTotalPrice()) > 0) {
                    return R.error("改价价格不能大于商品总价");
                }
                storeOrder.setPayPrice(param.getPayPrice());
            } else {
                storeOrder.setPayPrice(dto.getPayPrice());
            }

            //付款方式
            if (param.getPayType().equals("1")) {
                //全款支付
                storeOrder.setStatus(0);
            } else if (param.getPayType().equals("2")) {
                //物流代收
                storeOrder.setStatus(1);
            } else if (param.getPayType().equals("3")) {
                //货到付款
                BigDecimal amount = param.getAmount();  //货到付款 自定义代收金额
                if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
                    storeOrder.setStatus(0);
                    storeOrder.setPayMoney(amount);
                    storeOrder.setPayDelivery(storeOrder.getPayPrice().subtract(amount));
                } else {
                    storeOrder.setStatus(1);
                }
            }
            Boolean isPay = true;
            if (param.getOrderCreateType() != null && param.getOrderCreateType() == 3 && param.getCompanyId() != null) {
                //后台制单 判断是否需要付款
                Company company = companyMapper.selectCompanyById(param.getCompanyId());
                if (company != null) {
                    if (company.getIsPay() != null && company.getIsPay() == 0 && param.getIsUserApp()) {
                        //不需要付款
                        storeOrder.setStatus(1); //待发货
                        isPay = false;
                    }
                }
            }
            storeOrder.setOrderCreateType(param.getOrderCreateType());
            Long prescribe = carts.stream().filter(item -> item.getProductType() != null && item.getProductType() == 2).count();
            if (prescribe > 0) {
                storeOrder.setIsPrescribe(1);
            } else {
                storeOrder.setIsPrescribe(0);
            }
            if (storeOrder.getCustomerId() == null) {
                storeOrder.setCustomerId(param.getCustomerId());//6.13 添加客户id
            }
            FsStoreOrderScrm tempOrder = redisCache.getCacheObject("orderInfo:" + param.getCreateOrderKey());
            if (tempOrder != null) {
                storeOrder.setOrderType(tempOrder.getOrderType());
                storeOrder.setOrderMedium(tempOrder.getOrderMedium());
                redisCache.deleteObject("orderInfo:" + param.getCreateOrderKey());
            } else {
                storeOrder.setOrderType(param.getOrderType());
                storeOrder.setOrderMedium(param.getOrderMedium());
            }
            Integer flag = fsStoreOrderMapper.insertFsStoreOrder(storeOrder);
            if (flag == 0) {
                return R.error("订单创建失败");
            }
            if (!isPay && storeOrder.getCompanyId() != null) {
                // 添加订单审核
                addOrderAudit(storeOrder);
            }
            //使用了积分扣积分
            if (dto.getUsedIntegral() > 0) {
                this.decIntegral(userId, dto.getUsedIntegral(), dto.getDeductionPrice(), storeOrder.getId().toString());
            }
            //减库存加销量
            this.deStockIncSale(carts);
            //保存OrderItem
            List<FsStoreOrderItemScrm> 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());
                }

                FsStoreOrderItemScrm item = new FsStoreOrderItemScrm();
                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());
            if (config.getIsBrushOrders() == null || !(config.getIsBrushOrders() && param.getCompanyUserId() != null)) {//未开启刷单
                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());
            if (config.getUnPayTime() != null) {
                calendar.add(Calendar.MINUTE, config.getUnPayTime());
            }
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String payLimitTime = format.format(calendar.getTime());
            redisCache.setCacheObject("orderAmount:" + storeOrder.getId(), storeOrder.getPayMoney(), 24, TimeUnit.HOURS);//物流代收自定义金额
            //删除推荐订单KEY
            String createOrderKey = param.getCreateOrderKey();
            if("鸿森堂".equals(cloudHostProper.getCompanyName())){
                BigDecimal amount = redisCache.getCacheObject("createOrderAmount:" + createOrderKey);
                redisCache.setCacheObject("orderAmount:" + storeOrder.getId(), amount, 24, TimeUnit.HOURS);//物流代收自定义金额
            }else {
                if (StringUtils.isNotEmpty(createOrderKey)) {
                    if (config.getIsBrushOrders() == null || !(config.getIsBrushOrders() && param.getCompanyUserId() != null)) {//未开启刷单
                        redisCache.deleteObject("createOrderKey:" + createOrderKey);
                        redisCache.deleteObject("orderCarts:" + createOrderKey);
                        redisCache.deleteObject("createOrderMoney:" + createOrderKey);
                    }

                    //货到付款自定义金额 key改为id存储
                    BigDecimal amount = redisCache.getCacheObject("createOrderAmount:" + createOrderKey);
                    redisCache.deleteObject("createOrderAmount:" + createOrderKey);
                }
            }
            return R.ok().put("order", storeOrder).put("payLimitTime", payLimitTime);
        } else {
            return R.error("订单已过期");
        }
    }

    @Override
    public R createOrderByPrescribe(Long prescribeId) {
        FsPrescribe prescribe = prescribeMapper.selectFsPrescribeByPrescribeId(prescribeId);
        FsPrescribeDrug map = new FsPrescribeDrug();
        map.setPrescribeId(prescribeId);
        List<FsPrescribeDrug> drugs = prescribeDrugMapper.selectFsPrescribeDrugList(map);
        FsStoreOrderScrm order = new FsStoreOrderScrm();
        List<FsStoreOrderItemScrm> items = new ArrayList<>();
        String orderSn = OrderCodeUtils.getOrderSn();
        if (StringUtils.isEmpty(orderSn)) {
            return R.error("订单生成失败，请重试");
        }
        order.setOrderCode(orderSn);
        order.setCycle(prescribe.getCycle());
        order.setStoreId(prescribe.getStoreOrderId());
        order.setUserId(prescribe.getUserId());
        order.setStoreId(prescribe.getStoreId());
        order.setDoctorId(prescribe.getDoctorId());
        order.setInquiryOrderId(prescribe.getInquiryOrderId());
        FsInquiryOrder fsInquiryOrder = fsInquiryOrderMapper.selectFsInquiryOrderByOrderId(prescribe.getInquiryOrderId());
        if (fsInquiryOrder != null) {
            order.setCompanyId(fsInquiryOrder.getCompanyId());
            order.setCompanyUserId(fsInquiryOrder.getCompanyUserId());
        }
        order.setPackageSecondName("医生处方");
        order.setPackageName("医生处方");
        order.setStatus(1);
        order.setPayType("1");
        order.setIsPrescribe(1);
        order.setPrescribeId(prescribe.getPrescribeId());
        order.setCreateTime(new Date());
        if (prescribe.getSource() != null) {
            order.setSource(prescribe.getSource());
        }
        Long totalNum = 0l;
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal totalCostPrice = new BigDecimal("0");
        for (FsPrescribeDrug drug : drugs) {
            totalPrice = totalPrice.add(drug.getDrugPrice().multiply(BigDecimal.valueOf(drug.getDrugNum())));
            totalNum = totalNum + drug.getDrugNum();
            FsStoreOrderItemScrm item = new FsStoreOrderItemScrm();
            item.setProductId(drug.getProductId());
            item.setIsDrug(drug.getIsDrug());
            item.setStoreId(prescribe.getStoreId());
            item.setProductAttrValueId(drug.getProductAttrValueId());
            if (drug.getProductAttrValueId() != null) {
                FsStoreProductAttrValueScrm value = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueById(drug.getProductAttrValueId());
                if (value.getCost() != null) {
                    if (drug.getDrugNum() != null) {
                        totalCostPrice = totalCostPrice.add(value.getCost().multiply(BigDecimal.valueOf(drug.getDrugNum())));
                    }
                }
            }

            item.setNum(drug.getDrugNum() != null ? drug.getDrugNum().intValue() : null);
            FsStoreOrderItemDTO dto = new FsStoreOrderItemDTO();
            dto.setImage(drug.getDrugImgUrl());
            dto.setNum(drug.getDrugNum());
            FsStoreProductScrm product = fsStoreProductMapper.selectFsStoreProductById(drug.getProductId());
            if (product != null) {
                dto.setProductName(product.getProductName());
                dto.setProductId(product.getProductId());
            }
            FsStoreProductAttrValueScrm value = fsStoreProductAttrValueMapper.selectFsStoreProductAttrValueById(drug.getProductAttrValueId());
            if (value != null) {
                dto.setSku(value.getSku());
                dto.setBarCode(value.getBarCode());
                dto.setPrice(value.getPrice());
                dto.setNum(drug.getDrugNum());
                dto.setImage(value.getImage());
            }
            item.setIsPrescribe(1);
            item.setJsonInfo(JSON.toJSONString(dto));
            items.add(item);
        }
        //中药总价处理
        if (prescribe.getPrescribeType().equals(2)) {
            FsPrescribeUsageDTO dto = JSONUtil.toBean(prescribe.getUsageJson(), FsPrescribeUsageDTO.class);
            totalPrice = totalPrice.multiply(BigDecimal.valueOf(dto.getCounts()));
            totalNum = dto.getCounts();
            totalCostPrice = totalCostPrice.multiply(BigDecimal.valueOf(dto.getCounts()));
        }
        order.setCostPrice(totalCostPrice);
        order.setOrderType(prescribe.getPrescribeType());
        order.setTotalNum(totalNum);
        order.setTotalPrice(totalPrice);
        order.setPayPrice(totalPrice);
        order.setItemJson(JSONUtil.toJsonStr(items));
        if (fsStoreOrderMapper.insertFsStoreOrder(order) > 0) {
            prescribe.setStoreOrderId(order.getId());
            prescribeMapper.updateFsPrescribe(prescribe);
            for (FsStoreOrderItemScrm item : items) {
                item.setOrderId(order.getId());
                fsStoreOrderItemMapper.insertFsStoreOrderItem(item);
            }
            fsStoreOrderLogsService.create(order.getId(), FsStoreOrderLogEnum.CREATE_ORDER.getValue(),
                    FsStoreOrderLogEnum.CREATE_ORDER.getDesc());
        }
        return R.ok();
    }

    /**
     * 积分抵扣
     */
    private void decIntegral(Long uid, double usedIntegral, BigDecimal deductionPrice, String busId) {
        userService.decIntegral(uid, usedIntegral);
        FsUserScrm user = userService.selectFsUserById(uid);
        //积分记录
        billService.addBill(uid, BillDetailEnum.CATEGORY_2.getValue(), 0, BillDetailEnum.TYPE_1.getDesc(), new BigDecimal(usedIntegral) ,new BigDecimal(user.getIntegral()),
                "购买商品使用" + 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) {
        FsStoreOrderScrm 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) {
        FsStoreOrderScrm 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 {
                FsStoreOrderScrm orderMap = new FsStoreOrderScrm();
                orderMap.setId(order.getId());
                orderMap.setRefundPrice(order.getPayMoney());
                orderMap.setRefundReason("拒绝开方自动退款");
                orderMap.setRefundReasonTime(new Date());
                fsStoreOrderMapper.updateFsStoreOrder(orderMap);
                //将钱退还给用户
                List<FsStorePaymentScrm> payments = paymentService.selectFsStorePaymentByOrderId(order.getId());
                if (payments != null) {
                    for (FsStorePaymentScrm payment : payments) {
                        //易宝退款
                        RefundDTO refundDTO = new 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(FsStoreOrderScrm order) {
        if (order.getCouponId() != null) {
            FsStoreCouponUserScrm couponUser = couponUserService.selectFsStoreCouponUserById(order.getCouponId());
            if (couponUser != null) {
                couponUser.setStatus(0);
                couponUser.setUseTime(null);
                couponUserService.updateFsStoreCouponUser(couponUser);
            }
        }
    }

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

        FsStoreOrderScrm 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) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderCode);
        if (order != null && order.getStatus() == OrderInfoEnum.STATUS_1.getValue()) {
            FsExpressScrm 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));

            List<FsStorePaymentScrm> fsStorePayments = fsStorePaymentMapper.selectFsStorePaymentByOrderId(order.getId());
            FsStorePaymentScrm fsStorePayment = fsStorePayments.get(0);
            FsWxExpressTask fsWxExpressTask = new FsWxExpressTask();
            fsWxExpressTask.setUserId(order.getUserId());
            fsWxExpressTask.setStatus(0);
            fsWxExpressTask.setRetryCount(0);
            fsWxExpressTask.setCreateTime(LocalDateTime.now());
            fsWxExpressTask.setUpdateTime(LocalDateTime.now());
            fsWxExpressTask.setOrderCode(order.getOrderCode());
            fsWxExpressTask.setExpressCompany(express.getCode());
            fsWxExpressTask.setExpressNo(deliveryId);
            fsWxExpressTask.setAppid(fsStorePayment.getAppId());
            fsWxExpressTaskMapper.insert(fsWxExpressTask);
        }
    }

    @Override
    public void updateDeliveryOrder(Long id, String deliveryId, String deliverCode, String deliverName) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(id);
        if (order != null) {
            FsExpressScrm 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 FsStoreOrderScrm selectFsStoreOrderByOrderCode(String orderCode) {
        return fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderCode);
    }

    @Override
    public R getExpress(FsStoreOrderScrm 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());
        FsExpressScrm 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()) {
            FsStoreCartScrm storeCart = FsStoreCartScrm.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());
            createParam.setCustomerId(param.getCustomerId());
            createParam.setAmount(param.getAmount());
            createParam.setOrderCreateType(3); //后台制单
            createParam.setOrderType(param.getOrderType());
            createParam.setOrderMedium(param.getOrderMedium()); //后台制单
            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 FsStoreOrderScrm 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) {
        FsUserAddressScrm address = userAddressMapper.selectFsUserAddressByDefaultAddress(uid);
        FsStoreProductPackageScrm storeProductPackage = productPackageService.selectFsStoreProductPackageById(param.getPackageId());
        // 由于套餐制单前面有生成oderkey，并且要取修改的价格，所以这里判断，如果有传就用传的orderkey，如果没有就生成（代表走的是直接购买）
        String uuid;
        BigDecimal totalMoney;
        if(param.getCreateOrderKey().isEmpty() ){
            //直接购买
            uuid = IdUtil.randomUUID();
            totalMoney = storeProductPackage.getPayMoney();
        } else {
            // 套餐制单
            uuid = param.getCreateOrderKey();
            totalMoney = redisCache.getCacheObject("createOrderMoney:" + param.getCreateOrderKey());
        }

        if (param.getCouponUserId() != null) {
            FsStoreCouponUserScrm couponUser = couponUserService.selectFsStoreCouponUserById(param.getCouponUserId());
            if (couponUser != null && couponUser.getStatus() == 0) {
                if (couponUser.getUseMinPrice().compareTo(storeProductPackage.getPayMoney()) == -1) {
                    totalMoney = totalMoney != null ? totalMoney.subtract(couponUser.getCouponPrice()) : BigDecimal.ZERO.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) {
            FsStoreProductPackageScrm storeProductPackage = productPackageService.selectFsStoreProductPackageById(param.getPackageId());
            if (storeProductPackage.getStatus().equals(0)) {
                return R.error("此套餐已下架");
            }
            //限购处理
            if (storeProductPackage.getLimitCount() != null && storeProductPackage.getLimitCount() > 0) {
                //查看是否已购买
                FsUserScrm user = userService.selectFsUserById(uid);
                if (!user.getLevel().equals(1)) {
                    if (fsStoreOrderMapper.checkPackageOrderCount(uid, packageId) >= storeProductPackage.getLimitCount()) {
                        return R.error("此套餐限购:" + storeProductPackage.getLimitCount() + "次");
                    }
                }
            }
            //获取地址
            FsUserAddressScrm address = userAddressMapper.selectFsUserAddressById(param.getAddressId());
            //获取套餐数据
            JSONArray jsonArray = JSONUtil.parseArray(storeProductPackage.getProducts());
            List<StorePackageProductDTO> goodsList = JSONUtil.toList(jsonArray, StorePackageProductDTO.class);
            //检测库存
            Integer totalNum = 0;
            List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + param.getOrderKey());
            String joinCartIds = null;
            if(carts == null || carts.isEmpty()){
                carts = new ArrayList<>();
                for (StorePackageProductDTO goods : goodsList) {
                    FsStoreProductAttrValueScrm attrValue = attrValueService.selectFsStoreProductAttrValueById(goods.getId());
                    if (attrValue != null && attrValue.getProductId() != null) {
                        FsStoreProductScrm 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);

                        }
                    }
                    cartService.checkProductStock(attrValue.getProductId(), attrValue.getId());
                }
            } else {
                // 如果cartIds不为空，则表示是套餐制单购买，非套餐制单是没有购物车信息的。
                List<Long> cartIds = carts.stream().map(FsStoreCartQueryVO::getId).collect(Collectors.toList());
                joinCartIds = Joiner.on(",").join(cartIds);
            }
            //生成分布式唯一值
            String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
            //是否使用积分
            Boolean isIntegral = false;
            //组合数据
            CompanyUser user = companyUserService.selectCompanyUserById(param.getCompanyUserId());
            FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
            storeOrder.setCartId(joinCartIds);
            //修改默认仓库

            storeOrder.setStoreHouseCode("CK01");

            if (user != null) {
                storeOrder.setCompanyId(user.getCompanyId());
                storeOrder.setDeptId(user.getDeptId());
            }
            BigDecimal totalMoney;
            if(param.getIsPackage() != null && param.getIsPackage() == 1){
                totalMoney = redisCache.getCacheObject("createOrderMoney:" + param.getOrderKey());
            } else {
                totalMoney = storeProductPackage.getPayMoney();
            }

            //优惠券处理
            if (param.getCouponUserId() != null) {
                FsStoreCouponUserScrm 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);
            FsStoreProductPackageScrm productPackage = new FsStoreProductPackageScrm();
            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);
            } else {
                storeOrder.setIsPrescribe(0);
            }
            Integer flag = fsStoreOrderMapper.insertFsStoreOrder(storeOrder);
            if (flag == 0) {
                return R.error("订单创建失败");
            }
            //减库存加销量
            this.deStockIncSale(carts);
            //保存购物车商品信息
            List<FsStoreOrderItemScrm> 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());
                if (StringUtils.isEmpty(vo.getProductAttrImage())) {
                    fsStoreCartDTO.setImage(vo.getProductImage());
                } else {
                    fsStoreCartDTO.setImage(vo.getProductAttrImage());
                }
                FsStoreOrderItemScrm item = new FsStoreOrderItemScrm();
                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.isEmpty()) {
                storeOrder.setItemJson(JSONUtil.toJsonStr(listOrderItem));
            }
            fsStoreOrderMapper.updateFsStoreOrder(storeOrder);

            //删除缓存
            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());
            if (ObjectUtil.isNotEmpty(config.getUnPayTime())) {
                calendar.add(Calendar.MINUTE, config.getUnPayTime());
            } else {
                calendar.add(Calendar.MINUTE, 30);
            }
            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) {
        IFsStoreOrderScrmService fsStoreOrderService = (IFsStoreOrderScrmService) AopContext.currentProxy();
        return fsStoreOrderService.finishStoreOrder(orderId);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    public R finishStoreOrder(Long orderId) {
        FsStoreOrderScrm 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);
                }
            }

            FsErpConfig erpConfig = configUtil.getErpConfig();
            Integer erpType = erpConfig.getErpType();
            Integer erpOpen = erpConfig.getErpOpen();
            if (erpOpen != null && erpOpen == 1) {
                if (erpType != null && erpType == 2) {
                    // 同步订单完成状态到erp
                    // 如果是物流代收 或者 货到付款
                    if ("2".equals(order.getPayType()) || "3".equals(order.getPayType())) {
                        // 已结算
                        if ("1".equals(order.getDeliveryPayStatus())) {
                            FsErpFinishPush fsErpFinishPush = new FsErpFinishPush();
                            fsErpFinishPush.setOrderId(order.getId());
                            fsErpFinishPush.setTaskStatus(0);
                            fsErpFinishPush.setRetryCount(0);
                            fsErpFinishPush.setCreateTime(new Date());
                            fsErpFinishPushMapper.insert(fsErpFinishPush);
                        }
                    }
                }
            }


            //模板消息支付成功发布事件
            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
    public BigDecimal selectFsStoreOrderByPayPriceCount(FsStoreOrderStatisticsParam param) {
        return fsStoreOrderMapper.selectFsStoreOrderByPayPriceCount(param);
    }

    @Override
    @Transactional
    //类型1支付回调 类型2货到付款
    public String payConfirm(Integer type, Long orderId, String payCode, String tradeNo, String bankTransactionId, String bankSerialNo) {
        //支付订单
//        try {
        FsStoreOrderScrm order = null;
        if (type.equals(1)) {
            FsStorePaymentScrm storePayment = paymentService.selectFsStorePaymentByCode(payCode);
            if (storePayment == null || !storePayment.getStatus().equals(0)) {
                return "";
            }
            FsStorePaymentScrm storePaymentMap = new FsStorePaymentScrm();
            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) {
            //处理佣金 套餐不分佣金
            FsStoreOrderItemScrm orderItemMap = new FsStoreOrderItemScrm();
            orderItemMap.setOrderId(order.getId());
            List<FsStoreOrderItemScrm> 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());
        FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
        storeOrder.setId(order.getId());
        storeOrder.setPaid(OrderInfoEnum.PAY_STATUS_1.getValue());
        storeOrder.setStatus(OrderInfoEnum.STATUS_1.getValue());
        storeOrder.setPayTime(new Date());
        fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
        // 添加订单审核
        if (storeOrder.getCompanyId() != null) {
            addOrderAudit(order);
        }


    return "SUCCESS";


        //非处方直接提交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 "";
//        }
    }

    /**
     * 添加审核
     *
     * @param order 订单信息
     */
    private void addOrderAudit(FsStoreOrderScrm order) {
        if (!getAuditSwitch()) {
            return;
        }

        FsStoreOrderAuditScrm orderAudit = new FsStoreOrderAuditScrm();
        orderAudit.setOrderId(order.getId());
        orderAudit.setCompanyId(order.getCompanyId());
        orderAudit.setCompanyUserId(order.getCompanyUserId());
        orderAudit.setAuditStatus(OrderAuditStateEnum.COMPANY_PENDING.getValue());
        orderAudit.setCreateTime(LocalDateTime.now());
        orderAuditService.save(orderAudit);

        FsStoreOrderAuditLogScrm auditLog = new FsStoreOrderAuditLogScrm();
        auditLog.setAuditId(orderAudit.getId());
        auditLog.setOrderId(order.getId());
        auditLog.setContent("系统:提交审核");
        auditLog.setCreateTime(LocalDateTime.now());
        orderAuditLogService.save(auditLog);
    }

    /**
     * 获取是否需要订单审核
     *
     * @return boolean
     */
    private boolean getAuditSwitch() {
        try {
            String json = configService.selectConfigByKey("store.config");
            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
            return config.getAuditSwitch() == 1;
        } catch (Exception e) {
            return false;
        }
    }

    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 R createOmsOrder(Long orderId) throws ParseException {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        FsSysConfig erpConfig = configUtil.generateStructConfigByKey(SysConfigEnum.HIS_CONFIG.getKey(), FsSysConfig.class);
        List<Long> noErpCompany = erpConfig.getNoErpCompany();
        if (noErpCompany != null && noErpCompany.contains(order.getCompanyId())) {
            log.info("订单:{},相关公司不推送erp", order.getOrderCode());
            return R.error("订单:" + order.getOrderCode() + ",相关公司不推送erp");
        }
        IErpOrderService erpOrderService = getErpService();
        if (erpOrderService == null) {
            log.info("未启用erp");
            return R.error("暂未启用erp");
        }
        if (!StringUtils.isEmpty(order.getExtendOrderId()) && order.getStatus() != 1) {
            return R.error("订单:" + order.getOrderCode() + ",已推送erp/订单状态不正确");
        }
        ErpOrder erpOrder = getErpOrder(order);
        if (erpOrderService == jSTOrderService) {
            erpOrder.setShop_code(erpConfig.getErpJstShopCode());
        }
        ErpOrderResponse response = erpOrderService.addOrderScrm(erpOrder);
//        ErpOrderResponse response= k9OrderService.addOmsOrder(order.getId());

        //写入日志
        logger.info("ErpCreate:" + order.getOrderCode() + ":" + JSONUtil.toJsonStr(response));
        //支付成功后 将订单号写入待发货的REDIS中
        redisCache.setCacheObject(DELIVERY + ":" + response.getCode(), order.getOrderCode());
        //写入外部订单号
        order.setExtendOrderId(response.getCode());
        fsStoreOrderMapper.updateFsStoreOrder(order);
        return R.ok("订单:" + order.getOrderCode() + ",创建erp订单成功");
    }

    @Override
    public ErpOrder getErpOrder(FsStoreOrderScrm order) throws ParseException {
        FsSysConfig erpConfig = configUtil.generateStructConfigByKey("his.config", FsSysConfig.class);
        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());
        erpOrder.setWarehouse_code(erpConfig.getErpWarehouseCode());
        erpOrder.setShop_code(erpConfig.getErpShopCode());
        erpOrder.setBuyer_account(order.getRealName());

//      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);
        if (CloudHostUtils.hasCloudHostName("康年堂")){
            FsExpressScrm express = expressService.selectFsExpressByOmsCode("SF");
            erpOrder.setExpress_code(express.getOmsCode());
            order.setDeliveryName(express.getName());
            order.setDeliverySn(express.getCode());
        } else {
            if (order.getCompanyId() != null) {

                FsExpressScrm express = expressService.selectFsExpressByOmsCode("SF.0235402855");
                erpOrder.setExpress_code(express.getOmsCode());
                order.setDeliveryName(express.getName());
                order.setDeliverySn(express.getCode());

            } else {
                FsExpressScrm 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());
            }
        }


        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.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()));
        FsStoreOrderItemScrm itemMap = new FsStoreOrderItemScrm();
        itemMap.setOrderId(order.getId());
        List<FsStoreOrderItemScrm> orderItems = storeOrderItemService.selectFsStoreOrderItemList(itemMap);
        List<ErpOrderItem> details = new ArrayList<>();
        for (FsStoreOrderItemScrm orderItem : orderItems) {
            FsStoreCartDTO cartDTO = JSONUtil.toBean(orderItem.getJsonInfo(), FsStoreCartDTO.class);
            //如果是组合码，查询出真实的商品数据 然后写入
            if (StringUtils.isNotEmpty(cartDTO.getGroupBarCode())) {
                FsStoreProductGroupScrm 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) {
                            FsStoreProductAttrValueScrm 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, Long companyUserId) {
        return fsStoreOrderMapper.selectFsStoreOrderTotalCount(type, companyId, companyUserId);
    }

    @Override
    @Transactional
    public R editTuiMoney(FsStoreOrderEditTuiMoneyParam param) {
        FsStoreOrderScrm 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<>();
                FsStoreOrderItemScrm map = new FsStoreOrderItemScrm();
                map.setOrderId(vo.getOrderid());
                List<FsStoreOrderItemScrm> items = fsStoreOrderItemMapper.selectFsStoreOrderItemList(map);
                if (items != null) {
                    for (FsStoreOrderItemScrm 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<FsStoreOrderScrm> selectFsStoreOrderByCompanyId(Long companyId) {
        return fsStoreOrderMapper.selectFsStoreOrderByCompanyId(companyId);
    }

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

    @Autowired
    private IFsStoreAfterSalesScrmService fsStoreAfterSalesScrmService;
    @Override
    @Transactional
    public R refundOrderMoney(Long orderId) {
        IErpOrderService erpOrderService = getErpService();
        FsErpConfig erpConfig = configUtil.generateStructConfigByKey("his.config", FsErpConfig.class);
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if (order.getStatus() == -2) {
            return R.error("已退款");
        }
        if (order.getStatus() != 1 && order.getStatus() != 2) {
            return R.error("非法操作");
        }
        if (erpConfig.getErpOpen() != null
                && erpConfig.getErpOpen() == 1
                && order.getExtendOrderId() == null
                && !CloudHostUtils.hasCloudHostName("康年堂")) {
            return R.error("暂未推送至erp,请稍后再试！");
        }
        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());
//            }

            if(ObjectUtils.equals(order.getStatus(),2)){
                FsStoreAfterSalesParam fsStoreAfterSalesParam = new FsStoreAfterSalesParam();
                fsStoreAfterSalesParam.setOrderCode(order.getOrderCode());
                fsStoreAfterSalesParam.setRefundAmount(order.getPayMoney());
                fsStoreAfterSalesParam.setServiceType(1);
                fsStoreAfterSalesParam.setReasons("后台手动退款流程");
                fsStoreAfterSalesParam.setExplainImg(null);
                List<FsStoreAfterSalesProductParam> productParams = new ArrayList<>();
                List <FsStoreOrderItemScrm> items = fsStoreOrderMapper.selectOrderItem(order.getId());
                for (FsStoreOrderItemScrm item : items){
                    FsStoreAfterSalesProductParam param1 = new FsStoreAfterSalesProductParam();
                    param1.setProductId(item.getProductId());
                    param1.setNum(item.getNum());
                    productParams.add(param1);
                }
                fsStoreAfterSalesParam.setProductList(productParams);

                return fsStoreAfterSalesScrmService.applyForAfterSales(order.getUserId(),fsStoreAfterSalesParam);
            } else{
                jSTOrderService.refundUpdateScrm(request);
            }
        }
        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<FsStorePaymentScrm> payments = paymentService.selectFsStorePaymentByOrderId(order.getId());
            if (payments != null) {
                String json = configService.selectConfigByKey("his.pay");

                FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
                for (FsStorePaymentScrm payment : payments) {
                    if (payment.getPayMode() == null || payment.getPayMode().equals("wx")) {
                        WxPayConfig payConfig = new WxPayConfig();
                        payConfig.setAppId(fsPayConfig.getAppId());
                        payConfig.setMchId(fsPayConfig.getWxMchId());
                        payConfig.setMchKey(fsPayConfig.getWxMchKey());
                        payConfig.setKeyPath(fsPayConfig.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")) {
                                FsStorePaymentScrm paymentMap = new FsStorePaymentScrm();
                                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")) {
                        String huifuId="";
                        FsHfpayConfigMapper fsHfpayConfigMapper = SpringUtils.getBean(FsHfpayConfigMapper.class);
                        if (payment.getAppId() != null) {
                            FsHfpayConfig fsHfpayConfig = fsHfpayConfigMapper.selectByAppId(payment.getAppId());
                            huifuId = fsHfpayConfig.getHuifuId();
                        } else {
                            if (("益善缘".equals(cloudHostProper.getCompanyName()))) {

                                FsHfpayConfig fsPayConfig2 = fsHfpayConfigMapper.selectByAppId("wx0d1a3dd485268521");
                                huifuId = fsPayConfig2.getHuifuId();
                            }else {
                                huifuId=fsPayConfig.getHuifuId();
                            }
                        }


                        V2TradePaymentScanpayRefundRequest request = new V2TradePaymentScanpayRefundRequest();
                        request.setOrgHfSeqId(payment.getTradeNo());
                        request.setHuifuId(huifuId);
                        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) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(param.getOrderId());
        FsErpConfig erpConfig = configUtil.getErpConfig();
        List<Long> noErpCompany = erpConfig.getNoErpCompany();
        if (noErpCompany.contains(order.getCompanyId())) {
            logger.info("订单:{},相关公司不推送erp", order.getOrderCode());
            return R.ok("订单:" + order.getOrderCode() + "相关公司不推送erp");
        }
        IErpOrderService erpOrderService = getErpService();
        if (erpOrderService == null) {
            log.info("未启用erp");
            return R.error("暂未启用erp");
        }
        if (order.getStatus() != 1) {
            return R.error("只有待发货状态可以同步");
        }
        if (order.getExtendOrderId() == null) {
            return R.error("未生成erp订单");
        }
        ErpOrderQueryRequert request = new ErpOrderQueryRequert();
        request.setCode(order.getExtendOrderId());
        ErpOrderQueryResponse response = erpOrderService.getScrmOrder(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())) {
                            FsStoreOrderScrm map = new FsStoreOrderScrm();
                            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) {
        FsStoreOrderScrm 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);
        FsStoreOrderScrm map = new FsStoreOrderScrm();
        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) {
        FsStoreOrderScrm 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, Integer orderType, Integer orderMedium) {
        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);

        //2025.7.23 倍力优需求 制单添加订单类型，媒体来源（非必填）
        if (orderType != null || orderMedium != null) {
            FsStoreOrderScrm fsStoreOrder = new FsStoreOrderScrm();
            fsStoreOrder.setOrderMedium(orderMedium);
            fsStoreOrder.setOrderType(orderType);
            redisCache.setCacheObject("orderInfo:" + uuid, fsStoreOrder, 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);
        Integer payType = redisCache.getCacheObject("createOrderPayType:" + createOrderKey);
        //展示代收金额
        if (payType != null && payType == 3) {
            money = redisCache.getCacheObject("createOrderAmount:" + createOrderKey);
        }
        if (StringUtils.isEmpty(key)) {
            throw new CustomException("订单已过期", 501);
        }
        return R.ok().put("carts", carts).put("totalMoney", money).put("payType", payType);
    }

    @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) {
            FsStoreCartScrm storeCart = FsStoreCartScrm.builder()
                    .cartNum(vo.getCartNum())
                    .productAttrValueId(vo.getProductAttrValueId())
                    .productId(vo.getProductId())
                    .userId(userId)
                    .isPay(0)
                    .isDel(0)
                    .isBuy(1)
                    .changePrice(vo.getPrice())
                    .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, BigDecimal payAmount,Integer payType, Integer isPackage) {
        //货到付款自定义金额
        if (payAmount == null) {
            String configJson = configService.selectConfigByKey("store.config");
            StoreConfig config = JSONUtil.toBean(configJson, StoreConfig.class);
            Integer amount = config.getPayAmount();
            if (amount != null) {
                payAmount = new BigDecimal(amount);
            }
        }


        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;
        if(isPackage == 0){
            for (FsStoreCartQueryVO vo : carts) {
                totalMoney = totalMoney.add(vo.getPrice().multiply(new BigDecimal(vo.getCartNum().toString())));
            }
        } else {
            //套餐制单
            totalMoney = carts.get(0).getPrice();
        }
        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);
        redisCache.setCacheObject("createOrderAmount:" + createOrderKey, payAmount, 24, TimeUnit.HOURS);//物流代收自定义金额
        redisCache.setCacheObject("createOrderPayType:" + createOrderKey, payType, 24, TimeUnit.HOURS);//支付类型 1-全付款 3-物流代收（货到付款）
        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<FsStoreOrderErpExportVO> selectFsStoreOrderListVOByExport(FsStoreOrderParam param) {
        if (CloudHostUtils.hasCloudHostName("金牛明医","康年堂")){
            return fsStoreOrderMapper.selectFsStoreOrderErpListVOByExport(param);

        } else {
            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<FsStoreOrderScrm> 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) {
        //支付订单
        FsStoreOrderScrm order = null;
        FsStorePaymentScrm 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());

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

        // 添加审核
        if (storeOrder.getCompanyId()!=null){
            addOrderAudit(order);
        }

        return "SUCCESS";
    }

    @Override
    public R auditPayRemain(Long orderId) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if (order.getIsPayRemain() == 1) {
            FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
            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 Integer selectFsStoreOrderCount(FsStoreOrderStatisticsParam param) {
        return fsStoreOrderMapper.selectFsStoreOrderCountByParam(param);
    }

    @Override
    public R computedPackageOrder(long userId, FsStoreComputedPackageIdOrderParam param) {
        FsStoreProductPackageScrm storeProductPackage = productPackageService.selectFsStoreProductPackageById(param.getPackageId());
        BigDecimal totalMoney = storeProductPackage.getPayMoney();
        if (param.getCouponUserId() != null) {
            FsStoreCouponUserScrm 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 FsStoreOrderScrm 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);
                FsStoreOrderScrm 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"))) {
                        FsStoreOrderScrm orderMap = new FsStoreOrderScrm();
                        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() + " 导入成功");


                        FsErpConfig erpConfig = configUtil.getErpConfig();
                        Integer erpType = erpConfig.getErpType();
                        Integer erpOpen = erpConfig.getErpOpen();
                        if (erpOpen != null && erpOpen == 1) {
                            if (erpType != null && erpType == 2) {
                                // 同步订单完成状态到erp
                                // 如果是物流代收 或者 货到付款
                                if ("2".equals(order.getPayType()) || "3".equals(order.getPayType())) {
                                    // 已结算
                                    if ("1".equals(dto.getDeliveryPayStatus())) {
                                        FsErpFinishPush fsErpFinishPush = new FsErpFinishPush();
                                        fsErpFinishPush.setOrderId(order.getId());
                                        fsErpFinishPush.setTaskStatus(0);
                                        fsErpFinishPush.setRetryCount(0);
                                        fsErpFinishPush.setCreateTime(new Date());
                                        fsErpFinishPushMapper.insert(fsErpFinishPush);
                                    }
                                }
                            }
                        }


                    } 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(FsStoreOrderScrm 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;
        }
        FsUserScrm user = userService.selectFsUserById(order.getUserId());
        //增加积分
        BigDecimal newIntegral = NumberUtil.add(order.getUseIntegral(), user.getIntegral());
        user.setIntegral(newIntegral.longValue());
        userService.updateFsUser(user);
        //增加流水
        billService.addBill(user.getUserId(), BillDetailEnum.CATEGORY_2.getValue(), 1, BillDetailEnum.TYPE_5.getDesc(),
                order.getUseIntegral(),
                newIntegral,
                "购买商品失败,回退积分" + order.getUseIntegral(), order.getId().toString(), 0l);
        //更新订单回退积分
        FsStoreOrderScrm storeOrder = new FsStoreOrderScrm();
        storeOrder.setBackIntegral(order.getUseIntegral());
        storeOrder.setId(order.getId());
        fsStoreOrderMapper.updateFsStoreOrder(storeOrder);
    }


    /**
     * 退回库存
     */
    private void refundStock(FsStoreOrderScrm 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, FsUserAddressScrm
            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, FsUserAddressScrm userAddress) {
        BigDecimal storePostage = BigDecimal.ZERO;
        if (userAddress != null) {
            if (userAddress.getCityId() == null) {
                return storePostage;
            }
            String cityId = userAddress.getCityId();
            List<String> citys = new ArrayList<>();
            citys.add(cityId);
            citys.add("0");//城市包括默认
            List<Long> tempIds = cartInfo
                    .stream()
                    .map(FsStoreCartQueryVO::getTempId)
                    .collect(Collectors.toList());

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

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

            //提取运费模板类型
            Map<Long, Integer> shippingTemplatesMap = shippingTemplatesList
                    .stream()
                    .collect(Collectors.toMap(FsShippingTemplatesScrm::getId,
                            FsShippingTemplatesScrm::getType));
            //提取运费模板有相同值覆盖
            Map<Long, FsShippingTemplatesRegionScrm> shippingTemplatesRegionMap =
                    shippingTemplatesRegionList.stream()
                            .collect(Collectors.toMap(FsShippingTemplatesRegionScrm::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();
                }

                FsShippingTemplatesRegionScrm 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(FsStoreOrderScrm 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<FsStoreOrderScrm> selectFsStoreOrderItemJson() {
        return fsStoreOrderMapper.selectFsStoreOrderItemJson();
    }

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

    @Override
    public ExpressResultDTO updateDeliveryItem(ExpressNotifyDTO notifyDTO) {
        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<FsStoreOrderScrm> orders = this.selectFsStoreOrderListByDeliveryId(dto.getLogisticCode());
                if (orders != null) {
                    for (FsStoreOrderScrm 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) {
                                FsStoreOrderScrm map = new FsStoreOrderScrm();
                                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()) {
                                logger.info("物流状态异常：{}", dto);
                            }
                            //如果无轨迹重新订阅
                            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);
                            }

                        }
                    }
                }

            }
            return ExpressResultDTO.success(sysConfig.getKdnId().trim());
        }
        return ExpressResultDTO.error(sysConfig.getKdnId().trim(), "物流详情数据为null");
    }

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


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


    /**
     * 获取当前ERP类型
     * @return ERP类型
     */
    public ErpTypeEnum getErpType(){
        FsSysConfig erpConfig = configUtil.getSysConfig();
        Integer erpType = erpConfig.getErpType();
        ErpTypeEnum byCode = ErpTypeEnum.getByCode(erpType);
        Asserts.notNull(byCode,String.format("当前ERP 类型: %d 未找到！",erpType));
        return byCode;
    }


    private IErpOrderService getErpService() {
        //判断是否开启erp
        IErpOrderService erpOrderService = null;
        //FsErpConfig erpConfig = configUtil.getErpConfig();
        FsSysConfig erpConfig = configUtil.getSysConfig();
        Integer erpOpen = erpConfig.getErpOpen();
        if (erpOpen != null && erpOpen == 1) {
            //判断erp类型
            Integer erpType = erpConfig.getErpType();
            if (erpType == 1) {
                //管易
                erpOrderService = gyOrderService;
            } else if (erpType == 2) {
                //旺店通
                erpOrderService = wdtOrderService;
            } else if (erpType == 3) {
                //瀚智OMS
                erpOrderService = hzOMSOrderService;
            } else if (erpType == 4) {
                //代服
                erpOrderService = dfOrderService;
            } else if (erpType == 5) {
                //聚水潭
                erpOrderService = jSTOrderService;
            } else if (erpType == 6) {
                //金博
                erpOrderService = k9OrderService;
            }
        }
        return erpOrderService;
    }

    @Override
    public List<OrderStatisticsVo> selectOrderDimensionStatisticsList(OrderStatisticsParam param) {
        return fsStoreOrderMapper.selectOrderSaleStatisticsList(param);
//        if(param.getGroupType()==1){
//            return fsStoreOrderMapper.selectOrderSaleStatisticsList(param);
//        }else {
//            return fsStoreOrderMapper.selectOrderDimensionStatisticsList(param);
//        }
    }

    @Override
    public List<FsStoreOrderCountsVO> selectFsStoreOrderCountsByDept(Map<String, Object> map, Long deptId) {
        List<FsStoreOrderCountsVO> vos = fsStoreOrderMapper.selectFsStoreOrderCountsByDept(map);
        if (!vos.isEmpty()) {
            List<FsStoreOrderCountsVO> totalVos = new ArrayList<>();
            //查询组名
            List<CompanyDept> companyDeptList = companyDeptMapper.selectChildrenDeptById(deptId);
            if (companyDeptList.isEmpty()) {
                CompanyDept companyDept = companyDeptMapper.selectCompanyDeptById(deptId);
                FsStoreOrderCountsVO vo = addTotal(companyDept, vos, true);
                totalVos.add(vo);
            } else {
                for (CompanyDept companyDept : companyDeptList) {
                    FsStoreOrderCountsVO vo = addTotal(companyDept, vos, false);
                    totalVos.add(vo);
                }
            }
            vos.addAll(totalVos);
        }
        return vos;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R updateSalesOrderMoneyByProduct(FsStoreOrderMoneyByProductParam param) {
        String json = configService.selectConfigByKey("store.config");
        StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
        Integer createSalesOrderType = config.getCreateSalesOrderType();
        if (createSalesOrderType != null) {
            if (createSalesOrderType != 1) {
                return R.error("改价方式错误");
            }
        } else {
            return R.error("未设置改价方式");
        }

        String createOrderKey = param.getCreateOrderKey();
        String key = redisCache.getCacheObject("createOrderKey:" + createOrderKey);
        if (StringUtils.isEmpty(key)) {
            throw new CustomException("订单已过期", 501);
        }
//        List<FsStoreCartQueryVO> carts = redisCache.getCacheObject("orderCarts:" + createOrderKey);
        List<FsStoreCartQueryVO> carts = param.getCarts();
        if (carts.isEmpty()) {
            return R.error("购物车不能为空");
        }
        BigDecimal totalMoney = BigDecimal.ZERO;
        //新购物车明细
        for (FsStoreCartQueryVO vo : carts) {
            //单个价格不能为0
            BigDecimal price = vo.getPrice();
            if (price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
                return R.error("商品单价不能为0");
            }
            //更新购物车表
            FsStoreCartScrm storeCart = new FsStoreCartScrm();
            storeCart.setId(vo.getId());
            storeCart.setChangePrice(price);
            cartMapper.updateFsStoreCart(storeCart);
            //计算总价
            totalMoney = totalMoney.add(price.multiply(new BigDecimal(vo.getCartNum().toString())));
        }

        redisCache.setCacheObject("createOrderMoney:" + createOrderKey, totalMoney, 24, TimeUnit.HOURS);
        //更新redis的购物车明细
        redisCache.setCacheObject("orderCarts:" + createOrderKey, carts, 24, TimeUnit.HOURS);

        return R.ok();
    }

    private FsStoreOrderCountsVO addTotal(CompanyDept companyDept, List<FsStoreOrderCountsVO> vos,
                                          boolean isEmpty) {
        FsStoreOrderCountsVO vo = new FsStoreOrderCountsVO();
        Long totalCalls = 0L;
        BigDecimal totalAmount = BigDecimal.ZERO;
        BigDecimal validAmount = BigDecimal.ZERO;
        Long waitingOrders = 0L;
        BigDecimal waitingAmount = BigDecimal.ZERO;
        Long unPassedOrders = 0L;
        BigDecimal unPassedAmount = BigDecimal.ZERO;
        Long cancelOrders = 0L;
        BigDecimal cancelAmount = BigDecimal.ZERO;
        Long unshippedOrders = 0L;
        BigDecimal unshippedAmount = BigDecimal.ZERO;
        Long shippedOrders = 0L;
        BigDecimal shippedAmount = BigDecimal.ZERO;
        Long transitOrders = 0L;
        BigDecimal transitAmount = BigDecimal.ZERO;
        Long receivedOrders = 0L;
        BigDecimal receivedAmount = BigDecimal.ZERO;
        Long returnOrders = 0L;
        BigDecimal returnAmount = BigDecimal.ZERO;
        Long paybackOrders = 0L;
        BigDecimal paybackAmount = BigDecimal.ZERO;
        vo.setName("组名：" + companyDept.getDeptName());
        Long deptId = companyDept.getDeptId();
        vo.setDeptId(deptId);
        for (FsStoreOrderCountsVO orderCountsVO : vos) {
            if (!isEmpty) {
                if (!Objects.equals(deptId, orderCountsVO.getDeptId())) {
                    continue;
                }
            }
            orderCountsVO.setIsGroup(false);
            orderCountsVO.setGroupName(companyDept.getDeptName());
            totalCalls = totalCalls + orderCountsVO.getTotalCalls();
            totalAmount = totalAmount.add(orderCountsVO.getTotalAmount());
            validAmount = validAmount.add(orderCountsVO.getValidAmount());
            waitingOrders = waitingOrders + orderCountsVO.getWaitingOrders();
            waitingAmount = waitingAmount.add(orderCountsVO.getWaitingAmount());
            unPassedOrders = unPassedOrders + orderCountsVO.getUnPassedOrders();
            unPassedAmount = unPassedAmount.add(orderCountsVO.getUnPassedAmount());
            cancelOrders = cancelOrders + orderCountsVO.getCancelOrders();
            cancelAmount = cancelAmount.add(orderCountsVO.getCancelAmount());
            unshippedOrders = unshippedOrders + orderCountsVO.getUnshippedOrders();
            unshippedAmount = unshippedAmount.add(orderCountsVO.getUnshippedAmount());
            shippedOrders = shippedOrders + orderCountsVO.getShippedOrders();
            shippedAmount = shippedAmount.add(orderCountsVO.getShippedAmount());
            transitOrders = transitOrders + orderCountsVO.getTransitOrders();
            transitAmount = transitAmount.add(orderCountsVO.getTransitAmount());
            receivedOrders = receivedOrders + orderCountsVO.getReceivedOrders();
            receivedAmount = receivedAmount.add(orderCountsVO.getReceivedAmount());
            returnOrders = returnOrders + orderCountsVO.getReturnOrders();
            returnAmount = returnAmount.add(orderCountsVO.getReturnAmount());
            paybackOrders = paybackOrders + orderCountsVO.getPaybackOrders();
            paybackAmount = paybackAmount.add(orderCountsVO.getPaybackAmount());
        }
        vo.setTotalCalls(totalCalls);
        vo.setTotalAmount(totalAmount);
        vo.setValidAmount(validAmount);
        vo.setWaitingOrders(waitingOrders);
        vo.setWaitingAmount(waitingAmount);
        vo.setUnPassedOrders(unPassedOrders);
        vo.setUnPassedAmount(unPassedAmount);
        vo.setCancelOrders(cancelOrders);
        vo.setCancelAmount(cancelAmount);
        vo.setUnshippedOrders(unshippedOrders);
        vo.setUnshippedAmount(unshippedAmount);
        vo.setShippedOrders(shippedOrders);
        vo.setShippedAmount(shippedAmount);
        vo.setTransitOrders(transitOrders);
        vo.setTransitAmount(transitAmount);
        vo.setReceivedOrders(receivedOrders);
        vo.setReceivedAmount(receivedAmount);
        vo.setReturnOrders(returnOrders);
        vo.setReturnAmount(returnAmount);
        vo.setPaybackOrders(paybackOrders);
        vo.setPaybackAmount(paybackAmount);
        vo.setIsGroup(true);
        vo.setGroupName(companyDept.getDeptName());
        return vo;
    }

    @Override
    public List<FsStoreProductCountsVO> selectFsStoreProductCountsByDept(Map<String, Object> map, Long deptId) {
        //查询所有产品
        List<FsStoreProductScrm> products = fsStoreProductMapper.selectFsStoreProductList(null);
        List<FsStoreProductCountsVO> vos = new ArrayList<>();
        if (!products.isEmpty()) {
            for (FsStoreProductScrm product : products) {
                FsStoreProductCountsVO vo = new FsStoreProductCountsVO();
                vo.setName(product.getProductName());
                map.put("productId", product.getProductId());
                //查询该产品销售数量 和金额
                List<Map<String, Object>> temp = fsStoreOrderMapper.selectFsStoreProductCountsByDept(map);
                HashMap<String, Object> productMap = new HashMap<>();
                if (!temp.isEmpty()) {
                    for (Map<String, Object> stringMap : temp) {
                        String orderType = stringMap.get("orderType").toString();
                        stringMap.remove("orderType");
                        productMap.put(orderType, stringMap);
                    }
                }
                vo.setProductCounts(productMap);
                vos.add(vo);
            }
        }

        return vos;
    }

    @Override
    public FsStoreOrderScrm selectFsStoreOrderByOrderId(Long storeOrderId) {
        return fsStoreOrderMapper.selectFsStoreOrderById(storeOrderId);
    }

    @Override
    public List<FsStoreOrderExcelVO> selectFsStoreOrderExcelListSVO(FsStoreOrderParam fsStoreOrder) {
        List<FsStoreOrderExcelVO> fsStoreOrderVOS = fsStoreOrderMapper.selectFsStoreOrderExcelListVO(fsStoreOrder);

        for (FsStoreOrderExcelVO vo : fsStoreOrderVOS) {
            vo.setProductName(vo.getPackageSecondName());
            int count = 1;
            if (vo.getCycle() != null) {
                count = vo.getCycle() / 6;
                if (count == 0) {
                    count = 1;
                }
                vo.setFollowNum(count);
            }
            BigDecimal money = new BigDecimal(count * 300);
            vo.setInquiryMoney(money);
            if (vo.getTotalCostMoney() == null) {
                if (vo.getCostPrice() != null) {
                    vo.setTotalCostMoney(vo.getCostPrice());
                } else {
                    vo.setTotalCostMoney(new BigDecimal("0"));
                }
            }
            vo.setTotalMoney(vo.getInquiryMoney().add(vo.getTotalCostMoney()));
            vo.setInquiryDiscountMoney(vo.getTotalMoney().subtract(vo.getPrescribePrice()));
        }
        return fsStoreOrderVOS;
    }

    @Override
    public String importSroreOrder(List<FsStoreProductDeliverExcelVO> list, Long storeId, Long companyId) {
        if (StringUtils.isNull(list) || list.size() == 0) {
            throw new ServiceException("导入商品数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (FsStoreProductDeliverExcelVO vo : list) {
            try {
                FsStoreOrderScrm o = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(vo.getOrderCode());
                if (storeId != null) {
                    if (o.getStoreId() != storeId) {
                        throw new CustomException("不是本店铺订单");
                    }
                }

                if (companyId != null) {
                    if (o.getCompanyId() != companyId) {
                        throw new CustomException("不是本公司订单");
                    }
                }
                if (o.getStatus() != 2) {
                    throw new CustomException("订单状态不为待发货");
                }
                // 判断每个字段是否为null或为空字符串
                if (vo.getOrderCode() == null || vo.getOrderCode().isEmpty()) {
                    throw new CustomException("订单编号为空");
                }

                if (vo.getDeliveryName() == null || vo.getDeliveryName().isEmpty()) {
                    throw new CustomException("快递名称为空");
                }

                if (vo.getDeliverySn() == null || vo.getDeliverySn().isEmpty()) {
                    throw new CustomException("快递单号为空");
                }
                FsStoreOrderScrm fsStoreOrder = new FsStoreOrderScrm();

                fsStoreOrder.setDeliverySn(vo.getDeliverySn());
                fsStoreOrder.setDeliveryName(vo.getDeliveryName());
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                fsStoreOrder.setDeliveryTime(formatter.format(new Date()));
                fsStoreOrder.setDeliveryCode(vo.getDeliveryCode());

                fsStoreOrder.setOrderCode(vo.getOrderCode());
                fsStoreOrder.setStatus(3);
                if (o.getCompanyId() != null) {
                    companyService.subtractCompanyMoneyScrm(o);
                }
                FsStoreScrm store = fsStoreMapper.selectFsStoreByStoreId(o.getStoreId());
                int i = fsStoreOrderMapper.updateFsStoreOrderByOrderCode(fsStoreOrder);
                String lastFourNumber = "";
                if (fsStoreOrder.getDeliveryCode().equals(com.fs.his.enums.ShipperCodeEnum.SF.getValue())) {
                    if (store.getSendPhone() != null) {
                        lastFourNumber = store.getSendPhone();
                    } else {
                        lastFourNumber = o.getUserPhone();
                    }
                    if (lastFourNumber.length() == 11) {
                        lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
                    }
                }
                expressService.subscribeEspress(o.getOrderCode(), fsStoreOrder.getDeliveryCode(), fsStoreOrder.getDeliverySn(), lastFourNumber);

                try {
                    String s = fsPrescribeService.PrescribeImg(o.getPrescribeId());
                } catch (Exception e) {

                }

                successNum++;
                successMsg.append("<br/>" + successNum + "、订单编号 " + vo.getOrderCode() + " 导入成功");

            } catch (Exception e) {

                failureNum++;
                String msg = "<br/>" + failureNum + "、订单编号 " + vo.getOrderCode() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public int deleteFsStoreOrderByOrderIds(String[] orderIds) {
        Long[] ids = Arrays.stream(orderIds).map(Long::parseLong).toArray(Long[]::new);
        return fsStoreOrderMapper.deleteFsStoreOrderByIds(ids);
    }

    @Override
    public List<FsStoreOrderItemScrm> selectFsStoreOrderItemList(String orderId) {
        FsStoreOrderItemScrm fsStoreOrderItem = new FsStoreOrderItemScrm();
        fsStoreOrderItem.setOrderId(Long.parseLong(orderId));
        return fsStoreOrderItemMapper.selectFsStoreOrderItemList(fsStoreOrderItem);
    }

    @Override
    public List<FsStoreOrderLogsScrm> selectFsStoreOrderLogsList(String orderId) {
        FsStoreOrderLogsScrm fsStoreOrderLogs = new FsStoreOrderLogsScrm();
        fsStoreOrderLogs.setOrderId(Long.parseLong(orderId));
        return fsStoreOrderLogsMapper.selectFsStoreOrderLogsList(fsStoreOrderLogs);
    }

    @Override
    public FsPrescribeVO selectFsPrescribeByPrescribeIdVO(Long prescribeId) {
        return prescribeMapper.selectFsPrescribeByPrescribeIdVO(prescribeId);
    }

    @Override
    public List<FsStorePaymentScrm> selectFsStorePaymentByOrderId(Long orderId) {
        FsStoreOrderScrm fsStoreOrder = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if (fsStoreOrder.getPackageOrderId() == null) {
            return fsStorePaymentMapper.selectFsStorePaymentByOrderId(orderId);
        } else {
            return fsStorePaymentMapper.selectFsStorePaymentByPay(3, fsStoreOrder.getPackageOrderId());

        }
    }

    @Override
    public int sendGoods(FsStoreOrderScrm fsStoreOrder) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(fsStoreOrder.getId());
        if (order == null) throw new CustomException("订单不存在");
        if (order.getStatus() != 2) throw new CustomException("非法更改");
        FsStoreOrderScrm o1 = new FsStoreOrderScrm();
        o1.setId(fsStoreOrder.getId());
        o1.setStatus(3);
        o1.setUpdateTime(new DateTime());
        o1.setDeliveryCode(fsStoreOrder.getDeliveryCode());
        o1.setDeliveryName(fsStoreOrder.getDeliveryName());
        o1.setDeliverySn(fsStoreOrder.getDeliverySn());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateString = formatter.format(new Date());
        o1.setDeliveryTime(dateString);
        int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
        if (order.getCompanyId() != null) {
            companyService.subtractCompanyMoneyScrm(order);
        }
        FsStoreOrderLogsScrm Logs = new FsStoreOrderLogsScrm();
        Logs.setChangeMessage("订单发货");
        Logs.setOrderId(fsStoreOrder.getId());
        Logs.setChangeTime(new DateTime());
        Logs.setChangeType("delivery_goods");
        fsStoreOrderLogsMapper.insertFsStoreOrderLogs(Logs);

        String lastFourNumber = "";
        if (order.getDeliveryCode().equals(com.fs.his.enums.ShipperCodeEnum.SF.getValue())) {
            lastFourNumber = order.getUserPhone();
            if (lastFourNumber.length() == 11) {
                lastFourNumber = StrUtil.sub(lastFourNumber, lastFourNumber.length(), -4);
            }
        }
        expressService.subscribeEspress(order.getOrderCode(), fsStoreOrder.getDeliveryCode(), fsStoreOrder.getDeliverySn(), lastFourNumber);
        return i;
    }

    @Override
    public int getGoods(Long orderId) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(orderId);
        if (order == null) throw new CustomException("订单不存在");
        if (order.getStatus() != FsStoreOrderStatusEnum.STATUS_3.getValue()) throw new CustomException("非法更改");
        FsStoreOrderScrm o1 = new FsStoreOrderScrm();
        o1.setUpdateTime(new DateTime());
        o1.setFinishTime(new Date());
        o1.setId(orderId);
        o1.setStatus(FsStoreOrderStatusEnum.STATUS_4.getValue());
        log.info("确认收货：" + orderId);
        if (order.getCompanyId() != null && order.getTuiMoneyStatus() == 0 && "1".equals(order.getPayType())) {
            log.info("分佣：" + orderId);
            companyService.addCompanyMoney(order);
            o1.setTuiMoneyTime(new Date());
        }
        fsUserWatchService.addUserWatchScrm(order);
        int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
        fsStoreOrderLogsService.create(order.getId(), FsStoreOrderLogEnum.FINISH_ORDER.getValue(),
                FsStoreOrderLogEnum.FINISH_ORDER.getDesc());
        return i;
    }

    @Override
    public int updateMoney(FsStoreOrderScrm fsStoreOrder) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(fsStoreOrder.getId());
        if (order == null) {
            throw new CustomException("订单不存在");
        }
        if (order.getStatus() != 1) {
            throw new CustomException("非法更改");
        }
        FsStoreOrderScrm o1 = new FsStoreOrderScrm();
        o1.setUpdateTime(new DateTime());
        o1.setPayPrice(fsStoreOrder.getPayPrice());
        o1.setId(fsStoreOrder.getId());
        int i = fsStoreOrderMapper.updateFsStoreOrder(o1);
        FsStoreOrderLogsScrm Logs = new FsStoreOrderLogsScrm();
        Logs.setChangeMessage("改价");
        Logs.setOrderId(fsStoreOrder.getId());
        Logs.setChangeTime(new DateTime());
        Logs.setChangeType("edit_order_money");
        fsStoreOrderLogsMapper.insertFsStoreOrderLogs(Logs);
        return i;
    }

    @Override
    public int tuiOrder(Long orderId) {
        CreateOrderParam op = new CreateOrderParam();

        FsStoreOrderScrm o = fsStoreOrderMapper.selectFsStoreOrderById(orderId);

        if (o.getStatus() != 2) {
            throw new CustomException("订单状态不为代发货");
        }
        if (o.getUserAddress() == null || o.getUserAddress() == "") {
            throw new CustomException("用户收货地址为空");
        }
        if (o.getUserPhone() == null || o.getUserPhone() == "") {
            throw new CustomException("用户收货电话为空");
        }
        FsPrescribeVO fp = prescribeMapper.selectFsPrescribeByPrescribeIdVO(o.getPrescribeId());

        String s = fsPrescribeService.PrescribeImg(fp.getPrescribeId());

        FsPrescribeUsageDTO usage = JSONUtil.toBean(fp.getUsageJson(), FsPrescribeUsageDTO.class);

        FsInquiryOrderVO io = fsInquiryOrderMapper.selectFsInquiryOrderVOByOrderId(fp.getInquiryOrderId());

        FsStoreOrderItemScrm item = new FsStoreOrderItemScrm();
        item.setOrderId(o.getId());
        List<FsStoreOrderItemScrm> fsStoreOrderItems = fsStoreOrderItemMapper.selectFsStoreOrderItemList(item);
        log.info("" + fsStoreOrderItems);
        ArrayList<RecipeDetailParam> list = new ArrayList<>();
        Integer i = 1;
        BigDecimal dprice = new BigDecimal(0);
        for (FsStoreOrderItemScrm fsStoreOrderItem : fsStoreOrderItems) {

            RecipeDetailParam p = new RecipeDetailParam();
            String json = fsStoreOrderItem.getJsonInfo();
            FsProdItemDTO fsProdItemDTO = JSON.parseObject(json, FsProdItemDTO.class);
            String barCode = fsProdItemDTO.getBarCode();

            log.info("" + fsProdItemDTO);
            if (fsStoreOrderItem.getIsGift() != null && fsStoreOrderItem.getIsGift() == 1) {
                continue;
            }
            if (barCode.equals("106013")) {
                continue;
            }

            String barCodeTrim = barCode.replaceAll("[^a-zA-Z0-9]", "");
            ;
            p.setGranule_his(barCodeTrim);
            p.setGranule_name(new org.json.JSONObject(json).getString("productName"));
            BigDecimal price = new org.json.JSONObject(json).getBigDecimal("price");
            p.setGranule_price(price.toString());
            BigDecimal counts = new org.json.JSONObject(json).getBigDecimal("num");
            p.setHerb_dose(counts.toString());
            p.setGranule_no(i.toString());
            list.add(p);
            i++;
            dprice = dprice.add(price.multiply(counts));
        }

        op.setRecipe_name(fp.getPrescribeCode());

        op.setBirthday(fp.getPatientBirthday());
        op.setName(fp.getPatientName());
        op.setSex(fp.getPatientGender().equals("1") ? "男" : "女");
        op.setAge(Integer.parseInt(fp.getPatientAge()));
        if (o.getUserPhone().length() > 11) {
            op.setPhone(decryptPhone(o.getUserPhone()));
        } else {
            op.setPhone(o.getUserPhone());
        }

        if (io != null) {
            op.setDepartment(io.getDeptName());
        }
        op.setDoctor(fp.getDoctorName());
        op.setRecipe_no(usage.getCounts().intValue());//处方副数
        op.setGranule_total_no(i - 1);
        String usageFrequencyUnit = usage.getUsageFrequencyUnit();
        int dayNum = 2;
        if (usageFrequencyUnit != null) {
            if (usageFrequencyUnit.equals("每日一次")) {
                dayNum = 1;
            } else if (usageFrequencyUnit.equals("每日二次")) {
                dayNum = 2;
            } else if (usageFrequencyUnit.equals("每日三次")) {
                dayNum = 3;
            } else if (usageFrequencyUnit.equals("每日四次")) {
                dayNum = 4;
            }
        }

        if (fp.getRecipeType() != null) {
            op.setRecipe_type(fp.getRecipeType());
        }
        op.setTimes_day(dayNum);
        op.setFactor(0);
        String remark = usage.getRemark();
        if (remark != null && remark.length() > 50) {
            remark = remark.substring(0, 40);
        }

        op.setAttention(remark);//医嘱
        op.setSymptoms(fp.getDiagnose());
        op.setRecipe_time(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fp.getCreateTime()));
        op.setPrice(dprice.toString());
        op.setPrice_total(dprice.multiply(new BigDecimal(usage.getCounts())).toString());
        op.setRecipe_sale_price(o.getPayMoney().toString()); //实际收款
        op.setPayment_type("1");
        op.setPayment_status("PAYED");
        op.setRecipe_source("HIS");
        op.setMachine_name("");
        op.setRecipe_status("NEW");
        op.setDescription(s);
        if (fp.getPatientId() != null) {
            op.setPatient_id(fp.getPatientId().toString());
        }

        op.setAddress(o.getUserAddress());
        op.setRecipe_detail_list(list);
        ApiResponse order = hisApiService.createOrder(op);
        if (order.getState().equals("error")) {
            throw new CustomException(order.getMsg());
        }
        FsStoreOrderScrm fso = new FsStoreOrderScrm();
        fso.setId(o.getId());
        fso.setExtendOrderId("HIS");
        fsStoreOrderMapper.updateFsStoreOrder(fso);

        return 1;
    }

    @Override
    public int afterSales(FsStoreOrderSalesParam fsStoreOrderSalesParam) {
        FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderById(fsStoreOrderSalesParam.getOrderId());
        if (order.getStatus() < 0) {
            throw new CustomException("订单不可提交售后");
        }
        FsStoreAfterSalesScrm fsStoreAfterSales = new FsStoreAfterSalesScrm();
        fsStoreAfterSales.setOrderId(order.getId());
        fsStoreAfterSales.setStoreId(order.getStoreId());
        fsStoreAfterSales.setRefundAmount(order.getPayMoney());
        fsStoreAfterSales.setCreateTime(DateUtils.getNowDate());
        if (order.getStatus() == 2 || order.getStatus() == 3) {
            fsStoreAfterSales.setRefundType(0);
        }
        if (order.getStatus() == 4) {
            FsStoreScrm fsStore = fsStoreMapper.selectFsStoreByStoreId(order.getStoreId());
            fsStoreAfterSales.setRefundType(1);
            fsStoreAfterSales.setPhoneNumber(fsStore.getRefundPhone());
            fsStoreAfterSales.setAddress(fsStore.getRefundAddress());
            fsStoreAfterSales.setConsignee(fsStore.getRefundConsignee());
        }
        fsStoreAfterSales.setStatus(0);
        fsStoreAfterSales.setDeptId(order.getDeptId());
        fsStoreAfterSales.setSalesStatus(0);
        fsStoreAfterSales.setOrderStatus(order.getStatus());
        fsStoreAfterSales.setUserId(order.getUserId());
        fsStoreAfterSales.setCompanyId(order.getCompanyId());
        fsStoreAfterSales.setCompanyUserId(order.getCompanyUserId());
        fsStoreAfterSales.setIsDel(0);
        fsStoreAfterSalesService.insertFsStoreAfterSales(fsStoreAfterSales);
        List<FsStoreOrderItemVO> fsStoreOrderItems = fsStoreOrderItemMapper.selectFsStoreOrderItemListByOrderId(order.getId());
        for (FsStoreOrderItemVO fsStoreOrderItem : fsStoreOrderItems) {
            FsStoreAfterSalesItemScrm item = new FsStoreAfterSalesItemScrm();
            item.setStoreAfterSalesId(fsStoreAfterSales.getId());
            item.setProductId(fsStoreOrderItem.getProductId());
            item.setJsonInfo(fsStoreOrderItem.getJsonInfo());
            fsStoreAfterSalesItemMapper.insertFsStoreAfterSalesItem(item);
        }
        //增加操作日志
        FsStoreAfterSalesLogsScrm logs = new FsStoreAfterSalesLogsScrm();
        logs.setChangeTime(new DateTime());
        logs.setChangeType(0);
        logs.setStoreAfterSalesId(fsStoreAfterSales.getId());
        logs.setOperator(fsStoreOrderSalesParam.getOperator());
        logs.setCompanyId(fsStoreOrderSalesParam.getCompanyId());
        logs.setChangeMessage("平台提交售后");
        fsStoreAfterSalesLogsMapper.insertFsStoreAfterSalesLogs(logs);
        //判断是否开启erp
        FsSysConfig sysConfig = configUtil.getSysConfig();
        Integer erpOpen = sysConfig.getErpOpen();
        if (erpOpen != null && erpOpen == 1) {
            //判断erp类型
            Integer erpType = sysConfig.getErpType();
            if (erpType != null) {

                IErpOrderService erpOrderService = null;
                if (erpType == 1) {
                    //管易
                    erpOrderService = gyOrderService;
                } else if (erpType == 2) {
                    //旺店通
                    erpOrderService = wdtOrderService;
                } else if (erpType == 3) {
                    //瀚智
                    erpOrderService = hzOMSOrderService;
                } else if (erpType == 4) {
                    //瀚智
                    erpOrderService = dfOrderService;
                } else if (erpType == 5) {
                    erpOrderService = jSTOrderService;
                } else if (erpType == 6) {
                    erpOrderService = k9OrderService;
                }
                if (erpOrderService != null && StringUtils.isNotEmpty(order.getExtendOrderId())) {
                    if (!order.getExtendOrderId().equals("HIS")) {
                        if (erpType != 3) {
                            ErpRefundUpdateRequest request = new ErpRefundUpdateRequest();
                            request.setTid(order.getOrderCode());
                            request.setOid(order.getOrderCode());
                            request.setRefund_state(1);
                            erpOrderService.refundUpdate(request);
                        } else {
                            ErpRefundOrder param = new ErpRefundOrder();
                            param.setOrderCode(order.getOrderCode());
                            param.setAfterSalesId(fsStoreAfterSales.getId());
                            erpOrderService.refundOrder(param);
                        }
                    }
                }
            }
        }


        order.setStatus(-1);
        order.setRefundStatus(1);
        fsStoreOrderMapper.updateFsStoreOrder(order);
        if (order.getPackageOrderId() != null) {
            FsPackageOrder fsPackageOrder = fsPackageOrderMapper.selectFsPackageOrderByOrderId(order.getPackageOrderId());
            fsPackageOrder.setRefundStatus(1);
            fsPackageOrderMapper.updateFsPackageOrder(fsPackageOrder);
        }
        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R importDeliveryNoteExpress(List<FsOrderDeliveryNoteDTO> dtoList) {
        try {
            // 检查必填字段
            List<FsOrderDeliveryNoteDTO> list = new LinkedList<>();
            Map<String, String> expressDeliveryMap = buildExpressDeliveryMap();
            for (FsOrderDeliveryNoteDTO dto : dtoList) {
                if (StringUtils.isEmpty(dto.getOrderNumber())) {
                    return R.error("导入失败，系统订单不能为空！");
                } else if (StringUtils.isEmpty(dto.getDeliveryId())) {
                    return R.error("导入失败，快递单号不能为空！");
                } else if (StringUtils.isEmpty(dto.getDeliverySn())) {
                    return R.error("导入失败，快递公司编号不能为空！");
                }
                if (dto.getDeliveryStatus() == null) {
                    dto.setDeliveryStatus(0);
                }
                if (ObjectUtil.isNotNull(dto.getDeliveryTime())) {
                    dto.setDeliveryTime(parseCstToDateOnlyString(dto.getDeliveryTime()));
                }
                if (ObjectUtil.isNotNull(dto.getDeliveryPayTime()) && !dto.getDeliveryPayTime().equals("")) {
                    dto.setDeliveryPayTime(parseCstToDateOnlyString(dto.getDeliveryPayTime()));
                }
                if (expressDeliveryMap.containsKey(dto.getDeliverySn())) {
                    dto.setDeliveryName(expressDeliveryMap.get(dto.getDeliverySn()));
                } else {
                    return R.error("导入失败，订单号为" + dto.getOrderNumber() + "物流编码异常,请核对后再导入！");
                }
                list.add(dto);


                //批量导入物流单号 存在快递鸟时订阅下方参数，进行调整
                if(CloudHostUtils.hasCloudHostName("内蒙古一贴")){
                    FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(dto.getOrderNumber());
                    //订阅物流回调
                    String lastFourNumber = "";
                    if (dto.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));
                }
            }

            //分批次处理
            int batchSize = 500;
            int total = list.size();
            int batches = (total + batchSize - 1) / batchSize;
            for (int i = 0; i < batches; i++) {
                int start = i * batchSize;
                int end = Math.min(start + batchSize, total);
                List<FsOrderDeliveryNoteDTO> subList = list.subList(start, end);
                fsStoreOrderMapper.batchUpdateInOrderCode(subList);
            }
            return R.ok("导入成功，共更新 " + total + " 条记录");
        } catch (Exception e) {
            // 处理其他异常
            log.error("导入物流信息异常", e);
            return R.error("导入失败：" + e.getMessage());
        }
    }

    public static void main(String[] args) {
        String lastFourNumber = "15808582581";
    }
    @Override
    @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
    public R pay(FsStoreOrderPayParam param) {
        FsStoreOrderScrm order=this.selectFsStoreOrderById(param.getOrderId());
        if(order==null){
            return R.error("订单不存在");
        }
        if(order.getStatus()!= OrderInfoEnum.STATUS_0.getValue()){
            return R.error("订单状态不正确");
        }
        String orderId=redisCache.getCacheObject("isPaying:"+param.getOrderId());
        if(StringUtils.isNotEmpty(orderId)&&orderId.equals(order.getId().toString())){
            return R.error("正在支付中...");
        }

        FsUserScrm user=userService.selectFsUserById(order.getUserId());
        if(user!=null){
            //已改价处理
            if(order.getIsEditMoney()!=null&&order.getIsEditMoney()==1){
                //改过价不做处理

            }
            else{
                String config=configService.selectConfigByKey("his.store");
                com.fs.store.config.StoreConfig storeConfig= JSONUtil.toBean(config, com.fs.store.config.StoreConfig.class);
                if(param.getPayType().equals(1)){
                    order.setPayType("1");
                    order.setPayMoney(order.getPayPrice());
                    order.setPayDelivery(BigDecimal.ZERO);
                }
                else if(param.getPayType().equals(2)){
                    order.setPayType("2");
                    BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
                    // 如果小程序需要支付的金额小于0.01元，不能走物流代收，让走货到付款 xgb
                    if (payMoney.compareTo(new BigDecimal("0.01")) < 0) {
                        return R.error("物流代收计算支付金额为0,不允许选择物流代收");
                    }
                    order.setPayDelivery(order.getPayPrice().subtract(payMoney));
                    order.setPayMoney(payMoney);
                }
                else if(param.getPayType().equals(3)){
                    //货到付款
                    order.setPayType("3");
                    BigDecimal amount=redisCache.getCacheObject("orderAmount:"+order.getId());
                    BigDecimal payMoney = BigDecimal.ZERO;
                    if (amount != null){
                        payMoney=amount;
                    }
                    order.setPayMoney(payMoney);
                    order.setPayDelivery(order.getPayPrice().subtract(payMoney) );
                }
                this.updateFsStoreOrder(order);
            }
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
            if((order.getPayType().equals("1")||order.getPayType().equals("2")||order.getPayType().equals("3")) && order.getPayMoney().compareTo(new BigDecimal(0))>0){
                String json = configService.selectConfigByKey(STORE_PAY_CONF);
                FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
                FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
                storePayment.setCompanyId(order.getCompanyId());
                storePayment.setCompanyUserId(order.getCompanyUserId());
                storePayment.setPayMode(fsPayConfig.getType());
                storePayment.setStatus(0);
                storePayment.setPayCode(payCode);
                storePayment.setPayMoney(order.getPayMoney());
                storePayment.setCreateTime(new Date());
                storePayment.setPayTypeCode("weixin");
                storePayment.setBusinessType(2);
                storePayment.setRemark("商城订单支付");
                storePayment.setOpenId(user.getRealName());
                storePayment.setUserId(user.getUserId());
                storePayment.setBusinessOrderId(order.getId().toString());
                storePayment.setOrderId(order.getId());
                storePayment.setAppId(fsPayConfig.getAppId() == null ? "" : fsPayConfig.getAppId());
                fsStorePaymentMapper.insertFsStorePayment(storePayment);

                if (fsPayConfig.getType().equals("hf")){
                    HuiFuCreateOrder o = new HuiFuCreateOrder();
                    o.setTradeType("T_MINIAPP");
                    o.setOpenid(user.getMaOpenId());
                    o.setReqSeqId("store-"+storePayment.getPayCode());
                    o.setTransAmt(storePayment.getPayMoney().toString());
                    o.setGoodsDesc("商城订单支付");
                    o.setAppId(param.getAppId());
                    try {
                        HuiFuUtils.doDiv(o,order.getCompanyId());
                        //存储分账明细
                        HuiFuUtils.saveDivItem(o, order.getOrderCode(), storePayment.getPayCode());
                    } catch (Exception e) {
                        logger.error("-------------分账出错：{}", e.getMessage());
                    }
                    HuifuCreateOrderResult result = huiFuService.createOrder(o);
                    if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){
                        FsStorePaymentScrm mt=new FsStorePaymentScrm();
                        mt.setPaymentId(storePayment.getPaymentId());
                        mt.setTradeNo(result.getHf_seq_id());
                        mt.setAppId(param.getAppId());
                        mt.setBusinessCode(order.getOrderCode());
                        fsStorePaymentMapper.updateFsStorePayment(mt);
                        redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                        Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                        String s = (String) resultMap.get("package");
                        resultMap.put("packageValue",s);
                        return R.ok().put("payType",param.getPayType()).put("result",resultMap);
                    }
                    else{
                        return R.error(result.getResp_desc());
                    }
                }else  if (fsPayConfig.getType().equals("wx")){
                    WxPayConfig payConfig = new WxPayConfig();
                    payConfig.setAppId(fsPayConfig.getAppId());
                    payConfig.setMchId(fsPayConfig.getWxMchId());
                    payConfig.setMchKey(fsPayConfig.getWxMchKey());
                    payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                    payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                    payConfig.setKeyPath(fsPayConfig.getKeyPath());
                    payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
                    wxPayService.setConfig(payConfig);
                    WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                    orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                    orderRequest.setBody("商城订单支付");
                    orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                    orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                    orderRequest.setTradeType("JSAPI");
                    orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                    //调用统一下单接口，获取"预支付交易会话标识"
                    try {
                        WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                        return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0).put("payType",param.getPayType());
                    } catch (WxPayException e) {
                        e.printStackTrace();
                        throw new CustomException("支付失败" + e.getMessage());
                    }
                }
            }
            else if(order.getPayType().equals("3") && order.getPayMoney().compareTo(new BigDecimal(0))<=0){
                //货到付款
                IFsStoreOrderScrmService fsStoreOrderScrmService = (IFsStoreOrderScrmService) AopContext.currentProxy();
                fsStoreOrderScrmService.payConfirm(2,order.getId(),null,null,null,null);
                return R.ok().put("payType",param.getPayType());
            }
            return R.error();
        }
        else{
            return R.error("用户OPENID不存在");
        }
    }

    @Override
    public void cancelPay(FsStoreOrderPayParam param) {
        redisCache.deleteObject("isPaying:"+param.getOrderId());
    }

    @Override
    @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
    public R otherPaymentRemain(FsStoreOrderOtherPayParam param) {
        final WxMaService wxService = WxMaConfiguration.getMaService(properties.getConfigs().get(0).getAppid());
        try {
            String ip = IpUtil.getRequestIp();
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
            FsUserScrm user=userService.selectFsUserByMaOpenId(session.getOpenid());
            if(user==null){
                //创建
                user=new FsUserScrm();
                user.setUsername("");
                user.setNickname("微信用户");
                user.setStatus(1);
                user.setMaOpenId(session.getOpenid());
                user.setUnionId(session.getUnionid());
                user.setIsWeixinAuth(0);
                user.setLastIp(ip);
                user.setCreateTime(new Date());
                userService.insertFsUser(user);
            }
            FsStoreOrderScrm order=this.selectFsStoreOrderById(param.getOrderId());
            if(order==null){
                return R.error("订单不存在");
            }
            if(order.getStatus()!= OrderInfoEnum.STATUS_2.getValue()){
                return R.error("待收货订单可申请支付尾款");
            }
            if(order.getPayType().equals(1)){
                return R.error("此订单已支付");
            }
            //只有顺风才可以付尾
            if(!order.getDeliverySn().trim().equals("SF")){
                return R.error("只有顺丰物流支持尾款支付");
            }

            if(!order.getIsPayRemain().equals(0)){
                return R.error("此订单已支付");
            }
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
            String json = configService.selectConfigByKey(STORE_PAY_CONF);
            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
            FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
            storePayment.setCompanyId(order.getCompanyId());
            storePayment.setCompanyUserId(order.getCompanyUserId());
            storePayment.setStatus(0);
            storePayment.setPayMode(fsPayConfig.getType());
            storePayment.setPayCode(payCode);
            storePayment.setPayMoney(order.getPayDelivery());
            storePayment.setCreateTime(new Date());
            storePayment.setPayTypeCode("weixin");
            storePayment.setBusinessType(2);
            storePayment.setRemark("商城订单尾款支付");
            storePayment.setOpenId(user.getRealName());
            storePayment.setUserId(user.getUserId());
            storePayment.setBusinessOrderId(order.getId().toString());
            storePayment.setOrderId(order.getId());
            storePayment.setIsPayRemain(1);
            fsStorePaymentMapper.insertFsStorePayment(storePayment);

            if (fsPayConfig.getType().equals("hf")){
                HuiFuCreateOrder o = new HuiFuCreateOrder();
                o.setTradeType("T_MINIAPP");
                o.setOpenid(user.getMaOpenId());
                o.setReqSeqId("store-"+storePayment.getPayCode());
                o.setTransAmt(storePayment.getPayMoney().toString());
                o.setGoodsDesc("商城订单支付");
                HuifuCreateOrderResult result = huiFuService.createOrder(o);
                if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){

                    FsStorePaymentScrm mt=new FsStorePaymentScrm();
                    mt.setPaymentId(storePayment.getPaymentId());
                    mt.setTradeNo(result.getHf_seq_id());
                    fsStorePaymentMapper.updateFsStorePayment(mt);
                    redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                    Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                    String s = (String) resultMap.get("package");
                    resultMap.put("packageValue",s);
                    return R.ok().put("result",resultMap);
                }
                else{
                    return R.error(result.getResp_desc());
                }
            }else  if (fsPayConfig.getType().equals("wx")){
                //创建微信订单
                WxPayConfig payConfig = new WxPayConfig();
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setKeyPath(null);
                payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
                wxPayService.setConfig(payConfig);
                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                orderRequest.setBody("商城订单支付");
                orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                orderRequest.setTradeType("JSAPI");
                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                //调用统一下单接口，获取"预支付交易会话标识"
                try {
                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                    return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0);
                } catch (WxPayException e) {
                    e.printStackTrace();
                    throw new CustomException("支付失败" + e.getMessage());
                }
            }
        } catch (WxErrorException e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }
        return R.error("无支付类型");
    }

    @Override
    @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
    public R otherPayment(FsStoreOrderOtherPayParam param) {
        final WxMaService wxService = WxMaConfiguration.getMaService(properties.getConfigs().get(0).getAppid());
        try {
            String ip = IpUtil.getRequestIp();
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(param.getCode());
            FsUserScrm user=userService.selectFsUserByMaOpenId(session.getOpenid());
            if(user==null){
                //创建
                user=new FsUserScrm();
                user.setUsername("");
                user.setNickname("微信用户");
                user.setStatus(1);
                user.setMaOpenId(session.getOpenid());
                user.setUnionId(session.getUnionid());
                user.setIsWeixinAuth(0);
                user.setLastIp(ip);
                user.setCreateTime(new Date());
                userService.insertFsUser(user);
            }
            FsStoreOrderScrm order=selectFsStoreOrderById(param.getOrderId());
            if(order==null){
                return R.error("订单不存在");
            }
            if(!Objects.equals(order.getStatus(), OrderInfoEnum.STATUS_0.getValue())){
                return R.error("此订单不能支付");
            }
            if(order.getPayMoney().compareTo(new BigDecimal(0))<1){
                return R.error("此订单没有可支付的金额");
            }

            String orderId=redisCache.getCacheObject("isPaying:"+order.getId());
            if(StringUtils.isNotEmpty(orderId)&&orderId.equals(order.getId().toString())){
                return R.error("正在支付中...");
            }

            String json = configService.selectConfigByKey(STORE_PAY_CONF);
            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
            //易宝支付
            FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
            storePayment.setCompanyId(order.getCompanyId());
            storePayment.setCompanyUserId(order.getCompanyUserId());
            storePayment.setStatus(0);
            storePayment.setPayCode(payCode);
            storePayment.setPayMode(fsPayConfig.getType());
            storePayment.setPayMoney(order.getPayMoney());
            storePayment.setCreateTime(new Date());
            storePayment.setPayTypeCode("weixin");
            storePayment.setBusinessType(2);
            storePayment.setRemark("商城订单支付");
            storePayment.setOpenId(session.getOpenid());
            storePayment.setUserId(user.getUserId());
            storePayment.setBusinessOrderId(order.getId().toString());
            storePayment.setOrderId(order.getId());
            fsStorePaymentMapper.insertFsStorePayment(storePayment);

            if (fsPayConfig.getType().equals("hf")){
                HuiFuCreateOrder o = new HuiFuCreateOrder();
                o.setTradeType("T_MINIAPP");
                o.setOpenid(user.getMaOpenId());
                o.setReqSeqId("store-"+storePayment.getPayCode());
                o.setTransAmt(storePayment.getPayMoney().toString());
                o.setGoodsDesc("商城订单支付");
                HuifuCreateOrderResult result = huiFuService.createOrder(o);
                if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){

                    FsStorePaymentScrm mt=new FsStorePaymentScrm();
                    mt.setPaymentId(storePayment.getPaymentId());
                    mt.setTradeNo(result.getHf_seq_id());
                    fsStorePaymentMapper.updateFsStorePayment(mt);
                    redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                    Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                    String s = (String) resultMap.get("package");
                    resultMap.put("packageValue",s);
                    return R.ok().put("result",resultMap);
                }
                else{
                    return R.error(result.getResp_desc());
                }
            }else  if (fsPayConfig.getType().equals("wx")){
                //创建微信订单
                WxPayConfig payConfig = new WxPayConfig();
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setKeyPath(null);
                payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
                wxPayService.setConfig(payConfig);
                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                orderRequest.setBody("商城订单支付");
                orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                orderRequest.setTradeType("JSAPI");
                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                //调用统一下单接口，获取"预支付交易会话标识"
                try {
                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                    return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0);
                } catch (WxPayException e) {
                    e.printStackTrace();
                    throw new CustomException("支付失败" + e.getMessage());
                }
            }
        } catch (WxErrorException e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }
        return R.error("无支付类型");
    }

    @Override
    @Transactional(rollbackFor = Throwable.class,propagation = Propagation.REQUIRED)
    public R payRemain(FsStoreOrderPayParam param) {
        FsStoreOrderScrm order=selectFsStoreOrderById(param.getOrderId());
        if(order==null){
            return R.error("订单不存在");
        }
        if(order.getStatus()!= OrderInfoEnum.STATUS_2.getValue()){
            return R.error("待收货订单可申请支付尾款");
        }
        if(order.getPayType().equals(1)){
            return R.error("此订单已支付");
        }
        //只有顺风才可以付尾
        if(!order.getDeliverySn().trim().equals("SF")){
            return R.error("只有顺丰物流支持尾款支付");
        }

        if(!order.getIsPayRemain().equals(0)){
            return R.error("此订单已支付");
        }
        FsUserScrm user=userService.selectFsUserById(order.getUserId());
        if(user!=null){
            String payCode = IdUtil.getSnowflake(0, 0).nextIdStr();
            String json = configService.selectConfigByKey(STORE_PAY_CONF);
            FsPayConfigScrm fsPayConfig = JSON.parseObject(json, FsPayConfigScrm.class);
            FsStorePaymentScrm storePayment=new FsStorePaymentScrm();
            storePayment.setCompanyId(order.getCompanyId());
            storePayment.setCompanyUserId(order.getCompanyUserId());
            storePayment.setStatus(0);
            storePayment.setPayMode(fsPayConfig.getType());
            storePayment.setPayCode(payCode);
            storePayment.setPayMoney(order.getPayDelivery());
            storePayment.setCreateTime(new Date());
            storePayment.setPayTypeCode("weixin");
            storePayment.setBusinessType(2);
            storePayment.setRemark("商城订单尾款支付");
            storePayment.setOpenId(user.getRealName());
            storePayment.setUserId(user.getUserId());
            storePayment.setBusinessOrderId(order.getId().toString());
            storePayment.setOrderId(order.getId());
            storePayment.setIsPayRemain(1);
            fsStorePaymentMapper.insertFsStorePayment(storePayment);

            if (fsPayConfig.getType().equals("hf")){
                HuiFuCreateOrder o = new HuiFuCreateOrder();
                o.setTradeType("T_MINIAPP");
                o.setOpenid(user.getMaOpenId());
                o.setReqSeqId("store_remain-"+storePayment.getPayCode());
                o.setTransAmt(storePayment.getPayMoney().toString());
                o.setGoodsDesc("商城订单尾款支付");
                HuifuCreateOrderResult result = huiFuService.createOrder(o);
                //创建订单
                if(result.getResp_code()!=null&&(result.getResp_code().equals("00000000")||result.getResp_code().equals("00000100"))){

                    FsStorePaymentScrm mt=new FsStorePaymentScrm();
                    mt.setPaymentId(storePayment.getPaymentId());
                    mt.setTradeNo(result.getHf_seq_id());
                    fsStorePaymentMapper.updateFsStorePayment(mt);
                    redisCache.setCacheObject("isPaying:"+order.getId(),order.getId().toString(),1, TimeUnit.MINUTES);
                    Map<String, Object> resultMap = JSON.parseObject(result.getPay_info(), new TypeReference<Map<String, Object>>() {});
                    String s = (String) resultMap.get("package");
                    resultMap.put("packageValue",s);
                    return R.ok().put("payType",param.getPayType()).put("result",resultMap);
                }
                else{
                    return R.error(result.getResp_desc());
                }
            }else if(fsPayConfig.getType().equals("wx")) {
                WxPayConfig payConfig = new WxPayConfig();
                payConfig.setAppId(fsPayConfig.getAppId());
                payConfig.setMchId(fsPayConfig.getWxMchId());
                payConfig.setMchKey(fsPayConfig.getWxMchKey());
                payConfig.setSubAppId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setSubMchId(org.apache.commons.lang3.StringUtils.trimToNull(null));
                payConfig.setKeyPath(null);
                payConfig.setNotifyUrl(fsPayConfig.getNotifyUrlScrm());
                wxPayService.setConfig(payConfig);
                WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
                orderRequest.setOpenid(user.getMaOpenId());//公众号支付提供用户openid
                orderRequest.setBody("商城订单支付");
                orderRequest.setOutTradeNo("store-" + storePayment.getPayCode());
                orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(storePayment.getPayMoney().toString()));//测试
                //orderRequest.setTotalFee(WxPayUnifiedOrderRequest.yuanToFen(money));//测试
                orderRequest.setTradeType("JSAPI");
                orderRequest.setSpbillCreateIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
                //调用统一下单接口，获取"预支付交易会话标识"
                try {
                    WxPayMpOrderResult orderResult = wxPayService.createOrder(orderRequest);
                    return R.ok().put("result", orderResult).put("type", "wx").put("isPay", 0);
                } catch (WxPayException e) {
                    e.printStackTrace();
                    throw new CustomException("支付失败" + e.getMessage());
                }
            }
        }
        else{
            return R.error("用户OPENID不存在");
        }
        return R.error("无支付类型");
    }

    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public R editPayType(FsStoreOrderPayParam param) {
        FsStoreOrderScrm order=this.selectFsStoreOrderById(param.getOrderId());
        if(order==null){
            return R.error("订单不存在");
        }
        if(!Objects.equals(order.getStatus(), OrderInfoEnum.STATUS_0.getValue())){
            return R.error("订单状态不正确");
        }
        String orderId=redisCache.getCacheObject("isPaying:"+order.getId());
        if(StringUtils.isNotEmpty(orderId)&&orderId.equals(order.getId().toString())){
            return R.error("正在支付中...");
        }
        List<FsStorePaymentScrm>  payments=fsStorePaymentMapper.selectFsStorePaymentByOrder(order.getId());
        if(CollectionUtils.isNotEmpty(payments)){
            for(FsStorePaymentScrm payment : payments){
                OrderQueryDTO orderQueryDTO = new OrderQueryDTO();
                orderQueryDTO.setLowOrderId("store-"+payment.getPayCode());
                OrderResult orderResult = ybPayService.getOrder(orderQueryDTO);
                if(orderResult.getStatus()!= null&&orderResult.getStatus().equals("100")){
                    if(orderResult.getState()!=null&&orderResult.getState().equals("0")){
                        return R.error("订单已支付");
                    }

                }
            }
        }
        FsUserScrm user=userService.selectFsUserById(order.getUserId());
        if(user!=null){
            //已改价处理
            if(order.getIsEditMoney()!=null&&order.getIsEditMoney()==1){
                //改过价不做处理
            }
            else{
                String config=configService.selectConfigByKey("his.store");
                com.fs.store.config.StoreConfig storeConfig= JSONUtil.toBean(config, com.fs.store.config.StoreConfig.class);
                if(param.getPayType().equals(1)){
                    order.setPayType("1");
                    order.setPayMoney(order.getPayPrice());
                    order.setPayDelivery(BigDecimal.ZERO);
                }
                else if(param.getPayType().equals(2)){
                    // 物流代收
                    order.setPayType("2");
                    BigDecimal payMoney=order.getPayPrice().multiply(new BigDecimal(storeConfig.getPayRate())).divide(new BigDecimal(100));
                    payMoney=new BigDecimal(payMoney.setScale(0, BigDecimal.ROUND_HALF_UP).longValue());
                    order.setPayDelivery(order.getPayPrice().subtract(payMoney));
                    order.setPayMoney(payMoney);
                }
                else if(param.getPayType().equals(3)){
                    //货到付款
                    order.setPayType("3");
                    BigDecimal amount=redisCache.getCacheObject("orderAmount:"+order.getId());
                    BigDecimal payMoney = BigDecimal.ZERO;
                    if (amount != null){
                        payMoney=amount;
                    }
                    order.setPayMoney(payMoney);
                    order.setPayDelivery(order.getPayPrice().subtract(payMoney) );
                }
                IFsStoreOrderScrmService fsStoreOrderScrmService = (IFsStoreOrderScrmService) AopContext.currentProxy();
                fsStoreOrderScrmService.updateFsStoreOrder(order);
            }
            return R.ok().put("order",order);
        }
        else{
            return R.error("用户OPENID不存在");
        }
    }

    @Override
    public List<FsStoreOrderVO> selectFsStoreOrderListVOByErpAccount(FsStoreOrderParam param) {
        List<FsStoreOrderVO> list = fsStoreOrderMapper.selectFsStoreOrderListVOByErpAccount(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.isEmpty()) {
                    vo.setItems(items);
                }
            }
            //List<FsStoreOrderItemVO> items=storeOrderItemService.selectFsStoreOrderItemListByOrderId(vo.getId());
            //vo.setItems(items);
        }
        return list;
    }

    @Override
    @Transactional
    public int batchUpdateErpByOrderIds(FsStoreOrderScrmSetErpPhoneParam param) {
        //判断是根据orderId还是查询设置
        List<Long> orderIds = param.getOrderIds();
        if (orderIds == null || orderIds.isEmpty()) {
            if(!StringUtils.isEmpty(param.getCreateTimeRange())){
                param.setCreateTimeList(param.getCreateTimeRange().split("--"));
            }
            if(!StringUtils.isEmpty(param.getPayTimeRange())){
                param.setPayTimeList(param.getPayTimeRange().split("--"));
            }
            if(!StringUtils.isEmpty(param.getDeliveryImportTimeRange())){
                param.setDeliveryImportTimeList(param.getDeliveryImportTimeRange().split("--"));
            }
            if(!StringUtils.isEmpty(param.getDeliverySendTimeRange())){
                param.setDeliverySendTimeList(param.getDeliverySendTimeRange().split("--"));
            }
            param.setNotHealth(1);
            List<FsStoreOrderVO> list = fsStoreOrderMapper.selectFsStoreOrderListVO(param);
            orderIds = list.stream().map(FsStoreOrderVO::getId).collect(Collectors.toList());
            param.setOrderIds(orderIds);
        }
        if (orderIds.isEmpty()) {
            return 0;
        }
        //分配手机号
        //1.手机号大于/等于orderIds长度
        List<String> erpPhones = param.getErpPhone();
        int phoneSize = erpPhones.size();
        int orderSize = orderIds.size();
        ArrayList<Map<String, String>> maps = new ArrayList<>();
        if (phoneSize >= orderSize) {
            for (int i = 0; i < orderSize; i++) {
                HashMap<String, String> map = new HashMap<>();
                map.put("orderId", orderIds.get(i).toString());
                map.put("erpPhone", erpPhones.get(i));
                maps.add(map);
                fsStoreOrderLogsService.create(orderIds.get(i), FsStoreOrderLogEnum.SET_PUSH_MOBILE.getValue(),
                        param.getOpeName() + " " +FsStoreOrderLogEnum.SET_PUSH_MOBILE.getDesc() + ":" + erpPhones.get(i));
            }
        } else {
            //2.手机号小于orderIds长度
            int size = orderSize / phoneSize;
            int num = orderSize % phoneSize;
            if (num > 0) {
                size = size + 1;
            }
            int orderIndex = 0;
            for (String erpPhone : erpPhones) {
                for (int i = 0; i < size; i++) {
                    if (orderIndex > (orderSize - 1)) {
                        break;
                    }
                    HashMap<String, String> map = new HashMap<>();
                    map.put("orderId", orderIds.get(orderIndex).toString());
                    map.put("erpPhone", erpPhone);
                    maps.add(map);
                    orderIndex++;
                    fsStoreOrderLogsService.create(orderIds.get(i), FsStoreOrderLogEnum.SET_PUSH_MOBILE.getValue(),
                            param.getOpeName() + " " +FsStoreOrderLogEnum.SET_PUSH_MOBILE.getDesc() + ":" + erpPhone);
                }
            }
        }
        return fsStoreOrderMapper.batchUpdateErpByOrderIds(maps);
    }

    @Override
    public Map<String, BigDecimal> selectFsStoreOrderStatistics(FsStoreOrderParam param) {
        return fsStoreOrderMapper.selectFsStoreOrderStatistics(param);
    }

    @Override
    public String selectFsStoreOrderProductStatistics(FsStoreOrderParam param) {
        return fsStoreOrderMapper.selectFsStoreOrderProductStatistics(param);
    }

    @Override
    public int create(Long orderId, String type, String msg) {
        FsStoreOrderLogsScrm logs=new FsStoreOrderLogsScrm();
        logs.setOrderId(orderId);
        logs.setChangeType(type);
        logs.setChangeMessage(msg);
        logs.setCreateTime(new Date());
        return fsStoreOrderLogsScrmMapper.insertFsStoreOrderLogs(logs);
    }

    @Override
    @Transactional
    public R dfOrderResult(String body) {
        //先判断 取消订单/创建订单
        DFCancelOrderResultRequest cancelParam = JSON.parseObject(body, DFCancelOrderResultRequest.class);
        if (cancelParam.getIsCancelSuss() != null) {
            //取消订单
            log.info("代服管家取消订单回调,{}", JSON.toJSONString(cancelParam));
            FsStoreOrderScrm fsStoreOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(cancelParam.getOrderNumber());
            if (fsStoreOrder != null) {
//                //1.修改订单
//                FsStoreOrderSalesParam afterSalesParam = new FsStoreOrderSalesParam();
//                afterSalesParam.setOrderId(fsStoreOrder.getOrderId());
//                afterSalesParam.setReasons("代服管家取消订单");
//                afterSalesParam.setOperator("代服管家");
//                afterSales(afterSalesParam);
            }

        } else {
            BspOrderResponseWrapper addParam = JSON.parseObject(body, BspOrderResponseWrapper.class);
            if (addParam == null) {
                return R.ok("接收成功").put("code", "ok");
            }
            String failMsg = addParam.getFailMsg();
            if (com.hc.openapi.tool.util.StringUtils.isNotBlank(failMsg)) {
                if (failMsg.equals("暂未结果, 请稍后再查")) {
                    return R.ok("接收成功").put("code", "ok");
                }
                //下单失败 返回未推送状态
                String orderNumber = addParam.getOrderNumber();
                FsStoreOrderScrm fsStoreOrder = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderNumber);
                FsStoreOrderScrm tempOrder = new FsStoreOrderScrm();
                tempOrder.setId(fsStoreOrder.getId());
                Integer deliveryStatus = fsStoreOrder.getDeliveryStatus();
                if (deliveryStatus == null || deliveryStatus == 0) {
                    //没有物流信息
                    //修改订单状态 方便后续重新发货
                    tempOrder.setStatus(FsStoreOrderStatusEnum.STATUS_2.getValue());
                    tempOrder.setExtendOrderId("");
                    tempOrder.setDeliverySn("");
                    fsStoreOrderMapper.updateFsStoreOrder(tempOrder);
                    fsStoreOrderLogsService.create(tempOrder.getId(), OrderLogEnum.UPDATE_ORDER_DF.getValue(),
                            "运单不存在,"+OrderLogEnum.UPDATE_ORDER_DF.getDesc());
                } else {
                    //有物流信息->售后处理
                    //取消订单
//                    FsStoreOrderSalesParam afterSalesParam = new FsStoreOrderSalesParam();
//                    afterSalesParam.setOrderId(tempOrder.getOrderId());
//                    afterSalesParam.setReasons("代服管家取消订单");
//                    afterSalesParam.setOperator("代服管家");
//                    fsStoreOrderService.afterSales(afterSalesParam);
                    refundOrderMoney(fsStoreOrder.getId());
                    fsStoreOrderLogsService.create(tempOrder.getId(), OrderLogEnum.REFUND_ORDER_DF.getValue(),
                            "运单不存在,"+OrderLogEnum.REFUND_ORDER_DF.getDesc());
                }
                FsStoreOrderDf df = new FsStoreOrderDf();
                df.setOrderId(tempOrder.getId());
                df.setStatus(0); //回到默认
                df.setUpdateTime(new Date());
                df.setFailMsg(failMsg); //失败消息
                fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
                //推送失败消息
                return R.ok("接收成功").put("code", "ok");
            }
            if (addParam.getBspResponse() != null) {
                //更新物流
                log.info("代服管家创建订单回调,{}", JSON.toJSONString(addParam));
                List<OrderResponse> list = addParam.getBspResponse().getBody();
                if (list != null && !list.isEmpty()) {
                    for (OrderResponse orderResponse : list) {
                        List<RlsInfo> rlsInfos = orderResponse.getRlsInfo();
                        String orderNumber = orderResponse.getOrderNumber();
                        String mailNumber = orderResponse.getMailNumber();
                        if (rlsInfos != null && rlsInfos.size() > 0) {
                            RlsInfo rlsInfo = rlsInfos.get(0);
                            List<RlsDetail> rlsDetails = rlsInfo.getRlsDetail();
                            if (rlsDetails != null && !rlsDetails.isEmpty()) {
                                RlsDetail rlsDetail = rlsDetails.get(0);
                                String proName = rlsDetail.getProName();
                                if (com.hc.openapi.tool.util.StringUtils.isNotBlank(proName)) {
                                    FsStoreOrderScrm order = fsStoreOrderMapper.selectFsStoreOrderByOrderCode(orderNumber);
                                    if (order != null && order.getStatus() == 2) {
                                        order.setDeliveryId(mailNumber);
                                        order.setDeliveryName(proName);
                                        order.setDeliveryCode("SF");
                                        order.setStatus(OrderInfoEnum.STATUS_2.getValue());
                                        order.setDeliverySendTime(DateUtils.getNowDate());
                                        fsStoreOrderMapper.updateFsStoreOrder(order);
                                        fsStoreOrderLogsService.create(order.getId(), OrderLogEnum.DELIVERY_GOODS.getValue(), OrderLogEnum.DELIVERY_GOODS.getDesc());
                                    }
                                    break;
                                }
                            }
                        }
                    }

                }
            }
        }
        return R.ok("接收成功").put("code", "ok");
    }

    @Override
    public R receiveWaybillPush(String body) {
        DFApiResponse dfApiResponse = JSON.parseObject(body, DFApiResponse.class);
        Object result = dfApiResponse.getResult();
        if (result != null) {

            String jsonString = JSON.toJSONString(result);
            log.info("ct1111111111111111111{}", jsonString);
            com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(jsonString);
            if (jsonObject != null) {
                Object listObj = jsonObject.get("list");
                String listJson = JSON.toJSONString(listObj);
                List<DFOrderStatusResultRequest> requestList = JSON.parseArray(listJson, DFOrderStatusResultRequest.class);
                if (requestList != null && !requestList.isEmpty()) {
                    //0待揽收 1已揽收 2运输中 3派送中 4异常件 5退回件 6退回签收 7转寄件 8作废件 9已签收 10 已取消
                    for (DFOrderStatusResultRequest temp : requestList) {
                        if (temp.getStatus() == 10) {
                            //取消订单
                            String mailNumber = temp.getMailNumber();
                            List<FsStoreOrderScrm> fsStoreOrders = fsStoreOrderMapper.selectFsStoreOrderListByDeliveryId(mailNumber);
                            if (fsStoreOrders != null && !fsStoreOrders.isEmpty()) {
                                fsStoreOrders.forEach(order -> {
//                                    FsStoreOrderSalesParam afterSalesParam = new FsStoreOrderSalesParam();
                                    //修改订单状态 方便后续重新发货
                                    order.setStatus(OrderInfoEnum.STATUS_1.getValue());
                                    order.setExtendOrderId("");
                                    fsStoreOrderMapper.updateFsStoreOrder(order);
//                                    afterSalesParam.setOrderId(order.getOrderId());
//                                    afterSalesParam.setReasons("代服管家取消订单");
//                                    afterSalesParam.setOperator("代服管家");
//                                    afterSales(afterSalesParam);
                                    refundOrderMoney(order.getId());
                                    FsStoreOrderDf df = new FsStoreOrderDf();
                                    df.setOrderId(order.getId());
                                    df.setStatus(2);
                                    df.setUpdateTime(new Date());
                                    fsStoreOrderDfMapper.updateFsStoreOrderDf(df);
                                    fsStoreOrderLogsService.create(order.getId(), OrderLogEnum.REFUND_ORDER_DF.getValue(),
                                            OrderLogEnum.REFUND_ORDER_DF.getDesc());
                                });
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R importDeliveryNoteExpress(List<FsOrderDeliveryNoteDTO> dtoList, String appId) {
        try {
            StringBuilder builder = new StringBuilder();
            //获取商城配置
            String json = configService.selectConfigByKey("store.config");
            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);

            List<FsOrderDeliveryNoteDTO> successList = new ArrayList<>(dtoList.size());
            //提前获取所有必要数据
            Map<String, String> expressDeliveryMap = buildExpressDeliveryMap();
            //提取所有有效订单号
            List<String> orderCodeList = new ArrayList<>(dtoList.size());
            for (int i = 0; i < dtoList.size(); i++) {
                FsOrderDeliveryNoteDTO dto = dtoList.get(i);
                if (StringUtils.isEmpty(dto.getOrderNumber())) {
                    builder.append("数据第").append(i + 2).append("行系统订单为空！").append(System.lineSeparator());
                }
                if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
                    builder.append("数据第").append(i + 2).append("行物流公司为空！").append(System.lineSeparator());
                }
                if (StringUtils.isEmpty(dto.getDeliveryId())) {
                    builder.append("数据第").append(i + 2).append("行快递单号为空！").append(System.lineSeparator());
                } else {
                    //处理订单ID信息
                    String originalOrderNumber = dto.getOrderNumber();
                    String processedOrderNumber = extractNumbers(originalOrderNumber);
                    dto.setOrderNumber(processedOrderNumber);
                    orderCodeList.add(dto.getOrderNumber());
                }
            }

            //批量查询订单信息
            if (orderCodeList.isEmpty()) {
                return R.ok(builder.toString());
            }
            List<FsStoreOrderCodeOpenIdVo> orderCodeOpenIdVoList = fsStoreOrderMapper.selectOrderCodeOpenIdInOrderCode(orderCodeList);
            Map<String, OrderOpenIdTransDTO> orderMap = new HashMap<>(orderCodeOpenIdVoList.size());
            Map<String, List<FsStoreOrderCodeOpenIdVo>> orderDetailsMap = new HashMap<>(orderCodeOpenIdVoList.size());

            for (FsStoreOrderCodeOpenIdVo vo : orderCodeOpenIdVoList) {
                orderMap.computeIfAbsent(vo.getId(), k -> {
                    OrderOpenIdTransDTO dto = new OrderOpenIdTransDTO();
                    dto.setOpenId(vo.getOpenId());
                    dto.setTransactionId(vo.getOutTransId());
                    return dto;
                });

                orderDetailsMap
                        .computeIfAbsent(vo.getId(), k -> new ArrayList<>())
                        .add(vo);
            }
            final WxMaService wxService = WxMaConfiguration.getMaService(appId);
            String uploadTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"))
                    .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);

            for (int i = 0; i < dtoList.size(); i++) {
                FsOrderDeliveryNoteDTO dto = dtoList.get(i);
                int rowNum = i + 2;
                if (StringUtils.isEmpty(dto.getOrderNumber())) {
                    continue;
                }
                if (StringUtils.isEmpty(dto.getDeliveryId())) {
                    builder.append("数据第").append(rowNum).append("行快递单号为空！")
                            .append(System.lineSeparator());
                    continue;
                }

                if (StringUtils.isEmpty(dto.getLogisticsCompany())) {
                    builder.append("数据第").append(rowNum).append("行快递公司编号为空！")
                            .append(System.lineSeparator());
                    continue;
                }
//                if (dto.getDeliveryStatus() == null) {
//                    dto.setDeliveryStatus(0);
//                }
//                if (ObjectUtil.isNotNull(dto.getDeliveryTime())) {
//                    dto.setDeliveryTime(parseCstToDateOnlyString(dto.getDeliveryTime()));
//                }
//
//                if (ObjectUtil.isNotNull(dto.getDeliveryPayTime()) &&
//                        !dto.getDeliveryPayTime().isEmpty()) {
//                    dto.setDeliveryPayTime(parseCstToDateOnlyString(dto.getDeliveryPayTime()));
//                }
                // 验证快递公司
                String deliverySn = expressDeliveryMap.get(dto.getLogisticsCompany());
                if (deliverySn == null) {
                    builder.append("数据第").append(rowNum).append("行订单号为")
                            .append(dto.getOrderNumber()).append("物流公司名称异常")
                            .append(System.lineSeparator());
                    continue;
                }
                dto.setDeliverySn(deliverySn);

                // 检查订单是否存在
                String orderNumber = dto.getOrderNumber();
                OrderOpenIdTransDTO orderInfo = orderMap.get(orderNumber);
                if (orderInfo == null) {
                    builder.append("数据第").append(rowNum).append("行订单号")
                            .append(orderNumber).append("不存在").append(System.lineSeparator());
                    continue;
                }
                //验证是否开启微信发货
                if (config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
                    // 上传物流信息到微信
                    List<FsStoreOrderCodeOpenIdVo> orderDetails = orderDetailsMap.get(orderNumber);
                    if (uploadShippingInfoToWechat(wxService, orderInfo, orderDetails, dto, uploadTime)) {
                        successList.add(dto);
                    } else {
                        builder.append("数据第").append(rowNum).append("行订单号为")
                                .append(orderNumber).append("上传微信失败").append(System.lineSeparator());
                    }
                } else {
                    successList.add(dto);
                }
            }

            //批量更新数据
            if (!successList.isEmpty()) {
                batchUpdateDeliveryNotes(successList);
            }

            return R.ok(builder.toString().equals("") ? "操作成功！" : builder.toString());
        } catch (Exception e) {
            log.error("导入发货单快递信息失败", e);
            return R.error("导入失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    public void refreshOrderSettlementStatus() {
        try {
            // 判断是否对接微信发货
            String json = configService.selectConfigByKey("store.config");
            StoreConfig config = JSONUtil.toBean(json, StoreConfig.class);
            logger.info("进入微信结算订单定时任务--------------->{}", "start");
            if (config != null && config.getIsWeChatShipping() != null && config.getIsWeChatShipping()) {
                // 获取未结算订单
                List<FsStoreOrderScrm> orderScrmList = fsStoreOrderMapper.getUnsettledOrder();

                String payConfig = configService.selectConfigByKey("store.pay");
                JSONObject js = JSON.parseObject(payConfig);
                String appId = js.getString("appId");

                if (ObjectUtil.isNotNull(appId) && !appId.isEmpty()) {
                    final WxMaService wxService = WxMaConfiguration.getMaService(appId);

                    if (!orderScrmList.isEmpty()) {
                        for (FsStoreOrderScrm order : orderScrmList) {
                            WxMaOrderShippingInfoGetRequest request = new WxMaOrderShippingInfoGetRequest();
                            request.setTransactionId(order.getBankTransactionId());
                            WxMaOrderShippingInfoGetResponse response;

                            try {
                                response = wxService.getWxMaOrderShippingService().get(request);

                                if (response.getErrCode().equals(0)) {
                                    // 订单状态枚举：(1) 待发货；(2) 已发货；(3) 确认收货；(4) 交易完成；(5) 已退款
                                    if (response.getOrder().getOrderState().equals(3) || response.getOrder().getOrderState().equals(4)) {
                                        if (order.getStatus() == OrderInfoEnum.STATUS_2.getValue()) {
                                            this.finishOrder(order.getId());
                                        }
                                    }
                                    logger.info("请求信息------------------------》{}", response);
                                }

                            } catch (WxErrorException e) {
                                logger.info("异常信息------------------------》{}", e.getMessage());
                                continue;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.getStackTrace();
        } finally {
            logger.info("进入微信结算订单定时任务--------------->{}", "end");
        }
    }

    private void batchUpdateDeliveryNotes(List<FsOrderDeliveryNoteDTO> list) {
        int batchSize = 500;
        int total = list.size();
        int batches = (total + batchSize - 1) / batchSize;
        for (int i = 0; i < batches; i++) {
            int start = i * batchSize;
            int end = Math.min(start + batchSize, total);
            List<FsOrderDeliveryNoteDTO> subList = list.subList(start, end);
            fsStoreOrderMapper.batchUpdateInOrderCode(subList);
        }
    }

    private boolean uploadShippingInfoToWechat(WxMaService wxService,
                                               OrderOpenIdTransDTO orderInfo,
                                               List<FsStoreOrderCodeOpenIdVo> orderDetails,
                                               FsOrderDeliveryNoteDTO dto,
                                               String uploadTime) {
        try {
            WxMaOrderShippingInfoUploadRequest request = new WxMaOrderShippingInfoUploadRequest();
            OrderKeyBean orderKeyBean = new OrderKeyBean();
            orderKeyBean.setOrderNumberType(2);
            orderKeyBean.setTransactionId(orderInfo.getTransactionId());
            request.setOrderKey(orderKeyBean);
            request.setDeliveryMode(1);
            request.setLogisticsType(1);
            List<ShippingListBean> shippingList = new ArrayList<>(orderDetails.size());
            ShippingListBean shippingListBean = null;
            for (FsStoreOrderCodeOpenIdVo detail : orderDetails) {
                if (shippingListBean == null) {
                    shippingListBean = new ShippingListBean();
                    shippingListBean.setTrackingNo(dto.getDeliveryId());
                    shippingListBean.setExpressCompany(dto.getDeliverySn());
                    JSONObject js = JSON.parseObject(detail.getJsonInfo());
                    shippingListBean.setItemDesc(js.getString("productName"));
                    ContactBean contactBean = new ContactBean();
                    contactBean.setReceiverContact(detail.getPhone());
                    shippingListBean.setContact(contactBean);
                } else {
                    //拼接
//                    JSONObject js = JSON.parseObject(detail.getJsonInfo());
//                    shippingListBean.setItemDesc(shippingListBean.getItemDesc()+"-"+js.getString("productName"));
                    break;
                }
            }
            shippingList.add(shippingListBean);
            request.setShippingList(shippingList);
            request.setUploadTime(uploadTime);
            // 设置支付者信息
            PayerBean payerBean = new PayerBean();
            payerBean.setOpenid(orderInfo.getOpenId());
            request.setPayer(payerBean);

            // 上传物流信息
            return wxService.getWxMaOrderShippingService().upload(request).getErrCode() == 0;
        } catch (Exception e) {
            log.error("上传物流信息到微信失败，订单号: {}", dto.getOrderNumber(), e);
            return false;
        }
    }

    @Override
    public R createPackageSalesOrder(CompanyUser companyUser, String packageId, Integer orderType, Integer orderMedium) {
        FsStoreProductPackageScrm storeProductPackage = productPackageService.selectFsStoreProductPackageById(Long.parseLong(packageId));
        if(storeProductPackage == null){
            return R.error("商品套餐不存在");
        }

        /**
         * 由于套餐包制单前端页面没有走购物车，因为为了保证后续可以使用之前商品制单的改价接口、创建订单接口、支付等接口，
         * 也为了保持结构一致，因此这里手动添加购物车
         */
        // 获取套餐包的商品信息，然后添加购物车
        JSONArray jsonArray = JSONUtil.parseArray(storeProductPackage.getProducts());
        List<StorePackageProductDTO> goodsList = JSONUtil.toList(jsonArray, StorePackageProductDTO.class);
        String cartIds = "";
        for (StorePackageProductDTO goods : goodsList) {
            FsStoreCartParam fsStoreCartParam = new FsStoreCartParam();
            FsStoreProductAttrValueScrm attrValue = attrValueService.selectFsStoreProductAttrValueById(goods.getId());
            if (attrValue != null && attrValue.getProductId() != null) {
                    fsStoreCartParam.setProductId(attrValue.getProductId());
                    fsStoreCartParam.setCartNum(goods.getCount());
                    fsStoreCartParam.setIsBuy(1);
                    fsStoreCartParam.setAttrValueId(goods.getId());
                R r = fsStoreCartScrmService.addCart(companyUser.getUserId(), fsStoreCartParam);
                Object id = r.get("id");
                if(id != null){
                    cartIds += id + ",";
                }
            }

        }

        List<FsStoreCartQueryVO> carts = cartMapper.selectFsStoreCartListByIds(cartIds);
        String uuid = IdUtil.randomUUID();
        redisCache.setCacheObject("createOrderKey:" + uuid, companyUser.getCompanyId() + "-" + companyUser.getUserId(), 24, TimeUnit.HOURS);

        // 这里的carts是购物车信息，价格取的套餐包价格
        for (FsStoreCartQueryVO vo : carts) {
            vo.setPrice(storeProductPackage.getPayMoney());
        }
        redisCache.setCacheObject("orderCarts:" + uuid, carts, 24, TimeUnit.HOURS);
        if (orderType != null || orderMedium != null) {
            FsStoreOrderScrm fsStoreOrder = new FsStoreOrderScrm();
            fsStoreOrder.setOrderMedium(orderMedium);
            fsStoreOrder.setOrderType(orderType);
            redisCache.setCacheObject("orderInfo:" + uuid, fsStoreOrder, 24, TimeUnit.HOURS);
        }

        redisCache.setCacheObject("createOrderMoney:" + uuid, storeProductPackage.getPayMoney(), 24, TimeUnit.HOURS);
        // 根据前端要求，为了前端方便取值，所以返回的参数key与商品制单的接口保持一致
        return R.ok().put("orderKey", uuid);
    }

    private static final DateTimeFormatter CST_FORMATTER = DateTimeFormatter
            .ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US)
            .withZone(ZoneId.of("Asia/Shanghai"));

    private static final DateTimeFormatter STANDARD_FORMATTER = DateTimeFormatter
            .ofPattern("yyyy-MM-dd HH:mm:ss");

    public static LocalDateTime parseCstToLocalDateTime(String cstDateStr) {
        if (cstDateStr == null || cstDateStr.trim().isEmpty()) {
            return null;
        }

        try {
            // 解析为带时区的日期时间
            ZonedDateTime zonedDateTime = ZonedDateTime.parse(cstDateStr, CST_FORMATTER);
            // 转换为本地日期时间（忽略时区，仅保留年月日时分秒）
            return zonedDateTime.toLocalDateTime();
        } catch (DateTimeParseException e) {
            System.err.println("日期解析失败: " + e.getMessage());
            return null;
        }
    }

    public static String parseCstToDateOnlyString(String cstDateStr) {
        LocalDateTime dateTime = parseCstToLocalDateTime(cstDateStr);
        return dateTime != null ? dateTime.format(DateTimeFormatter
                .ofPattern("yyyy-MM-dd")) : null;
    }

    public Map<String, String> buildExpressDeliveryMap() {
        Map<String, String> map = new HashMap<>();
        map.put("SF", "顺丰");
        map.put("EMS", "邮政");
        map.put("ZTO", "中通");
        map.put("JD", "京东");
        map.put("DBL", "德邦");
        map.put("YTO", "圆通");
        return map;
    }

    //高性能截取订单ID
    private static String extractNumbers(String str) {
        if (str == null || str.isEmpty()) {
            return "";
        }
        int start = 0;
        int len = str.length();
        while (start < len && !Character.isDigit(str.charAt(start))) {
            start++;
        }
        return start < len ? str.substring(start) : "";
    }


    @Override
    public FsStoreOrderAmountScrmStatsVo selectFsStoreOrderAmountScrmStats(FsStoreOrderAmountScrmStatsQueryDto queryDto) {
        return fsStoreOrderMapper.selectFsStoreOrderAmountScrmStats(queryDto);
    }
}
