package com.prolog.eis.service.shelves.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.codingapi.tx.annotation.TxTransaction;
import com.prolog.cs.basic.warehouse.model.vo.BaseEisWarehouseLocatorVo;
import com.prolog.eis.common.util.ListHelper;
import com.prolog.eis.common.util.PrologStringUtils;
import com.prolog.eis.common.util.location.LocationConstants;
import com.prolog.eis.constants.base.*;
import com.prolog.eis.constants.wms.WmsConstants;
import com.prolog.eis.core.dto.route.ItemContainerReqDto;
import com.prolog.eis.core.model.base.area.WhArea;
import com.prolog.eis.core.model.base.locator.WhLocator;
import com.prolog.eis.core.model.biz.carry.CarryTask;
import com.prolog.eis.dao.out.ContainerInfoDetailMapper;
import com.prolog.eis.dao.out.ContainerInfoMapper;
import com.prolog.eis.dao.out.StationCfgMapper;
import com.prolog.eis.dao.shelves.PalletInfoMapper;
import com.prolog.eis.dao.shelves.PalletLocationMapper;
import com.prolog.eis.dao.shelves.sys.SysParamMapper;
import com.prolog.eis.dto.item.ItemSyncVO;
import com.prolog.eis.dto.shelves.*;
import com.prolog.eis.dto.wms.WmsContainerStatusUpdateDto;
import com.prolog.eis.enums.base.LayerEnum;
import com.prolog.eis.enums.wms.WmsCarryTaskInCode;
import com.prolog.eis.model.container.ContainerInfo;
import com.prolog.eis.model.container.ContainerInfoDetail;
import com.prolog.eis.model.container.LocationCfg;
import com.prolog.eis.model.container.StationCfg;
import com.prolog.eis.model.shelves.PalletInfo;
import com.prolog.eis.model.shelves.PalletLocation;
import com.prolog.eis.model.sys.SysParam;
import com.prolog.eis.router.vo.ContainerLocationVo;
import com.prolog.eis.service.container.EmptyContainerTaskService;
import com.prolog.eis.service.feign.RouteFeignService;
import com.prolog.eis.service.out.ContainerStoreChangeService;
import com.prolog.eis.service.out.GoodsInfoService;
import com.prolog.eis.service.out.LocationCfgService;
import com.prolog.eis.service.out.StationCfgService;
import com.prolog.eis.service.route.RouteInterfaceService;
import com.prolog.eis.service.shelves.*;
import com.prolog.eis.service.wms.WmsContainerStatusUpdateService;
import com.prolog.eis.utils.ListPageUtils;
import com.prolog.eis.utils.MapUtils;
import com.prolog.eis.utils.PalletListener;
import com.prolog.eis.vo.GoodsInfoVO;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.framework.utils.AssertUtils;
import com.prolog.fx.inf.core.InterfaceType;
import com.prolog.fx.inf.core.annotation.InterfaceMethod;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 货架服务实现类
 *
 * @author zhanghan
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ShelvesServiceImpl implements ShelvesService {

    private final PalletInfoMapper palletInfoMapper;
    private final PalletLocationMapper palletLocationMapper;
    private final ContainerInfoDetailMapper containerInfoDetailMapper;
    private final ShelvesGoodsInfoService shelvesGoodsInfoService;
    private final StationCfgMapper stationCfgMapper;
    private final PalletMoveExecuteService palletMoveExecuteService;
    private final RouteInterfaceService routeInterfaceService;
    private final RouteFeignService routeFeignService;
    private final SysParamMapper sysParamMapper;
    private final ItemService itemService;
    private final ContainerInfoMapper containerInfoMapper;
    private final LocationCfgService locationCfgService;
    private final EmptyContainerTaskService emptyContainerTaskService;
    private final WmsContainerStatusUpdateService wmsContainerStatusUpdateService;
    @Resource
    ContainerStoreChangeService containerStoreChangeService;

    @Resource
    StoreService storeService;

    @Resource
    private StationCfgService stationCfgService;

    @Resource
    GoodsInfoService goodsInfoService;

    @Override
    public Page<ShelvesInfoDTO> findShelvesInfoPage(ShelvesInfoPage page) {
        PageUtils.startPage(page.getPageNum(), page.getPageSize());
        List<ShelvesInfoDTO> palletInfoPage = palletInfoMapper.getPalletInfoPage(page);
        return PageUtils.getPage(palletInfoPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @TxTransaction(rollbackFor = Exception.class)
    @InterfaceMethod(key = "addShelves", name = "新增货架(PC->EIS)", type = InterfaceType.Receive)
    public void addShelves(ShelvesConfigureDTO dto) {
        //校验货架号是否唯一
        List<PalletInfo> palletInfoList = palletInfoMapper.findByMap(MapUtils.put(PalletInfo::getPalletNo, dto.getPalletNo()).getMap(), PalletInfo.class);
        AssertUtils.isEmpty(palletInfoList, String.format("%s已存在无法新增", dto.getPalletNo()));
        //根据点位查询点位信息
        List<BaseEisWarehouseLocatorVo> locatorByLocationList = routeInterfaceService.findLocatorByLocationList(Collections.singletonList(dto.getLocation()));
        AssertUtils.isNotEmpty(locatorByLocationList, String.format("%s不存在", dto.getLocation()));
        //容器上架
        routeInterfaceService.createItemContainer(dto.getPalletNo(), dto.getLocation(), dto.getPalletNo());
        //根据点位获取点位信息
        List<WhLocator> whLocatorList = routeInterfaceService.getLocatorByLocation(Collections.singletonList(dto.getLocation()));
        WhLocator whLocator = whLocatorList.stream().findFirst().orElseThrow(() -> new PrologException(String.format("%s点位信息不存在", dto.getLocation())));
        //保存货架信息
        PalletInfo palletInfo = new PalletInfo();
        palletInfo.setPalletNo(dto.getPalletNo());
        palletInfo.setIsLock(0);
        palletInfo.setIsMode(0);
        palletInfo.setStatus(0);
        palletInfo.setPalletType("0");
        palletInfo.setSubArea(whLocator.getAreaNo());
        palletInfo.setAngle(dto.getAngle());
        palletInfo.setRemark(dto.getRemark());
        palletInfo.setCreateTime(LocalDateTime.now());
        palletInfoMapper.save(palletInfo);
        List<CargoInformationDTO> cargoInformationList = Optional.ofNullable(dto.getCargoInformation()).orElse(new ArrayList<>());
        if (ObjectUtils.isEmpty(cargoInformationList)) {
            return;
        }
        List<PalletLocation> palletLocationList = new ArrayList<>();
        //层级校验
        this.layerCheck(cargoInformationList);
        //校验列
        Map<Integer, List<CargoInformationDTO>> checkX = ListHelper.buildGroupDictionary(cargoInformationList, CargoInformationDTO::getLayer);
        for (Map.Entry<Integer, List<CargoInformationDTO>> layerEntry : checkX.entrySet()) {
            List<CargoInformationDTO> cargoInformationList1 = layerEntry.getValue();
            Map<String, List<CargoInformationDTO>> checkDirection = ListHelper.buildGroupDictionary(cargoInformationList1, CargoInformationDTO::getDirection);
            for (Map.Entry<String, List<CargoInformationDTO>> directionEntry : checkDirection.entrySet()) {
                List<CargoInformationDTO> cargoInformationList2 = directionEntry.getValue();
                this.xCheck(cargoInformationList2);
            }
        }
        //保存货格信息
        for (CargoInformationDTO cargoInformation : cargoInformationList) {
            PalletLocation palletLocation = new PalletLocation();
            palletLocation.setPalletNo(dto.getPalletNo());
            palletLocation.setLayer(cargoInformation.getLayer());
            palletLocation.setX(cargoInformation.getX());
            palletLocation.setIsLock(0);
            palletLocation.setPlanes(cargoInformation.getDirection());
            palletLocation.setAbcType(cargoInformation.getAbcType());
            palletLocation.setVolume(cargoInformation.getVolume());
            palletLocation.setCreateTime(LocalDateTime.now());
            String layerStr = palletLocation.getLayer().toString();
            String xStr = palletLocation.getX().toString().length() > 1 ? palletLocation.getX().toString() :
                    "0" + palletLocation.getX();
            String number = dto.getPalletNo() + cargoInformation.getDirection() + layerStr + xStr;
            palletLocation.setPalletLocation(number);
            palletLocationList.add(palletLocation);
        }
        palletLocationMapper.saveBatch(palletLocationList);
    }

    @Override
    public PalletLocationDTO findCargoInformationDetail(String palletNo) {
        PalletLocationDTO palletLocationDTO = new PalletLocationDTO();
        List<PalletInfo> palletInfoList = palletInfoMapper.findByMap(MapUtils.put(PalletInfo::getPalletNo, palletNo).getMap(), PalletInfo.class);
        PalletInfo palletInfo = palletInfoList.stream().findFirst().orElseThrow(() -> new PrologException(String.format("货架[%s]不存在", palletNo)));
        //根据货架号查询货格明细
        List<CargoInformationDTO> cargoInformationList = palletLocationMapper.palletDetail(palletNo);
        //根据货架号查询点位信息
        List<ContainerLocationVo> containerLocationList = routeInterfaceService.findLocationByContainerList(Collections.singletonList(palletNo));
        ContainerLocationVo containerLocation = containerLocationList.stream().findFirst()
                .orElseThrow(() -> new PrologException(String.format("货架[%s]点位不存在", palletNo)));
        palletLocationDTO.setPalletNo(palletInfo.getPalletNo());
        palletLocationDTO.setRemark(palletInfo.getRemark());
        palletLocationDTO.setLocation(containerLocation.getCurrentLocation());
        palletLocationDTO.setCargoInformation(cargoInformationList);
        return palletLocationDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @InterfaceMethod(key = "updateShelves", name = "修改货架(PC->EIS)", type = InterfaceType.Receive)
    public void updateShelves(PalletLocationDTO dto) {
        //编辑前需要有查看库存，若当前有货格有库存则不允许操作
        List<ContainerInfoDetail> containerInfoDetailList = containerInfoDetailMapper.findByMap(MapUtils
                .put(ContainerInfoDetail::getContainerNo, dto.getPalletNo()).getMap(), ContainerInfoDetail.class);
        AssertUtils.isEmpty(containerInfoDetailList, "货架已有库存无法编辑");
        palletLocationMapper.updatePallet(dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @InterfaceMethod(key = "deleteShelves", name = "删除货架(PC->EIS)", type = InterfaceType.Receive)
    public void deleteShelves(String palletNo) {
        //删除前需要有查看库存的操作
        List<ContainerInfoDetail> containerInfoDetailList = containerInfoDetailMapper.findByMap(MapUtils
                .put(ContainerInfoDetail::getContainerNo, palletNo).getMap(), ContainerInfoDetail.class);
        AssertUtils.isEmpty(containerInfoDetailList, "货架已有库存无法删除");
        palletLocationMapper.deleteShelves(palletNo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @InterfaceMethod(key = "setTemplateShelves", name = "设置模板货架(PC->EIS)", type = InterfaceType.Receive)
    public void setTemplateShelves(TemplateShelvesDTO dto) {
        List<PalletInfo> palletInfoList = palletInfoMapper.findByMap(MapUtils
                .put(PalletInfo::getModeType, dto.getModeType()).getMap(), PalletInfo.class);
        AssertUtils.isEmpty(palletInfoList, String.format("模板名称[%s]不允许重复", dto.getModeType()));
        palletInfoMapper.updateMapById(dto.getId(), MapUtils.put(PalletInfo::getIsMode, 1)
                .put(PalletInfo::getModeType, dto.getModeType()).getMap(), PalletInfo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @TxTransaction(rollbackFor = Exception.class)
    public void batchImport(MultipartFile file) throws IOException {
        String fileName = file.getOriginalFilename();
        AssertUtils.isTrue(StringUtils.endsWithIgnoreCase(fileName, ".xls"), "请上传正确的excel文件!");
        List<PalletImportDTO> palletImportList = EasyExcelFactory.read(file.getInputStream(), PalletImportDTO.class, new PalletListener()).sheet().doReadSync();
        //Excel数据校验
        boolean empty = palletImportList.stream().anyMatch(item -> StringUtils.isEmpty(item.getPalletNo()) ||
                StringUtils.isEmpty(item.getLocationNo()) || StringUtils.isEmpty(item.getModeType())
        );
        AssertUtils.isNotTrue(empty || palletImportList.size() == 0, "Excel中有数据为空");
        //去重
        Map<String, List<PalletImportDTO>> afterGrouping = palletImportList.stream().collect(Collectors.groupingBy(PalletImportDTO::getPalletNo));
        AssertUtils.isTrue(palletImportList.size() == afterGrouping.size(), "Excel中有重复货架号");
        //验证货号与模板类型
        List<PalletInfo> palletInfoList = palletInfoMapper.findByMap(null, PalletInfo.class);
        for (PalletImportDTO palletImportDto : palletImportList) {
            boolean isItRepeat = palletInfoList.stream().anyMatch(item -> palletImportDto.getPalletNo().equals(item.getPalletNo()));
            AssertUtils.isNotTrue(isItRepeat, String.format("货架号不可以与现有货架号重复:%s", palletImportDto.getPalletNo()));
            boolean isItBeing = palletInfoList.stream().noneMatch(item -> palletImportDto.getModeType().equals(item.getModeType()));
            AssertUtils.isNotTrue(isItBeing, String.format("不存在此模板类型:%s", palletImportDto.getModeType()));
        }
        //验证点位是否存在
        List<String> locationNoList = ListHelper.select(palletImportList, PalletImportDTO::getLocationNo);
        List<BaseEisWarehouseLocatorVo> baseEisWarehouseLocatorList = routeInterfaceService.findLocatorByLocationList(locationNoList);
        AssertUtils.isNotEmpty(baseEisWarehouseLocatorList, "未查到相关点位");

        List<PalletInfo> readyToInsertPalletInfo = new ArrayList<>();
        List<PalletLocation> readyToInsertPalletLocation = new ArrayList<>();
        //查询货格
        List<PalletLocation> palletLocationList = palletLocationMapper.findByMap(null, PalletLocation.class);
        List<ItemContainerReqDto> itemContainerReqDtoList = new ArrayList<>();
        //根据点位获取点位信息
        List<WhLocator> whLocatorList = routeInterfaceService.getLocatorByLocation(locationNoList);
        Map<String, WhLocator> whLocatorMap = whLocatorList.stream().collect(Collectors.toMap(WhLocator::getLocationNo, o -> o));
        for (PalletImportDTO palletImportDto : palletImportList) {
            //校验点位
            List<BaseEisWarehouseLocatorVo> warehouseLocatorVos = baseEisWarehouseLocatorList.stream()
                    .filter(item -> item.getLocationNo().equals(palletImportDto.getLocationNo())).collect(Collectors.toList());
            AssertUtils.isNotEmpty(warehouseLocatorVos, String.format("点位[%s]不存在", palletImportDto.getLocationNo()));
            //上架
            ItemContainerReqDto reqDto = new ItemContainerReqDto();
            reqDto.setContainerNo(palletImportDto.getPalletNo());
            reqDto.setLocationNo(palletImportDto.getLocationNo());
            reqDto.setBusinessProperty(palletImportDto.getPalletNo());
            itemContainerReqDtoList.add(reqDto);
            //保存货架
            PalletInfo palletInfoEntity = new PalletInfo();
            palletInfoEntity.setPalletNo(palletImportDto.getPalletNo());
            palletInfoEntity.setIsLock(0);
            palletInfoEntity.setAngle(palletImportDto.getAngle());
            palletInfoEntity.setStatus(0);
            palletInfoEntity.setCreateTime(LocalDateTime.now());
            palletInfoEntity.setModeType("0");
            palletInfoEntity.setIsMode(0);
            palletInfoEntity.setPalletType("0");
            palletInfoEntity.setSubArea(whLocatorMap.get(palletImportDto.getLocationNo()).getAreaNo());
            readyToInsertPalletInfo.add(palletInfoEntity);

            PalletInfo palletInfo = palletInfoList.stream().filter(item ->
                    palletImportDto.getModeType().equals(item.getModeType())).findFirst().orElse(new PalletInfo());
            List<PalletLocation> matchedPalletLocation = palletLocationList.stream().filter(item ->
                    palletInfo.getPalletNo().equals(item.getPalletNo())).collect(Collectors.toList());
            for (PalletLocation palletLocation : matchedPalletLocation) {
                //保存货格
                PalletLocation palletLocationEntity = new PalletLocation();
                palletLocationEntity.setPalletNo(palletImportDto.getPalletNo());
                palletLocationEntity.setPalletLocation(palletImportDto.getPalletNo() + palletLocation.getPalletLocation()
                        .substring(palletLocation.getPalletLocation().indexOf(palletLocation.getPlanes())));
                palletLocationEntity.setLayer(palletLocation.getLayer());
                palletLocationEntity.setPlanes(palletLocation.getPlanes());
                palletLocationEntity.setAbcType(palletLocation.getAbcType());
                palletLocationEntity.setVolume(palletLocation.getVolume());
                palletLocationEntity.setX(palletLocation.getX());
                palletLocationEntity.setIsLock(0);
                palletLocationEntity.setCreateTime(LocalDateTime.now());
                readyToInsertPalletLocation.add(palletLocationEntity);
            }
        }
        //批量容器上架
        routeInterfaceService.commonContainerUpList(itemContainerReqDtoList);
        palletInfoMapper.saveBatch(readyToInsertPalletInfo);
        palletLocationMapper.saveBatch(readyToInsertPalletLocation);
    }

    @Override
    public RestMessage<Object> validateStation(String stationNo, Integer taskType) {
        if (ObjectUtils.isEmpty(stationNo)) {
            return RestMessage.newInstance(false, "202", "请输入站台号", null);
        }

        Criteria criteriaStation = Criteria.forClass(StationCfg.class);
        String[] stationNos = new String[]{StationTypeConstant.STATION_TYP_70, StationTypeConstant.STATION_TYP_71};
        criteriaStation.restrictionBuilder().in(StationCfg::getStationType, stationNos).eq("stationNo", stationNo).build();
        List<StationCfg> stationCfgs = stationCfgService.findByCriteria(criteriaStation);
        StationCfg stationCfg = stationCfgs.stream().findFirst().orElse(null);
        if (ObjectUtils.isEmpty(stationCfg)) {
            return RestMessage.newInstance(false, "201", "站台信息未配置，请检查", null);
        }
        if (ObjectUtils.nullSafeEquals(stationCfg.getIsLock(), 1)) {
            return RestMessage.newInstance(false, "站台 [" + stationNo + "]已锁定");
        }
        if (Optional.ofNullable(stationCfg.getMaxCachePosition()).orElse(0) <= 0) {
            return RestMessage.newInstance(false, "201", "站台缓存配置错误，请检查", null);
        }

        WhArea whArea = routeInterfaceService.getAreaByAreaNo(stationCfg.getAreaNo());
        if (ObjectUtils.isEmpty(whArea)) {
            return RestMessage.newInstance(false, "201", stationCfg.getAreaNo() + "区域不存在", null);
        }
       /* List<WhAreaDirection> whAreaDirectionList = routeInterfaceService.findStartAreaOrEndArea(Collections.singletonList(stationCfg.getAreaNo()));
        if (ObjectUtils.isEmpty(whAreaDirectionList)) {
            return RestMessage.newInstance(false, "201", stationCfg.getStationNo() + "区域方向不存在", null);
        }*/
        return RestMessage.newInstance(true, "200", "验证通过", null);
    }

    @Override
    public Page<GoodsInfoVO> findShelvesPage(ShelvesPage page) throws Exception {
        List<GoodsInfoVO> goodsInfoList = containerInfoDetailMapper.findCallPalletNo(page.getPalletLocation(), null);
        AssertUtils.isNotEmpty(goodsInfoList, "货架为空");
        List<GoodsInfoVO> goodsInfoVOS = goodsInfoService.getGoodsInfo(goodsInfoList);
        if (!Objects.isNull(page.getItemCode()) && !StringUtils.isEmpty(page.getItemCode())) {
            goodsInfoVOS = goodsInfoVOS.stream().filter(x -> !Objects.isNull(x.getItemCode()) && x.getItemCode().contains(page.getItemCode())).collect(Collectors.toList());
        }
        if (StrUtil.isNotBlank(page.getItemName())) {
            goodsInfoVOS = goodsInfoVOS.stream().filter(item -> StrUtil.isNotBlank(item.getItemName()) && item.getItemName().contains(page.getItemName())).collect(Collectors.toList());
        }
        if (StrUtil.isNotBlank(page.getLotNo())) {
            goodsInfoVOS = goodsInfoVOS.stream().filter(item -> StrUtil.isNotBlank(item.getManufacturerLotNum()) && item.getManufacturerLotNum().contains(page.getLotNo())).collect(Collectors.toList());
        }
        List<GoodsInfoVO> list = ListPageUtils.startPage(goodsInfoVOS, page.getPageNum(), page.getPageSize());
        Page<GoodsInfoVO> goodsInfoPage = new Page<>();
        goodsInfoPage.setList(list);
        goodsInfoPage.setTotalCount(goodsInfoVOS.size());
        goodsInfoPage.setPageNum(page.getPageNum());
        goodsInfoPage.setPageSize(page.getPageSize());
        goodsInfoPage.setPageCount(CollectionUtil.isEmpty(list) ? 0 : list.size());
        return goodsInfoPage;
    }

    @Override
    @InterfaceMethod(key = "callOutShelves", name = "调出货架(PC->EIS)", type = InterfaceType.Receive)
    @Transactional(rollbackFor = Exception.class)
    @TxTransaction(rollbackFor = Exception.class)
    public void callOutShelves(CallOutShelvesDTO dto) throws Exception {
        AssertUtils.isNotEmpty(dto.getStationNo(), "请输入站台号");
        List<StationCfg> stationCfgList = stationCfgMapper.findByMap(MapUtils
                .put(StationCfg::getStationNo, dto.getStationNo()).getMap(), StationCfg.class);
        StationCfg stationCfg = stationCfgList.stream().findFirst().orElseThrow(() -> new PrologException("站台配置不存在"));
        GoodsInfoDTO goodsInfoDTO = dto.getParams();
        Criteria criteria = new Criteria(ContainerInfo.class);
        criteria.restrictionBuilder().eq(ContainerInfo::getContainerNo, goodsInfoDTO.getPalletNo()).build();
        containerInfoMapper.updateMapByCriteria(MapUtils.put(ContainerInfo::getTaskType, ContainerTaskTypeConstants.PALLET_ADJUST).getMap(), criteria);
        List<PalletInfo> palletInfoList = palletInfoMapper.findByMap(MapUtils
                .put(PalletInfo::getPalletNo, goodsInfoDTO.getPalletNo()).getMap(), PalletInfo.class);
        Criteria criteria1 = new Criteria(LocationCfg.class);
        criteria1.restrictionBuilder().in(LocationCfg::getType, Arrays.asList(3, 4)).build();
        List<String> collect = locationCfgService.findByCriteria(criteria1).stream().map(LocationCfg::getAreaNo).collect(Collectors.toList());
        List<ContainerLocationVo> locationByContainerList = routeFeignService.findLocationByContainerList(Arrays.asList(goodsInfoDTO.getPalletNo()));
        ContainerLocationVo containerLocationVo = locationByContainerList.get(0);
        List<CarryTask> carryTaskListByContainerList = routeFeignService.findCarryTaskListByContainerList(Arrays.asList(goodsInfoDTO.getPalletNo()));
        if (CollectionUtil.isNotEmpty(carryTaskListByContainerList) || !StrUtil.equals(containerLocationVo.getSourceArea(), containerLocationVo.getTargetArea())
                || !collect.contains(containerLocationVo.getCurrentArea())) {
            throw new PrologException("当前容器正在任务中");
        }
        if (CollectionUtil.isEmpty(palletInfoList)) {
            CarryTask carryTask = new CarryTask();
            carryTask.setId(StrUtil.uuid());
            carryTask.setPalletNo(goodsInfoDTO.getPalletNo());
            carryTask.setContainerNo(goodsInfoDTO.getPalletNo());
            carryTask.setTaskType(LocationConstants.PATH_TASK_TYPE_CARRY);
            carryTask.setEndRegion(stationCfg.getAreaNo());
            carryTask.setCreateTime(new Date());
            carryTask.setBusinessType(String.valueOf(BaseTaskTypeConstants.MOVE_TYPE)); //todo 类型确认
            carryTask.setTaskRemark("货位调整调出至站台");
            carryTask.setPriority(99);
            routeFeignService.createBatchCarry(Arrays.asList(carryTask));
        } else {
            PalletInfo palletInfo = palletInfoList.stream().findFirst().orElseThrow(() -> new PrologException("货架信息不存在"));
            palletMoveExecuteService.palletArriveIng(goodsInfoDTO.getPalletNo(), palletInfo.getSubArea(),
                    stationCfg.getAreaNo(), goodsInfoDTO.getPlanes(), stationCfg.getAngle(),
                    ContainerTaskTypeConstants.PALLET_ADJUST);
        }
    }

    @Override
    public GoodsInfoVO querySourcePalletLocationInfo(QueryLocationDto dto) throws Exception {
        AssertUtils.isNotEmpty(dto.getPalletLocation(), "请输入原货位");
        List<GoodsInfoVO> goodsInfoDtoList = containerInfoDetailMapper.findCallPalletNo(null, dto.getPalletLocation());
        List<GoodsInfoVO> goodsInfo = goodsInfoService.getGoodsInfo(goodsInfoDtoList);
        return goodsInfo.isEmpty() ? null : goodsInfo.get(0);
    }

    @Override
    public GoodsInfoVO queryTargetPalletLocationInfo(QueryLocationDto dto) {
        AssertUtils.isNotEmpty(dto.getInPalletLocation(), "请输入目标货位");
        List<PalletLocation> palletLocations = palletLocationMapper.findByMap(com.prolog.framework.utils.MapUtils.put("palletLocation", dto.getInPalletLocation()).getMap(), PalletLocation.class);
        String containerNo = dto.getInPalletLocation();
        if (CollectionUtil.isNotEmpty(palletLocations)) {
            containerNo = palletLocations.get(0).getPalletNo();
        }
        GoodsInfoVO goodsInfoVO = new GoodsInfoVO();
        goodsInfoVO.setPalletLocation(dto.getInPalletLocation());
        goodsInfoVO.setContainerNo(containerNo);
        List<ContainerInfoDetail> containerInfoDetails = containerInfoDetailMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerSubNo", dto.getInPalletLocation()).getMap(), ContainerInfoDetail.class);
        BigDecimal qty = containerInfoDetails.isEmpty() ? BigDecimal.ZERO : containerInfoDetails.get(0).getQty();
        goodsInfoVO.setStoreQty(qty);
        return goodsInfoVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmAdjust(ConfirmAdjustDto dto) throws Exception {
        List<ContainerInfoDetail> sourcePalletLocations = containerInfoDetailMapper.findByMap(MapUtils.put(ContainerInfoDetail::getContainerSubNo, dto.getSourcePalletLocation()).getMap(), ContainerInfoDetail.class);
        Assert.notEmpty(sourcePalletLocations, "原货位无商品，请重新输入！");
        Assert.isTrue(sourcePalletLocations.get(0).getQty().compareTo(dto.getAdjustQty()) > -1, "调整数量不允许超过原货位数量！");

        List<PalletInfo> palletInfos = palletInfoMapper.findByMap(MapUtils.put(PalletInfo::getPalletNo, dto.getTargetPalletNo()).getMap(), PalletInfo.class);
        if (CollectionUtil.isNotEmpty(palletInfos)) {
            List<PalletLocation> targetPalletLocations = palletLocationMapper.findByMap(MapUtils.put(PalletLocation::getPalletLocation, dto.getTargetPalletLocation()).getMap(), PalletLocation.class);

            Assert.notEmpty(targetPalletLocations, "不存在的目的货位，请重新输入！");

            List<ContainerInfoDetail> containerInfoDetailList = containerInfoDetailMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerSubNo", dto.getTargetPalletLocation()).getMap(), ContainerInfoDetail.class);
           /* List<ContainerInfoDetail> containerInfoDetailList = containerInfoDetailMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerSubNo", dto.getTargetPalletLocation())
                    .put("itemId",dto.getItemId()).put("lotId",dto.getLotId()).getMap(), ContainerInfoDetail.class);
    */
            GoodsInfoVO goodsInfoVO = new GoodsInfoVO();
            goodsInfoVO.setGoodsId(dto.getGoodsId());
            goodsInfoVO.setLotId(dto.getLotId());
            //List<GoodsInfoVO> goodsInfo = goodsInfoService.getGoodsInfo(Lists.newArrayList(goodsInfoVO));

            List<GoodsInfoVO> goodsInfo = new ArrayList<>();
            GoodsInfoVO infoVO = new GoodsInfoVO();
            goodsInfo.add(infoVO);
            //已经存在此商品
            BigDecimal qty = BigDecimal.ZERO;
            if (containerInfoDetailList.isEmpty()) {
                ItemSyncVO itemInfo = itemService.queryItemMst(Arrays.asList(dto.getGoodsId())).get(0);
                PalletInfo palletInfo = palletInfos.get(0);
                if (StrUtil.isBlank(palletInfo.getPalletType()) || StrUtil.equals(palletInfo.getPalletType(), "0")) {
                    palletInfo.setPalletType(itemInfo.getItemHealthCategory());
                    palletInfoMapper.update(palletInfo);
                }
                //校验同货架同品必须同批
                List<ContainerInfoDetail> containerInfoDetailList1 = containerInfoDetailMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerNo", dto.getTargetPalletNo()).put("itemId", dto.getGoodsId()).getMap(), ContainerInfoDetail.class);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(containerInfoDetailList1)) {
                    long count = containerInfoDetailList1.stream().filter(item -> !StrUtil.equals(item.getLotId(), dto.getLotId())).count();
                    AssertUtils.isNotTrue(count > 0, String.format("货架%s已存在此商品，批次必须相同", dto.getTargetPalletNo()));
                }

                Assert.notEmpty(goodsInfo, "商品信息查询为空！");
                ContainerInfoDetail containerInfoDetail = new ContainerInfoDetail();
                containerInfoDetail.setContainerNo(dto.getTargetPalletNo());
                containerInfoDetail.setContainerSubNo(dto.getTargetPalletLocation());
                containerInfoDetail.setExpireDate(goodsInfo.get(0).getBatchExpiredDate());
                containerInfoDetail.setProdDate(goodsInfo.get(0).getBatchProductionDate());
                containerInfoDetail.setVolume(goodsInfo.get(0).getSingleVolume());
                containerInfoDetail.setAreaType(AreaTypeConstant.AGV_CL);
                containerInfoDetail.setCreateTime(LocalDateTime.now());
                containerInfoDetail.setIsLock(0);
                containerInfoDetail.setTaskType(0);
                containerInfoDetail.setQty(dto.getAdjustQty());
                containerInfoDetail.setLockQty(BigDecimal.ZERO);
                containerInfoDetail.setItemId(sourcePalletLocations.get(0).getItemId());
                containerInfoDetail.setLotId(sourcePalletLocations.get(0).getLotId());
                containerInfoDetail.setPackId(sourcePalletLocations.get(0).getPackId());
                containerInfoDetail.setOwnerId(sourcePalletLocations.get(0).getOwnerId());

                BigDecimal singleVolume = null == itemInfo.getUomList() || itemInfo.getUomList().isEmpty() ? BigDecimal.ZERO
                        : itemInfo.getUomList().get(0).getVolume().divide(itemInfo.getUomList().get(0).getConversionRate(), 2, BigDecimal.ROUND_DOWN);
                containerInfoDetail.setSingleVolume(singleVolume);
                containerInfoDetail.setVolume(singleVolume.multiply(containerInfoDetail.getQty()));
                ContainerInfo containerInfo = containerInfoMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerNo", dto.getTargetPalletNo()).getMap(), ContainerInfo.class).stream().findFirst().orElse(null);
                if (Objects.isNull(containerInfo)) {
                    containerInfo = new ContainerInfo();
                    containerInfo.setContainerType(ContainerInfoTypeConstants.GOODS_SHELF);
                    containerInfo.setContainerNo(dto.getTargetPalletNo());
                    containerInfo.setAreaType(AreaTypeConstant.AGV_CL);
                    containerInfo.setIsLock(0);
                    containerInfo.setTaskType(ContainerTaskTypeConstants.PALLET_ADJUST);
                    containerInfo.setCreateTime(LocalDateTime.now());
                    containerInfo.setWarehouseArea(WmsCarryTaskInCode.AGVL.getCode());
                    containerInfoMapper.save(containerInfo);
                }
                containerInfoDetailMapper.save(containerInfoDetail);
                containerStoreChangeService.saveContainerStoreChange(dto.getTargetPalletNo(), dto.getTargetPalletLocation(), goodsInfo.get(0), ContainerTaskTypeConstants.PALLET_ADJUST, BigDecimal.ZERO, dto.getAdjustQty(), "货位调整增加库存", PrologStringUtils.newGUID());
            } else {
                //根据现场调整，除中药大类不能混货架其他可以混货架
                /*ItemSyncVO itemInfo = itemService.queryItemMst(Arrays.asList(dto.getGoodsId())).stream().findFirst().orElseThrow(() -> new PrologException(String.format("未查询到物料id%s的物料信息", dto.getGoodsId())));
                List<PalletInfo> targetPalletInfoList = palletInfoMapper.findByMap(com.prolog.framework.utils.MapUtils.put("palletNo", dto.getTargetPalletNo()).getMap(), PalletInfo.class);
                if (StrUtil.isNotBlank(targetPalletInfoList.get(0).getPalletType()) && !targetPalletInfoList.get(0).getPalletType().equals("0")) {
                    Assert.isTrue(itemInfo.getItemHealthCategory().equals(targetPalletInfoList.get(0).getPalletType()), "货架商品大类不一致，请重新分配货架！");
                }*/
                ContainerInfoDetail containerInfoDetail = containerInfoDetailList.get(0);
                AssertUtils.isNotTrue(!StrUtil.equals(containerInfoDetail.getItemId(), dto.getGoodsId())
                                || !StrUtil.equals(containerInfoDetail.getLotId(), dto.getLotId())
                        , "目标容器货位必须同品同批");
                //校验同货架同品必须同批
                List<ContainerInfoDetail> containerInfoDetailList1 = containerInfoDetailMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerNo", dto.getTargetPalletNo()).put("itemId", dto.getGoodsId()).getMap(), ContainerInfoDetail.class);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(containerInfoDetailList1)) {
                    long count = containerInfoDetailList1.stream().filter(item -> !StrUtil.equals(item.getLotId(), dto.getLotId())).count();
                    AssertUtils.isNotTrue(count > 0, String.format("货架%s已存在此商品，批次必须相同", dto.getTargetPalletNo()));
                }

                qty = containerInfoDetail.getQty();
                containerInfoDetail.setQty(containerInfoDetail.getQty().add(dto.getAdjustQty()));
                containerInfoDetail.setVolume(containerInfoDetail.getSingleVolume().multiply(containerInfoDetail.getQty()));
                goodsInfoVO = new GoodsInfoVO();
                goodsInfoVO.setGoodsId(dto.getGoodsId());
                goodsInfoVO.setLotId(dto.getLotId());
                goodsInfoVO.setPackId(containerInfoDetail.getPackId());
                goodsInfoVO.setOwnerId(containerInfoDetail.getOwnerId());
                containerStoreChangeService.saveContainerStoreChange(dto.getTargetPalletNo(), dto.getTargetPalletLocation(), goodsInfoVO, ContainerTaskTypeConstants.PALLET_ADJUST, qty, dto.getAdjustQty(), "货位调整增加库存", PrologStringUtils.newGUID());
                containerInfoDetailMapper.update(containerInfoDetail);
//                storeService.storeChange(containerInfoDetail.getContainerNo(), containerInfoDetail.getContainerSubNo(),
//                        goodsInfo.get(0), dto.getAdjustQty(), "货位调整增加库存", ContainerTaskTypeConstants.PALLET_ADJUST, null, AreaTypeConstant.AGV_CL);
            }
//            storeService.storeChange(dto.getSourcePalletNo(), dto.getSourcePalletLocation(),
//                    goodsInfoVO, dto.getAdjustQty().negate(), "货位调整扣减库存！", ContainerTaskTypeConstants.PALLET_ADJUST, null, AreaTypeConstant.AGV_CL);
        } else {
            List<ContainerInfoDetail> containerInfoDetailList = containerInfoDetailMapper.findByMap(MapUtils.put(ContainerInfoDetail::getContainerNo, dto.getTargetPalletNo()).getMap(), ContainerInfoDetail.class);
            AssertUtils.isNotTrue(CollectionUtil.isEmpty(containerInfoDetailList), "目标容器库存信息不存在");
            ContainerInfoDetail containerInfoDetail = containerInfoDetailList.get(0);
            BigDecimal qty = BigDecimal.ZERO;
            if (StrUtil.equals(containerInfoDetail.getItemId(), "-1")) {
                containerInfoDetail.setQty(dto.getAdjustQty());
                containerInfoDetail.setItemId(dto.getGoodsId());
                containerInfoDetail.setLotId(dto.getLotId());
                containerInfoDetail.setPackId(dto.getPackId());
                containerInfoDetail.setOwnerId(dto.getOwnerId());
                containerInfoDetail.setIsLock(0);
                containerInfoDetail.setLockQty(BigDecimal.ZERO);
//                ItemSyncVO itemInfo = itemService.queryItemMst(Arrays.asList(dto.getGoodsId())).get(0);
//                BigDecimal singleVolume = null == itemInfo.getUomList() || itemInfo.getUomList().isEmpty() ? BigDecimal.ZERO
//                        : itemInfo.getUomList().get(0).getVolume().divide(itemInfo.getUomList().get(0).getConversionRate(), 2, BigDecimal.ROUND_DOWN);
//                containerInfoDetail.setMaxVolume(itemInfo.getPalletStdQuantity());
//                containerInfoDetail.setSingleVolume(singleVolume);
//                containerInfoDetail.setVolume(singleVolume.multiply(containerInfoDetail.getQty()));

                ContainerInfo containerInfo = containerInfoMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerNo", dto.getTargetPalletNo()).getMap(), ContainerInfo.class).stream().findFirst().orElseThrow(() -> new PrologException(String.format("容器%s没有库存信息", dto.getTargetPalletNo())));
                containerInfo.setContainerType(ContainerInfoTypeConstants.GOODS_PALLET);
                containerInfo.setAreaType(AreaTypeConstant.AGV_CL);
                containerInfo.setWarehouseArea(WmsCarryTaskInCode.AGVL.getCode());
                containerInfoMapper.update(containerInfo);

            } else {
                AssertUtils.isNotTrue(!StrUtil.equals(containerInfoDetail.getItemId(), dto.getGoodsId())
                                || !StrUtil.equals(containerInfoDetail.getLotId(), dto.getLotId())
                        , "目标容器货位必须同品同批");
                qty = containerInfoDetail.getQty();
                containerInfoDetail.setQty(containerInfoDetail.getQty().add(dto.getAdjustQty()));
//                containerInfoDetail.setVolume(containerInfoDetail.getSingleVolume().multiply(containerInfoDetail.getQty()));
            }
            GoodsInfoVO goodsInfoVO = new GoodsInfoVO();
            goodsInfoVO.setGoodsId(dto.getGoodsId());
            goodsInfoVO.setLotId(dto.getLotId());
            goodsInfoVO.setPackId(containerInfoDetail.getPackId());
            goodsInfoVO.setOwnerId(containerInfoDetail.getOwnerId());
            containerStoreChangeService.saveContainerStoreChange(dto.getTargetPalletNo(), dto.getTargetPalletLocation(), goodsInfoVO, ContainerTaskTypeConstants.PALLET_ADJUST, qty, dto.getAdjustQty(), "货位调整增加库存", PrologStringUtils.newGUID());
            containerInfoDetailMapper.update(containerInfoDetail);
        }

        ContainerInfoDetail containerInfoDetail = containerInfoDetailMapper.findByMap(com.prolog.framework.utils.MapUtils.put("containerSubNo", dto.getSourcePalletLocation())
                .put("itemId", dto.getGoodsId()).put("lotId", dto.getLotId()).getMap(), ContainerInfoDetail.class).stream().findFirst().orElseThrow(() -> new PrologException("未查询到原容器库存信息"));
        if (containerInfoDetail.getQty().compareTo(dto.getAdjustQty()) < 0) {
            throw new PrologException(String.format("原货位%s库存不足", dto.getSourcePalletLocation()));
        }
        containerInfoDetail.setQty(containerInfoDetail.getQty().subtract(dto.getAdjustQty()));
        if (!StrUtil.equals(containerInfoDetail.getContainerNo(), containerInfoDetail.getContainerSubNo())) {
            containerInfoDetail.setVolume(containerInfoDetail.getSingleVolume().multiply(containerInfoDetail.getQty()));
        }
        GoodsInfoVO goodsInfoVO = new GoodsInfoVO();
        goodsInfoVO.setGoodsId(dto.getGoodsId());
        goodsInfoVO.setLotId(dto.getLotId());
        goodsInfoVO.setPackId(containerInfoDetail.getPackId());
        goodsInfoVO.setOwnerId(containerInfoDetail.getOwnerId());
        containerStoreChangeService.saveContainerStoreChange(dto.getSourcePalletNo(), dto.getSourcePalletLocation(), goodsInfoVO, ContainerTaskTypeConstants.PALLET_ADJUST, containerInfoDetail.getQty(), dto.getAdjustQty().negate(), "货位调整扣减库存", PrologStringUtils.newGUID());

        if (containerInfoDetail.getQty().compareTo(BigDecimal.ZERO) == 0) {
            ContainerInfo containerInfo = containerInfoMapper.findByMap(MapUtils.put(ContainerInfo::getContainerNo, dto.getSourcePalletNo()).getMap(), ContainerInfo.class).stream().findFirst().orElseThrow(() -> new PrologException(String.format("容器%s没有库存信息", dto.getTargetPalletNo())));
            if (StrUtil.equals(containerInfoDetail.getContainerNo(), containerInfoDetail.getContainerSubNo())) {
                containerInfoDetail.setItemId(BasePropertyConstants.EMPTY_PALLET_PILE);
                containerInfoDetail.setLotId(BasePropertyConstants.EMPTY_PALLET_PILE);
                containerInfoDetail.setOwnerId(BasePropertyConstants.EMPTY_PALLET_PILE);
                containerInfoDetail.setPackId(BasePropertyConstants.EMPTY_PALLET_PILE);
                containerInfoDetail.setQty(BigDecimal.ONE);
                containerInfo.setContainerType(ContainerInfoTypeConstants.EMPTY_PALLET);
                containerInfoMapper.update(containerInfo);
                containerInfoDetailMapper.update(containerInfoDetail);
            } else {
                containerInfoDetailMapper.deleteById(containerInfoDetail.getId(), ContainerInfoDetail.class);
                final List<ContainerInfoDetail> containerInfoDetailList = containerInfoDetailMapper.findByMap(MapUtils.put(ContainerInfoDetail::getContainerNo, dto.getSourcePalletNo()).getMap(), ContainerInfoDetail.class);
                if (CollectionUtils.isEmpty(containerInfoDetailList)) {
                    containerInfoMapper.deleteById(containerInfo.getId(), ContainerInfo.class);
                }
            }
        } else {
            containerInfoDetailMapper.update(containerInfoDetail);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @TxTransaction(rollbackFor = Exception.class)
    public RestMessage<String> returnGoodsShelf(ReturnGoodsShelfDto dto) throws Exception {
        StationCfg stationCfg = stationCfgMapper.findByMap(MapUtils.put(StationCfg::getStationNo, dto.getStationNo()).getMap(), StationCfg.class).get(0);

        List<PalletInfo> palletInfos = palletInfoMapper.findByMap(MapUtils.put(PalletInfo::getPalletNo, dto.getPalletNo()).getMap(), PalletInfo.class);
        Criteria criteria = new Criteria(ContainerInfo.class);
        criteria.restrictionBuilder().eq(ContainerInfo::getContainerNo, dto.getPalletNo()).build();
        containerInfoMapper.updateMapByCriteria(MapUtils.put(ContainerInfo::getTaskType, ContainerTaskTypeConstants.IDLE).getMap(), criteria);

        if (CollectionUtil.isNotEmpty(palletInfos)) {
            List<PalletInfo> palletInfoList = palletInfoMapper.findByMap(MapUtils.put(PalletInfo::getSubArea, stationCfg.getAreaNo())
                    .put(PalletInfo::getStatus, BaseConstant.NO).put(PalletInfo::getPalletNo, dto.getPalletNo()).getMap(), PalletInfo.class);

            if (palletInfoList.isEmpty()) {
                return RestMessage.newInstance(false, "201", "当前站台区域无货架或者货架正在移动中，货架号：" + dto.getPalletNo(), null);
            }

            palletMoveExecuteService.palletLeaveIng(dto.getPalletNo(), palletInfoList.get(0).getSubArea(),
                    BaseTaskTypeConstants.HJ_TYPE, palletInfoList.get(0).getPalletType());
        } else {

            String targetAreaNo = sysParamMapper
                    .findByMap(MapUtils.put(SysParam::getParamNo, WmsConstants.DEFAULT_TP_AREA_NO).getMap(), SysParam.class).stream()
                    .findFirst().orElse(new SysParam()).getParamValue();

            if (Objects.isNull(targetAreaNo)) {
                throw new BizException(String.format("货位存储区为空"));
            }

            //判断托盘是否发往叠盘机（空货架邬库存）
            ContainerInfo containerInfo = containerInfoMapper.findByCriteria(criteria).stream().findFirst().orElseThrow(() -> new PrologException("未查询到容器信息"));
            if (containerInfo.getContainerType() == ContainerInfoTypeConstants.EMPTY_PALLET) {
                emptyContainerTaskService.save(dto.getPalletNo(), LayerEnum.TWO, WmsCarryTaskInCode.AGVL);
                wmsContainerStatusUpdateService.execute(WmsContainerStatusUpdateDto.builder()
                        .containerCode(dto.getPalletNo())
                        .warehouseId("901884530611326976")
                        .enterpriseId("900356013474058240").build());
            } else {
                CarryTask carryTask = new CarryTask();
                carryTask.setId(StrUtil.uuid());
                carryTask.setPalletNo(dto.getPalletNo());
                carryTask.setContainerNo(dto.getPalletNo());
                carryTask.setTaskType(LocationConstants.PATH_TASK_TYPE_CARRY);
                carryTask.setEndRegion(targetAreaNo);
                carryTask.setCreateTime(new Date());
                carryTask.setBusinessType(String.valueOf(BaseTaskTypeConstants.MOVE_TYPE)); //todo 类型确认
                carryTask.setTaskRemark("货位调整回库");
                carryTask.setPriority(99);
                routeFeignService.createBatchCarry(Arrays.asList(carryTask));
            }
        }
        return RestMessage.newInstance(true, "200", "货架归还成功", null);
    }

    private void layerCheck(List<CargoInformationDTO> cargoInformationList) {
        List<Integer> layerList = ListHelper.select(cargoInformationList, CargoInformationDTO::getLayer);
        layerList = layerList.stream().distinct().collect(Collectors.toList());
        layerList.sort(Comparator.comparingInt(p -> p));
        if (layerList.get(0) != 1) {
            throw new PrologException("层级必须从1开始");
        }
        if (layerList.size() != layerList.get(layerList.size() - 1)) {
            throw new PrologException("层级间不能间断");
        }
    }

    private void xCheck(List<CargoInformationDTO> cargoInformationList) {
        List<Integer> x = ListHelper.select(cargoInformationList, CargoInformationDTO::getX);
        x = x.stream().distinct().collect(Collectors.toList());
        x.sort(Comparator.comparingInt(p -> p));
        if (x.get(0) != 1) {
            throw new PrologException("列级必须从1开始");
        }
        if (x.size() != x.get(x.size() - 1)) {
            throw new PrologException("列级间不能间断");
        }
    }

}
