
package com.tmerclub.cloud.search.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.order.constant.OrderStatus;
import com.tmerclub.cloud.api.order.feign.OrderFeignClient;
import com.tmerclub.cloud.api.vo.EsPageVO;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.PayType;
import com.tmerclub.cloud.common.constant.SearchPayType;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.i18n.I18nMessage;
import com.tmerclub.cloud.common.i18n.LanguageEnum;
import com.tmerclub.cloud.common.order.bo.EsOrderBO;
import com.tmerclub.cloud.common.order.bo.EsOrderItemBO;
import com.tmerclub.cloud.common.order.constant.DeliveryType;
import com.tmerclub.cloud.common.order.constant.OrderType;
import com.tmerclub.cloud.common.order.constant.RefundStatusEnum;
import com.tmerclub.cloud.common.order.dto.OrderSearchDTO;
import com.tmerclub.cloud.common.order.vo.EsOrderItemVO;
import com.tmerclub.cloud.common.order.vo.EsOrderVO;
import com.tmerclub.cloud.common.order.vo.OrderExcelVO;
import com.tmerclub.cloud.common.order.vo.UserOrderStatisticVO;
import com.tmerclub.cloud.common.product.constant.PreSaleType;
import com.tmerclub.cloud.common.product.constant.SupplierDeliveryType;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.common.util.Json;
import com.tmerclub.cloud.common.util.PriceUtil;
import com.tmerclub.cloud.search.constant.EsConstant;
import com.tmerclub.cloud.search.constant.EsIndexEnum;
import com.tmerclub.cloud.search.util.EsSearchUtil;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
import org.elasticsearch.search.aggregations.metrics.ParsedValueCount;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tmerclub
 * @date 2020/11/16
 */
@Component
public class OrderSearchManager {

    private static final Logger log = LoggerFactory.getLogger(OrderSearchManager.class);


    /**
     * 订单类别 0.实物商品 1. 虚拟商品
     */
    public static final String PHYSICAL_ORDER = "实物商品订单";
    public static final String VIRTUAL_ORDER = "虚拟商品订单";

    /**
     * 余额支付（搜索类型）
     */
    private static final Integer SEARCH_BALANCE = 3;

    /**
     * 1、统计：消费金额 优惠总金额 消费次数
     */
    private static final Integer COUNT_TYPE_FIRST = 1;
    /**
     * 2、统计：实付金额
     */
    private static final Integer COUNT_TYPE_SECOND = 2;
    /**
     * 3、统计：最近消费时间
     */
    private static final Integer COUNT_TYPE_THIRD = 3;

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    @DubboReference
    private OrderFeignClient orderFeignClient;

    private void addPayTypeList(OrderSearchDTO orderSearchDTO) {
        List<Integer> payTypeList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.WECHATPAY.value())) {
            payTypeList.addAll(Arrays.asList(PayType.WE_CHAT_PAY_ARRAY));
        } else if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.ALIPAY.value())) {
            payTypeList.addAll(Arrays.asList(PayType.ALI_PAY_ARRAY));
        } else if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.BALANCE.value())) {
            payTypeList.add(PayType.BALANCE.value());
        } else if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.SCOREPAY.value())) {
            payTypeList.add(PayType.SCOREPAY.value());
        }
        orderSearchDTO.setPayTypeList(payTypeList);
    }

    /**
     * 通过搜索信息分页搜索es数据的信息
     *
     * @param orderSearchDTO 订单搜索条件
     * @return 搜索结果
     */
    public EsPageVO<EsOrderVO> pageSearchResult(OrderSearchDTO orderSearchDTO) {
        if (Objects.isNull(orderSearchDTO.getPageSize())) {
            orderSearchDTO.setPageSize(10);
        }
        if (Objects.isNull(orderSearchDTO.getPageNum())) {
            orderSearchDTO.setPageNum(1);
        }
        //1、查询订单数据
        SearchResponse response = searchResult(orderSearchDTO);
        //2.处理响应的数据
        return pageEsOrderBO(response, orderSearchDTO.getPageSize());
    }

    /**
     * 获取检索列表（不分页，获取全部数据）
     *
     * @param orderSearchDTO
     * @return
     */
    public List<EsOrderVO> listSearchResult(OrderSearchDTO orderSearchDTO) {
        List<SearchHits> searchHitsList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        int pageNum = 0;
        int pageSize = 10000;
        orderSearchDTO.setPageSize(pageSize);
        SearchResponse response;
        // es默认可获取数据最大条数10000，若命中数据超出此值，继续分页查询数据，来实现将全部数据取出
        do {
            orderSearchDTO.setPageNum(++pageNum);
            response = searchResult(orderSearchDTO);
            searchHitsList.add(response.getHits());
        } while ((long) pageNum * pageSize < response.getHits().getTotalHits().value);
        // 取出es数据
        List<EsOrderVO> orderList = new ArrayList<>(16);
        for (SearchHits searchHits : searchHitsList) {
            orderList.addAll(this.getOrderListByResponse(searchHits.getHits()));
        }
        return orderList;
    }

    /**
     * 通过搜索信息分页搜索es数据的信息
     *
     * @param orderIds
     * @return 搜索结果
     */
    public List<EsOrderVO> listByOrderIds(List<Long> orderIds) {
        return listByOrderIds(orderIds, null);
    }

    /**
     * 通过搜索信息分页搜索es数据的信息
     *
     * @param orderIds
     * @return 搜索结果
     */
    public List<EsOrderVO> listByOrderIds(List<Long> orderIds, String[] fetchSource) {
        if (CollUtil.isEmpty(orderIds)) {
            return new ArrayList<>(0);
        }

        OrderSearchDTO orderSearchDTO = new OrderSearchDTO();
        orderSearchDTO.setOrderIds(orderIds);
        orderSearchDTO.setPageSize(orderIds.size());
        orderSearchDTO.setPageNum(1);
        if (ArrayUtil.isNotEmpty(fetchSource)) {
            orderSearchDTO.setFetchSource(fetchSource);
        }
        EsPageVO<EsOrderVO> esOrderPage = pageSearchResult(orderSearchDTO);
        return esOrderPage.getList();
    }

    private EsPageVO<EsOrderVO> pageEsOrderBO(SearchResponse response, Integer pageSize) {
        EsPageVO<EsOrderVO> pageVO = new EsPageVO<>();
        List<EsOrderVO> orderList = getOrderListByResponse(response.getHits().getHits());
        pageVO.setList(orderList);
        buildSearchPage(pageVO, response, pageSize);
        return pageVO;
    }

    /**
     * 构建分页数据
     *
     * @param esPageVO
     * @param response
     * @param pageSize
     */
    private void buildSearchPage(EsPageVO<?> esPageVO, SearchResponse response, Integer pageSize) {
        //总记录数
        long total = response.getHits().getTotalHits().value;
        esPageVO.setTotal(total);
        // 总页码
        int totalPages = (int) total % pageSize == 0 ?
                (int) total / pageSize : ((int) total / pageSize + 1);
        esPageVO.setPages(totalPages);
    }

    private SearchResponse searchResult(OrderSearchDTO orderSearchDTO) {
        // 封装检索条件
        SearchRequest searchRequest = buildSearchRequest(orderSearchDTO);
        SearchResponse response;
        try {
            //2、执行检索请求
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

            log.info("订单搜索返回结果：{}", response.toString());

        } catch (IOException e) {
            log.error(e.toString());
            throw new LuckException("搜索服务出了点小差，请稍后再试", e);
        }
        return response;
    }

    /*
      构建结果数据
     */

    /**
     * 从es返回的数据中获取spu列表
     *
     * @param hits es返回的数据
     * @return
     */
    private List<EsOrderVO> getOrderListByResponse(SearchHit[] hits) {
        List<EsOrderVO> esOrders = new ArrayList<>(Constant.INITIAL_CAPACITY);
        Integer lang = I18nMessage.getLang();
        for (SearchHit hit : hits) {
            EsOrderBO esOrderBO = Json.parseObject(hit.getSourceAsString(), EsOrderBO.class);
            EsOrderVO esOrderVO = BeanUtil.map(esOrderBO, EsOrderVO.class);
            esOrders.add(esOrderVO);
            if (CollUtil.isEmpty(esOrderBO.getOrderItems())) {
                continue;
            }
            for (EsOrderItemBO orderItem : esOrderBO.getOrderItems()) {
                if (Objects.equals(lang, LanguageEnum.LANGUAGE_EN.getLang())) {
                    orderItem.setSpuName(orderItem.getSpuNameEn());
                    orderItem.setSkuName(orderItem.getSkuNameEn());
                    orderItem.setSupplierSpuName(orderItem.getSupplierSpuNameEn());
                    orderItem.setSupplierSkuName(orderItem.getSupplierSkuNameEn());
                }
                if (StrUtil.isBlank(orderItem.getSpuName())) {
                    orderItem.setSpuName(orderItem.getSpuNameZh());
                }
                if (StrUtil.isBlank(orderItem.getSkuName())) {
                    orderItem.setSkuName(orderItem.getSkuNameZh());
                }
                if (StrUtil.isBlank(orderItem.getSkuName())) {
                    orderItem.setSkuName(orderItem.getSkuNameZh());
                }
                if (StrUtil.isBlank(orderItem.getSupplierSpuName())) {
                    orderItem.setSupplierSpuName(orderItem.getSupplierSpuNameZh());
                }
                if (StrUtil.isBlank(orderItem.getSupplierSkuName())) {
                    orderItem.setSupplierSkuName(orderItem.getSupplierSkuNameZh());
                }
            }
            esOrderVO.setOrderItems(BeanUtil.mapAsList(esOrderBO.getOrderItems(), EsOrderItemVO.class));
        }
        return esOrders;
    }


    /**
     * 准备检索请求
     *
     * @param param 搜索参数
     * @return
     */
    private SearchRequest buildSearchRequest(OrderSearchDTO param) {

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建bool-query
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        // 指定返回数组中的字段
        if (ArrayUtil.isNotEmpty(param.getFetchSource())) {
            searchSourceBuilder.fetchSource(param.getFetchSource(), null);
        }

        // 过滤
        filterQueryIfNecessary(param, boolQueryBuilder);

        // 关键字搜索
        keywordSearch(param, boolQueryBuilder);

        // 排序
        sort(searchSourceBuilder, boolQueryBuilder);

        if (Objects.nonNull(param.getPageNum()) && Objects.nonNull(param.getPageSize())) {
            //分页
            searchSourceBuilder.size(param.getPageSize());
            searchSourceBuilder.from((param.getPageNum() - 1) * param.getPageSize());
        }
        if(Objects.nonNull(param.getBegin())){
            searchSourceBuilder.from(param.getBegin());
        }
        log.info("构建的订单DSL语句 {}", searchSourceBuilder);

        return new SearchRequest(new String[]{EsIndexEnum.ORDER.value()}, searchSourceBuilder);
    }


    /**
     * 关键字搜索
     */
    private void keywordSearch(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {

        // 创建查询语句 ES中must和should不能同时使用 同时使用should失效 嵌套多个must 将should条件拼接在一个must中即可


        BoolQueryBuilder keywordShouldQuery = QueryBuilders.boolQuery();

        // 店铺名称
        if (StrUtil.isNotBlank(param.getShopName())) {
            keywordShouldQuery.should(QueryBuilders.matchQuery("shopName", param.getShopName()));
        }

        // 商品名称
        if (StrUtil.isNotBlank(param.getSpuName())) {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            boolQuery.should(QueryBuilders.matchQuery("orderItems.spuNameZh", param.getSpuName()));
            boolQuery.should(QueryBuilders.matchQuery("orderItems.spuNameEn", param.getSpuName()));
            NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("orderItems", boolQuery, ScoreMode.None);
            boolQueryBuilder.must(nestedQueryBuilder);
        }

        //收货人姓名
        if (StrUtil.isNotBlank(param.getConsignee())) {
            keywordShouldQuery.should(QueryBuilders.matchQuery("consignee", param.getConsignee()));
        }

        //收货人手机号
        if (StrUtil.isNotBlank(param.getMobile())) {
            BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery()
                    .should(QueryBuilders.matchPhraseQuery("mobile", param.getMobile()));
            boolQueryBuilder.must(shouldQuery);
        }

        // 商品编码
        if (StrUtil.isNotBlank(param.getSpuCodes())) {
            keywordShouldQuery.should(QueryBuilders.termQuery("spuCodes", param.getSpuCodes()));
        }

        // sku编码
        if (StrUtil.isNotBlank(param.getPartyCodes())) {
            BoolQueryBuilder partyCodesShouldQuery = QueryBuilders.boolQuery()
                    .should(QueryBuilders.matchPhraseQuery("partyCodes", param.getPartyCodes()));
            boolQueryBuilder.must(partyCodesShouldQuery);
        }

        //自提点名称
        if (StrUtil.isNotBlank(param.getStationName())) {
            keywordShouldQuery.should(QueryBuilders.matchQuery("stationName", param.getStationName()));
        }

        boolQueryBuilder.must(keywordShouldQuery);
    }

    /**
     * 进行排序
     */
    private void sort(SearchSourceBuilder searchSourceBuilder, BoolQueryBuilder boolQueryBuilder) {
        searchSourceBuilder.sort("createTime", SortOrder.DESC);
        searchSourceBuilder.query(boolQueryBuilder);
    }

    /**
     * 过滤查询条件，如果有必要的话
     *
     * @param param            查询条件
     * @param boolQueryBuilder 组合进boolQueryBuilder
     */
    private static void filterQueryIfNecessary(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        if (Objects.nonNull(param.getSupplierDeliveryType())) {
            if (Objects.equals(param.getSupplierDeliveryType(), SupplierDeliveryType.SHOP_DELIVERY.value())) {
                boolQueryBuilder.mustNot(QueryBuilders.termQuery("supplierDeliveryType", SupplierDeliveryType.SUPPLIER_DELIVERY.value()));
            } else {
                boolQueryBuilder.filter(QueryBuilders.termQuery("supplierDeliveryType", param.getSupplierDeliveryType()));
            }
        }
        // 店铺id
        if (Objects.nonNull(param.getShopId()) && !Objects.equals(param.getShopId(), Constant.PLATFORM_SHOP_ID)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("shopId", param.getShopId()));
        }
        // 店铺id集合
        if (CollUtil.isNotEmpty(param.getShopIds())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("shopId", param.getShopIds()));
        }
        // 供应商id
        if (Objects.nonNull(param.getSupplierId())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("supplierId", param.getSupplierId()));
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("waitPurchase", 1));
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("status", OrderStatus.WAIT_GROUP.value()));
        } else if (Objects.equals(param.getWaitPurchase(), 1)) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("waitPurchase", param.getWaitPurchase()));
        }
        // 供应商id集合
        if (CollUtil.isNotEmpty(param.getSupplierIds())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("supplierId", param.getSupplierIds()));
        }
        if (Objects.equals(param.getWaitPurchase(), 0)) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("waitPurchase", 1));
        }
        // 用户id
        if (Objects.nonNull(param.getUserId())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("userId", param.getUserId()));
        }
        // 订单id和订单项id和主单号
        handleOrderIdAndOrderItemId(param, boolQueryBuilder);
        // 处理虚拟订单和自提订单
        handleVritualAndStation(param, boolQueryBuilder);
        // 订单状态
        handleOrderStatus(param, boolQueryBuilder);
        // 支付相关
        handlePay(param, boolQueryBuilder);
        // 订单时间相关
        handleTime(param, boolQueryBuilder);
        // 处理预售订单
        handlePreSaleOrder(param, boolQueryBuilder);
        // 退款相关
        handleRefund(param, boolQueryBuilder);
        // 评论
        handleComm(param, boolQueryBuilder);

        // 删除类型
        if (Objects.nonNull(param.getDeleteStatus())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("deleteStatus", param.getDeleteStatus()));
        }

        //订单类型参考orderType ,1团购订单 2秒杀订单,3积分订单
        if (Objects.nonNull(param.getOrderType())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("orderType", param.getOrderType()));
        }
        // 商品类型为空，且用户id为空(orderIds有值时，是查询指定的订单，不需要订单类型的筛选) -> 商家、平台端获取的非积分订单列表
        else if (Objects.isNull(param.getUserId()) && CollUtil.isEmpty(param.getOrderIds()) && CollUtil.isEmpty(param.getOrderItemIds())) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("orderType", OrderType.SCORE.value()));
        }

        // 是否已经进行结算
        if (Objects.nonNull(param.getIsSettled())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("isSettled", param.getIsSettled()));
        }

        if (Objects.nonNull(param.getMaxBalanceAmount())) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("balanceAmount").lte(param.getMaxBalanceAmount());
            boolQueryBuilder.filter(rangeQueryBuilder);
        }

        // 物流类型  1:快递 2:自提 3：无需快递 4：同城快递
        if (Objects.nonNull(param.getDeliveryType())) {
            if (Objects.equals(param.getDeliveryType(), DeliveryType.DELIVERY.value())) {
                BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
                shouldQuery.should(QueryBuilders.matchQuery("deliveryType", DeliveryType.ONLINE.value()));
                shouldQuery.should(QueryBuilders.matchQuery("deliveryType", DeliveryType.DELIVERY.value()));
                boolQueryBuilder.must(shouldQuery);
            } else {
                boolQueryBuilder.filter(QueryBuilders.termQuery("deliveryType", param.getDeliveryType()));
            }
        }
    }
    private static void handlePay(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        // 是否已经支付，1：已经支付过，0：，没有支付过
        if (Objects.equals(param.getPayType(), PayType.UNPAY.value())) {
            param.setIsPayed(0);
        }
        if (Objects.nonNull(param.getIsPayed())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("isPayed", param.getIsPayed()));
        }
        // 支付类型  1:积分支付 2:微信支付 3：支付宝支付
        if (CollUtil.isNotEmpty(param.getPayTypeList())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("payType", param.getPayTypeList()));
        }
    }

    private static void handleRefund(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        // 订单退款状态（0:暂无物流 1:申请退款 2:退款成功 3:部分退款成功 4:退款失败）
        if (Objects.equals(param.getRefundStatus(), 0)) {
            boolQueryBuilder.mustNot(QueryBuilders.existsQuery("orderItems.refundStatus"));
        } else if (Objects.nonNull(param.getRefundStatus())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("refundStatus", param.getRefundStatus()));
        }

        if (Objects.nonNull(param.getNotRefundStatus())) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("refundStatus", param.getNotRefundStatus()));
        }
    }

    private static void handleTime(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        // 支付时间
        if (Objects.nonNull(param.getPayTime())) {
            RangeQueryBuilder rangeQueryBuilder;
            if (BooleanUtil.isTrue(param.isGtePayTime())) {
                rangeQueryBuilder = QueryBuilders.rangeQuery("payTime").gte(param.getPayTime());
            } else {
                rangeQueryBuilder = QueryBuilders.rangeQuery("payTime").lte(param.getPayTime());
            }
            boolQueryBuilder.filter(rangeQueryBuilder);
        }

        // 发货时间
        if (Objects.nonNull(param.getDeliveryTime())) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("deliveryTime").lte(param.getDeliveryTime());
            boolQueryBuilder.filter(rangeQueryBuilder);
        }

        // 确认收货时间
        if (Objects.nonNull(param.getFinallyTime())) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("finallyTime").lte(param.getFinallyTime());
            boolQueryBuilder.filter(rangeQueryBuilder);
        }
        // 开始时间 - 结束时间
        if (Objects.nonNull(param.getStartTime()) || Objects.nonNull(param.getEndTime())) {
            String createTime = "createTime";
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(createTime);
            if (Objects.nonNull(param.getStartTime())) {
                rangeQueryBuilder.gte(param.getStartTime());
            }
            if (Objects.nonNull(param.getEndTime())) {
                rangeQueryBuilder.lte(param.getEndTime());
            }
            boolQueryBuilder.filter(rangeQueryBuilder);
        }
    }

    private static void handleOrderStatus(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        //平台端会员详情不展示未付款的订单
        if (CollUtil.isNotEmpty(param.getMustNotStatusList())) {
            boolQueryBuilder.mustNot(QueryBuilders.termsQuery("status", param.getMustNotStatusList()));
        }
        //平台端会员详情不展示未付款的订单
        if (Objects.equals(param.getShopId(), Constant.PLATFORM_SHOP_ID) && Objects.nonNull(param.getUserId())) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("status", OrderStatus.UNPAY.value()));
        }
        if (Objects.equals(param.getStatus(), OrderStatus.UNPAY.value())) {
            BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
            // or条件用should查询，必须配合must使用
            shouldQuery.should(QueryBuilders.matchQuery("status", OrderStatus.UNPAY.value()));
            shouldQuery.should(QueryBuilders.matchQuery("status", OrderStatus.WAIT_BALANCE.value()));
            boolQueryBuilder.must(shouldQuery);
        }
        // 订单状态 参考OrderStatus
        if (Objects.nonNull(param.getStatus()) && !Objects.equals(param.getStatus(), 0) && !Objects.equals(param.getStatus(), OrderStatus.UNPAY.value())) {
            boolQueryBuilder.filter(QueryBuilders.termQuery("status", param.getStatus()));
        }
        // 订单状态 参考OrderStatus
        if (CollUtil.isNotEmpty(param.getStatusList())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("status", param.getStatusList()));
        }
    }

    private static void handleOrderIdAndOrderItemId(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        // 订单id
        if (param.getOrderId() != null) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("orderId", param.getOrderId().toString()));
        }

        // 主订单id
        if (Objects.nonNull(param.getMainOrderId())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("mainOrderId", param.getMainOrderId().toString()));
        }

        if (CollUtil.isNotEmpty(param.getOrderIds())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("orderId", param.getOrderIds()));
        }

        if (CollUtil.isNotEmpty(param.getOrderItemIds())) {
            boolQueryBuilder.filter(EsSearchUtil.nestedQuery("orderItems", "orderItems.orderItemId", param.getOrderItemIds()));
        }
    }

    private static void handleComm(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        if (Objects.nonNull(param.getIsComm())) {
            param.setStatus(OrderStatus.SUCCESS.value());
        }
        if (Objects.nonNull(param.getIsComm())) {
            if (Objects.equals(param.getIsComm(), 0)) {
                boolQueryBuilder.mustNot(QueryBuilders.termQuery("refundStatus", 1));
                boolQueryBuilder.mustNot(QueryBuilders.termQuery("orderType", OrderType.SCORE.value()));
            }
            // 退款状态为退款失败或者为空的
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
            boolQuery.must(QueryBuilders.matchQuery("orderItems.isComm", param.getIsComm()));
            // or条件用should查询，必须配合must使用
            shouldQuery.should(QueryBuilders.matchQuery("orderItems.refundStatus", 4));
            shouldQuery.should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("orderItems.refundStatus")));
            boolQuery.must(shouldQuery);
            NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("orderItems", boolQuery, ScoreMode.None);
            boolQueryBuilder.filter(nestedQueryBuilder);
        }
    }

    private static void handlePreSaleOrder(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        // 预售开始时间
        if (Objects.nonNull(param.getBalanceStartTime())) {
            RangeQueryBuilder rangeStartQueryBuilder = QueryBuilders.rangeQuery("balanceStartTime").lte(param.getBalanceStartTime());
            RangeQueryBuilder rangeEndQueryBuilder = QueryBuilders.rangeQuery("balanceEndTime").gte(param.getBalanceStartTime());
            boolQueryBuilder.filter(rangeStartQueryBuilder);
            boolQueryBuilder.filter(rangeEndQueryBuilder);
        }

        // 预售结束时间
        if (Objects.nonNull(param.getBalanceEndTime())) {
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("balanceEndTime").lte(param.getBalanceEndTime());
            boolQueryBuilder.filter(rangeQueryBuilder);
        }
        List<Integer> preSaleTypeList = new ArrayList<>(1);
        // 预售类型 0.全款预售类型 1.定金预售
        if (Objects.nonNull(param.getPreSaleType())) {
            preSaleTypeList.add(param.getPreSaleType());
        }
        if (Objects.nonNull(param.getIsPreSale()) && Objects.equals(param.getIsPreSale(), 1)) {
            // 预售类型 0.全款预售类型 1.定金预售
            preSaleTypeList.add(0);
            preSaleTypeList.add(1);
        }
        if (CollUtil.isNotEmpty(preSaleTypeList)) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("preSaleType", preSaleTypeList));
        }
        // 是否预售订单 1.是 0.否
        if (Objects.equals(param.getIsPreSale(), 1)) {
            boolQueryBuilder.mustNot(QueryBuilders.termQuery("preSaleType", PreSaleType.DISABLE.value()));
        }
        if (Objects.equals(param.getIsPreSale(), 0)) {
            // 存在没有'preSaleType'字段的数据，用mustNot来进行查询非预售订单
            boolQueryBuilder.mustNot(QueryBuilders.termsQuery("preSaleType", Arrays.asList(PreSaleType.FULLPAY.value(), PreSaleType.DEPOSIT.value())));
        }
    }

    private static void handleVritualAndStation(OrderSearchDTO param, BoolQueryBuilder boolQueryBuilder) {
        // 判断是否是虚拟订单或自提订单
        if (param.getStationId() != null || param.getOrderMold() != null) {
            if (param.getStationId() == null) {
                // 虚拟订单
                boolQueryBuilder.filter(QueryBuilders.termQuery("orderMold", param.getOrderMold()));
            } else if (param.getOrderMold() == null) {
                // 自提订单以及部分核销过的虚拟订单
                BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
                BoolQueryBuilder stationQuery = QueryBuilders.boolQuery();
                stationQuery.must(QueryBuilders.termsQuery("stationId", param.getStationId().toString()));
                BoolQueryBuilder codeShouldQuery = QueryBuilders.boolQuery();
                codeShouldQuery.must(QueryBuilders.matchQuery("orderVirtualInfoList.stationId", param.getStationId()));
                NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("orderVirtualInfoList", codeShouldQuery, ScoreMode.None);
                shouldQuery.should(nestedQueryBuilder);
                shouldQuery.should(stationQuery);
                boolQueryBuilder.must(shouldQuery);
            } else {
                // 虚拟订单加自提订单
                BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
                // or条件用should查询，必须配合must使用
                BoolQueryBuilder virtualQuery = QueryBuilders.boolQuery();
                BoolQueryBuilder rangeQuery = QueryBuilders.boolQuery();
                rangeQuery.should(QueryBuilders.rangeQuery("writeOffEnd").gt(new Date()));
                BoolQueryBuilder existsQuery = QueryBuilders.boolQuery();
                rangeQuery.should(existsQuery.mustNot(QueryBuilders.existsQuery("writeOffEnd")));
                virtualQuery.must(rangeQuery);
                virtualQuery.filter(QueryBuilders.termQuery("orderMold", param.getOrderMold()));
                virtualQuery.must(QueryBuilders.termsQuery("status", Arrays.asList(
                        OrderStatus.CONSIGNMENT.value(),
                        OrderStatus.SUCCESS.value())
                ));
                virtualQuery.mustNot(QueryBuilders.termQuery("writeOffNum", 0));
                virtualQuery.must(QueryBuilders.termQuery("writeOffStatus", 0));

                BoolQueryBuilder stationQuery = QueryBuilders.boolQuery();
                stationQuery.filter(QueryBuilders.termsQuery("stationId", param.getStationId().toString()));
                stationQuery.must(QueryBuilders.termQuery("status", OrderStatus.PAYED.value()));
                shouldQuery.should(virtualQuery);
                shouldQuery.should(stationQuery);
                boolQueryBuilder.must(shouldQuery);
            }
        }

        // 自提提货码
        if (StrUtil.isNotBlank(param.getStationCode())) {
            boolQueryBuilder.filter(QueryBuilders.termsQuery("stationCode", param.getStationCode()));
        }

        // 核销码
        if (StrUtil.isNotBlank(param.getWriteOffCode())) {
            BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
            // or条件用should查询，必须配合must使用
            BoolQueryBuilder idShouldQuery = QueryBuilders.boolQuery();
            idShouldQuery.must(QueryBuilders.termQuery("orderId", param.getWriteOffCode()));
            BoolQueryBuilder codeShouldQuery = QueryBuilders.boolQuery();
            codeShouldQuery.must(QueryBuilders.matchQuery("orderVirtualInfoList.writeOffCode", param.getWriteOffCode()));
            NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery("orderVirtualInfoList", codeShouldQuery, ScoreMode.None);
            shouldQuery.should(idShouldQuery);
            shouldQuery.should(nestedQueryBuilder);
            BoolQueryBuilder rangBuilder = QueryBuilders.boolQuery();
            rangBuilder.should(QueryBuilders.rangeQuery("writeOffEnd").gt(new Date()));
            BoolQueryBuilder existsBuilder = QueryBuilders.boolQuery();
            rangBuilder.should(existsBuilder.mustNot(QueryBuilders.existsQuery("writeOffEnd")));
            boolQueryBuilder.must(shouldQuery);
            boolQueryBuilder.must(rangBuilder);
        }

        // 核销状态
        if (param.getWriteOffStatus() != null) {
            boolQueryBuilder.must(QueryBuilders.termQuery("writeOffStatus", param.getWriteOffStatus()));
        }
    }

    /**
     * 统计用户的订单相关信息
     *
     * @param userIds 用户id集合
     * @return 用户的订单相关统计数据
     */
    public List<UserOrderStatisticVO> countOrderByUserIds(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return null;
        }
        List<UserOrderStatisticVO> userOrderStatistics = new ArrayList<>(Constant.INITIAL_CAPACITY);
        //1、准备检索请求

        // 1统计：消费金额 优惠总金额 消费次数
        SearchRequest searchRequest1 = buildCountOrderSearchRequest(userIds, COUNT_TYPE_FIRST);
        // 2统计：实付金额
        SearchRequest searchRequest2 = buildCountOrderSearchRequest(userIds, COUNT_TYPE_SECOND);
        // 3统计：最近消费时间
        SearchRequest searchRequest3 = buildCountOrderSearchRequest(userIds, COUNT_TYPE_THIRD);
        try {
            //2、执行检索请求
            SearchResponse response1 = restHighLevelClient.search(searchRequest1, RequestOptions.DEFAULT);
            SearchResponse response2 = restHighLevelClient.search(searchRequest2, RequestOptions.DEFAULT);
            SearchResponse response3 = restHighLevelClient.search(searchRequest3, RequestOptions.DEFAULT);

            log.debug("消费金额 优惠总金额 消费次数,搜索返回结果：{}", response1.toString());
            log.debug("实付金额,搜索返回结果：{}", response2.toString());
            log.debug("最近消费时间,搜索返回结果：{}", response3.toString());

            //3、分析响应数据，封装成我们需要的格式
            combinedEsOrderAggData(userOrderStatistics, userIds, response1, response2, response3);
        } catch (IOException e) {
            log.error(e.toString());
            throw new LuckException("搜索服务出了点小差，请稍后再试", e);
        }
        return userOrderStatistics;
    }

    private void combinedEsOrderAggData(List<UserOrderStatisticVO> userOrderStatistics, List<Long> userIds, SearchResponse response1, SearchResponse response2, SearchResponse response3) {

        ParsedLongTerms userIdTerms1 = response1.getAggregations().get("userIdTerms");
        ParsedLongTerms userIdTerms2 = response2.getAggregations().get("userIdTerms");
        ParsedLongTerms userIdTerms3 = response3.getAggregations().get("userIdTerms");

        Map<Number, Terms.Bucket> buckets1Map = userIdTerms1.getBuckets().stream().collect(Collectors.toMap(Terms.Bucket::getKeyAsNumber, (k) -> k));
        Map<Number, Terms.Bucket> buckets2Map = userIdTerms2.getBuckets().stream().collect(Collectors.toMap(Terms.Bucket::getKeyAsNumber, (k) -> k));
        Map<Number, Terms.Bucket> buckets3Map = userIdTerms3.getBuckets().stream().collect(Collectors.toMap(Terms.Bucket::getKeyAsNumber, (k) -> k));
        if (buckets1Map.size() == 0 && buckets2Map.size() == 0 && buckets3Map.size() == 0) {
            return;
        }
        for (Long userId : userIds) {
            UserOrderStatisticVO userOrderStatisticVO = new UserOrderStatisticVO();
            userOrderStatisticVO.setUserId(userId);
            Terms.Bucket bucket1 = buckets1Map.get(userId);
            if (Objects.nonNull(bucket1)) {

                // 消费金额
                Aggregations aggregations = bucket1.getAggregations();
                ParsedSum actualTotalAgg = aggregations.get("actualTotalAgg");
                double consAmount = actualTotalAgg.getValue();
                userOrderStatisticVO.setConsAmount(new BigDecimal(Double.valueOf(consAmount).toString()));

                // 优惠总金额
                ParsedSum reduceAmountAgg = aggregations.get("reduceAmountAgg");
                double reduceAmount = reduceAmountAgg.getValue();
                userOrderStatisticVO.setReduceAmount(new BigDecimal(Double.valueOf(reduceAmount).toString()));

                // 消费次数
                ParsedValueCount consTimesAgg = aggregations.get("consTimesAgg");
                long consTimes = consTimesAgg.getValue();
                userOrderStatisticVO.setConsTimes(Long.valueOf(consTimes).intValue());
            } else {
                userOrderStatisticVO.setConsAmount(new BigDecimal("0.0"));
                userOrderStatisticVO.setReduceAmount(new BigDecimal("0.0"));
                userOrderStatisticVO.setConsTimes(0);
            }
            // 实付金额
            Terms.Bucket bucket2 = buckets2Map.get(userId);
            if (Objects.nonNull(bucket2)) {
                ParsedSum actualTotalAgg = bucket2.getAggregations().get("actualTotalAgg");
                double actualTotal = actualTotalAgg.getValue();
                userOrderStatisticVO.setActualAmount(new BigDecimal(Double.valueOf(actualTotal).toString()));
            } else {
                userOrderStatisticVO.setActualAmount(new BigDecimal("0.0"));
            }
            // 最新消费时间
            Terms.Bucket bucket3 = buckets3Map.get(userId);
            if (Objects.nonNull(bucket3)) {
                ParsedMax payTime = bucket3.getAggregations().get("maxPayTime");
                String payTimeStr = payTime.getValueAsString();
                userOrderStatisticVO.setReConsTime(DateUtil.parse(payTimeStr));
            }
            userOrderStatistics.add(userOrderStatisticVO);
        }

    }


    /**
     * @param countType 1、统计：消费金额 优惠总金额 消费次数
     *                  2、统计：实付金额
     *                  3、统计：最近消费时间
     * @return
     */
    private SearchRequest buildCountOrderSearchRequest(List<Long> userIds, int countType) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建bool-query
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.matchQuery("isPayed", 1));
        boolQueryBuilder.must(QueryBuilders.matchQuery("deleteStatus", 0));
        boolQueryBuilder.must(QueryBuilders.termsQuery("userId", userIds));
        if (countType == COUNT_TYPE_FIRST) {
            boolQueryBuilder.mustNot(QueryBuilders.matchQuery("payType", PayType.SCOREPAY.value()));
        } else if (countType == COUNT_TYPE_SECOND) {
            List<Integer> payTypes = new ArrayList<>(Constant.INITIAL_CAPACITY);
            payTypes.add(PayType.SCOREPAY.value());
            payTypes.add(PayType.BALANCE.value());
            boolQueryBuilder.mustNot(QueryBuilders.termsQuery("payType", payTypes));
        }

        // 聚合条件
        // 1. 按照userId进行聚合（分组）
        TermsAggregationBuilder userIdAgg = AggregationBuilders.terms("userIdTerms");
        userIdAgg.field("userId").size(userIds.size());
        if (countType == COUNT_TYPE_FIRST) {
            // 消费金额
            userIdAgg.subAggregation(AggregationBuilders.sum("actualTotalAgg").field("actualTotal"));
            // 优惠总金额
            userIdAgg.subAggregation(AggregationBuilders.sum("reduceAmountAgg").field("reduceAmount"));
            // 消费次数
            userIdAgg.subAggregation(AggregationBuilders.count("consTimesAgg").field("orderId"));
        } else if (countType == COUNT_TYPE_SECOND) {
            // 实付金额
            userIdAgg.subAggregation(AggregationBuilders.sum("actualTotalAgg").field("actualTotal"));
        } else if (countType == COUNT_TYPE_THIRD) {
            // 最近消费时间
            userIdAgg.subAggregation(AggregationBuilders.max("maxPayTime").field("payTime"));
        }

        searchSourceBuilder.aggregation(userIdAgg);
        // 聚合数据，不需要获取命中的结果，只需要聚合的结果
        searchSourceBuilder.size(0);
        searchSourceBuilder.query(boolQueryBuilder);

        log.info("构建的DSL语句 {}", searchSourceBuilder);
        return new SearchRequest(new String[]{EsIndexEnum.ORDER.value()}, searchSourceBuilder);
    }

    public SearchRequest buildScrollSearchRequest(OrderSearchDTO param, Scroll scroll) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 构建bool-query
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        // 指定返回数组中的字段
        if (ArrayUtil.isNotEmpty(param.getFetchSource())) {
            searchSourceBuilder.fetchSource(param.getFetchSource(), null);
        }
        // 过滤
        filterQueryIfNecessary(param, boolQueryBuilder);
        // 关键词搜索
        keywordSearch(param, boolQueryBuilder);
        searchSourceBuilder.query(boolQueryBuilder);
        //设置最多一次能够取出100笔数据，从第101笔数据开始，将开启滚动查询
        //PS:滚动查询也属于这一次查询，只不过因为一次查不完，分多次查
        if (Objects.nonNull(param.getPageSize()) && param.getPageSize() > 0) {
            searchSourceBuilder.size(param.getPageSize());
        } else {
            searchSourceBuilder.size(EsConstant.MAX_PAGE_SIZE);
        }

        log.info("构建滚动查询的DSL语句 {}", searchSourceBuilder);

        return new SearchRequest(new String[]{EsIndexEnum.ORDER.value()}, searchSourceBuilder).scroll(scroll);
    }

    public List<OrderExcelVO> orderExcelScrollSearch(OrderSearchDTO orderSearchDTO) {
        // 校验一下店铺名称和供应商名称
        ServerResponseEntity<OrderSearchDTO> orderResponseEntity = orderFeignClient.checkOrderSearchInfo(orderSearchDTO);
        if (!orderResponseEntity.isSuccess()) {
            throw new LuckException(orderResponseEntity.getMsg());
        }
        orderSearchDTO = orderResponseEntity.getData();
        // 补充支付方式
        this.addPayTypeList(orderSearchDTO);
        List<SearchHit> searchHits = new ArrayList<>(Constant.INITIAL_CAPACITY);
        // 设置查询超时时间
        Scroll scroll = new Scroll(TimeValue.timeValueMinutes(5L));
        SearchRequest searchRequest = this.buildScrollSearchRequest(orderSearchDTO, scroll);
        // 进行第一次滚动查询
        SearchResponse searchResponse = EsSearchUtil.search(searchRequest);
        String scrollId = searchResponse.getScrollId();

        //记录要滚动的ID
        //滚动查询部分，将从第1001笔数据开始取
        SearchHit[] hitsScroll = searchResponse.getHits().getHits();
        searchHits.addAll(Arrays.asList(hitsScroll));

        while (hitsScroll.length > 0) {
            //构造滚动查询条件
            SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
            searchScrollRequest.scroll(scroll);
            searchResponse = EsSearchUtil.scroll(searchScrollRequest);
            scrollId = searchResponse.getScrollId();
            hitsScroll = searchResponse.getHits().getHits();
            searchHits.addAll(Arrays.asList(hitsScroll));
        }
        // 将searchHit转成excelVO并返回
        SearchHit[] searchHitArr = new SearchHit[searchHits.size()];
        searchHits.toArray(searchHitArr);
        return this.hitsToOrderExcelList(searchHitArr);
    }

    private List<OrderExcelVO> hitsToOrderExcelList(SearchHit[] hitsScroll) {
        List<OrderExcelVO> orderExcelList = new ArrayList<>(hitsScroll.length);
        List<EsOrderVO> orderList = getOrderListByResponse(hitsScroll);
        int seq = 1;
        for (EsOrderVO orderBO : orderList) {
            for (EsOrderItemVO orderItem : orderBO.getOrderItems()) {
                OrderExcelVO orderExcelVO = new OrderExcelVO();
                orderExcelVO.setSeq(String.valueOf(seq));
                // 订单数据
                orderExcelVO.setOrderId(String.valueOf(orderBO.getOrderId()));
                orderExcelVO.setCreateTime(orderBO.getCreateTime());
                orderExcelVO.setDeliveryType(DeliveryType.getDescription(orderBO.getDeliveryType()));
                orderExcelVO.setConsignee(orderBO.getConsignee());
                orderExcelVO.setMobile(orderBO.getMobile());
                orderExcelVO.setReceivingAddr(orderBO.getReceivingAddr());
                orderExcelVO.setTotal(PriceUtil.toDecimalPriceStr(orderBO.getTotal()));
                orderExcelVO.setFreightAmount(PriceUtil.toDecimalPriceStr(orderBO.getFreightAmount()));
                orderExcelVO.setReduceAmount(PriceUtil.toDecimalPriceStr(orderBO.getReduceAmount()));
                orderExcelVO.setOrderScore(Objects.isNull(orderBO.getOrderScore()) ? "0" : String.valueOf(orderBO.getOrderScore()));
                orderExcelVO.setActualTotal(PriceUtil.toDecimalPriceStr(orderBO.getActualTotal()));
                String payType = Objects.isNull(orderBO.getPayType()) ? Constant.UNPAID : PayType.getPayTypeName(orderBO.getPayType());
                orderExcelVO.setPayType(payType);
                if (Objects.equals(orderBO.getDeliveryType(), DeliveryType.STATION.value())) {
                    orderExcelVO.setStatus(OrderStatus.getStationName(orderBO.getStatus()));
                } else {
                    orderExcelVO.setStatus(OrderStatus.getDeliveryName(orderBO.getStatus()));
                }
                String refundStatus = Objects.isNull(orderBO.getRefundStatus()) ? Constant.NO_AFTER_SALES : RefundStatusEnum.getRefundName(orderBO.getRefundStatus());
                orderExcelVO.setRefundStatus(refundStatus);
                orderExcelVO.setOrderMold(Objects.equals(orderBO.getOrderMold(), 1) ? VIRTUAL_ORDER : PHYSICAL_ORDER);
                // 订单项数据
                orderExcelVO.setSpuName(orderItem.getSpuName());
                orderExcelVO.setSkuName(orderItem.getSkuName());
                orderExcelVO.setPrice(PriceUtil.toDecimalPriceStr(orderItem.getPrice()));
                orderExcelVO.setCount(orderItem.getCount());
                orderExcelVO.setSpuTotalAmount(PriceUtil.toDecimalPriceStr(orderItem.getSpuTotalAmount()));
                orderExcelVO.setShareReduce(PriceUtil.toDecimalPriceStr(orderItem.getShareReduce()));
                orderExcelVO.setActualTotalItem(PriceUtil.toDecimalPriceStr(orderItem.getActualTotal()));
                orderExcelVO.setUseScore(orderItem.getUseScore());
                String refundStatusItem = Objects.isNull(orderItem.getRefundStatus()) ? Constant.NO_AFTER_SALES : RefundStatusEnum.getRefundName(orderItem.getRefundStatus());
                orderExcelVO.setRefundStatusItem(refundStatusItem);
                orderExcelList.add(orderExcelVO);
            }
            seq ++;
        }
        return orderExcelList;
    }
}
