
package com.tmerclub.cloud.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.tmerclub.cloud.api.auth.feign.AccountFeignClient;
import com.tmerclub.cloud.api.auth.vo.AuthAccountVO;
import com.tmerclub.cloud.api.delivery.feign.StationFeignClient;
import com.tmerclub.cloud.api.delivery.vo.StationVO;
import com.tmerclub.cloud.api.product.bo.SpuSimpleBO;
import com.tmerclub.cloud.api.product.dto.StockBillLogItemDTO;
import com.tmerclub.cloud.api.product.dto.WarehouseDTO;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.SysTypeEnum;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.i18n.I18nMessage;
import com.tmerclub.cloud.common.order.vo.WarehouseVO;
import com.tmerclub.cloud.common.product.constant.*;
import com.tmerclub.cloud.common.product.dto.ProductSearchDTO;
import com.tmerclub.cloud.common.product.vo.SkuVO;
import com.tmerclub.cloud.common.product.vo.StockBillLogItemVO;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.common.util.ExcelUtil;
import com.tmerclub.cloud.product.bo.mongo.MongoStockBillLogBO;
import com.tmerclub.cloud.product.constant.ProdKeyType;
import com.tmerclub.cloud.product.dto.StockBillLogDTO;
import com.tmerclub.cloud.product.mapper.SkuMapper;
import com.tmerclub.cloud.product.model.SkuStock;
import com.tmerclub.cloud.product.service.*;
import com.tmerclub.cloud.product.vo.SkuExcelVO;
import com.tmerclub.cloud.product.vo.StockBillLogItemExcelVO;
import com.tmerclub.cloud.product.vo.StockBillLogItemImportExcelVO;
import com.tmerclub.cloud.product.vo.StockBillLogItemImportVO;
import com.tmerclub.cloud.product.vo.mongo.MongoStockBillLogItemVO;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 出入库商品项
 *
 * @author lhd
 * @date 2022-06-22 16:57:27
 */
@Service
public class StockBillLogItemServiceImpl implements StockBillLogItemService {

    private static final Logger logger = LoggerFactory.getLogger(StockBillLogItemServiceImpl.class);

    @Autowired
    private SkuService skuService;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private SkuStockService skuStockService;
    @Autowired
    private SpuService spuService;
    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private WarehouseService warehouseService;
    @DubboReference
    private StationFeignClient stationFeignClient;
    @DubboReference
    private AccountFeignClient accountFeignClient;

    @Value("${tmerclub.expose.operation.auth:}")
    private Boolean permission;

    @Override
    public PageVO<MongoStockBillLogItemVO> page(PageDTO pageDTO, StockBillLogDTO stockBillLogDTO) {
        // 只查询已 出/入 库的数据
        stockBillLogDTO.setStatus(StockBillStatus.SUCCESS.value());
        // 主表查询条件
        Criteria criteria = loadStockBillLogItemQuery(stockBillLogDTO);
        ProjectionOperation projectionOperation = Aggregation.project("stockBillNo", "sourceOrderNo", "stockBillType", "type",  "createTime", "makerMobile")
                .and("_id").as("stockBillLogId")
                .and("stockPointId").as("stockPointId")
                .and("stockPointType").as("stockPointType")
                .and("employeeId").as("employeeId")
                .and("stockBillItemLogs.skuId").as("skuId")
                .and("stockBillItemLogs.spuId").as("spuId")
                .and("stockBillItemLogs.spuName").as("spuName")
                .and("stockBillItemLogs.stockCount").as("stockCount")
                .and("stockBillItemLogs.unitPrice").as("unitPrice")
                .and("stockBillItemLogs.partyCode").as("partyCode");
        // 查询结果进行排序
        SortOperation sortOperation = Aggregation.sort(Sort.Direction.DESC, "createTime").and(Sort.Direction.DESC, "skuId");
        // 分页数据 -
        SkipOperation skipOperation = Aggregation.skip((long) pageDTO.getPageSize() * (pageDTO.getPageNum() - 1));
        LimitOperation limitOperation = Aggregation.limit(pageDTO.getPageSize());

        TypedAggregation<MongoStockBillLogItemVO> typedAggregation = Aggregation.newAggregation(
                MongoStockBillLogItemVO.class,
                Aggregation.unwind("stockBillItemLogs"),
                Aggregation.match(criteria),
                sortOperation,
                skipOperation,
                limitOperation,
                projectionOperation
                );
        logger.info("pageStockItem()的mongodb查询语句： {}", typedAggregation);

        // 执行聚合操作获取当前页数据
        AggregationResults<MongoStockBillLogItemVO> aggregationResults = mongoTemplate.aggregate(typedAggregation, "stock_bill_log", MongoStockBillLogItemVO.class);
        List<MongoStockBillLogItemVO> curList = aggregationResults.getMappedResults();
        // 查询信息
        Map<Long, String> warehouseNameMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        Map<Long, AuthAccountVO> userMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (!CollectionUtils.isEmpty(curList)) {
            Set<Long> stockPointIds = new HashSet<>(Constant.INITIAL_CAPACITY);
            Set<Long> userIds = new HashSet<>(Constant.INITIAL_CAPACITY);
            for (MongoStockBillLogItemVO mongoStockBillLogItemVO : curList) {
                stockPointIds.add(mongoStockBillLogItemVO.getStockPointId());
                userIds.add(mongoStockBillLogItemVO.getEmployeeId());
            }
            // 查询库存点
            if (!CollectionUtils.isEmpty(stockPointIds)) {
                WarehouseDTO warehouseDTO = new WarehouseDTO();
                warehouseDTO.setWarehouseIds(new ArrayList<>(stockPointIds));
                List<WarehouseVO> warehouses = warehouseService.listWarehouse(warehouseDTO);
                if(!CollectionUtils.isEmpty(warehouses)) {
                    warehouseNameMap = warehouses.stream().collect(Collectors.toMap(WarehouseVO::getWarehouseId, WarehouseVO::getWarehouseName));
                }
            }
            // 查询制单人
            if (!CollectionUtils.isEmpty(userIds)) {
                List<AuthAccountVO> accounts = accountFeignClient.listByUserIdsAndPhoneAndType(new ArrayList<>(userIds), null, SysTypeEnum.MULTISHOP.value()).getData();
                if (!CollectionUtils.isEmpty(accounts)) {
                    userMap = accounts.stream().collect(Collectors.toMap(AuthAccountVO::getUserId, x -> x));
                }
            }
        }
        // 补充信息
        AuthAccountVO accountVO;
        for (MongoStockBillLogItemVO mongoStockBillLogItem : curList) {
            // 补充库存点名称
            mongoStockBillLogItem.setStockPointName(warehouseNameMap.get(mongoStockBillLogItem.getStockPointId()));
            mongoStockBillLogItem.setStockPointType(mongoStockBillLogItem.getStockPointType() == null ? StockPointType.WAREHOUSE.getValue() : mongoStockBillLogItem.getStockPointType());
            // 补充制单人信息
            if (!Objects.isNull(accountVO = userMap.get(mongoStockBillLogItem.getEmployeeId()))) {
                mongoStockBillLogItem.setMakerName(accountVO.getUsername());
                mongoStockBillLogItem.setMakerMobile(accountVO.getPhone());
            }
            // 手机号隐藏
            if (StrUtil.isNotBlank(mongoStockBillLogItem.getMakerMobile())) {
                mongoStockBillLogItem.setMakerMobile(PhoneUtil.hideBetween(mongoStockBillLogItem.getMakerMobile()).toString());
            }
        }

        TypedAggregation<MongoStockBillLogBO> totalTypedAggregation = Aggregation.newAggregation(
                MongoStockBillLogBO.class,
                Aggregation.unwind("stockBillItemLogs"),
                Aggregation.match(criteria),
                Aggregation.count().as("totalCount")
        );
        AggregationResults<MongoStockBillLogBO> totalAggregationResults = mongoTemplate.aggregate(totalTypedAggregation, "stock_bill_log", MongoStockBillLogBO.class);

        // 总条数
        long count = 0L;
        if (CollUtil.isNotEmpty(totalAggregationResults.getMappedResults())) {
            count = totalAggregationResults.getMappedResults().get(0).getTotalCount();
        }

        PageVO<MongoStockBillLogItemVO> stockBillLogItemPage = new PageVO<>();
        stockBillLogItemPage.setTotal(count);
        stockBillLogItemPage.setList(curList);
        stockBillLogItemPage.setPages(PageUtil.getPages(count, pageDTO.getPageSize()));
        return stockBillLogItemPage;
    }

    private Criteria loadStockBillLogItemQuery(StockBillLogDTO stockBillLogDTO) {
        Criteria criteria = new Criteria();
        if (StrUtil.isNotBlank(stockBillLogDTO.getProdKey())) {
            if (Objects.equals(stockBillLogDTO.getProdKeyType(), ProdKeyType.SPU_NAME.value())) {
                SpuSimpleBO spuSimpleBO = new SpuSimpleBO();
                spuSimpleBO.setLang(I18nMessage.getLang());
                // 商品名称
                spuSimpleBO.setSpuName(stockBillLogDTO.getProdKey());
                List<SpuSimpleBO> spuList = spuService.listSimple(spuSimpleBO);
                List<Long> spuIds = spuList.stream().map(SpuSimpleBO::getSpuId).collect(Collectors.toList());
                criteria.and("stockBillItemLogs.spuId").in(spuIds);
            } else if (Objects.equals(stockBillLogDTO.getProdKeyType(), ProdKeyType.PARTY_CODE.value())) {
                logger.info("通过商品编码查询库存流水，商品编码：{}", stockBillLogDTO.getProdKey());
                // 商品编码
                List<SkuVO> skuVoList = skuMapper.listSkuByPartyCodeAndShopId(stockBillLogDTO.getProdKey(), stockBillLogDTO.getShopId(), stockBillLogDTO.getSupplierId());
                // skuId
                List<Long> skuIdList = skuVoList.stream().map(SkuVO::getSkuId).collect(Collectors.toList());
                // 供应商skuId
                List<Long> supplierSkuIdList = skuVoList.stream().filter(skuVO->Objects.nonNull(skuVO.getSupplierSkuId())).map(SkuVO::getSupplierSkuId).collect(Collectors.toList());
                if(CollUtil.isNotEmpty(supplierSkuIdList)   ){
                    skuIdList.addAll(supplierSkuIdList);
                }
                criteria.and("stockBillItemLogs.skuId").in(skuIdList);
            }
        }
        if (!ObjectUtils.isEmpty(stockBillLogDTO.getStockPointName())) {
            WarehouseDTO warehouseDTO = new WarehouseDTO();
            warehouseDTO.setWarehouseName(stockBillLogDTO.getStockPointName());
            List<WarehouseVO> warehouse = warehouseService.listWarehouse(warehouseDTO);
            if (!CollectionUtils.isEmpty(warehouse)) {
                List<Long> warehouseIds = warehouse.stream().map(WarehouseVO::getWarehouseId).toList();
                criteria.and("stockPointId").in(warehouseIds);
            }
        }
        if (CollUtil.isNotEmpty(stockBillLogDTO.getStockBillLogItemIds())) {
            criteria.and("_id").in(stockBillLogDTO.getStockBillLogItemIds());
        }
        if (AuthUserContext.get().getSysType().equals(SysTypeEnum.MULTISHOP.value())) {
            criteria.and("supplierId").isNull();
        }
        criteria.and("shopId").is(stockBillLogDTO.getShopId());
        if (Objects.nonNull(stockBillLogDTO.getCreateStartTime()) && Objects.nonNull(stockBillLogDTO.getCreateEndTime())) {
            criteria.andOperator(Criteria.where("createTime").lte(stockBillLogDTO.getCreateEndTime()),
                    Criteria.where("createTime").gte(stockBillLogDTO.getCreateStartTime()));
        }
        if (StrUtil.isNotBlank(stockBillLogDTO.getSourceOrderNo())) {
            // 模糊查询只支持字段属性是字符串
            criteria.and("sourceOrderNo").regex(Pattern.compile("^.*" + stockBillLogDTO.getSourceOrderNo() + ".*$", Pattern.CASE_INSENSITIVE));
        }
        if (StrUtil.isNotBlank(stockBillLogDTO.getStockBillNo())) {
            criteria.and("stockBillNo").regex(Pattern.compile("^.*" + stockBillLogDTO.getStockBillNo() + ".*$", Pattern.CASE_INSENSITIVE));
        }
        if (Objects.nonNull(stockBillLogDTO.getStockBillType()) && !Objects.equals(stockBillLogDTO.getStockBillType(), 0)) {
            criteria.and("stockBillType").is(stockBillLogDTO.getStockBillType());
        }
        if (Objects.nonNull(stockBillLogDTO.getType())) {
            criteria.and("type").is(stockBillLogDTO.getType());
        }
        if (Objects.nonNull(stockBillLogDTO.getStatus())) {
            criteria.and("status").is(stockBillLogDTO.getStatus());
        }
        if (StrUtil.isNotBlank(stockBillLogDTO.getMakerMobile())) {
            criteria.and("makerMobile").is(stockBillLogDTO.getMakerMobile());
        }
        return criteria;
    }

    private Map<Long, SkuExcelVO> getSkuMap(Stream<Long> curList) {
        List<Long> skuIds = curList.collect(Collectors.toList());
        ProductSearchDTO productSearchDTO = new ProductSearchDTO();
        productSearchDTO.setSkuIds(skuIds);
        List<SkuExcelVO> skuList = skuService.exportSkuList(productSearchDTO);
        return skuList.stream().collect(Collectors.toMap(SkuExcelVO::getSkuId, s -> s));
    }

    @Override
    public List<StockBillLogItemExcelVO> exportFlow(StockBillLogDTO stockBillLogDTO, HttpServletResponse response) {
         // 主表查询条件
        Criteria criteria = loadStockBillLogItemQuery(stockBillLogDTO);
        ProjectionOperation projectionOperation = Aggregation.project("stockBillNo", "sourceOrderNo", "stockBillType", "type", "measureUnit", "createTime", "makerMobile")
                .and("stockPointId").as("stockPointId")
                .and("stockPointType").as("stockPointType")
                .and("stockBillItemLogs.skuId").as("skuId")
                .and("stockBillItemLogs.spuId").as("spuId")
                .and("stockBillItemLogs.spuName").as("spuName")
                .and("stockBillItemLogs.stockCount").as("stockCount")
                .and("stockBillItemLogs.unitPrice").as("unitPrice")
                .and("stockBillItemLogs.partyCode").as("partyCode");
        // 查询结果进行排序
        SortOperation sortOperation = Aggregation.sort(Sort.Direction.DESC, "createTime").and(Sort.Direction.DESC, "skuId");
        TypedAggregation<MongoStockBillLogItemVO> typedAggregation = Aggregation.newAggregation(
                MongoStockBillLogItemVO.class,
                Aggregation.unwind("stockBillItemLogs"),
                Aggregation.match(criteria),
                sortOperation,
                projectionOperation
        );
        logger.info("exportFlow()的mongodb查询语句： {}", typedAggregation);
        // 执行聚合操作获取当前页数据
        AggregationResults<MongoStockBillLogItemVO> aggregationResults = mongoTemplate.aggregate(typedAggregation, "stock_bill_log", MongoStockBillLogItemVO.class);
        List<MongoStockBillLogItemVO> mappedResults = aggregationResults.getMappedResults();
        List<StockBillLogItemExcelVO> excelStockBillLogItemList = BeanUtil.mapAsList(mappedResults, StockBillLogItemExcelVO.class);
        Map<Long, SkuExcelVO> skuMap = getSkuMap(excelStockBillLogItemList.stream().map(StockBillLogItemExcelVO::getSkuId));
        List<Long> warehouseIds = mappedResults.stream().filter(logItem-> Objects.equals(logItem.getStockPointType(), StockPointType.WAREHOUSE.getValue())).map(MongoStockBillLogItemVO::getStockPointId).collect(Collectors.toList());
        WarehouseDTO warehouseDTO = new WarehouseDTO();
        warehouseDTO.setWarehouseIds(warehouseIds);
        List<WarehouseVO> warehouseVOS = warehouseService.listWarehouse(warehouseDTO);
        Map<Long, String> warehouseMap = warehouseVOS.stream().collect(Collectors.toMap(WarehouseVO::getWarehouseId, WarehouseVO::getWarehouseName));

        List<Long> stationIds = mappedResults.stream().filter(logItem-> Objects.equals(logItem.getStockPointType(), StockPointType.STATION.getValue())).map(MongoStockBillLogItemVO::getStockPointId).collect(Collectors.toList());
        List<StationVO> stationVOList = stationFeignClient.listStationByIds(stationIds);
        Map<Long, String> stationMap = stationVOList.stream().collect(Collectors.toMap(StationVO::getStationId, StationVO::getStationName));

        for (StockBillLogItemExcelVO stockBillLogItemExcel : excelStockBillLogItemList) {
            if (Objects.equals(stockBillLogItemExcel.getStockPointType(), String.valueOf(StockPointType.STATION.getValue()))) {
                stockBillLogItemExcel.setStockPointType(StockPointType.STATION.getDesc());
                stockBillLogItemExcel.setStockPointName(stationMap.get(stockBillLogItemExcel.getStockPointId()));
            } else {
                stockBillLogItemExcel.setStockPointType(StockPointType.WAREHOUSE.getDesc());
                stockBillLogItemExcel.setStockPointName(warehouseMap.get(stockBillLogItemExcel.getStockPointId()));
            }
            if (StrUtil.isNotBlank(stockBillLogItemExcel.getMakerMobile())) {
                stockBillLogItemExcel.setMakerMobile(PhoneUtil.hideBetween(stockBillLogItemExcel.getMakerMobile()).toString());
            }
            stockBillLogItemExcel.setStockBillTypeName(Objects.nonNull(stockBillLogItemExcel.getStockBillType()) ? Objects.requireNonNull(StockBillType.instance(stockBillLogItemExcel.getStockBillType())).text() : "");
            if (!skuMap.containsKey(stockBillLogItemExcel.getSkuId())) {
                continue;
            }
            SkuExcelVO skuExcelVO = skuMap.get(stockBillLogItemExcel.getSkuId());
            stockBillLogItemExcel.setSpuName(skuExcelVO.getSpuName());
            stockBillLogItemExcel.setSkuName(skuExcelVO.getSkuName());
            stockBillLogItemExcel.setPartyCode(skuExcelVO.getPartyCode());
        }
        return excelStockBillLogItemList;
    }

    @Override
    public void downloadModel(HttpServletResponse response, Integer type) {
        List<StockBillLogItemExcelVO> list = new ArrayList<>(Constant.INITIAL_CAPACITY);
        Map<Integer, String[]> map = new HashMap<>(8);
        list.add(new StockBillLogItemExcelVO());
        ExcelWriter excelWriter = null;
        try {
            // 先执行合并策略
            ExcelWriterBuilder excelWriterMerge = ExcelUtil.getExcelWriterMerge(response, Objects.equals(type, StockType.OUT_OF_STOCK.value()) ? StockBillLogItemImportExcelVO.EXCEL_NAME_EXPORT : StockBillLogItemImportExcelVO.EXCEL_NAME_IMPORT, StockBillLogItemImportExcelVO.MERGE_ROW_INDEX, StockBillLogItemImportExcelVO.MERGE_COLUMN_INDEX);
            excelWriter = ExcelUtil.getExcelModel(excelWriterMerge, map, Constant.START_ROW).build();
            // 业务代码
            if (CollUtil.isNotEmpty(list)) {
                // 进行写入操作
                WriteSheet sheetWriter = EasyExcel.writerSheet(Objects.equals(type, StockType.OUT_OF_STOCK.value()) ? StockBillLogItemImportExcelVO.SHEET_NAME_EXPORT : StockBillLogItemImportExcelVO.SHEET_NAME_IMPORT).head(StockBillLogItemImportExcelVO.class).build();
                excelWriter.write(list, sheetWriter);
            }

        } catch (Exception e) {
            logger.error("导出出入库商品项模板excel失败", e);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }

    @Override
    public void importExcel(List<StockBillLogItemImportExcelVO> list, List<String> errorList, Integer stockType, StockBillLogItemImportVO stockBillLogItemImportVO) {
        Long shopId = AuthUserContext.get().getTenantId();
        Integer sysType = AuthUserContext.get().getSysType();
        List<StockBillLogItemVO> stockBillLogItemVOList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        int i = 0;
        String tips;
        if (list.size() == 0) {
            tips = "导入数据为空，请检查下文件";
            stockBillLogItemImportVO.setTips(tips);
        } else {
            try {
                for (StockBillLogItemImportExcelVO item : list) {
                    i++;
                    String partyCode = item.getPartyCode();
                    if (Objects.isNull(partyCode)) {
                        throw new LuckException("商品编码不能为空");
                    }

                    StockBillLogItemDTO stockBillLogItemDTO = skuService.getSkuByPartyCodeAndShopId(partyCode, shopId, sysType);
                    if (Objects.isNull(stockBillLogItemDTO)) {
                        throw new LuckException("商品不存在");
                    }
                    if (Objects.isNull(item.getStockCount())) {
                        throw new LuckException("出入库数量不能为空");
                    }
                    if (Objects.equals(stockType, StockType.WAREHOUSING.value()) && item.getStockCount() <= 0) {
                        throw new LuckException("入库数量不能少于零");
                    }
                    SkuStock skuStock = skuStockService.getBySkuId(stockBillLogItemDTO.getSkuId(), SpuMold.REAL.value());
                    if (Objects.equals(stockType, StockType.OUT_OF_STOCK.value())) {
                        if (Objects.nonNull(skuStock) && item.getStockCount() > skuStock.getStock()) {
                            throw new LuckException("出库数量不能超过商品库存");
                        }
                    }
                    StockBillLogItemVO stockBillLogItemVO = new StockBillLogItemVO();
                    stockBillLogItemVO.setSkuId(stockBillLogItemDTO.getSkuId());
                    stockBillLogItemVO.setPartyCode(item.getPartyCode());
                    stockBillLogItemVO.setStock(skuStock.getStock());
                    stockBillLogItemVO.setMainImgUrl(stockBillLogItemDTO.getMainImgUrl());
                    stockBillLogItemVO.setStockBillType(stockType);
                    stockBillLogItemVO.setSpuId(stockBillLogItemDTO.getSpuId());
                    stockBillLogItemVO.setStockCount(item.getStockCount());
                    stockBillLogItemVO.setSpuName(stockBillLogItemDTO.getSpuName());
                    stockBillLogItemVO.setSkuName(stockBillLogItemDTO.getSkuName());
                    stockBillLogItemVOList.add(stockBillLogItemVO);
                }
            } catch (LuckException e) {
                //错误信息提示
                errorList.add("第" + (i + 1) + "行数据有错误：" + e.getMessage());
            }
            tips = "检查到" + list.size() + "条商品信息，成功导入" +
                    (stockBillLogItemVOList.size()) + "条商品信息！错误" + (list.size() - stockBillLogItemVOList.size()) + "条商品信息!" +
                    (CollUtil.isNotEmpty(errorList) ? errorList.toString() : "");
        }

        stockBillLogItemImportVO.setTips(tips);
        stockBillLogItemImportVO.setStockBillLogItemList(stockBillLogItemVOList);
    }

    private Criteria getLogCriteriaByParam(StockBillLogDTO stockBillLogDTO) {
        Criteria criteria = new Criteria();
        criteria.and("stockBillLogs.shopId").is(stockBillLogDTO.getShopId());
        if (Objects.nonNull(stockBillLogDTO.getCreateStartTime()) && Objects.nonNull(stockBillLogDTO.getCreateEndTime())) {
            criteria.andOperator(Criteria.where("stockBillLogs.createTime").lte(stockBillLogDTO.getCreateEndTime()),
                    Criteria.where("stockBillLogs.createTime").gte(stockBillLogDTO.getCreateStartTime()));
        }
        if (StrUtil.isNotBlank(stockBillLogDTO.getSourceOrderNo())) {
            // 模糊查询只支持字段属性是字符串
            criteria.and("stockBillLogs.sourceOrderNo").regex(Pattern.compile("^.*" + stockBillLogDTO.getSourceOrderNo() + ".*$", Pattern.CASE_INSENSITIVE));
        }
        if (StrUtil.isNotBlank(stockBillLogDTO.getStockBillNo())) {
            criteria.and("stockBillLogs.stockBillNo").regex(Pattern.compile("^.*" + stockBillLogDTO.getStockBillNo() + ".*$", Pattern.CASE_INSENSITIVE));
        }
        if (Objects.nonNull(stockBillLogDTO.getStockBillType()) && !Objects.equals(stockBillLogDTO.getStockBillType(), 0)) {
            criteria.and("stockBillLogs.stockBillType").is(stockBillLogDTO.getStockBillType());
        }
        if (Objects.nonNull(stockBillLogDTO.getType())) {
            criteria.and("stockBillLogs.type").is(stockBillLogDTO.getType());
        }
        if (Objects.nonNull(stockBillLogDTO.getStatus())) {
            criteria.and("stockBillLogs.status").is(stockBillLogDTO.getStatus());
        }
        if (StrUtil.isNotBlank(stockBillLogDTO.getMakerMobile())) {
            criteria.and("stockBillLogs.makerMobile").is(stockBillLogDTO.getMakerMobile());
        }
        return criteria;
    }

    private Criteria getItemCriteriaByParam(StockBillLogDTO stockBillLogDTO) {
        Criteria criteria = new Criteria();
        if (StrUtil.isNotBlank(stockBillLogDTO.getProdKey())) {
            if (Objects.equals(stockBillLogDTO.getProdKeyType(), ProdKeyType.SPU_NAME.value())) {
                SpuSimpleBO spuSimpleBO = new SpuSimpleBO();
                spuSimpleBO.setLang(I18nMessage.getLang());
                // 商品名称
                spuSimpleBO.setSpuName(stockBillLogDTO.getProdKey());
                List<SpuSimpleBO> spuList = spuService.listSimple(spuSimpleBO);
                List<Long> spuIds = spuList.stream().map(SpuSimpleBO::getSpuId).collect(Collectors.toList());
                criteria.and("spuId").in(spuIds);
            } else if (Objects.equals(stockBillLogDTO.getProdKeyType(), ProdKeyType.PARTY_CODE.value())) {
                logger.info("通过商品编码查询库存流水，商品编码：{}", stockBillLogDTO.getProdKey());
                // 商品编码
                List<SkuVO> skuVoList = skuMapper.listSkuByPartyCodeAndShopId(stockBillLogDTO.getProdKey(), stockBillLogDTO.getShopId(), stockBillLogDTO.getSupplierId());
                // skuId
                List<Long> skuIdList = skuVoList.stream().map(SkuVO::getSkuId).collect(Collectors.toList());
                // 供应商skuId
                List<Long> supplierSkuIdList = skuVoList.stream().filter(skuVO->Objects.nonNull(skuVO.getSupplierSkuId())).map(SkuVO::getSupplierSkuId).collect(Collectors.toList());
                if(CollUtil.isNotEmpty(supplierSkuIdList)){
                    skuIdList.addAll(supplierSkuIdList);
                }
                criteria.and("skuId").in(skuIdList);
            }
        }
        if (CollUtil.isNotEmpty(stockBillLogDTO.getStockBillLogItemIds())) {
            criteria.and("_id").in(stockBillLogDTO.getStockBillLogItemIds());
        }
        return criteria;
    }
}
