package com.liquidnet.client.admin.zhengzai.kylin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liquidnet.client.admin.common.exception.BusinessException;
import com.liquidnet.client.admin.common.utils.StringUtils;
import com.liquidnet.client.admin.zhengzai.admin.service.impl.utils.CodeUtil;
import com.liquidnet.client.admin.zhengzai.admin.service.impl.utils.UploadUtil;
import com.liquidnet.client.admin.zhengzai.admin.service.impl.utils.ZipMultiFileUtil;
import com.liquidnet.client.admin.zhengzai.kylin.dto.performancesExpressImportVo;
import com.liquidnet.client.admin.zhengzai.kylin.utils.DataUtils;
import com.liquidnet.client.admin.zhengzai.kylin.utils.ShunfengSignUtils;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
import com.liquidnet.service.kylin.dao.*;
import com.liquidnet.service.kylin.dto.param.*;
import com.liquidnet.service.kylin.dto.vo.basicServices.UploadVo;
import com.liquidnet.service.kylin.dto.vo.express.KylinOrderExpressPrintVo;
import com.liquidnet.service.kylin.dto.vo.express.KylinOrderExpressVo;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketVo;
import com.liquidnet.service.kylin.entity.*;
import com.liquidnet.service.kylin.mapper.*;
import com.liquidnet.service.kylin.service.IKylinOrderExpress;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 演出 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-05-05
 */
@Service
@Slf4j
public class PerformancesExpressServiceImpl extends ServiceImpl<KylinOrderExpressMapper, KylinOrderExpress> implements IKylinOrderExpress {

    @Value("${liquidnet.express.shunfeng.custid}")
    private String custid;
    @Value("${liquidnet.express.shunfeng.jCompany}")
    private String jCompany;
    @Value("${liquidnet.express.shunfeng.jContact}")
    private String jContact;
    @Value("${liquidnet.express.shunfeng.jTel}")
    private String jTel;
    @Value("${liquidnet.express.shunfeng.jProvince}")
    private String jProvince;
    @Value("${liquidnet.express.shunfeng.jCity}")
    private String jCity;
    @Value("${liquidnet.express.shunfeng.jAddress}")
    private String jAddress;
    @Value("${liquidnet.express.shunfeng.expressType}")
    private Integer expressType;
    @Value("${liquidnet.express.shunfeng.depositumInfo}")
    private String depositumInfo;

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private ShunfengSignUtils shunfengSignUtils;

    @Autowired
    private KylinPerformancesMapper performancesMapper;

    @Autowired
    private KylinOrderTicketsMapper kylinOrderTicketsMapper;

    @Autowired
    private KylinOrderExpressMapper kylinOrderExpressMapper;

    @Autowired
    private KylinOrderExpressFeeInfoMapper kylinOrderExpressFeeInfoMapper;

    @Autowired
    private KylinOrderExpressRouteMapper kylinOrderExpressRouteMapper;

    @Autowired
    private KylinOrderTicketRelationsMapper kylinOrderTicketRelationsMapper;

    @Autowired
    private KylinOrderTicketStatusMapper kylinOrderTicketStatusMapper;

    @Autowired
    private KylinTicketsMapper kylinTicketsMapper;

    @Autowired
    private KylinTicketTimesMapper kylinTicketTimesMapper;

    @Autowired
    private DataUtils dataUtils;

    @Autowired
    private CodeUtil codeUtil;

    @Autowired
    private ZipMultiFileUtil zipMultiFileUtil;

    @Autowired
    private UploadUtil uploadUtil;

    public List<PerformanceExpressPerformanceListAdminDao> getPerformancesList(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<PerformanceExpressPerformanceListAdminDao> voList = new ArrayList();
        try {
            Map<String, Object> map = BeanUtil.convertBeanToMap(performanceExpressSearchAdminParam);
            voList = performancesMapper.performanceExpressPerformanceList(map);
            if (!CollectionUtil.isEmpty(voList)) {
                for (PerformanceExpressPerformanceListAdminDao info : voList) {
                    PerformanceExpressPerformanceListAdminDao countInfo = performancesMapper.countExpressNumber(info.getPerformancesId());
                    if (null != countInfo) {
                        info.setTotalNumber(countInfo.getTotalNumber());
                    }
                    // 已下单
                    Integer total1 = kylinOrderExpressMapper.selectCount(
                            Wrappers.lambdaQuery(KylinOrderExpress.class)
                                    .ne(KylinOrderExpress::getExpressStatus, 1).ne(KylinOrderExpress::getExpressStatus, 3)
                                    .eq(KylinOrderExpress::getPerformancesId, info.getPerformancesId())
                                    .eq(KylinOrderExpress::getSendType, KylinTableStatusConst.ORDER_EXPRESS_SEND_TYPE1)
                    );
                    // 运输中
                    Integer total2 = kylinOrderExpressMapper.selectCount(
                            Wrappers.lambdaQuery(KylinOrderExpress.class).gt(KylinOrderExpress::getExpressStatus, 3)
                                    .ne(KylinOrderExpress::getExpressStatus, KylinTableStatusConst.ORDER_EXPRESS_STATUS80)
                                    .ne(KylinOrderExpress::getExpressStatus, KylinTableStatusConst.ORDER_EXPRESS_STATUS8000)
                                    .eq(KylinOrderExpress::getPerformancesId, info.getPerformancesId())
                                    .eq(KylinOrderExpress::getSendType, KylinTableStatusConst.ORDER_EXPRESS_SEND_TYPE1)
                    );
                    // 已签收
                    Integer[] statusList = new Integer[]{KylinTableStatusConst.ORDER_EXPRESS_STATUS80, KylinTableStatusConst.ORDER_EXPRESS_STATUS8000};
                    Integer total3 = kylinOrderExpressMapper.selectCount(
                            Wrappers.lambdaQuery(KylinOrderExpress.class).in(KylinOrderExpress::getExpressStatus, statusList)
                                    .eq(KylinOrderExpress::getPerformancesId, info.getPerformancesId())
                                    .eq(KylinOrderExpress::getSendType, KylinTableStatusConst.ORDER_EXPRESS_SEND_TYPE1)
                    );
                    info.setTotal1(total1);
                    info.setTotal2(total2);
                    info.setTotal3(total3);
                }
            }
        } catch (Exception e) {
            log.error("getPerformancesListException", e);
        }
        return voList;
    }

    public List<PerformanceExpressPerformanceOrderListAdminDao> getPerformancesOrderList(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<PerformanceExpressPerformanceOrderListAdminDao> voList = new ArrayList();
        try {
            Map<String, Object> map = BeanUtil.convertBeanToMap(performanceExpressSearchAdminParam);
            voList = kylinOrderTicketsMapper.performanceExpressPerformanceOrderList(map);
        } catch (Exception e) {
        }
        return voList;
    }

    public ResponseDto placeOrder(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();
        Integer idCount = ids.size();
        for (String orderTicketsId : ids) {
            // 已经存在未取消的下单数据过滤掉
            Integer[] expressStatus = {KylinTableStatusConst.ORDER_EXPRESS_STATUS1, KylinTableStatusConst.ORDER_EXPRESS_STATUS3};
            KylinOrderExpress orderExpressInfo = kylinOrderExpressMapper.selectOne(
                    new QueryWrapper<KylinOrderExpress>().eq("order_tickets_id", orderTicketsId)
                            .notIn("express_status", expressStatus)
            );
            if (null != orderExpressInfo) {
                continue;
            }
            KylinOrderTickets orderInfo = kylinOrderTicketsMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderTickets.class).eq(KylinOrderTickets::getOrderTicketsId, orderTicketsId)
            );
            KylinOrderTicketStatus orderStatus = kylinOrderTicketStatusMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderTicketStatus.class).eq(KylinOrderTicketStatus::getOrderId, orderTicketsId)
            );
            KylinOrderTicketRelations Relations = kylinOrderTicketRelationsMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderTicketRelations.class).eq(KylinOrderTicketRelations::getOrderId, orderTicketsId)
            );
            if (orderStatus.getStatus() != KylinTableStatusConst.ORDER_STATUS1 && orderStatus.getStatus() != KylinTableStatusConst.ORDER_STATUS6) {
                if (idCount > 1) {
                    continue;
                } else {
                    return ResponseDto.failure("当前状态不能下单");
                }
            }
            // 生成预快递单 防止因失败没办法再次发起也不能主动获取数据
            KylinOrderExpress kylinOrderExpressPre = new KylinOrderExpress();
            String orderExpressId = IDGenerator.nextSnowId();
            kylinOrderExpressPre.setExpressStatus(KylinTableStatusConst.ORDER_EXPRESS_STATUS1);
            kylinOrderExpressPre.setOrderExpressId(orderExpressId);
            kylinOrderExpressPre.setOrderTicketsId(orderTicketsId);
            // 防止重复前面加上 "NEW" 因取消后再发起订单号也不能一致所以直接使用orderExpressId
            String OrderExpressCode = "NOW" + orderExpressId;
            kylinOrderExpressPre.setOrderExpressCode(OrderExpressCode);
            kylinOrderExpressPre.setExpressType(Integer.valueOf(orderStatus.getProduceCode()));
            kylinOrderExpressPre.setCreatedAt(DateUtil.getNowTime());
            kylinOrderExpressPre.setPerformancesId(Relations.getPerformanceId());
            kylinOrderExpressPre.setExpressContacts(orderInfo.getExpressContacts());
            kylinOrderExpressPre.setExpressPhone(orderInfo.getExpressPhone());
            kylinOrderExpressPre.setSendExpressAddress(orderInfo.getExpressAddress());
            kylinOrderExpressMapper.insert(kylinOrderExpressPre);

            // 请求下单数据
            Map<String, String> hBody = new HashMap<>();
            hBody.put("custid", custid);
            hBody.put("jCompany", jCompany);
            hBody.put("jContact", jContact);
            hBody.put("jTel", jTel);
            hBody.put("jProvince", jProvince);
            hBody.put("jCity", jCity);
            hBody.put("jAddress", jAddress);

            //胡佳晨添加
            //获取票种名称
            KylinTickets kylinTickets = kylinTicketsMapper.selectOne(
                    Wrappers.lambdaQuery(KylinTickets.class).eq(KylinTickets::getTicketsId, Relations.getTicketId())
            );
            //获取场次名称
            KylinTicketTimes kylinTicketTimes = kylinTicketTimesMapper.selectOne(
                    Wrappers.lambdaQuery(KylinTicketTimes.class).eq(KylinTicketTimes::getTicketTimesId, Relations.getTimeId())
            );
            //添加备注
            hBody.put("remark", kylinTicketTimes.getTitle()+"，"+kylinTickets.getTitle());

            // 1寄付|2到付|3包邮
            // 运费付款方式：0-寄付月结；1-寄付现结；2-收方付；3-第三方付；
            if (orderStatus.getExpressType() == 1 || orderStatus.getExpressType() == 3) {
                hBody.put("payMethod", "0");
            } else {
                hBody.put("payMethod", "2");
            }

            hBody.put("expressType", orderStatus.getProduceCode());// 顺丰特快

            hBody.put("depositumInfo", depositumInfo);

            hBody.put("orderId", OrderExpressCode);

            hBody.put("depositumNo", orderInfo.getNumber().toString());

            hBody.put("dContact", orderInfo.getExpressContacts());
            hBody.put("dMobile", orderInfo.getExpressPhone());
            hBody.put("dAddress", orderInfo.getExpressAddress());

            // 生成签名并请求
            String result = shunfengSignUtils.generateSignatureAndRequestNew(hBody, "/public/order/v1/placeOrder");
            HashMap hashMap = new HashMap();
            try {
                hashMap = JsonUtils.fromJson(result, HashMap.class);
            } catch (Exception e) {
                return ResponseDto.failure(result);
            }
            if (null == hashMap.get("succ") || hashMap.get("succ").equals("fail")) {
                String msg = "" ;
                if (null == hashMap.get("succ")) {
                    msg = result;
                } else {
                    msg = (String) hashMap.get("msg");
                }
                if (idCount > 1) {
                    continue;
                } else {
                    return ResponseDto.failure(msg);
                }
            } else {
                HashMap hashMapResult = (HashMap) hashMap.get("result");
                KylinOrderExpress kylinOrderExpress = new KylinOrderExpress();
                kylinOrderExpress.setExpressStatus(KylinTableStatusConst.ORDER_EXPRESS_STATUS2);
                kylinOrderExpress.setMailno((String) hashMapResult.get("mailno"));
                kylinOrderExpress.setFilterResult(hashMapResult.get("filter_result").toString());
                kylinOrderExpress.setRemark((String) hashMapResult.get("remark"));
                kylinOrderExpress.setOrigincode((String) hashMapResult.get("origincode"));
                kylinOrderExpress.setDestcode((String) hashMapResult.get("destcode"));
                kylinOrderExpress.setTwoDimensionCode((String) hashMapResult.get("twoDimensionCode"));

                kylinOrderExpress.setReturn_tracking_no((String) hashMapResult.get("return_tracking_no"));
                kylinOrderExpress.setSourceTransferCode((String) hashMapResult.get("sourceTransferCode"));
                kylinOrderExpress.setSourceCityCode((String) hashMapResult.get("sourceCityCode"));
                kylinOrderExpress.setSourceDeptCode((String) hashMapResult.get("sourceDeptCode"));
                kylinOrderExpress.setSourceTeamCode((String) hashMapResult.get("sourceTeamCode"));
                kylinOrderExpress.setDestCityCode((String) hashMapResult.get("destCityCode"));
                kylinOrderExpress.setDestDeptCode((String) hashMapResult.get("destDeptCode"));
                kylinOrderExpress.setDestDeptCodeMapping((String) hashMapResult.get("destDeptCodeMapping"));
                kylinOrderExpress.setDestTeamCode((String) hashMapResult.get("destTeamCode"));
                kylinOrderExpress.setDestTeamCodeMapping((String) hashMapResult.get("destTeamCodeMapping"));
                kylinOrderExpress.setDestTransferCode((String) hashMapResult.get("destTransferCode"));
                kylinOrderExpress.setDestRouteLabel((String) hashMapResult.get("destRouteLabel"));
                kylinOrderExpress.setProName((String) hashMapResult.get("proName"));
                kylinOrderExpress.setCargoTypeCode((String) hashMapResult.get("cargoTypeCode"));
                kylinOrderExpress.setLimitTypeCode((String) hashMapResult.get("limitTypeCode"));
                kylinOrderExpress.setExpressTypeCode((String) hashMapResult.get("expressTypeCode"));
                kylinOrderExpress.setCodingMapping((String) hashMapResult.get("codingMapping"));
                kylinOrderExpress.setCodingMappingOut((String) hashMapResult.get("codingMappingOut"));
                kylinOrderExpress.setXbFlag((String) hashMapResult.get("xbFlag"));
                kylinOrderExpress.setPrintFlag((String) hashMapResult.get("printFlag"));
                kylinOrderExpress.setProCode((String) hashMapResult.get("proCode"));
                kylinOrderExpress.setPrintIcon((String) hashMapResult.get("printIcon"));
                kylinOrderExpress.setAbFlag((String) hashMapResult.get("abFlag"));
                kylinOrderExpress.setDestPortCode((String) hashMapResult.get("destPortCode"));
                kylinOrderExpress.setDestPortCode((String) hashMapResult.get("destPortCode"));
                kylinOrderExpress.setDestCountry((String) hashMapResult.get("destCountry"));
                kylinOrderExpress.setDestPostCode((String) hashMapResult.get("destPostCode"));
                kylinOrderExpress.setGoodsValueTotal((String) hashMapResult.get("goodsValueTotal"));
                kylinOrderExpress.setCurrencySymbol((String) hashMapResult.get("currencySymbol"));
                kylinOrderExpress.setGoodsNumber((String) hashMapResult.get("goodsNumber"));
                kylinOrderExpress.setTwoDimensionCode2((String) hashMapResult.get("twoDimensionCode2"));
                kylinOrderExpress.setNewIcon((String) hashMapResult.get("newIcon"));
                kylinOrderExpress.setNewAbflag((String) hashMapResult.get("newAbflag"));

                kylinOrderExpress.setUpdatedAt(DateUtil.getNowTime());
                kylinOrderExpressMapper.update(
                        kylinOrderExpress
                        , new UpdateWrapper<KylinOrderExpress>().in("order_express_id", orderExpressId)
                );

                KylinOrderExpressVo kylinOrderExpressVo = new KylinOrderExpressVo();
                BeanUtils.copyProperties(kylinOrderExpressPre, kylinOrderExpressVo);
                kylinOrderExpressVo.setMailno(kylinOrderExpress.getMailno());
                kylinOrderExpressVo.setExpressStatus(kylinOrderExpress.getExpressStatus());
                dataUtils.setOrderExpressInfo(orderTicketsId, kylinOrderExpressVo);
            }
        }
        return ResponseDto.success();
    }

    public ResponseDto cancelOrder(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();
        Integer idCount = ids.size();
        for (String orderExpressId : ids) {
            KylinOrderExpress orderExpressInfo = kylinOrderExpressMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderExpress.class).eq(KylinOrderExpress::getOrderExpressId, orderExpressId)
            );
            String orderTicketsId = orderExpressInfo.getOrderTicketsId();
            if (null != orderExpressInfo) {
                Map<String, String> hBody = new HashMap<>();
                hBody.put("orderId", orderExpressInfo.getOrderExpressCode());

                // 生成签名并请求
                String result = shunfengSignUtils.generateSignatureAndRequestNew(hBody, "/public/order/v1/cancelOrder");
                HashMap hashMap = JsonUtils.fromJson(result, HashMap.class);
                if (hashMap.get("succ").equals("fail")) {
                    String msg = (String) hashMap.get("msg");
                    if (idCount > 1) {
                        continue;
                    } else {
                        return ResponseDto.failure(msg);
                    }
                } else {
                    KylinOrderExpress kylinOrderExpress = new KylinOrderExpress();
                    kylinOrderExpress.setExpressStatus(KylinTableStatusConst.ORDER_EXPRESS_STATUS3);
                    kylinOrderExpress.setUpdatedAt(DateUtil.getNowTime());
                    kylinOrderExpressMapper.update(
                            kylinOrderExpress
                            , new UpdateWrapper<KylinOrderExpress>().in("order_express_id", orderExpressInfo.getOrderExpressId())
                    );
                    dataUtils.delOrderExpressInfo(orderTicketsId);
                }
            }
        }
        return ResponseDto.success();
    }

    public ResponseDto getResult(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();
        for (String orderExpressId : ids) {
            KylinOrderExpress orderExpressInfo = kylinOrderExpressMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderExpress.class).eq(KylinOrderExpress::getOrderExpressId, orderExpressId)
            );
            if (null != orderExpressInfo) {
                Map<String, String> hBody = new HashMap<>();
                hBody.put("orderId", orderExpressInfo.getOrderExpressCode());
                hBody.put("searchType", "1"); //查询类型：1,正向单查询，传入的orderid为正向定单号，2，退货单查询，传入的orderid为退货原始订单号

                // 生成签名并请求
                String result = shunfengSignUtils.generateSignatureAndRequestNew(hBody, "/public/order/v1/getResult");
                HashMap hashMap = JsonUtils.fromJson(result, HashMap.class);
                if (hashMap.get("succ").equals("fail")) {
                    String msg = (String) hashMap.get("msg");
                    return ResponseDto.failure(msg);
                } else {
                    HashMap hashMapResult = (HashMap) hashMap.get("result");
                    KylinOrderExpress kylinOrderExpress = new KylinOrderExpress();
                    kylinOrderExpress.setExpressStatus(KylinTableStatusConst.ORDER_EXPRESS_STATUS2);
                    kylinOrderExpress.setMailno((String) hashMapResult.get("mailno"));
                    kylinOrderExpress.setFilterResult(hashMapResult.get("filter_result").toString());
                    kylinOrderExpress.setRemark((String) hashMapResult.get("remark"));
                    kylinOrderExpress.setOrigincode((String) hashMapResult.get("origincode"));
                    kylinOrderExpress.setDestcode((String) hashMapResult.get("destcode"));
                    kylinOrderExpress.setPrintIcon((String) hashMapResult.get("printIcon"));
                    kylinOrderExpress.setPrintFlag((String) hashMapResult.get("printFlag"));
                    kylinOrderExpress.setTwoDimensionCode((String) hashMapResult.get("twoDimensionCode"));
                    kylinOrderExpress.setUpdatedAt(DateUtil.getNowTime());
                    kylinOrderExpressMapper.update(
                            kylinOrderExpress
                            , new UpdateWrapper<KylinOrderExpress>().in("order_express_id", orderExpressInfo.getOrderExpressId())
                    );
                }
            }
        }
        return ResponseDto.success();
    }

    public ResponseDto getFreight(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();
        for (String orderExpressId : ids) {
            KylinOrderExpress orderExpressInfo = kylinOrderExpressMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderExpress.class).eq(KylinOrderExpress::getOrderExpressId, orderExpressId)
            );
            String orderTicketsId = orderExpressInfo.getOrderTicketsId();
            KylinOrderTickets orderInfo = kylinOrderTicketsMapper.selectOne(
                    new QueryWrapper<KylinOrderTickets>().eq("order_tickets_id", orderTicketsId)
            );
            if (null != orderExpressInfo) {
                Map<String, String> hBody = new HashMap<>();
                hBody.put("jProvince", jProvince);
                hBody.put("jCity", jCity);
                hBody.put("jAddress", jAddress);

                hBody.put("dProvince", orderInfo.getProvince());
                hBody.put("dCity", orderInfo.getCity());
                hBody.put("dAddress", orderInfo.getExpressAddress());
                hBody.put("expressType", expressType.toString());
                // hBody.put("parcelWeighs", 2.00);
                // hBody.put("volume", "10,10,20");

                // 生成签名并请求
                String result = shunfengSignUtils.generateSignatureAndRequestNew(hBody, "/public/order/v1/getFreight");
                HashMap hashMap = JsonUtils.fromJson(result, HashMap.class);
                if (hashMap.get("succ").equals("fail")) {
                    String msg = (String) hashMap.get("msg");
                    return ResponseDto.failure(msg);
                } else {
                    HashMap hashMapResult = (HashMap) hashMap.get("result");
                    KylinOrderExpress kylinOrderExpress = new KylinOrderExpress();
                    BigDecimal price = dataUtils.getBigDecimal(hashMapResult.get("price"));
                    kylinOrderExpress.setFreightPrice(price);
                    kylinOrderExpress.setUpdatedAt(DateUtil.getNowTime());
                    kylinOrderExpressMapper.update(
                            kylinOrderExpress
                            , new UpdateWrapper<KylinOrderExpress>().in("order_express_id", orderExpressInfo.getOrderExpressId())
                    );
                    // {"result":{"deliverTime":"2021-07-01 18:00:00,2021-07-01 18:00:00","price":"23元","businessTypeDesc":"顺丰特快","businessType":"1"},"succ":"ok","msg":null}
                }
            }
        }
        return ResponseDto.success();
    }

    public ResponseDto getListFreight(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();
        for (String orderExpressId : ids) {
            KylinOrderExpress orderExpressInfo = kylinOrderExpressMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderExpress.class).eq(KylinOrderExpress::getOrderExpressId, orderExpressId)
            );
            if (null != orderExpressInfo) {
                Map<String, String> hBody = new HashMap<>();
                hBody.put("orderId", orderExpressInfo.getOrderExpressCode());

                // 生成签名并请求
                String result = shunfengSignUtils.generateSignatureAndRequestNew(hBody, "/public/order/v1/getListFreight");
                HashMap hashMap = JsonUtils.fromJson(result, HashMap.class);
                if (hashMap.get("succ").equals("fail")) {
                    String msg = (String) hashMap.get("msg");
                    return ResponseDto.failure(msg);
                } else {
                    HashMap resultResult = (HashMap) hashMap.get("result");
                    List<HashMap> feeList = (List) resultResult.get("feeList");
                    if (!CollectionUtil.isEmpty(feeList)) {
                        kylinOrderExpressFeeInfoMapper.delete(new QueryWrapper<KylinOrderExpressFeeInfo>().eq("order_express_id", orderExpressInfo.getOrderExpressId()));
                        for (HashMap feeInfo : feeList) {
                            KylinOrderExpressFeeInfo kylinOrderExpressFeeInfo = new KylinOrderExpressFeeInfo();
                            String orderExpressFeeInfoId = IDGenerator.nextSnowId();
                            kylinOrderExpressFeeInfo.setOrderExpressFeeInfoId(orderExpressFeeInfoId);
                            kylinOrderExpressFeeInfo.setOrderExpressId(orderExpressInfo.getOrderExpressId());
                            kylinOrderExpressFeeInfo.setType((String) feeInfo.get("type"));
                            kylinOrderExpressFeeInfo.setName((String) feeInfo.get("name"));
                            kylinOrderExpressFeeInfo.setValue(new BigDecimal(feeInfo.get("value").toString()));
                            kylinOrderExpressFeeInfo.setCreatedAt(DateUtil.getNowTime());
                            kylinOrderExpressFeeInfoMapper.insert(kylinOrderExpressFeeInfo);
                        }
                    }
                }
            }
        }
        return ResponseDto.success();
    }

    public ResponseDto listOrderRoute(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();
        for (String orderExpressId : ids) {
            KylinOrderExpress orderExpressInfo = kylinOrderExpressMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderExpress.class).eq(KylinOrderExpress::getOrderExpressId, orderExpressId)
            );
            if (null != orderExpressInfo) {
                Map<String, String> hBody = new HashMap<>();
                hBody.put("orderId", orderExpressInfo.getOrderExpressCode());

                // 生成签名并请求
                String result = shunfengSignUtils.generateSignatureAndRequestNew(hBody, "/public/order/v1/listOrderRoute");
                HashMap hashMap = JsonUtils.fromJson(result, HashMap.class);
                if (hashMap.get("succ").equals("fail")) {
                    String msg = (String) hashMap.get("msg");
                    return ResponseDto.failure(msg);
                } else {
                    List<HashMap> resultResult = (List) hashMap.get("result");
                    if (!CollectionUtil.isEmpty(resultResult)) {
                        kylinOrderExpressRouteMapper.delete(new QueryWrapper<KylinOrderExpressRoute>().eq("order_express_id", orderExpressInfo.getOrderExpressId()));
                        for (HashMap routeInfo : resultResult) {
                            KylinOrderExpressRoute kylinOrderExpressRoute = new KylinOrderExpressRoute();
                            String orderExpressRouteId = IDGenerator.nextSnowId();
                            kylinOrderExpressRoute.setOrderExpressRouteId(orderExpressRouteId);
                            kylinOrderExpressRoute.setOrderExpressId(orderExpressInfo.getOrderExpressId());
                            kylinOrderExpressRoute.setAcceptAddress((String) routeInfo.get("accept_address"));
                            kylinOrderExpressRoute.setAcceptDate((String) routeInfo.get("accept_date"));
                            kylinOrderExpressRoute.setAcceptTime((String) routeInfo.get("accept_time"));
                            kylinOrderExpressRoute.setAcceptTotaltime((String) routeInfo.get("accept_totaltime"));
                            kylinOrderExpressRoute.setRemark((String) routeInfo.get("remark"));
                            kylinOrderExpressRoute.setOpcode((String) routeInfo.get("opcode"));
                            kylinOrderExpressRoute.setCreatedAt(DateUtil.getNowTime());
                            kylinOrderExpressRouteMapper.insert(kylinOrderExpressRoute);
                            // 这里没清缓存 推送正常的话这个用不到
                        }
                    }
                }
            }
        }
        return ResponseDto.success();
    }

    @Async
    public void batchPlaceOrder(String performanceId) {
        int count;
        int limitNum = 10; // 因单个那边判断了如果数量不大于1如果有错误直接返回 所以这里必须大于1
        int mid = 0;
        do {
            List<KylinOrderTickets> orderList = kylinOrderTicketsMapper.getCanPlaceOrderList(performanceId, mid, limitNum);

            if (!CollectionUtil.isEmpty(orderList)) {
                List<String> orderIds = orderList.stream().map(KylinOrderTickets -> KylinOrderTickets.getOrderTicketsId()).collect(Collectors.toList());
                PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam = new PerformanceExpressSearchAdminParam();
                performanceExpressSearchAdminParam.setIds(orderIds);
                placeOrder(performanceExpressSearchAdminParam);
            }

            count = orderList.size();
            if (count > 0) {
                KylinOrderTickets lastInfo = orderList.get(count - 1);
                mid = lastInfo.getMid();
            }
        } while (count >= limitNum);
    }

    @Async
    public void batchCancelOrder(String performanceId) {
        int count;
        int limitNum = 10; // 因单个那边判断了如果数量不大于1如果有错误直接返回 所以这里必须大于1
        int mid = 0;
        do {
            List<KylinOrderExpress> expressList = kylinOrderExpressMapper.getCanCancelExpressList(performanceId, mid, limitNum);

            if (!CollectionUtil.isEmpty(expressList)) {
                List<String> expressIds = expressList.stream().map(KylinOrderExpress -> KylinOrderExpress.getOrderExpressId()).collect(Collectors.toList());
                PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam = new PerformanceExpressSearchAdminParam();
                performanceExpressSearchAdminParam.setIds(expressIds);
                cancelOrder(performanceExpressSearchAdminParam);
            }

            count = expressList.size();
            if (count > 0) {
                KylinOrderExpress lastInfo = expressList.get(count - 1);
                mid = lastInfo.getMid();
            }
        } while (count >= limitNum);
    }

    public String generateImage(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();

        for (String orderExpressId : ids) {
            long s = System.currentTimeMillis();
            KylinOrderExpress kylinOrderExpress = kylinOrderExpressMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderExpress.class)
                            .eq(KylinOrderExpress::getOrderExpressId, orderExpressId)
            );
//            System.out.println(System.currentTimeMillis() - s);
            KylinOrderTickets orderInfo = kylinOrderTicketsMapper.selectOne(
                    Wrappers.lambdaQuery(KylinOrderTickets.class)
                            .eq(KylinOrderTickets::getOrderTicketsId, kylinOrderExpress.getOrderTicketsId())
            );
//            System.out.println(System.currentTimeMillis() - s);
            String imgPath = codeUtil.html2img(kylinOrderExpress, jContact, jProvince.concat(jCity).concat(jAddress), jTel, orderInfo);
//            System.out.println(System.currentTimeMillis() - s);
        }

        String zpiPath = zipMultiFileUtil.goZip();

        //上传
        UploadVo upload = uploadUtil.upload(new File(zpiPath), "faceImgZip", "zip");

        return upload.getOssPath();
    }

    public String batchGenerateImage(String performanceId) {
        /*List<KylinOrderTickets> orderList = kylinOrderTicketsMapper.getCanCancelExpressList(performanceId, 0, 9999999);

        String ossPath = "";
        if (!CollectionUtil.isEmpty(orderList)) {
            List<String> orderIds = orderList.stream().map(KylinOrderTickets -> KylinOrderTickets.getOrderTicketsId()).collect(Collectors.toList());
            PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam = new PerformanceExpressSearchAdminParam();
            performanceExpressSearchAdminParam.setIds(orderIds);
            ossPath = generateImage(performanceExpressSearchAdminParam);
        }
        return ossPath;*/
        return "" ;
    }

    public KylinOrderExpressPrintVo printExpress(PerformanceExpressSearchAdminParam performanceExpressSearchAdminParam) {
        List<String> ids = performanceExpressSearchAdminParam.getIds();

        List<OrderExpressListDao> list = kylinOrderExpressMapper.selectPrintList(ids);

        KylinOrderExpressPrintVo kylinOrderExpressPrintVo = new KylinOrderExpressPrintVo();
        kylinOrderExpressPrintVo.setExpressList(list);
        kylinOrderExpressPrintVo.setJContact(jContact);
        kylinOrderExpressPrintVo.setJAddress(jAddress);
        kylinOrderExpressPrintVo.setJTel(jTel);

        return kylinOrderExpressPrintVo;
    }

    public KylinOrderExpressPrintVo batchPrintExpress(String performanceId, String ticketId, Integer printNum) {
        List<OrderExpressListDao> newList = new ArrayList<>();
        int count = 0;
        int limitNum = 1000;
        int mid = 0;
        do {
            List<OrderExpressListDao> list = kylinOrderExpressMapper.selectPrintListOfPerformanceId(performanceId, ticketId, mid, limitNum, printNum);

            if (!CollectionUtil.isEmpty(list)) {
                newList.addAll(list);

                count = list.size();
                OrderExpressListDao lastInfo = list.get(count - 1);
                mid = lastInfo.getMid();
            } else {
                count = 0;
            }

        } while (count >= limitNum);

        KylinOrderExpressPrintVo kylinOrderExpressPrintVo = new KylinOrderExpressPrintVo();
        kylinOrderExpressPrintVo.setExpressList(newList);
        kylinOrderExpressPrintVo.setJContact(jContact);
        kylinOrderExpressPrintVo.setJAddress(jAddress);
        kylinOrderExpressPrintVo.setJTel(jTel);

        return kylinOrderExpressPrintVo;
    }

    public List<OrderExpressExportListDao> selectExpressList(String performanceId) {
        List<OrderExpressExportListDao> list = kylinOrderTicketsMapper.selectExpressList(performanceId);
        return list;
    }

    public List<PerformancesTicketListDao> getPerformancesTicketList(String performanceId) {
        List<PerformancesTicketListDao> list = kylinTicketsMapper.getPerformancesTicketList(performanceId);
        return list;
    }

    public String importExpress(List<performancesExpressImportVo> expressList) {
        if (StringUtils.isNull(expressList) || expressList.size() == 0) {
            throw new BusinessException("导入用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (performancesExpressImportVo info : expressList) {
            try {
                KylinOrderTickets orderInfo = kylinOrderTicketsMapper.selectOne(
                        Wrappers.lambdaQuery(KylinOrderTickets.class)
                                .eq(KylinOrderTickets::getOrderCode, info.getOrderCode())
                                .select(KylinOrderTickets::getOrderTicketsId)
                );
                KylinOrderTicketRelations relations = kylinOrderTicketRelationsMapper.selectOne(
                        Wrappers.lambdaQuery(KylinOrderTicketRelations.class)
                                .eq(KylinOrderTicketRelations::getOrderId, orderInfo.getOrderTicketsId())
                                .select(KylinOrderTicketRelations::getPerformanceId)
                );
                // 生成快递单 防止因失败没办法再次发起也不能主动获取数据
                KylinOrderExpress kylinOrderExpressPre = new KylinOrderExpress();
                String orderExpressId = IDGenerator.nextSnowId();
                kylinOrderExpressPre.setExpressStatus(30);
                kylinOrderExpressPre.setOrderExpressId(orderExpressId);
                kylinOrderExpressPre.setOrderTicketsId(orderInfo.getOrderTicketsId());
                String OrderExpressCode = "NOW" + orderExpressId;
                kylinOrderExpressPre.setOrderExpressCode(OrderExpressCode);
                kylinOrderExpressPre.setCreatedAt(DateUtil.getNowTime());
                kylinOrderExpressPre.setPerformancesId(relations.getPerformanceId());
                kylinOrderExpressPre.setMailno(info.getMailno());
                kylinOrderExpressMapper.insert(kylinOrderExpressPre);

                KylinOrderExpressVo kylinOrderExpressVo = new KylinOrderExpressVo();
                BeanUtils.copyProperties(kylinOrderExpressPre, kylinOrderExpressVo);
                dataUtils.setOrderExpressInfo(orderInfo.getOrderTicketsId(), kylinOrderExpressVo);

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