package com.sckw.report.service;

import cn.hutool.core.util.ObjectUtil;
import com.sckw.core.common.enums.NumberConstant;
import com.sckw.core.common.enums.StringConstant;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.model.enums.LogisticsOrderEnum;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.HttpResult;
import com.sckw.excel.utils.DateUtil;
import com.sckw.mongo.model.SckwLogisticsOrder;
import com.sckw.mongo.model.TableTops;
import com.sckw.report.service.param.ConsignOrderQuery;
import com.sckw.report.service.vo.ConsignOrderExcelVo;
import com.sckw.report.service.vo.ConsignOrderVo;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author lfdc
 * @description 托运service
 * @date 2023-07-24 13:07:47
 */
@Slf4j
@Service
public class KwConsignService {

    @Autowired
    public MongoTemplate mongoTemplate;

    @Autowired
    public KwTransportService transportService;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    RemoteSystemService remoteSystemService;


    /**
     * 托运订单列表查询
     *
     * @param query
     * @return
     * @throws ParseException
     */
    public HttpResult selectConsignOrderList(ConsignOrderQuery query, String unitType) {
        //模糊匹配
        //根据条件查询所有并排序，且分页
        //设置模糊查询匹配规则  忽略大小写
        // 创建条件对象
        Criteria criteria = new Criteria();
        // 1. 全等于
        //判断承运还是托运企业
        List<Long> entIds = new ArrayList<>();
        entIds.add(LoginUserHolder.getEntId());
        Long entId = LoginUserHolder.getEntId();
        if (unitType.equals(String.valueOf(NumberConstant.ONE))) {
            //托运
            criteria.orOperator(
                    Criteria.where("checkTopEntId").is(entId),
                    Criteria.where("checkEntId").is(entId));
        } else {
            //承运企业主键ID
//            criteria.and("carrierTopEntId").is(entMap.get(LoginUserHolder.getEntId()).getId());
            criteria.orOperator(
                    Criteria.where("carrierTopEntId").is(entId),
                    Criteria.where("carrierEntId").is(entId));
        }
        //装卸货地址
        String loadCode = query.getLoadAddressCode();
        if (StringUtils.isNotBlank(loadCode)) {
            switch (query.getLoadAddressLevel()) {
                case 1 -> criteria.and("loadCityCode")
                        .regex(Pattern.compile("^" + loadCode.substring(0, 2) + ".*$", Pattern.CASE_INSENSITIVE));
                case 2 -> criteria.and("loadCityCode")
                        .regex(Pattern.compile("^" + loadCode.substring(0, 4) + ".*$", Pattern.CASE_INSENSITIVE));
                case 3 -> criteria.and("loadCityCode").is(loadCode);
            }
        }
        String unloadCode = query.getUnloadAddressCode();
        if (StringUtils.isNotBlank(unloadCode)) {
            switch (query.getUnloadAddressLevel()) {
                case 1 -> criteria.and("unloadCityCode")
                        .regex(Pattern.compile("^" + unloadCode.substring(0, 2) + ".*$", Pattern.CASE_INSENSITIVE));
                case 2 -> criteria.and("unloadCityCode")
                        .regex(Pattern.compile("^" + unloadCode.substring(0, 4) + ".*$", Pattern.CASE_INSENSITIVE));
                case 3 -> criteria.and("unloadCityCode").is(unloadCode);
            }
        }
//        if (StringUtils.isNotBlank(query.getLoadAddress())) {
//            criteria.and("loadDetailAddress").is(query.getLoadAddress());
//        }
//        if (StringUtils.isNotBlank(query.getUnloadAddress())) {
//            criteria.and("unloadDetailAddress").is(query.getUnloadAddress());
//        }
        if (StringUtils.isNotBlank(query.getStatus())) {
            criteria.and("status").is(query.getStatus());
        }
        criteria.and("delFlag").is(String.valueOf(NumberConstant.ZERO));
        // 4. 日期范围
        if (StringUtils.isNotEmpty(query.getStartDateTime())) {
//            criteria.andOperator(Criteria.where("startTime").gte(query.getStartDateTime()).lte(query.getStartDateTime()));
            criteria.and("startTime").gte(query.getStartDateTime()).lte(query.getStartDateTime());
        }
        if (StringUtils.isNotEmpty(query.getEndDateTime())) {
//            criteria.andOperator(Criteria.where("endTime").gte(query.getEndDateTime()).lte(query.getEndDateTime()));
            criteria.and("endTime").gte(query.getEndDateTime()).lte(query.getEndDateTime());
        }
        if (StringUtils.isNotEmpty(query.getCreateTime())) {
//            criteria.andOperator(Criteria.where("createTime").gte(query.getCreateTime()).lte(query.getCreateTime()));
            criteria.and("createTime").gte(query.getCreateTime()).lte(query.getCreateTime());
        }
        //多条件模糊查询
        Criteria c1 = new Criteria();
        Criteria c2 = new Criteria();
        Criteria c3 = new Criteria();
        Criteria c4 = new Criteria();
        Criteria c5 = new Criteria();
        if (StringUtils.isNotBlank(query.getKeywords())) {
            Pattern pattern = Pattern.compile("^.*" + query.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
            c1 = Criteria.where("firmName").regex(pattern);
            c2 = Criteria.where("carrierFirmName").regex(pattern);
            c3 = Criteria.where("checkFirmName").regex(pattern);
            c4 = Criteria.where("tOrderNo").regex(pattern);
            c5 = Criteria.where("lOrderNo").regex(pattern);
            criteria.orOperator(c1, c2, c3, c4, c5);
        }

        Query query1 = new Query(criteria);
        //in查询
        List<String> stringList = StringUtils.splitStrToList(query.getIds(), StringConstant.COMMA, String.class);
        if (CollectionUtils.isNotEmpty(stringList)) {
            query1.addCriteria(Criteria.where("lOrderId").in(query.getIds()));
        }
        // 12. 总记录数
        long total = mongoTemplate.count(query1, SckwLogisticsOrder.class);
        // 10. 分页
        query1.with(PageRequest.of(query.getPage() - 1, query.getPageSize(),
                // 11. 排序list = {ArrayList@27436}  size = 3returnList = {ArrayList@27393}  size = 3
                Sort.by(Sort.Direction.DESC, "lOrderId", "createTime")));
        // 执行查询
        List<SckwLogisticsOrder> list = mongoTemplate.find(query1, SckwLogisticsOrder.class);
        List<ConsignOrderVo> returnList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            packageReturnList(list, returnList);
        }
        PageResult build = PageResult.build(query.getPage(), query.getPageSize(), total, returnList);
        return HttpResult.ok(build);
    }

    /**
     * 组装托运列表分页查询
     *
     * @param list
     * @param returnList
     */
    public void packageReturnList(List<SckwLogisticsOrder> list, List<ConsignOrderVo> returnList) {
        /**计量单位*/
//    Map<String, String> unitTypeDictData = getDictData(DictTypeEnum.UNIT_TYPE.getType());
        /**运价方式*/
        Map<String, String> priceDictData = getDictData(DictTypeEnum.PRICE_TYPE.getType());
        /**计费方式*/
        Map<String, String> chargingDictData = getDictData(DictTypeEnum.CHARGING_TYPE.getType());
        /**结算周期*/
        Map<String, String> settlementDictData = getDictData(DictTypeEnum.SETTLEMENT_CYCLE.getType());
        /**签约方式*/
        Map<String, String> signingWay = getDictData(DictTypeEnum.SIGNING_TYPE.getType());
        /**合理损耗*/
//        Map<String, String> taxRateTypeDictData = getDictData(DictTypeEnum.TAX_RATE_TYPE.getType());

        for (SckwLogisticsOrder logisticsOrder : list) {
            ConsignOrderVo vo = new ConsignOrderVo();
            vo.setAccountsCycle(logisticsOrder.getSettlementCycle() == null ?
                    null : String.valueOf(logisticsOrder.getSettlementCycle()));
            vo.setAppointor(logisticsOrder.getCreateByName());
            vo.setBillingMode(logisticsOrder.getBillingMode());
            vo.setCarrierCompany(logisticsOrder.getCarrierFirmName());
            vo.setCarrierOrder(logisticsOrder.getWOrderNo());
            vo.setCarrierPhone(logisticsOrder.getCarrierPhone());
            vo.setCarryingCapacity(logisticsOrder.getCarryingCapacity() == null ?
                    null : logisticsOrder.getCarryingCapacity());
            vo.setConsignCompany(logisticsOrder.getCheckFirmName());
            vo.setConsignContacts(logisticsOrder.getCheckContacts());
            vo.setConsignPhone(logisticsOrder.getCheckPhone());
            vo.setContract(logisticsOrder.getContractName());
            vo.setDeficitAmount(logisticsOrder.getDeficitAmount() == null ?
                    null : logisticsOrder.getDeficitAmount());
            vo.setGoodsName(logisticsOrder.getGoodsName());
            vo.setLoadCityName(logisticsOrder.getLoadDetailAddress());
            vo.setLoadAddress(logisticsOrder.getLoadCityName() + logisticsOrder.getLoadDetailAddress());
            vo.setUnloadAddress(logisticsOrder.getUnloadCityName() + logisticsOrder.getUnloadDetailAddress());
            vo.setUnloadCityName(logisticsOrder.getUnloadDetailAddress());
            vo.setLOrderId(String.valueOf(logisticsOrder.getLOrderId()));
            vo.setLOrderNo(logisticsOrder.getLOrderNo());
            vo.setLoss(logisticsOrder.getLoss() == null ?
                    null : logisticsOrder.getLoss());
            vo.setPrice(logisticsOrder.getPrice() == null ?
                    null : logisticsOrder.getPrice());
            vo.setReceiveGoodsContacts(logisticsOrder.getUnloadContacts());
            vo.setReceiveGoodsPhone(logisticsOrder.getUnloadPhone());
            vo.setRemark(logisticsOrder.getRemark());
            vo.setShipmentsContacts(logisticsOrder.getLoadContacts());
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setShipmentsDateTime(logisticsOrder.getLoadTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getLoadTime()));
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setSigning(logisticsOrder.getContractSigningWay());
            vo.setStatus(logisticsOrder.getStatus());
            vo.setUnloadAddress(logisticsOrder.getUnloadDetailAddress());
            vo.setWOrderNo(logisticsOrder.getWOrderNo());
            vo.setCreateTime(logisticsOrder.getCreateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getCreateTime()));
            vo.setUpdateTime(logisticsOrder.getUpdateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getUpdateTime()));
            vo.setShipmentsUnitEntId(logisticsOrder.getShipmentsUnitEntId());
            vo.setShipmentsUnit(logisticsOrder.getShipmentsUnit());
            vo.setReceiveGoodsUnitEntId(logisticsOrder.getReceiveGoodsUnitEntId());
            vo.setReceiveGoodsUnit(logisticsOrder.getReceiveGoodsUnit());
            vo.setGoodsPrice(logisticsOrder.getGoodsPrice());
//            vo.setGoodsPriceUnit(logisticsOrder.getGoodsPriceUnit());
            vo.setGoodsPriceUnit(priceDictData.get(logisticsOrder.getGoodsPriceUnit()));
            vo.setSigningLabel(signingWay.get(logisticsOrder.getContractSigningWay()));
//            vo.setSigningLabel(logisticsOrder.getContractSigningWay() == null ? null :
//                    (logisticsOrder.getContractSigningWay().equals("1")?"线上签约":"线下签约"));
            vo.setLossUnit(logisticsOrder.getLossUnit());
            vo.setStatusLabel(LogisticsOrderEnum.getDestination(logisticsOrder.getStatus()));
            vo.setAccountsCycleLabel(logisticsOrder.getSettlementCycle() == null ?
                    null : settlementDictData.get(String.valueOf(logisticsOrder.getSettlementCycle())));
            vo.setBillingModeLabel(chargingDictData.get(logisticsOrder.getBillingMode()));
            returnList.add(vo);
        }
    }

    public Map<String, String> getDictData(String type) {
        Map<String, String> maps = new HashMap<>(NumberConstant.SIXTEEN);
        List<SysDictResDto> list = remoteSystemService.queryDictByType(type);
        if (CollectionUtils.isNotEmpty(list)) {
            maps = list.stream().collect(Collectors.toMap(SysDictResDto::getValue, SysDictResDto::getLabel, (key1, key2) -> key2));
        }
        return maps;
    }

    /**
     * 托运订单导出
     *
     * @param query
     * @param unitType
     * @return
     */
    public List<ConsignOrderExcelVo> exportConsign(ConsignOrderQuery query, String unitType) {
        //模糊匹配
        //根据条件查询所有并排序，且分页
        //设置模糊查询匹配规则  忽略大小写
        // 创建条件对象
        Criteria criteria = new Criteria();
        // 1. 全等于
        Query query1 = new Query();
//        if (unitType.equals(NumberConstant.ONE)) {
//            criteria.and("checkEntId").is(LoginUserHolder.getEntId());
//        } else {
//            criteria.and("carrierEntId").is(LoginUserHolder.getEntId());
//        }
        List<Long> entIds = new ArrayList<>();
        entIds.add(LoginUserHolder.getEntId());
        Map<Long, EntCacheResDto> entMap = remoteSystemService.queryEntTreeByIds(entIds);
        if (unitType.equals(NumberConstant.ONE)) {
            //托运
            criteria.and("checkTopEntId").is(entMap.get(LoginUserHolder.getEntId()).getId());
        } else {
            //承运企业主键ID
            criteria.and("carrierTopEntId").is(entMap.get(LoginUserHolder.getEntId()).getId());
        }
        criteria.and("delFlag").is(String.valueOf(NumberConstant.ZERO));
        List<String> stringList = StringUtils.splitStrToList(query.getIds(), StringConstant.COMMA, String.class);
        if (CollectionUtils.isEmpty(stringList)) {
            if (StringUtils.isNotBlank(query.getLoadAddress())) {
                criteria.and("loadDetailAddress").is(query.getLoadAddress());
            }
            if (StringUtils.isNotBlank(query.getUnloadAddress())) {
                criteria.and("unloadDetailAddress").is(query.getUnloadAddress());
            }
            if (StringUtils.isNotBlank(query.getStatus())) {
                criteria.and("status").is(query.getStatus());
            }
            // 4. 日期范围
            if (StringUtils.isNotEmpty(query.getStartDateTime()) && StringUtils.isNotEmpty(query.getEndDateTime())) {
                criteria.andOperator(Criteria.where("createTime").gte(query.getStartDateTime()), Criteria.where("createTime")
                        .lte(query.getEndDateTime()));
            }
            //多条件模糊查询
            Criteria c1 = new Criteria();
            Criteria c2 = new Criteria();
            Criteria c3 = new Criteria();
            Criteria c4 = new Criteria();
            Criteria c5 = new Criteria();
            if (StringUtils.isNotBlank(query.getKeywords())) {
                Pattern pattern = Pattern.compile("^.*" + query.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
                c1 = Criteria.where("firmName").regex(pattern);
                c2 = Criteria.where("carrierFirmName").regex(pattern);
                c3 = Criteria.where("checkFirmName").regex(pattern);
                c4 = Criteria.where("tOrderNo").regex(pattern);
                c5 = Criteria.where("lOrderNo").regex(pattern);
                criteria.orOperator(c1, c2, c3, c4, c5);
            }
            query1.addCriteria(criteria);
            if (CollectionUtils.isNotEmpty(stringList)) {
                query1.addCriteria(Criteria.where("lOrderId").in(query.getIds()));
            }
        } else {
            query1.addCriteria(criteria);
            if (CollectionUtils.isNotEmpty(stringList)) {
                query1.addCriteria(Criteria.where("lOrderId").in(query.getIds()));
            }
        }
        // 执行查询
        List<SckwLogisticsOrder> list = mongoTemplate.find(query1, SckwLogisticsOrder.class);
        List<ConsignOrderExcelVo> returnList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            packageReturnExcelList(list, returnList);
        }
        return returnList;
    }

    private void packageReturnExcelList(List<SckwLogisticsOrder> list, List<ConsignOrderExcelVo> returnList) {
        for (SckwLogisticsOrder logisticsOrder : list) {
            ConsignOrderExcelVo vo = new ConsignOrderExcelVo();
            vo.setAccountsCycle(logisticsOrder.getSettlementCycle() == null ?
                    null : String.valueOf(logisticsOrder.getSettlementCycle()));
            vo.setAppointor(logisticsOrder.getCreateByName());
            vo.setBillingMode(logisticsOrder.getBillingMode());
            vo.setCarrierCompany(logisticsOrder.getCarrierFirmName());
            vo.setCarrierOrder(logisticsOrder.getWOrderNo());
            vo.setCarrierPhone(logisticsOrder.getCarrierPhone());
            vo.setCarryingCapacity(logisticsOrder.getCarryingCapacity() == null ?
                    null : String.valueOf(logisticsOrder.getCarryingCapacity()));
            vo.setConsignCompany(logisticsOrder.getCheckFirmName());
            vo.setConsignContacts(logisticsOrder.getCheckContacts());
            vo.setConsignPhone(logisticsOrder.getCheckPhone());
            vo.setContract(logisticsOrder.getContractName());
            vo.setDeficitAmount(logisticsOrder.getDeficitAmount() == null ?
                    null : String.valueOf(logisticsOrder.getDeficitAmount()));
            vo.setGoodsName(logisticsOrder.getGoodsName());
            vo.setLoadAddress(logisticsOrder.getLoadDetailAddress());
            vo.setUnloadAddress(logisticsOrder.getUnloadDetailAddress());
            vo.setLOrderId(String.valueOf(logisticsOrder.getLOrderId()));
            vo.setLOrderNo(logisticsOrder.getLOrderNo());
            vo.setLoss(logisticsOrder.getLoss() == null ?
                    null : String.valueOf(logisticsOrder.getLoss()));
            vo.setPrice(logisticsOrder.getPrice() == null ?
                    null : String.valueOf(logisticsOrder.getPrice()));
            vo.setReceiveGoodsContacts(logisticsOrder.getUnloadContacts());
            vo.setReceiveGoodsPhone(logisticsOrder.getUnloadPhone());
            vo.setRemark(logisticsOrder.getRemark());
            vo.setShipmentsContacts(logisticsOrder.getLoadContacts());
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setShipmentsDateTime(logisticsOrder.getLoadTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getLoadTime()));
            vo.setShipmentsPhone(logisticsOrder.getLoadPhone());
            vo.setSigning(logisticsOrder.getContractSigningWay());
            vo.setStatus(logisticsOrder.getStatus());
            vo.setUnloadAddress(logisticsOrder.getUnloadDetailAddress());
            vo.setWOrderNo(logisticsOrder.getWOrderNo());
            vo.setCreateTime(logisticsOrder.getCreateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getCreateTime()));
            vo.setUpdateTime(logisticsOrder.getUpdateTime() == null ?
                    null : DateUtil.getDateTime(logisticsOrder.getUpdateTime()));
            returnList.add(vo);
        }
    }

    public HttpResult statisticsConsign(ConsignOrderQuery param, String unitType) {
        //模糊匹配
        //根据条件查询所有并排序，且分页
        //设置模糊查询匹配规则  忽略大小写
        // 创建条件对象
        Criteria criteria = new Criteria();
        // 1. 全等于
        //判断承运还是托运企业
//        if (unitType.equals(NumberConstant.ONE)) {
//            criteria.and("checkEntId").is(LoginUserHolder.getEntId());
//        } else {
//            criteria.and("carrierEntId").is(LoginUserHolder.getEntId());
//        }
        List<Long> entIds = new ArrayList<>();
        entIds.add(LoginUserHolder.getEntId());
        Long entId = LoginUserHolder.getEntId();
//        Map<Long, EntCacheResDto> entMap = remoteSystemService.queryEntTreeByIds(entIds);
        if (unitType.equals(String.valueOf(NumberConstant.ONE))) {
            //托运
//            criteria.and("checkTopEntId").is(entMap.get(LoginUserHolder.getEntId()).getId());
            criteria.orOperator(
                    Criteria.where("checkTopEntId").is(entId),
                    Criteria.where("checkEntId").is(entId));
        } else {
            //承运企业主键ID
//            criteria.and("carrierTopEntId").is(entMap.get(LoginUserHolder.getEntId()).getId());
            criteria.orOperator(
                    Criteria.where("carrierTopEntId").is(entId),
                    Criteria.where("carrierEntId").is(entId));
        }
        //装卸货地址
        String loadCode = param.getLoadAddressCode();
        if (StringUtils.isNotBlank(loadCode)) {
            switch (param.getLoadAddressLevel()) {
                case 1 -> criteria.and("loadCityCode")
                        .regex(Pattern.compile("^" + loadCode.substring(0, 2) + ".*$", Pattern.CASE_INSENSITIVE));
                case 2 -> criteria.and("loadCityCode")
                        .regex(Pattern.compile("^" + loadCode.substring(0, 4) + ".*$", Pattern.CASE_INSENSITIVE));
                case 3 -> criteria.and("loadCityCode").is(loadCode);
            }
        }
        String unloadCode = param.getUnloadAddressCode();
        if (StringUtils.isNotBlank(unloadCode)) {
            switch (param.getUnloadAddressLevel()) {
                case 1 -> criteria.and("unloadCityCode")
                        .regex(Pattern.compile("^" + unloadCode.substring(0, 2) + ".*$", Pattern.CASE_INSENSITIVE));
                case 2 -> criteria.and("unloadCityCode")
                        .regex(Pattern.compile("^" + unloadCode.substring(0, 4) + ".*$", Pattern.CASE_INSENSITIVE));
                case 3 -> criteria.and("unloadCityCode").is(unloadCode);
            }
        }
//        if (StringUtils.isNotBlank(param.getLoadAddress())) {
//            criteria.and("loadDetailAddress").is(param.getLoadAddress());
//        }
//        if (StringUtils.isNotBlank(param.getUnloadAddress())) {
//            criteria.and("unloadDetailAddress").is(param.getUnloadAddress());
//        }
        if (StringUtils.isNotBlank(param.getStatus())) {
            criteria.and("status").is(param.getStatus());
        }
        criteria.and("delFlag").is(String.valueOf(NumberConstant.ZERO));
        // 4. 日期范围
        if (StringUtils.isNotEmpty(param.getStartDateTime())) {
//            criteria.andOperator(Criteria.where("startTime").gte(query.getStartDateTime()).lte(query.getStartDateTime()));
            criteria.and("startTime").gte(param.getStartDateTime()).lte(param.getStartDateTime());
        }
        if (StringUtils.isNotEmpty(param.getEndDateTime())) {
//            criteria.andOperator(Criteria.where("endTime").gte(query.getEndDateTime()).lte(query.getEndDateTime()));
            criteria.and("endTime").gte(param.getEndDateTime()).lte(param.getEndDateTime());
        }
        if (StringUtils.isNotEmpty(param.getCreateTime())) {
//            criteria.andOperator(Criteria.where("createTime").gte(query.getCreateTime()).lte(query.getCreateTime()));
            criteria.and("createTime").gte(param.getCreateTime()).lte(param.getCreateTime());
        }
        List<String> stringList = StringUtils.splitStrToList(param.getIds(), StringConstant.COMMA, String.class);
        if (CollectionUtils.isNotEmpty(stringList)) {
            criteria = Criteria.where("lOrderId").in(param.getIds());
        }
        //多条件模糊查询
        Criteria c1 = new Criteria();
        Criteria c2 = new Criteria();
        Criteria c3 = new Criteria();
        Criteria c4 = new Criteria();
        Criteria c5 = new Criteria();
        if (StringUtils.isNotBlank(param.getKeywords())) {
            Pattern pattern = Pattern.compile("^.*" + param.getKeywords() + ".*$", Pattern.CASE_INSENSITIVE);
            c1 = Criteria.where("firmName").regex(pattern);
            c2 = Criteria.where("carrierFirmName").regex(pattern);
            c3 = Criteria.where("checkFirmName").regex(pattern);
            c4 = Criteria.where("tOrderNo").regex(pattern);
            c5 = Criteria.where("lOrderNo").regex(pattern);
            criteria.orOperator(c1, c2, c3, c4, c5);
        }
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("status").count().as("total"),
                Aggregation.project("total").and("value").previousOperation()
        );
        AggregationResults<TableTops> outputTypeCount = mongoTemplate.aggregate(aggregation, SckwLogisticsOrder.class, TableTops.class);
        List<TableTops> mappedResults = outputTypeCount.getMappedResults();
        List<TableTops> arrayList = new ArrayList<>();
        arrayList.addAll(mappedResults);
        /**补全数据状态不齐的情况*/
        arrayList = packageReturnStatistics(mappedResults, arrayList);
        // 查询结果
        Map<String, Object> map = new HashMap<>(NumberConstant.SIXTEEN);
        map.put("tableTop", arrayList);
        return HttpResult.ok(map);
    }


    /**
     * 组装返回数据
     *
     * @param mappedResults
     * @param arrayList
     */
    private List<TableTops> packageReturnStatistics(List<TableTops> mappedResults, List<TableTops> arrayList) {
        List<String> codeList = LogisticsOrderEnum.getCodeStringList();
        List<String> collect = mappedResults.stream().map(e -> e.getValue()).collect(Collectors.toList());
        List<String> diffrentList = transportService.getDiffrentList(collect, codeList);
        if (CollectionUtils.isNotEmpty(mappedResults)) {
            if (CollectionUtils.isNotEmpty(diffrentList)) {
                for (String s : diffrentList) {
                    TableTops top = new TableTops();
                    top.setValue(s);
                    top.setTotal(NumberConstant.ZERO);
                    arrayList.add(top);
                }
            }
            for (TableTops top : arrayList) {
                top.setName(LogisticsOrderEnum.getName(Integer.valueOf(top.getValue())));
            }
        } else {
            for (LogisticsOrderEnum logisticsOrderEnum : LogisticsOrderEnum.values()) {
                TableTops top = new TableTops();
                top.setName(logisticsOrderEnum.getDestination());
                top.setValue(logisticsOrderEnum.getStatus());
                top.setTotal(NumberConstant.ZERO);
                arrayList.add(top);
            }
        }
        arrayList = arrayList.stream().sorted(Comparator.comparing(TableTops::getValue)).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(arrayList)) {
            /**已退回数据补充*/
            int total = 0;
            for (TableTops tops : arrayList) {
                if (LogisticsOrderEnum.REJECT_ORDER.getStatus().equals(tops.getValue())) {
                    total = total + tops.getTotal();
                }
                if (LogisticsOrderEnum.CANCEL_ORDER.getStatus().equals(tops.getValue())) {
                    total = total + tops.getTotal();
                }
            }
            for (TableTops tops : arrayList) {
                if (LogisticsOrderEnum.SEND_BACK.getStatus().equals(tops.getValue())) {
                    tops.setTotal(tops.getTotal() + total);
                }
            }
            Iterator iterator = arrayList.iterator();
            while (iterator.hasNext()) {
                TableTops tableTops = (TableTops) iterator.next();
                if (tableTops.getValue().equals(LogisticsOrderEnum.REJECT_ORDER.getStatus())) {
                    iterator.remove();
                }
                if (tableTops.getValue().equals(LogisticsOrderEnum.CANCEL_ORDER.getStatus())) {
                    iterator.remove();
                }
            }
            /**补全统计【全部字段】*/
            Integer sum = Math.toIntExact(arrayList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getTotal())).collect(Collectors.summarizingInt(item -> item.getTotal())).getSum());
            TableTops top = new TableTops();
            top.setName("全部");
            top.setValue("all");
            top.setTotal(sum);
            arrayList.add(0, top);
        }
        return arrayList;
    }

}
