package com.shkj.wms.scheduled;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.shkj.common.constant.RedisConstant;
import com.shkj.common.core.domain.Result;
import com.shkj.common.enums.HttpStatus;
import com.shkj.common.utils.DateUtils;
import com.shkj.common.utils.StringUtils;
import com.shkj.plc.sdk.device.PLCReadAndWrite;
import com.shkj.plc.sdk.device.PlcOperate;
import com.shkj.system.service.ISysParameterService;
import com.shkj.wms.bo.BasePunchRecordAddBo;
import com.shkj.wms.domain.BasePoint;
import com.shkj.wms.domain.BasePunch;
import com.shkj.wms.domain.BasePunchRecord;
import com.shkj.wms.domain.WcsPlcProperty;
import com.shkj.wms.mapper.*;
import com.shkj.wms.plc.PlcInit;
import com.shkj.wms.service.IBasePointService;
import com.shkj.wms.service.IBasePunchRecordService;
import com.shkj.wms.service.IBasePunchService;
import com.shkj.wms.service.IWcsPlcPropertyService;
import com.shkj.wms.third.rcs.RCSUtil;
import com.shkj.wms.third.rcs.enums.RCSTaskTypeEnum;
import com.shkj.wms.utils.TunnelTaskUtil;
import com.shkj.wms.vo.BasePunchRecordVo;
import com.shkj.wms.bo.*;
import com.shkj.wms.constants.ParameterConstants;
import com.shkj.wms.domain.*;
import com.shkj.wms.enums.TaskStatusEnum;
import com.shkj.wms.enums.TaskTypeEnum;
import com.shkj.wms.service.*;
import com.shkj.wms.service.impl.BaseLocationServiceImpl;
import com.shkj.wms.utils.JsonUtil;
import com.shkj.wms.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ScheduledTasks {

    @Resource
    IBusinDataTaskService iBusinDataTaskService;

    @Resource
    IBusinDataTaskGoodsService iBusinDataTaskGoodsService;

    @Resource
    IBaseDeriveService iBaseDeriveService;

    @Resource
    IBaseLocationService iBaseLocationService;

    @Resource
    IPutInOutStorageService iPutInOutStorageService;

    @Resource
    ISysParameterService sysParameterService;

    @Resource
    RCSUtil rcsUtil;

    @Autowired
    ISysStockDetailService iSysStockDetailService;
    @Resource
    IBasePunchService iBasePunchService;
    @Autowired
    BaseLocationServiceImpl baseLocationService;
    @Resource
    IBasePointService iBasePointService;

    @Resource
    BaseLocationPlcMapper baseLocationPlcMapper;

    @Resource
    BaseLocationMapper baseLocationMapper;

    @Autowired
    IBasePunchRecordService iBasePunchRecordService;

    @Autowired
    IWcsPlcPropertyService iWcsPlcPropertyService;

    @Autowired
    ISysParameterService isysParameterService;

    @Resource
    BusinDpsContainerRecordMapper businDpsContainerRecordMapper;

    @Resource
    RedisTemplate redisTemplate;

    @Resource
    BasePointDeviceMapper basePointDeviceMapper;

    @Autowired
    private IBaseStorageService iBaseStorageService;

    @Resource
    SysStockDetailMapper sysStockDetailMapper;

    @Autowired
    AllocationTasksUtils allocationTasksUtils;

    @Autowired
    IWcsPlcConnectService iWcsPlcConnectService;

    @Resource
    private TunnelTaskUtil tunnelTaskUtil;

    @Resource
    IBusinEnptyContainerService iBusinEnptyContainerService;
    @Resource
    IBaseGoodsDataService iBaseGoodsDataService;

    @Resource
    IBaseBarcodesInService iBaseBarcodesInService;
    @Resource
    IBaseBarcodesOutService iBaseBarcodesOutService;

    @Resource
    BusinDataTaskMapper businDataTaskMapper;


    @Resource
    PlcInit plcInit;

    //根据派生获取
    private Long getLocationByDervie(String vehicheModel, String color) {
        // 根据条码信息获取派生信息
        BaseDeriveQueryBo deriveQueryBo = new BaseDeriveQueryBo();
        deriveQueryBo.setVehicheModel(vehicheModel);
        deriveQueryBo.setColor(color);
        BaseDerive derive = iBaseDeriveService.getBaseDeriveBybarcodes(deriveQueryBo);
        Long deriveId = derive.getId();
        return deriveId;
    }

    //呼叫AGC
    public Result<Boolean> callAGV(Long taskId, int taskType, List<String> points) {


        AGVMoveBo moveBo = new AGVMoveBo();
        moveBo.setTaskId(taskId);
        moveBo.setTaskType(taskType);
        moveBo.setPoints(points);
        Result<Boolean> booleanResult = rcsUtil.moveByAGV(moveBo);
        return booleanResult;
    }

    public Result<Boolean> callAGV(Long taskId, int taskType, List<String> points, String agvno) {


        AGVMoveBo moveBo = new AGVMoveBo();
        moveBo.setTaskId(taskId);
        moveBo.setTaskType(taskType);
        moveBo.setPoints(points);
        moveBo.setRobotId(agvno);
        Result<Boolean> booleanResult = rcsUtil.moveByAGV(moveBo);
        return booleanResult;
    }

    //    @PostConstruct
//    @Scheduled(cron = "0/3 * * * * ? ")
  //  @Scheduled(fixedRate = 200)
    public void task() {
        log.info("开始获取需要执行的任务");
        //获取待下发任务数据
        BusinTaskQueryBo taskQueryBo = new BusinTaskQueryBo();
        List<BusinDataTaskVo> businDataTaskVos = new ArrayList<>();
       /* taskQueryBo.setTaskType("0");
        List<BusinDataTaskVo> businDataTaskVo0 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo0);*/

        taskQueryBo.setTaskType("1");
        List<BusinDataTaskVo> businDataTaskVo1 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo1);
        taskQueryBo.setTaskType("2");
        List<BusinDataTaskVo> businDataTaskVo2 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo2);
        taskQueryBo.setTaskType("3");
        List<BusinDataTaskVo> businDataTaskVo3 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo3);
        taskQueryBo.setTaskType("4");
        List<BusinDataTaskVo> businDataTaskVo4 = iBusinDataTaskService.selectOutBusinDataTask(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo4);
        taskQueryBo.setTaskType("5");
        List<BusinDataTaskVo> businDataTaskVo5 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo5);
        taskQueryBo.setTaskType("7");
        List<BusinDataTaskVo> businDataTaskVo7 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo7);
        taskQueryBo.setTaskType("10");
        List<BusinDataTaskVo> businDataTaskVo10 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo10);
        taskQueryBo.setTaskType("11");
        List<BusinDataTaskVo> businDataTaskVo11 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo11);
        taskQueryBo.setTaskType("12");
        List<BusinDataTaskVo> businDataTaskVo12 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo12);
        taskQueryBo.setTaskType("15");
        List<BusinDataTaskVo> businDataTaskVo15 = iBusinDataTaskService.selectOutBusinDataTask(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo15);
        taskQueryBo.setTaskType("17");
        List<BusinDataTaskVo> businDataTaskVo17 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo17);
//        taskQueryBo.setTaskType("18");
//        List<BusinDataTaskVo> businDataTaskVo18 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
//        businDataTaskVos.addAll(businDataTaskVo18);
        taskQueryBo.setTaskType("19");
        List<BusinDataTaskVo> businDataTaskVo19 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo19);
        taskQueryBo.setTaskType("21");
        List<BusinDataTaskVo> businDataTaskVo21 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo21);
        taskQueryBo.setTaskType("22");
        List<BusinDataTaskVo> businDataTaskVo22 = iBusinDataTaskService.selectBusinDataTask1(taskQueryBo);
        businDataTaskVos.addAll(businDataTaskVo22);

        for (BusinDataTaskVo businDataTaskVo : businDataTaskVos) {
            doTask(businDataTaskVo);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    void doTask(BusinDataTaskVo businDataTaskVo) {

        String taskType = businDataTaskVo.getTaskType();
        Long taskId = businDataTaskVo.getId();
        Long containerId = businDataTaskVo.getContainerId();

        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();

        //任务类型 0 正常入库 1维修异常 2扫码异常  3入库冲孔 4 正常出库 5紧急出库 6越库出库 7手工入库 8呼叫空治具
        if (taskType.equals("0") || taskType.equals("7")) {
            //获取要出入库的条码信息
            List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(businDataTaskVo.getId());
//            if (ObjectUtils.isEmpty(businDataTaskGoodsVos)) {
//                continue;
//            }
            BusinDataTaskGoodsVo goodsVo = businDataTaskGoodsVos.get(0);
            String vehicheModel = goodsVo.getVehicheModel();
            String color = goodsVo.getColor();
            String startPoint = businDataTaskVo.getTaskPath();
            String goodsNo = goodsVo.getGoodsNo();

            //是否有紧急出库，如果有紧急出库则优先紧急出库
//                BusinDataTaskOutVo businDataTaskOutVo = checkOutTaskData(goodsVo.getGoodsNo());
//                if (businDataTaskOutVo !=null){
//                    String outTaskType = businDataTaskOutVo.getTaskType();
//                    String outPoint ="";
//                    if (outTaskType.equals(TaskTypeEnum.urgent_out.getValue())){
//                        String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.urgency_out_point);
//                        this.updateOutTask(businDataTaskOutVo,businDataTaskVo,tepairGroup);
//                        break;
//                    }
//
//
//                    if (outTaskType.equals(TaskTypeEnum.normal_out.getValue())){
//                        String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.Manual_drop_point);
//                        this.updateOutTask(businDataTaskOutVo,businDataTaskVo,tepairGroup);
//                        break;
//                    }
//
//                }
            //查询获取每个货区的比例
//                BaseStorageQueryListBo baseStorageQueryListBo = new BaseStorageQueryListBo();
//
//                Map dataScopeBranchmap = new HashMap();
//                dataScopeBranchmap.put("dataScopeBranch",2);
//                baseStorageQueryListBo.setBranchParams(dataScopeBranchmap);
//                List<BaseStorageVo> baseStorageVos = iBaseStorageService.queryBaseStorageListA(baseStorageQueryListBo);
//
//                List<Map<String ,Double>> redisallotlist = (List<Map<String, Double>>) redisTemplate.opsForValue().get("redisallotlist");
//                List<Pair<String, Double>> olist=new ArrayList<>();
//
//                List<Pair<String, Double>> allotlist = new ArrayList<>();
//                for (BaseStorageVo basestorageVo: baseStorageVos) {
//                    allotlist.add(new ImmutablePair<>(basestorageVo.getStorageCode(), Double.valueOf(basestorageVo.getExtend1())));
//                }
//                if (redisallotlist==null || redisallotlist.size()!=allotlist.size()){
//                    List<Map> maps=new ArrayList<>();
//                    allotlist.stream().forEach(e->{
//                        Map map= new HashMap();
//                        map.put(e.getKey(),e.getValue());
//                        maps.add(map);
//                    });
//                    redisTemplate.opsForValue().set("redisallotlist",maps);
//                    allocationTasksUtils.WeightRandomStrategy(allotlist);
//                }
//                if(redisallotlist!=null&&redisallotlist.size()==allotlist.size()){
//                    for (Map map: redisallotlist
//                    ) {
//                        for (Object k:map.keySet()){
//                            olist.add(new ImmutablePair<String, Double>(String.valueOf(k), (Double) map.get(k)));
//                        }
//                    }
//
//                    List<Pair<String, Double>> pairList = allotlist.stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toList());
//                    List<Pair<String, Double>> rediscollect = olist.stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toList());
//                    if (!rediscollect.equals(pairList)){
//                        List<Map> maps=new ArrayList<>();
//                        allotlist.stream().forEach(e->{
//                            Map map= new HashMap();
//                            map.put(e.getKey(),e.getValue());
//                            maps.add(map);
//                        });
//                        redisTemplate.opsForValue().set("redisallotlist",maps);
//                        allocationTasksUtils.WeightRandomStrategy(allotlist);
//                    }
//                }
//                //拿到按比例分配的库区
//                String randome = allocationTasksUtils.randome();


            BasePointDeviceVo pointDevice = new BasePointDeviceVo();
            BasePointDeviceVo basePointDeviceVo = new BasePointDeviceVo();
            //立库输送线接驳点-入
            String toLocation = "";
            int agvTaskType = 0;
            BusinTaskExeBo exeBo = new BusinTaskExeBo();
            Long plcId = null;
            Long stkPlcId = null;

            String agvno = null;
            //获取派生
            // TODO 由于逻辑区域换成与车型相匹配，不是与派生匹配，所以注释掉
//                Long dervieId = getLocationByDervie(vehicheModel, color);


            String randome = "P01";
            if (businDataTaskVo.getWarehouseType().equals("1")) {
                randome = "P01";
            } else if (businDataTaskVo.getWarehouseType().equals("2")) {
                randome = "P02";
            }
            //从Redis中获取randome，如果没有设置为P01
            //randome = ObjectUtils.isEmpty(redisTemplate.opsForValue().get("randome").toString()) ? "P01" : redisTemplate.opsForValue().get("randome").toString();
            //randome = "P02";
            if ("P01".equals(randome)) {
                //根据车型分配库位  先判断该任务是否已经分配了货位
                Result<BaseLocationVo> locationVoResult = null;
                if (ObjectUtils.isEmpty(businDataTaskVo.getToRow())) {
                    //   locationVoResult = iBaseLocationService.assignEmptyLocation(vehicheModel, color,DateUtils.getDate(),businDataTaskGoodsVos);
                    // TODO: 2024/6/28  zjx
                    locationVoResult = iBaseLocationService.assignEmptyLocationByStock(goodsNo, vehicheModel, DateUtils.getDate(), businDataTaskGoodsVos);

                }

                if (ObjectUtils.isNotEmpty(locationVoResult) && locationVoResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                    //如果是P01则设置randome为P02
                    redisTemplate.opsForValue().set("randome", "P02");
                    BaseLocationVo locationVo = locationVoResult.getData();
                    String tunnel = locationVo.getTunnel();
                    Long locationId = locationVo.getId();
                    for (BusinDataTaskGoodsVo businDataTaskGoodsVo : businDataTaskGoodsVos) {
                        businDataTaskGoodsVo.setLocationId(locationId);
                    }
                    //回填任务的入行高列
                    businDataTaskVo.setBatch(DateUtils.getDate());
                    businDataTaskVo.setToColumn(locationVo.getLocationColumn());
                    businDataTaskVo.setToLayer(locationVo.getLayer());
                    businDataTaskVo.setToRow(locationVo.getLocationRow());
                    businDataTaskVo.setTunnel(tunnel);
                    //获取货位对应的巷道及巷道对应的设备信息
                    pointQueryBo.setTunnel(tunnel);
                    pointQueryBo.setDirection("0");
                    basePointDeviceVo = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo).get(0);

                    if (basePointDeviceVo != null) {
                        toLocation = basePointDeviceVo.getPointNo();
                        //输送线PLCID
                        plcId = Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id));
                    }

                    //获取巷道对应的堆垛机信息
                    pointQueryBo.setDevType("1");
                    BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
                    stkPlcId = baseDevicePlcVo.getPlcId();

                    exeBo.setTaskCode(taskId);
                    exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
                    exeBo.setContainerId(containerId);
                    exeBo.setBaseLocationVo(locationVo);
                    exeBo.setTransNo("1");
                    exeBo.setTransQual("1");

                    //根据取货时的的点位拿到对应的交互点用作取货完成点
                    agvTaskType = Integer.valueOf(basePointDeviceVo.getIsDown());
                    if (businDataTaskVo.getTaskType().equals("7")) {
                        if (businDataTaskVo.getTaskPath().contains("manMade")) {
                            agvTaskType = RCSTaskTypeEnum.TO_B_AND_PUT.getValue();
                            List agvtaskType = new ArrayList();
                            agvtaskType.add("15");
                            agvtaskType.add("12");
                            BusinDataTask manMade01 = iBusinDataTaskService.getOne(new LambdaQueryWrapper<BusinDataTask>()
                                    .in(BusinDataTask::getTaskType, agvtaskType)
                                    .eq(BusinDataTask::getContainerId, businDataTaskVo.getContainerId())
                                    .eq(BusinDataTask::getTaskStatus, "2")
                                    .orderByDesc(BusinDataTask::getId)
                                    .last("limit 1"));
                            if (ObjectUtils.isNotEmpty(manMade01)) {
                                agvno = manMade01.getAgvNo();
                            }
                        } else if (businDataTaskVo.getTaskPath().contains("Artificial")) {
                            agvTaskType = RCSTaskTypeEnum.TO_B_AND_PUT.getValue();
                            String idArr = redisTemplate.opsForValue().get(RedisConstant.Replenishment).toString();
                            String[] idArrs = idArr.split("_");
                            agvno = idArrs[1];
                        }
                    }
                }
                if (ObjectUtils.isNotEmpty(locationVoResult) && locationVoResult.getCode() == HttpStatus.ERROR.getCode()) {
                    //如果是P02则设置randome为P01
                    redisTemplate.opsForValue().set("randome", "P01");
                    String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_in01);
                    pointQueryBo.setGroupNo(tepairGroup);
                    BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
                    toLocation = pointDeviceout.getPointNo();
                    agvTaskType = Integer.valueOf(pointDeviceout.getIsDown());
                    exeBo.setTaskCode(taskId);
                    exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
                    exeBo.setContainerId(containerId);
                    exeBo.setTransNo("1");
                    exeBo.setTransQual("1");
                }

            }
            if ("P02".equals(randome)) {
                //如果是P02则设置randome为P01
                redisTemplate.opsForValue().set("randome", "P01");
                String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_in01);
                pointQueryBo.setGroupNo(tepairGroup);
                BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
                toLocation = pointDeviceout.getPointNo();
                agvTaskType = Integer.valueOf(pointDeviceout.getIsDown());
                exeBo.setTaskCode(taskId);
                exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
                exeBo.setContainerId(containerId);
                exeBo.setTransNo("1");
                exeBo.setTransQual("1");
            }


            List<String> points = new ArrayList<>();
            points.add(startPoint);

            String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point);
            BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
            pointQueryBoup.setGroupNo(tepairGroup);

            pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);
            if (!businDataTaskVo.getTaskType().equals("7")) {
                points.add(pointDevice.getHandshakePoint());
            }

            points.add(toLocation);
            Map<String, String> snPointMap = new HashMap<>(3);
            snPointMap.put("1", startPoint);
            if (!businDataTaskVo.getTaskType().equals("7")) {
                snPointMap.put("2", pointDevice.getHandshakePoint());
                snPointMap.put("3", toLocation);
            } else {
                snPointMap.put("2", toLocation);
            }


            businDataTaskVo.setPoints(JsonUtil.toJSONString(snPointMap));
            businDataTaskVo.setIsDown(String.valueOf(agvTaskType));
            //呼叫AGV
            Result<Boolean> booleanResult = new Result<>();
            if (businDataTaskVo.getTaskType().equals("7")) {
                booleanResult = rcsUtil.callAGV(taskId, agvTaskType, points, businDataTaskVo.getToRow(), agvno);
            } else {
                booleanResult = rcsUtil.callAGV(taskId, agvTaskType, points, businDataTaskVo.getToRow());
                log.error("入库呼叫AGV任务号:" + taskId + "   结果:" + booleanResult.getCode() + "返回信息:" + booleanResult.getMsg());
            }
            if (booleanResult.getCode() == HttpStatus.ERROR.getCode()) {
                BusinDataTask businDataTask = new BusinDataTask();
                businDataTask.setId(businDataTaskVo.getId());
                businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                iBusinDataTaskService.updateById(businDataTask);
                return;
            }

            //呼叫AGV成功
            if (booleanResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                businDataTaskVo.setTaskPath(toLocation);
                businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());

                //生成入库单
                if (randome.equals("P01")) {
                    Result<String> stringResult = iPutInOutStorageService.exeTaskPutinStorage(exeBo);

                    //生成入库单成功
                    if (stringResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                        businDataTaskVo.setTransId(stringResult.getData());
                    } else {
                        businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
                        businDataTaskVo.setExceptionMsg("生成入库单失败");
                    }
                }

            }
//                else {
//                    if (redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId)==null){
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,0);
//                    }
//                    Long a=Long.valueOf(String.valueOf(redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId)));
//
//                    businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
//                    businDataTaskVo.setExceptionMsg(booleanResult.getMsg());
//                    if (a<3L){
//                        long l = a + 1;
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,l);
//                    }else {
//                        businDataTaskVo.setTaskStatus("-2");
//                    }
//                }
            //立库输送线PLCID
            businDataTaskVo.setDpsNoOne(plcId);
            //巷道堆垛机PLCID
            businDataTaskVo.setDpsNoTwo(stkPlcId);
            iBusinDataTaskService.updateById(BeanUtil.toBean(businDataTaskVo, BusinDataTask.class));

        }
        else if (taskType.equals("2")) {
            Long plcId = 0L;
            Long stkPlcId = 0L;
            Boolean NUMBER = true;
            //维修异常 呼叫AGV
            //获取起始点位
            String startPoint = businDataTaskVo.getTaskPath();
            //查询维修地点是否有空闲
            String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.scanexc_group);
//                String tmpPoint = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point_tmp);

            pointQueryBo.setGroupNo(tepairGroup);
            BasePointDeviceVo basePointDeviceVo = null;
            List<BasePointDeviceVo> basePointDeviceVos = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
            List<String> points = new ArrayList<>();
            points.add(startPoint);
            Map<String, String> snPointMap = new HashMap<>(3);
            snPointMap.put("1", startPoint);
            //获取机械手上报点
            String tepairGroupin = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point);
            BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
            pointQueryBoup.setGroupNo(tepairGroupin);
            BasePointDeviceVo pointDevice = new BasePointDeviceVo();
            pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);
            points.add(pointDevice.getHandshakePoint());
            snPointMap.put("2", pointDevice.getHandshakePoint());
            BaseLocationVo locationVo = null;
            BusinTaskExeBo exeBo = new BusinTaskExeBo();
            // TODO 中科  测试 需要还原         已还原
            System.out.println("  测试 需要还原     已还原");
            //无空闲区 分配异常区库位
//                if (basePointDeviceVos.size() ==0) {
//                    NUMBER=false;
//
//                    if (businDataTaskVo.getWarehouseType().equals("2")) {
//                        String tepairGroup1 = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_in01);
//                        pointQueryBo.setGroupNo(tepairGroup1);
//                        BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
//                        basePointDeviceVo = pointDeviceout;
//                    } else {
//                        //异常区ID
//                        Long abnormalArea =Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.abnormal_area));
//                        List<BaseLocationVo> baseLocationVos = baseLocationMapper.getLocationByAreaId(abnormalArea);
//                        if (baseLocationVos.size() > 0) {
//                            locationVo = baseLocationVos.get(0);
//                        }
//                        businDataTaskVo.setToColumn(locationVo.getLocationColumn());
//                        businDataTaskVo.setToLayer(locationVo.getLayer());
//                        businDataTaskVo.setToRow(locationVo.getLocationRow());
//                        //获取货位及巷道；
//                        String tunnel = locationVo.getTunnel();
//                        businDataTaskVo.setTunnel(tunnel);
//                        pointQueryBo=new BasePointDeviceQueryBo();
//                        pointQueryBo.setTunnel(tunnel);
//                        pointQueryBo.setDirection("0");
//                        basePointDeviceVos = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
//                        if (basePointDeviceVos.size() > 0) {
//                            basePointDeviceVo = basePointDeviceVos.get(0);
//                            basePointDeviceVo.setPlcId(Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id)));
//
//                        }
//                        //获取巷道对应的堆垛机信息
//                        pointQueryBo.setDevType("1");
//                        BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
//                        stkPlcId = baseDevicePlcVo.getPlcId();
//                        List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(businDataTaskVo.getId());
////                    exeBo.setTaskCode(taskId);
////                    exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
////                    exeBo.setContainerId(containerId);
////                    exeBo.setBaseLocationVo(locationVo);
////                    exeBo.setTransNo("1");
////                    exeBo.setTransQual("1");
//                    }
//                }else {
            basePointDeviceVo = basePointDeviceVos.get(0);
//                }

            //plcId =basePointDeviceVo.getPlcId();
//                String toPointNo = basePointDeviceVo.getPointNo();
//                snPointMap.put("3",toPointNo);
//                points.add(toPointNo);
//                int  agvTaskType = Integer.valueOf(basePointDeviceVo.getIsDown());
            System.out.println("中科  测试 需要删除");
            // TODO 中科  测试 需要删除
            String toPointNo = basePointDeviceVo.getPointNo();
            ;
            int agvTaskType = 33;
            snPointMap.put("3", "XX");
            points.add("XX");
            snPointMap.put("4", "XX");
            points.add("XX");
            snPointMap.put("5", toPointNo);
            points.add(toPointNo);
            // TODO 中科  测试 需要删除
            businDataTaskVo.setPoints(JsonUtil.toJSONString(snPointMap));
            businDataTaskVo.setIsDown(String.valueOf(agvTaskType));
            Result<Boolean> booleanResult = new Result<>();
            //呼叫AGV
            if (StringUtils.isNotEmpty(businDataTaskVo.getAgvNo())) {
                booleanResult = callAGV(taskId, agvTaskType, points, businDataTaskVo.getAgvNo());
            } else {
                booleanResult = callAGV(taskId, agvTaskType, points);
            }
            if (booleanResult.getCode() == HttpStatus.ERROR.getCode()) {
                BusinDataTask businDataTask = new BusinDataTask();
                businDataTask.setId(businDataTaskVo.getId());
                businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                businDataTask.setTaskPath(toPointNo);
                iBusinDataTaskService.updateById(businDataTask);
                return;
            }
            //呼叫AGV成功
            if (booleanResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                businDataTaskVo.setTaskPath(toPointNo);
                // TODO 中科  测试 需要还原
                System.out.println("中科  测试 需要还原");
//                    //把占用的点位改为已占用
                if (NUMBER) {
                    BasePoint basePoint = iBasePointService.getById(basePointDeviceVo.getPointId());
                    basePoint.setIsOccupy("1");
                    iBasePointService.updateById(basePoint);
                }
//                    //更改货位状态为4已分配
//                    if (ObjectUtils.isNotEmpty(locationVo)){
//                        BaseLocation baseLocation = iBaseLocationService.getById(locationVo.getId());
//                        baseLocation.setLocationStatus("4");
//                        iBaseLocationService.updateById(baseLocation);
//                    }
                // TODO 中科  测试 需要还原
                // TODO 中科  测试 需要还原
            }
//                else{
//                    if (redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId)==null){
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,0);
//                    }
//                    Long a=Long.valueOf(String.valueOf(redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId)));
//                    businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
//                    businDataTaskVo.setExceptionMsg(booleanResult.getMsg());
//                    if (a<3L){
//                        long l = a + 1;
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,l);
//                    }else {
//                        businDataTaskVo.setTaskStatus("-2");
//                    }
//                }
            // TODO 测试注释  要打开
//                //更新入库条码表状态为异常
            List<BaseBarcodesIn> barcodesIns = new ArrayList<>();
            List<BusinDataTaskGoodsVo> goodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(taskId);
            for (BusinDataTaskGoodsVo goodsVo : goodsVos) {
                BaseBarcodesIn baseBarcodesIn = iBaseBarcodesInService.getOne(new LambdaQueryWrapper<BaseBarcodesIn>()
                        .eq(BaseBarcodesIn::getQrCode, goodsVo.getQrCode())
                );
                baseBarcodesIn.setInStatus("4");
                baseBarcodesIn.setInDate(DateUtils.getDate());
                barcodesIns.add(baseBarcodesIn);
            }
            iBaseBarcodesInService.saveOrUpdateBatch(barcodesIns);

            businDataTaskVo.setDpsNoOne(plcId);
            businDataTaskVo.setDpsNoTwo(stkPlcId);
        }
        else if (taskType.equals("1")) {
            Long plcId = 0L;
            Long stkPlcId = 0L;
            Boolean NUMBER = true;
            //维修异常 呼叫AGV
            //获取起始点位
            String startPoint = businDataTaskVo.getTaskPath();
            //查询维修地点是否有空闲
            String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.tepair_group);
            String tmpPoint = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point_tmp);

            pointQueryBo.setGroupNo(tepairGroup);
            BasePointDeviceVo basePointDeviceVo = null;
            List<BasePointDeviceVo> basePointDeviceVos = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
            List<String> points = new ArrayList<>();
            points.add(startPoint);
            Map<String, String> snPointMap = new HashMap<>(3);
            snPointMap.put("1", startPoint);
            //获取机械手上报点
            String tepairGroupin = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point);
            BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
            pointQueryBoup.setGroupNo(tepairGroupin);
            BasePointDeviceVo pointDevice = new BasePointDeviceVo();
            pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);
            points.add(pointDevice.getHandshakePoint());
            snPointMap.put("2", pointDevice.getHandshakePoint());
            BaseLocationVo locationVo = null;
            BusinTaskExeBo exeBo = new BusinTaskExeBo();
            // TODO 中科  测试 需要还原         已还原
//                System.out.println("中科  测试 需要还原         已还原");
//                //无空闲区 分配异常区库位
//                if (basePointDeviceVos.size() ==0) {
//                    NUMBER=false;
//
//                    if (businDataTaskVo.getWarehouseType().equals("2")) {
//                        String tepairGroup1 = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_in01);
//                        pointQueryBo.setGroupNo(tepairGroup1);
//                        BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
//                        basePointDeviceVo = pointDeviceout;
//                    } else {
//                        //异常区ID
//                        Long abnormalArea = Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.abnormal_area));
//                        List<BaseLocationVo> baseLocationVos = baseLocationMapper.getLocationByAreaId(abnormalArea);
//                        if (baseLocationVos.size() > 0) {
//                            locationVo = baseLocationVos.get(0);
//                        }
//                        businDataTaskVo.setToColumn(locationVo.getLocationColumn());
//                        businDataTaskVo.setToLayer(locationVo.getLayer());
//                        businDataTaskVo.setToRow(locationVo.getLocationRow());
//                        //获取货位及巷道；
//                        String tunnel = locationVo.getTunnel();
//                        businDataTaskVo.setTunnel(tunnel);
//                        pointQueryBo = new BasePointDeviceQueryBo();
//                        pointQueryBo.setTunnel(tunnel);
//                        pointQueryBo.setDirection("0");
//                        basePointDeviceVos = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
//                        if (basePointDeviceVos.size() > 0) {
//                            basePointDeviceVo = basePointDeviceVos.get(0);
//                            basePointDeviceVo.setPlcId(Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id)));
//
//                        }
//                        //获取巷道对应的堆垛机信息
//                        pointQueryBo.setDevType("1");
//                        BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
//                        stkPlcId = baseDevicePlcVo.getPlcId();
//                        List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(businDataTaskVo.getId());
//                        exeBo.setTaskCode(taskId);
//                        exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
//                        exeBo.setContainerId(containerId);
//                        exeBo.setBaseLocationVo(locationVo);
//                        exeBo.setTransNo("1");
//                        exeBo.setTransQual("1");
//                    }
//                }
//                else {
//                    basePointDeviceVo = basePointDeviceVos.get(0);
//                }
//                plcId =basePointDeviceVo.getPlcId();
//                String toPointNo = basePointDeviceVo.getPointNo();
//                snPointMap.put("3",toPointNo);
//                int  agvTaskType = Integer.valueOf(basePointDeviceVo.getIsDown());
//                if(toPointNo.contains("P_Lane")){
//                    // TODO 人车分流相关  需要修改对应的任务类型为 33   需要添加在RCS地图上添加对应的点位 abnormal_wait_point
//                    String abnormalWaitPintGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.abnormalWaitPint);
//                    BasePointDeviceQueryBo abnormalWaitPintBo = new BasePointDeviceQueryBo();
//                    abnormalWaitPintBo.setGroupNo(abnormalWaitPintGroup);
//                    BasePointDeviceVo abnormalWaitPintDeviceVo = basePointDeviceMapper.selectBasePointByGroupno(abnormalWaitPintBo);
//                    points.add(abnormalWaitPintDeviceVo.getPointNo());
//                    points.add(abnormalWaitPintDeviceVo.getPointNo());
//                    snPointMap.put("3",abnormalWaitPintDeviceVo.getPointNo());
//                    snPointMap.put("4",abnormalWaitPintDeviceVo.getPointNo());
//                    snPointMap.put("5",toPointNo);
//                    agvTaskType = Integer.valueOf(abnormalWaitPintDeviceVo.getIsDown());
//                }else{
//                    snPointMap.put("3",toPointNo);
//                }
            // TODO 中科  测试 需要还原
            System.out.println("中科  测试 需要删除");
            // TODO 中科  测试 需要删除
            String toPointNo = "KW18";
            int agvTaskType = 24;
            snPointMap.put("3", toPointNo);
            points.add(toPointNo);
            // TODO 中科  测试 需要删除

            businDataTaskVo.setPoints(JsonUtil.toJSONString(snPointMap));
            businDataTaskVo.setIsDown(String.valueOf(agvTaskType));
            Result<Boolean> booleanResult = new Result<>();
            //呼叫AGV
            if (StringUtils.isNotEmpty(businDataTaskVo.getAgvNo())) {
                booleanResult = callAGV(taskId, agvTaskType, points, businDataTaskVo.getAgvNo());
            } else {
                booleanResult = callAGV(taskId, agvTaskType, points);
            }
            if (booleanResult.getCode() == HttpStatus.ERROR.getCode()) {
                BusinDataTask businDataTask = new BusinDataTask();
                businDataTask.setId(businDataTaskVo.getId());
                businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                businDataTask.setTaskPath(toPointNo);
                iBusinDataTaskService.updateById(businDataTask);
                return;
            }
            //呼叫AGV成功
            if (booleanResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                businDataTaskVo.setTaskPath(toPointNo);
                // TODO 中科  测试 需要还原
//                    System.out.println("中科  测试 需要还原");
////                    把占用的点位改为已占用
//                    if (NUMBER) {
//                        BasePoint basePoint = iBasePointService.getById(basePointDeviceVo.getPointId());
//                        basePoint.setIsOccupy("1");
//                        iBasePointService.updateById(basePoint);
//                    }
//                    //更改货位状态为4已分配
//                    if (ObjectUtils.isNotEmpty(locationVo)){
//                        BaseLocation baseLocation = iBaseLocationService.getById(locationVo.getId());
//                        baseLocation.setLocationStatus("4");
//                        iBaseLocationService.updateById(baseLocation);
//                        //生成入库单成功
//                    }
//                    if(!NUMBER) {
//                        Result<String> stringResult = iPutInOutStorageService.exeTaskPutinStorage(exeBo);
//
//                        if (stringResult.getCode() == HttpStatus.SUCCESS.getCode()) {
//                            businDataTaskVo.setTransId(stringResult.getData());
//                        } else {
//                            businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
//                            businDataTaskVo.setExceptionMsg("生成入库单失败");
//                        }
//                    }
//                     TODO 中科  测试 需要还原
            }
//                else{
//                    if (redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId)==null){
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,0);
//                    }
//                    Long a=Long.valueOf((String)redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId));
//                    businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
//                    businDataTaskVo.setExceptionMsg(booleanResult.getMsg());
//                    if (a<3L){
//                        long l = a + 1;
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,l);
//                    }else {
//                        businDataTaskVo.setTaskStatus("-2");
//                    }
//                }
            // TODO 测试注释  要打开
//                //更新入库条码表状态为异常
            List<BaseBarcodesIn> barcodesIns = new ArrayList<>();
            List<BusinDataTaskGoodsVo> goodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(taskId);
            for (BusinDataTaskGoodsVo goodsVo : goodsVos) {
                BaseBarcodesIn baseBarcodesIn = iBaseBarcodesInService.getOne(new LambdaQueryWrapper<BaseBarcodesIn>()
                        .eq(BaseBarcodesIn::getQrCode, goodsVo.getQrCode())
                );
                baseBarcodesIn.setInStatus("4");
                baseBarcodesIn.setInDate(DateUtils.getDate());
                barcodesIns.add(baseBarcodesIn);
            }
            iBaseBarcodesInService.saveOrUpdateBatch(barcodesIns);

            businDataTaskVo.setDpsNoOne(plcId);
            businDataTaskVo.setDpsNoTwo(stkPlcId);
        }
        else if (taskType.equals("3")) {
            Long plcId = 0L;
            Long stkPlcId = 0L;
            Boolean NUMBER = true;
            //需要冲孔，呼叫AGV
            //获取起始点位
            String startPoint = businDataTaskVo.getTaskPath();
            String tmpPoint = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point_tmp);
            //冲孔模式是自动，并且是启用的，并且待冲孔任务小于最大冲孔任务量,，则可以到冲孔，否在到入库
            BasePunchRecordVo basePunchRecordVos = iBasePunchService.selectBasePunchRecord(new BasePunch());
            BasePointDeviceVo basePointDeviceVo = null;
            List<String> points = new ArrayList<>();
            points.add(startPoint);
            Map<String, String> snPointMap = new HashMap<>(3);
            snPointMap.put("1", startPoint);
            //获取机械手上报点
            String tepairGroupin = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point);
            BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
            pointQueryBoup.setGroupNo(tepairGroupin);
            BasePointDeviceVo pointDevice = new BasePointDeviceVo();
            pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);
            points.add(pointDevice.getHandshakePoint());
            snPointMap.put("2", pointDevice.getHandshakePoint());
            BaseLocationVo locationVo = null;

            if (businDataTaskVo.getWarehouseType().equals("2")) {
                NUMBER = false;
                String tepairGroup1 = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_in01);
                pointQueryBo.setGroupNo(tepairGroup1);
                BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
                basePointDeviceVo = pointDeviceout;
            } else {
                if (basePunchRecordVos != null) {
                    Long punchId = basePunchRecordVos.getId();
                    //获取冲孔机设备对用的点位
                    String punchingGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.punching_group);
                    pointQueryBo.setGroupNo(punchingGroup);
                    pointQueryBo.setDevCode(punchId);

                    List<BasePointDeviceVo> tempList = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
                    basePointDeviceVo = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo).get(0);
                    if (tempList.get(0).getPointNo().contains("KW11")) {
                        basePointDeviceVo = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo).get(1);
                    }
                } else {


                    NUMBER = false;
                    //先入待冲孔区
                    Long punchingArea = Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.punching_area));

                    List<BaseLocationVo> baseLocationVos = baseLocationMapper.getLocationByAreaId(punchingArea);
                    if (baseLocationVos.size() > 0) {
                        locationVo = baseLocationVos.get(0);
                    }
                    businDataTaskVo.setToColumn(locationVo.getLocationColumn());
                    businDataTaskVo.setToLayer(locationVo.getLayer());
                    businDataTaskVo.setToRow(locationVo.getLocationRow());
                    //获取货位及巷道；
                    String tunnel = locationVo.getTunnel();
                    businDataTaskVo.setTunnel(tunnel);
//                        Result<BaseLocationVo> baseLocationVoResult = iBaseLocationService.queryById(locationVo.getId());
                    List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(businDataTaskVo.getId());
                    BusinTaskExeBo exeBo = new BusinTaskExeBo();
                    exeBo.setTaskCode(taskId);
                    exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
                    exeBo.setContainerId(containerId);
                    exeBo.setBaseLocationVo(locationVo);
                    exeBo.setTransNo("1");
                    exeBo.setTransQual("1");
                    iPutInOutStorageService.exeTaskPutinStorage(exeBo);
                    //获取巷道对应的立库输送线接驳口
                    pointQueryBo.setTunnel(tunnel);
                    pointQueryBo.setDirection("0");
                    List<BasePointDeviceVo> basePointDeviceVos = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
                    if (basePointDeviceVos.size() > 0) {
                        basePointDeviceVo = basePointDeviceVos.get(0);
                        basePointDeviceVo.setPlcId(Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id)));
                    }

                    //获取巷道对应的堆垛机信息
                    pointQueryBo.setDevType("1");
                    BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
                    stkPlcId = baseDevicePlcVo.getPlcId();
//                    points.add(basePointDeviceVo.getHandshakePoint());
//                    points.add(basePointDeviceVo.getHandshakePoint());
//                    snPointMap.put("3",basePointDeviceVo.getHandshakePoint());
//                    snPointMap.put("4",basePointDeviceVo.getHandshakePoint());

                }
            }
            String toPointNo = "";
            toPointNo = basePointDeviceVo.getPointNo();
            if (basePointDeviceVo != null) {
                plcId = basePointDeviceVo.getPlcId();
            }

            points.add(toPointNo);
            snPointMap.put("3", toPointNo);
//                String toPointNo="KW18";
//                points.add(toPointNo);
//                snPointMap.put("3",toPointNo);
            int agvTaskType;
            if (toPointNo.equals("KW12")) {
                agvTaskType = 24;
            } else {
                agvTaskType = 27;
            }
            // TODO 中科  测试 需要删除
            businDataTaskVo.setPoints(JsonUtil.toJSONString(snPointMap));
            businDataTaskVo.setIsDown(String.valueOf(agvTaskType));
            //呼叫AGV
            Result<Boolean> callAGVResult = callAGV(taskId, agvTaskType, points);
            //下发任务成功
            if (callAGVResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                businDataTaskVo.setTaskPath(toPointNo);
                businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                log.info("任务" + businDataTaskVo.getId() + "修改目的地成功");
                if (toPointNo.equals("KW12")) {
                    //记录冲孔机排队数量
                    Long punchId = basePunchRecordVos.getId();
                    BasePunchRecordAddBo recordAddBo = new BasePunchRecordAddBo();
                    recordAddBo.setTaskCode(taskId);
                    recordAddBo.setPunchNo(punchId);
                    recordAddBo.setAgvNo(businDataTaskVo.getAgvNo());
                    recordAddBo.setIsState("0");
                    iBasePunchRecordService.insertBasePunchRecord(BeanUtil.toBean(recordAddBo, BasePunchRecord.class));
                }

                //更改货位状态为4已分配
                if (ObjectUtils.isNotEmpty(locationVo)) {
                    BaseLocation baseLocation = iBaseLocationService.getById(locationVo.getId());
                    baseLocation.setLocationStatus("4");
                    iBaseLocationService.updateById(baseLocation);
                }
            }
//                else{
//                    //呼叫agv失败超过三次将状态改为-2(临时)
//                    if (redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId)==null){
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,0);
//                    }
//                    Long a=Long.valueOf(String.valueOf(redisTemplate.opsForValue().get(RedisConstant.redisAgvTaskerror+taskId)));
//                    if (a<3L){
//                        long l = a + 1;
//                        redisTemplate.opsForValue().set(RedisConstant.redisAgvTaskerror+taskId,l);
//                    }else {
//                        businDataTaskVo.setTaskStatus("-2");
//                    }
//                    businDataTaskVo.setExceptionMsg(callAGVResult.getMsg());
//                }
            businDataTaskVo.setDpsNoOne(plcId);
            businDataTaskVo.setDpsNoTwo(stkPlcId);
        }
        else if (taskType.equals("4") || taskType.equals("5")) {
            String randome = null;
            //出库任务（正常出库、紧急出库）
            //获取要出库的物料信息
            List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = iBusinDataTaskGoodsService.getTaskGoodsByTaskCodeForOut(businDataTaskVo.getId());

            //拿到按比例分配的库区
            // randome = allocationTasksUtils.randomeout();
            //测试时使用
            randome = "P01";
            //TODO 测试注释  要到开
//                if (randome.equals("P02")) {
            if (businDataTaskVo.getDistinction().equals("2")) {
                int number = businDataTaskGoodsVos.size();
                List<String> goodsno = businDataTaskGoodsVos.stream().map(e -> e.getGoodsNo()).collect(Collectors.toList());
                //根据GoodsNo查看立库是否有库存
                List<SysStockDetail> list = iSysStockDetailService.list(new LambdaQueryWrapper<SysStockDetail>()
                        .in(SysStockDetail::getGoodsNo, goodsno)
                        .eq(SysStockDetail::getQty, "1")
                        .isNull(SysStockDetail::getOutQty)
                        .isNull(SysStockDetail::getLocationId));
                if (ObjectUtils.isEmpty(list)) {
                    businDataTaskVo.setDistinction("1");
                } else {
                    String frompoint = null;
                    String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_out01);
                    pointQueryBo.setGroupNo(tepairGroup);
                    BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
                    frompoint = pointDeviceout.getPointNo();
                    //查询平库出库任务使用状态
                    businDataTaskVo.setTaskStatus(TaskStatusEnum.four_out.getValue());
                    businDataTaskVo.setTaskType(TaskTypeEnum.thirteen_out.getValue());
                    businDataTaskVo.setTaskPath(frompoint);
                }

            }

            //TODO 测试注释  要到开
//                if (!randome.equals("P02")) {
            if (!businDataTaskVo.getDistinction().equals("2")) {
//                    int number = businDataTaskGoodsVos.size();
//                    List<String> goodsno = businDataTaskGoodsVos.stream().map(e -> e.getGoodsNo()).collect(Collectors.toList());
                //根据GoodsNo查看立库是否有库存
//                      log.info("查询立库库存条件：goodsno："+goodsno);
//                    List<SysStockDetail> list = iSysStockDetailService.list(new LambdaQueryWrapper<SysStockDetail>()
//                            .in(SysStockDetail::getGoodsNo, goodsno)
//                            .eq(SysStockDetail::getQty, "1")
//                            .ne(SysStockDetail::getOutQty ,"1" )
//                            .isNotNull(SysStockDetail::getLocationId));
                //查询库存并返回库位信息
                BusinTaskExeBo businTaskExeBo = iBusinDataTaskService.outboundInfo(businDataTaskGoodsVos, String.valueOf(businDataTaskVo.getId()));
                BusinDataTask businDataTask = iBusinDataTaskService.getById(businDataTaskVo.getId());
                if (ObjectUtils.isNotEmpty(businDataTask) && ObjectUtils.isNotEmpty(businDataTask.getFromLayer())) {
                    if (ObjectUtils.isNotEmpty(businTaskExeBo)) {
                        ////生成出库单
                        Result<String> billResult = iPutInOutStorageService.exeTaskPutinStorage(businTaskExeBo);
                        businDataTask.setTransId(billResult.getData());
                    }
                    //添加货位预占和库存预占
                    //获取货位信息
                    BaseLocation location = iBaseLocationService.getById(businDataTask.getLocationId());
                    location.setLocationStatus("4");
                    iBaseLocationService.updateById(location);
                    //根据货位拿到库存信息
                    List<SysStockDetail> sysStockDetailList = sysStockDetailMapper.getStockDetailByLocationId(String.valueOf(location.getId()));
                    sysStockDetailList.stream().forEach(e -> {
                        e.setOutQty(1);
                    });
                    //给库存添加出货预占
                    iSysStockDetailService.updateBatchById(sysStockDetailList);
//                                Result<Boolean> taskResult =new Result<>();
                    Result<Boolean> taskResult = outTask(businDataTask);
                    if (taskResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                        businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                        if (ObjectUtils.isEmpty(redisTemplate.opsForValue().get("outbound:" + businDataTask.getId()))) {
                            redisTemplate.opsForValue().set("outbound:" + businDataTask.getId(), businDataTask.toString());
                        }


                        //拿到库存里的治具编号(不分体的每个保险杠在一个货位一个任务,分体的只有一个任务一个货位所以只随机拿到一个库存信息的治具号就可以)
                        businDataTask.setContainerId(sysStockDetailList.get(0).getContainerCode());
                        if (!"5".equals(businDataTask.getTaskType())) {
                            //根据过点时间更改out表里的状态信息
                            List<BusinDataTaskGoods> businDataTaskGoods = iBusinDataTaskGoodsService.list(new LambdaQueryWrapper<BusinDataTaskGoods>()
                                    .eq(BusinDataTaskGoods::getTaskCode, businDataTask.getId()));
                            BaseBarcodesOut baseBarcodesOutServiceOne = iBaseBarcodesOutService.getOne(new LambdaQueryWrapper<BaseBarcodesOut>()
                                    .eq(BaseBarcodesOut::getTraverseDate, businDataTaskGoods.get(0).getTraverseDate()));
                            baseBarcodesOutServiceOne.setOutStatus("2");
                            iBaseBarcodesOutService.updateById(baseBarcodesOutServiceOne);
                        }

                        //添加巷道任务数和总任务数
                        //tunnelTaskUtil.addOutboundTaskNum(businDataTask.getTunnel());
                    } else {
                        if (ObjectUtils.isEmpty(redisTemplate.opsForValue().get("outbound:" + businDataTask.getId()))) {
                            businDataTask.setExceptionMsg("下发堆垛机失败");
                            businDataTask.setTaskStatus(TaskStatusEnum.err.getValue());
                        } else {
                            businDataTask.setExceptionMsg("已经下发堆垛机");
                            businDataTask.setTaskStatus("-3");
                        }
                    }
                    businDataTask.setDistinction(businDataTaskVo.getDistinction());
                    iBusinDataTaskService.saveOrUpdate(businDataTask);
                    businDataTaskVo = BeanUtil.toBean(businDataTask, BusinDataTaskVo.class);
                } else {
                    businDataTaskVo.setExceptionMsg("当前开放的货位已无当前库存");
                    businDataTaskVo.setTaskStatus("-3");
                }

//                    if (ObjectUtils.isNotEmpty(list)) {
//
//
//                    }else {
//                        businDataTaskVo.setExceptionMsg("当前开放的货位已无当前库存");
//                        businDataTaskVo.setTaskStatus("-3");
//                    }
//                    else {
//                        //如果立库没有库存那么查看平库是否有库存
//                        int numberT = businDataTaskGoodsVos.size();
//                        List<String> goodsnoT = businDataTaskGoodsVos.stream().map(e -> e.getGoodsNo()).collect(Collectors.toList());
//                        //根据GoodsNo查看立库是否有库存
//                        List<SysStockDetail> listT = iSysStockDetailService.list(new LambdaQueryWrapper<SysStockDetail>()
//                                .in(SysStockDetail::getGoodsNo, goodsno)
//                                .eq(SysStockDetail::getQty, "1")
//                                .isNull(SysStockDetail::getOutQty)
//                                .isNull(SysStockDetail::getLocationId));
//                        if (ObjectUtils.isEmpty(listT)) {
//                            businDataTaskVo.setTaskStatus("-3");
//                        }else {
//                            String frompoint = null;
//                            String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_out01);
//                            pointQueryBo.setGroupNo(tepairGroup);
//                            BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
//                            frompoint = pointDeviceout.getPointNo();
//                            businDataTaskVo.setTaskStatus(TaskStatusEnum.four_out.getValue());
//                            businDataTaskVo.setTaskType(TaskTypeEnum.thirteen_out.getValue());
//                            businDataTaskVo.setTaskPath(TaskTypeEnum.thirteen_out.getValue());
//                            businDataTaskVo.setTaskPath(frompoint);
//                        }
//                    }
            }

        }
        else if (taskType.equals("11") || taskType.equals("12")) {
            String agvno = "";
            int AgvType = 0;
            //空治具流向呼叫agv失败后再次呼叫agv
            if (StringUtils.isNotEmpty(businDataTaskVo.getAgvNo())) {
                agvno = businDataTaskVo.getAgvNo();
            }
            Map<String, String> agvMap = JsonUtil.JsonStrToMap(businDataTaskVo.getPoints());
            List<String> AgvPoints = agvMap.entrySet().stream().sorted(Map.Entry.comparingByKey()).map(e -> e.getValue()).collect(Collectors.toList());
            AgvType = Integer.valueOf(businDataTaskVo.getIsDown());
            //呼叫AGV
            AGVMoveBo bo = new AGVMoveBo();
            bo.setPoints(AgvPoints);
            bo.setTaskId(businDataTaskVo.getId());
            bo.setRobotId(agvno);
            bo.setTaskType(AgvType);
            Result<Boolean> result = rcsUtil.moveByAGV(bo);
            if (result.getCode() == HttpStatus.SUCCESS.getCode()) {
                businDataTaskVo.setTaskStatus("1");
                if (businDataTaskVo.getTaskType().equals(TaskTypeEnum.mechainical.getValue())) {
                    //更改空治具流向任务状态为进行中
                    BusinDpscontainerRecord businDpscontainerRecord = businDpsContainerRecordMapper.selectByTaskid(String.valueOf(businDataTaskVo.getId()));
                    businDpscontainerRecord.setIsState("0");
                    businDpsContainerRecordMapper.updateById(businDpscontainerRecord);
                }
                if (StringUtils.isNotEmpty(String.valueOf(businDataTaskVo.getLocationId())) && 0 != businDataTaskVo.getLocationId()) {
                    BaseLocation baseLocation = baseLocationService.getById(businDataTaskVo.getLocationId());
                    baseLocation.setLocationStatus("4");
                    baseLocationService.updateById(baseLocation);
                }
                if (StringUtils.isNotEmpty(businDataTaskVo.getRemark())) {
                    Long oldTaskId = Long.valueOf(businDataTaskVo.getRemark());
                    BusinDataTask oldDataTask = iBusinDataTaskService.getById(oldTaskId);
                    oldDataTask.setTaskStatus("3");
                    oldDataTask.setRemark("已取消，已被任务ID为：" + taskId + " 替代！");
                    iBusinDataTaskService.updateById(oldDataTask);
                    businDataTaskVo.setRemark(String.valueOf(oldDataTask.getId()));

                }
            } else {
                businDataTaskVo.setTaskStatus("5");
                businDataTaskVo.setExceptionMsg(result.getMsg());
            }


        }
        //空治具出库
        else if (taskType.equals("15")) {
            //给堆垛机下命令
            BusinDataTask businDataTask = iBusinDataTaskService.getById(taskId);
            if (ObjectUtils.isNotEmpty(businDataTask)) {
                Result<Boolean> taskResult = outTask(businDataTask);
                if (Result.isOk(taskResult)) {
                    //完成后更新库位状态为空闲
                    BaseLocation location = iBaseLocationService.getById(businDataTask.getLocationId());
                    location.setLocationStatus("0");
                    iBaseLocationService.updateById(location);
                    businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                    /**空治具出库库存信息处理*/
                    iSysStockDetailService.deleteBySysStockByLocationId(businDataTask.getLocationId());
                    //根据货位拿到库存信息
//                        List<SysStockDetail> listT = iSysStockDetailService.list(new LambdaQueryWrapper<SysStockDetail>()
//                                .eq(SysStockDetail::getLocationId,businDataTask.getLocationId()));
//                        if (listT.size()>0&&ObjectUtils.isNotEmpty(listT)){
//                            SysStockDetail sysStockDetail = listT.get(0);
//                            sysStockDetail.setOutQty(1);
//                            sysStockDetail.setQty(sysStockDetail.getQty().subtract(new BigDecimal("1")));
//                            iSysStockDetailService.updateById(sysStockDetail);
//                        }
                }
            }
        }
        else if (taskType.equals("10")) {
            //先判断补货入库是否是一套，如果是入存货区，否则入异常区
            List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = iBusinDataTaskGoodsService.getTaskGoodsByTaskCodeForOut(businDataTaskVo.getId());
            Result<BaseLocationVo> baseLocationVoResult = iBaseLocationService.queryById(businDataTaskVo.getLocationId());
            Result<Boolean> taskResult = outTask(businDataTaskVo);
            if (taskResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                //生成出库明细
                BusinTaskExeBo exeBo = new BusinTaskExeBo();
                exeBo.setTaskCode(businDataTaskVo.getId());
                exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
                exeBo.setBaseLocationVo(baseLocationVoResult.getData());
                exeBo.setTransNo("2");
                exeBo.setTransQual("2");
                ////生成出库单
                Result<String> billResult = iPutInOutStorageService.exeTaskPutinStorage(exeBo);
                businDataTaskVo.setTransId(billResult.getData());
            } else {
                businDataTaskVo.setExceptionMsg("下发堆垛机指令失败");
                businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
            }
        }
        else if (taskType.equals(TaskTypeEnum.abnormal_delivery.getValue())) {
            //异常出库
            //异常区货位
            Long abnormalArea = Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.abnormal_area));
            List<BaseLocationVo> baseLocationVos = baseLocationMapper.getOutLocationByAreaId(abnormalArea);

            List<String> tunnelall = baseLocationVos.stream().map(e -> e.getTunnel()).collect(Collectors.toList());
            //拿到任务数最少的巷道
            String tunnelone = this.quickSort(tunnelall);
            List<BaseLocationVo> tunnelLocation = baseLocationVos.stream().filter(e -> e.getTunnel().equals(tunnelone)).collect(Collectors.toList());
            List<Long> listlocationId = new ArrayList<>();
            //如果是双深位 查看外侧的货位是否有托盘
            for (BaseLocationVo baseLovationVO : tunnelLocation) {
                if (baseLovationVO.getIsDeep().equals("2")) {
                    BaseLocation one = baseLocationService.getOne(new LambdaQueryWrapper<BaseLocation>()
                            .eq(BaseLocation::getRoute, baseLovationVO.getRoute())
                            .eq(BaseLocation::getIsDeep, "1")
                            .eq(BaseLocation::getTunnel, baseLovationVO.getTunnel())
                            .eq(BaseLocation::getAreaId, baseLovationVO.getAreaId()));
                    if (one != null && (one.getLocationStatus().equals("4") || one.getLocationStatus().equals("1"))) {
                        listlocationId.add(baseLovationVO.getId());
                    }
                }
            }
            if (listlocationId.size() > 0) {
                for (int i = 0; i < tunnelLocation.size(); i++) {
                    int number = i;
                    listlocationId.stream().forEach(e -> {
                        if (e.equals(tunnelLocation.get(number).getId())) {
                            tunnelLocation.remove(number);
                        }
                    });
                }
            }

            //根据巷道分配货位
            BaseLocationVo baseLocationVo = tunnelLocation.get(0);

            businDataTaskVo.setFromColumn(baseLocationVo.getLocationColumn());
            businDataTaskVo.setFromLayer(baseLocationVo.getLayer());
            businDataTaskVo.setFromRow(baseLocationVo.getLocationRow());
            //获取货位及巷道；
            String tunnel = baseLocationVo.getTunnel();
            // 获取goods信息并和当前任务关联
            List<BusinDataTaskGoods> goods = new ArrayList<>();
            List<BusinDataTaskGoodsVo> goodsVo = new ArrayList<>();
            List<SysStockDetail> sysStockDetailList = iSysStockDetailService.list(new LambdaQueryWrapper<SysStockDetail>()
                    .eq(SysStockDetail::getLocationId, baseLocationVo.getId())
                    .eq(SysStockDetail::getQty, 1)
                    .isNull(SysStockDetail::getOutQty));
            for (SysStockDetail sysStockDetail : sysStockDetailList) {
                BusinDataTaskGoods taskGoods = new BusinDataTaskGoods();
                BusinDataTaskGoodsVo taskGoodsVo = new BusinDataTaskGoodsVo();
                taskGoods.setQrCode(sysStockDetail.getQrCode());
                taskGoods.setBranchId(sysStockDetail.getBranchId());
                taskGoods.setTaskCode(taskId);
                taskGoods.setCreateTime(DateUtils.getNowDate());
                taskGoods.setGoodsNo(sysStockDetail.getGoodsNo());
                BaseGoodsData baseGoodsData = iBaseGoodsDataService.getBaseGoodsByBarcodes(sysStockDetail.getGoodsNo());
                taskGoods.setIsPunching(baseGoodsData.getIsPunching());
                taskGoods.setIsRepair("1");
                goods.add(taskGoods);

                taskGoodsVo.setQrCode(sysStockDetail.getQrCode());
                taskGoodsVo.setTaskCode(String.valueOf(taskId));
                taskGoodsVo.setGoodsNo(sysStockDetail.getGoodsNo());
                taskGoodsVo.setIsPunching(baseGoodsData.getIsPunching());
                taskGoodsVo.setIsRepair("1");
                goodsVo.add(taskGoodsVo);
            }

            BasePointDeviceQueryBo pointQueryBo1 = new BasePointDeviceQueryBo();
            pointQueryBo1.setTunnel(tunnel);
            pointQueryBo1.setDirection("0");
            //获取巷道对应的堆垛机信息
            pointQueryBo1.setDevType("1");
            BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo1);
            Long stkPlcId = baseDevicePlcVo.getPlcId();
            Long plcId = Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id));

            businDataTaskVo.setDevId(baseLocationVo.getDevId());
            businDataTaskVo.setTunnel(baseLocationVo.getTunnel());
            businDataTaskVo.setDpsNoOne(plcId);
            businDataTaskVo.setDpsNoTwo(stkPlcId);
            //测试使用货位id
            businDataTaskVo.setLocationId(baseLocationVo.getId());
            //拿到库存里的治具编号(不分体的每个保险杠在一个货位一个任务,分体的只有一个任务一个货位所以只随机拿到一个库存信息的治具号就可以)
            businDataTaskVo.setContainerId(sysStockDetailList.get(0).getContainerCode());

            Result<Boolean> taskResult1 = outTask(businDataTaskVo);
            if (taskResult1.getCode() == HttpStatus.SUCCESS.getCode()) {
                businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                //生成出库单
                BusinTaskExeBo exeBo = new BusinTaskExeBo();
                exeBo.setTaskCode(taskId);
                exeBo.setBusinDataTaskGoodsVo(goodsVo);
                exeBo.setBaseLocationVo(baseLocationVo);
                exeBo.setTransNo("2");
                exeBo.setTransQual("2");

                Result<String> billResult = iPutInOutStorageService.exeTaskPutinStorage(exeBo);
                businDataTaskVo.setTransId(billResult.getData());
                //添加货位预占和库存预占
                //获取货位信息
                baseLocationVo.setLocationStatus("4");
                iBaseLocationService.updateById(baseLocationVo);
                //根据货位拿到库存信息
                sysStockDetailList.stream().forEach(e -> {
                    e.setOutQty(1);
                });
                //给库存添加出货预占
                iSysStockDetailService.updateBatchById(sysStockDetailList);
                //添加巷道任务数和总任务数
                tunnelTaskUtil.addOutboundTaskNum(businDataTaskVo.getTunnel());
            } else {
                businDataTaskVo.setExceptionMsg("下发堆垛机指令失败");
                businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
            }
            //新增物料明细
            boolean b = iBusinDataTaskGoodsService.saveOrUpdateBatch(goods);


        }
        else if (taskType.equals(TaskTypeEnum.punching_delivery.getValue())) {}
        else if (taskType.equals(TaskTypeEnum.replenished_in.getValue())) {
            String agvno = null;
            if (businDataTaskVo.getTaskPath().contains("manMade")) {
                List agvtaskType = new ArrayList();
                agvtaskType.add("15");
                agvtaskType.add("12");
                BusinDataTask manMade01 = iBusinDataTaskService.getOne(new LambdaQueryWrapper<BusinDataTask>()
                        .in(BusinDataTask::getTaskType, agvtaskType)
                        .eq(BusinDataTask::getContainerId, businDataTaskVo.getContainerId())
                        .eq(BusinDataTask::getTaskStatus, "2")
                        .orderByDesc(BusinDataTask::getId)
                        .last("limit 1"));
                if (ObjectUtils.isNotEmpty(manMade01)) {
                    agvno = manMade01.getAgvNo();
                }
            } else if (businDataTaskVo.getTaskPath().contains("Artificial")) {
                String idArr = redisTemplate.opsForValue().get(RedisConstant.Replenishment).toString();
                String[] idArrs = idArr.split("_");
                agvno = idArrs[1];
            }

            List<BusinDataTaskGoodsVo> goodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(taskId);
            List<String> goodsNoStr = goodsVos.stream().map(e -> e.getGoodsNo()).collect(Collectors.toList());

            iBusinDataTaskService.runReplenishIn(businDataTaskVo, agvno);
            Result<Boolean> booleanResult = iPutInOutStorageService.reduceInventory(taskId, goodsNoStr);
        }
        else if (taskType.equals("21")) {
            // 冲孔出库
            //待冲孔区货位
            Long abnormalArea = Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.punching_area));
            List<BaseLocationVo> baseLocationVos = baseLocationMapper.getOutLocationByAreaId(abnormalArea);

            List<String> tunnelall = baseLocationVos.stream().map(e -> e.getTunnel()).collect(Collectors.toList());
            //拿到任务数最少的巷道
            String tunnelone = this.quickSort(tunnelall);
            List<BaseLocationVo> tunnelLocation = baseLocationVos.stream().filter(e -> e.getTunnel().equals(tunnelone)).collect(Collectors.toList());
            List<Long> listlocationId = new ArrayList<>();
            //如果是双深位 查看外侧的货位是否有托盘
            for (BaseLocationVo baseLovationVO : tunnelLocation) {
                if (baseLovationVO.getIsDeep().equals("2")) {
                    BaseLocation one = baseLocationService.getOne(new LambdaQueryWrapper<BaseLocation>()
                            .eq(BaseLocation::getRoute, baseLovationVO.getRoute())
                            .eq(BaseLocation::getIsDeep, "1")
                            .eq(BaseLocation::getTunnel, baseLovationVO.getTunnel())
                            .eq(BaseLocation::getAreaId, baseLovationVO.getAreaId()));
                    if (one != null && (one.getLocationStatus().equals("4") || one.getLocationStatus().equals("1"))) {
                        listlocationId.add(baseLovationVO.getId());
                    }
                }
            }
            if (listlocationId.size() > 0) {
                for (int i = 0; i < tunnelLocation.size(); i++) {
                    int number = i;
                    listlocationId.stream().forEach(e -> {
                        if (e.equals(tunnelLocation.get(number).getId())) {
                            tunnelLocation.remove(number);
                        }
                    });
                }
            }
            if (tunnelLocation.size() > 0) {
                //根据巷道分配货位
                BaseLocationVo baseLocationVo = tunnelLocation.get(0);

                businDataTaskVo.setFromColumn(baseLocationVo.getLocationColumn());
                businDataTaskVo.setFromLayer(baseLocationVo.getLayer());
                businDataTaskVo.setFromRow(baseLocationVo.getLocationRow());
                //获取货位及巷道；
                String tunnel = baseLocationVo.getTunnel();
                // 获取goods信息并和当前任务关联
                List<BusinDataTaskGoods> goods = new ArrayList<>();
                List<BusinDataTaskGoodsVo> goodsVo = new ArrayList<>();
                List<SysStockDetail> sysStockDetailList = iSysStockDetailService.list(new LambdaQueryWrapper<SysStockDetail>()
                        .eq(SysStockDetail::getLocationId, baseLocationVo.getId())
                        .eq(SysStockDetail::getQty, 1)
                        .isNull(SysStockDetail::getOutQty));
                for (SysStockDetail sysStockDetail : sysStockDetailList) {
                    BusinDataTaskGoods taskGoods = new BusinDataTaskGoods();
                    BusinDataTaskGoodsVo taskGoodsVo = new BusinDataTaskGoodsVo();
                    taskGoods.setQrCode(sysStockDetail.getQrCode());
                    taskGoods.setBranchId(sysStockDetail.getBranchId());
                    taskGoods.setTaskCode(taskId);
                    taskGoods.setCreateTime(DateUtils.getNowDate());
                    taskGoods.setGoodsNo(sysStockDetail.getGoodsNo());
                    BaseGoodsData baseGoodsData = iBaseGoodsDataService.getBaseGoodsByBarcodes(sysStockDetail.getGoodsNo());
                    taskGoods.setIsPunching(baseGoodsData.getIsPunching());
                    taskGoods.setIsRepair("1");
                    goods.add(taskGoods);

                    taskGoodsVo.setQrCode(sysStockDetail.getQrCode());
                    taskGoodsVo.setTaskCode(String.valueOf(taskId));
                    taskGoodsVo.setGoodsNo(sysStockDetail.getGoodsNo());
                    taskGoodsVo.setIsPunching(baseGoodsData.getIsPunching());
                    taskGoodsVo.setIsRepair("1");
                    goodsVo.add(taskGoodsVo);
                }

                BasePointDeviceQueryBo pointQueryBo1 = new BasePointDeviceQueryBo();
                pointQueryBo1.setTunnel(tunnel);
                pointQueryBo1.setDirection("0");
                //获取巷道对应的堆垛机信息
                pointQueryBo1.setDevType("1");
                BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo1);
                Long stkPlcId = baseDevicePlcVo.getPlcId();
                Long plcId = Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id));

                businDataTaskVo.setDevId(baseLocationVo.getDevId());
                businDataTaskVo.setTunnel(baseLocationVo.getTunnel());
                businDataTaskVo.setDpsNoOne(plcId);
                businDataTaskVo.setDpsNoTwo(stkPlcId);
                //测试使用货位id
                businDataTaskVo.setLocationId(baseLocationVo.getId());
                //拿到库存里的治具编号(不分体的每个保险杠在一个货位一个任务,分体的只有一个任务一个货位所以只随机拿到一个库存信息的治具号就可以)
                businDataTaskVo.setContainerId(sysStockDetailList.get(0).getContainerCode());

                Result<Boolean> taskResult1 = outTask(businDataTaskVo);
                if (taskResult1.getCode() == HttpStatus.SUCCESS.getCode()) {
                    businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                    //生成出库单
                    BusinTaskExeBo exeBo = new BusinTaskExeBo();
                    exeBo.setTaskCode(taskId);
                    exeBo.setBusinDataTaskGoodsVo(goodsVo);
                    exeBo.setBaseLocationVo(baseLocationVo);
                    exeBo.setTransNo("2");
                    exeBo.setTransQual("2");

                    Result<String> billResult = iPutInOutStorageService.exeTaskPutinStorage(exeBo);
                    businDataTaskVo.setTransId(billResult.getData());
                    //添加货位预占和库存预占
                    //获取货位信息
                    baseLocationVo.setLocationStatus("4");
                    iBaseLocationService.updateById(baseLocationVo);
                    //根据货位拿到库存信息
                    sysStockDetailList.stream().forEach(e -> {
                        e.setOutQty(1);
                    });
                    //给库存添加出货预占
                    iSysStockDetailService.updateBatchById(sysStockDetailList);
                    //添加巷道任务数和总任务数
                    tunnelTaskUtil.addOutboundTaskNum(businDataTaskVo.getTunnel());
                } else {
                    businDataTaskVo.setExceptionMsg("下发堆垛机指令失败");
                    businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
                }
                //新增物料明细
                boolean b = iBusinDataTaskGoodsService.saveOrUpdateBatch(goods);
            } else {
                businDataTaskVo.setTaskStatus("-3");
            }
        }
        else if (taskType.equals("22")){
            BusinDataTask businDataTask = iBusinDataTaskService.getById(businDataTaskVo.getId());
            Result<Boolean> taskResult = outTask(businDataTask);
            if (Result.isOk(taskResult)) {
                businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
                if (ObjectUtils.isEmpty(redisTemplate.opsForValue().get("outbound:" + businDataTask.getId()))) {
                    redisTemplate.opsForValue().set("outbound:" + businDataTask.getId(), businDataTask.toString());
                }
            } else {
                if (ObjectUtils.isEmpty(redisTemplate.opsForValue().get("outbound:" + businDataTask.getId()))) {
                    businDataTask.setExceptionMsg("下发堆垛机失败");
                    businDataTask.setTaskStatus(TaskStatusEnum.err.getValue());
                } else {
                    businDataTask.setExceptionMsg("已经下发堆垛机");
                    businDataTask.setTaskStatus("-3");
                }
            }

        }
        log.info("任务号" + businDataTaskVo.getId() + "任务状态" + businDataTaskVo.getTaskStatus() + "点位信息" + businDataTaskVo.getPoints());
        //统一提交任务数据
        iBusinDataTaskService.saveOrUpdate(BeanUtil.toBean(businDataTaskVo, BusinDataTask.class));

    }

    //查看堆垛机是否拥堵
    public Result<Boolean> PLCout(BusinDataTask businDataTask) {
        Long plcId = businDataTask.getDpsNoOne();
        WcsPlcConnect wcsPlcConnect = iWcsPlcConnectService.getById(plcId);
        PlcOperate stkOperate = plcInit.getPlcOperateByIp(wcsPlcConnect.getPlcIp());
        List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(plcId);
        String outAddress = "";
        //根据连接的plcId获取属性
        PLCReadAndWrite plcReadAndWriteD = new PLCReadAndWrite();
        Map<String, Object> pointMap = plcReadAndWriteD.readPlcData(stkOperate, wcsPlcConnect.getPointTables());
        for (WcsPlcProperty wcsPlcProperty : propertyList) {
            if (wcsPlcProperty.getPointType().equals("3") && wcsPlcProperty.getTunnel().equals(businDataTask.getTunnel())) {
                outAddress = wcsPlcProperty.getAddress();
            }
        }
        if (pointMap.containsKey(outAddress) && Boolean.valueOf(pointMap.get(outAddress).toString())) {
            return Result.ok();
        }
        return Result.err();
    }

    // 出库任务
    public Result<Boolean> outTask(BusinDataTask businDataTask) {
        //查看输送线是否拥堵
        Result<Boolean> booleanResult = this.PLCout(businDataTask);
        if (HttpStatus.ERROR.getCode() == booleanResult.getCode()) {
            return Result.err();
        }
        String fromLayer = businDataTask.getFromLayer();
        String fromColumn = businDataTask.getFromColumn();
        String fromRow = businDataTask.getFromRow();
        //获取堆垛机
        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
        pointQueryBo.setDevType("1");
        pointQueryBo.setTunnel(businDataTask.getTunnel());
        BaseDevicePlcVo basePointVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
        Long plcId = basePointVo.getPlcId();

        PlcOperate stkOperate = plcInit.getPlcOperateByIp(basePointVo.getPlcIp());

        List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(plcId);
        String plcTaskId = "";
        String plcToRow = "";
        String plcToColumn = "";
        String plcToLayer = "";
        String plcHs = "";
        String plcCommand = "";
        String plcNulladdress = "";
        String Overonaddress = "";
        for (WcsPlcProperty stkProperty : propertyList) {
            //获取要堆垛机要写入的点位
            if (stkProperty.getPointType().equals("101")) {
                plcTaskId = stkProperty.getAddress();
            } else if (stkProperty.getPointType().equals("104")) {
                plcToRow = stkProperty.getAddress();
            } else if (stkProperty.getPointType().equals("105")) {
                plcToColumn = stkProperty.getAddress();
            } else if (stkProperty.getPointType().equals("106")) {
                plcToLayer = stkProperty.getAddress();
            } else if (stkProperty.getPointType().equals("107")) {
                plcHs = stkProperty.getAddress();
            } else if (stkProperty.getPointType().equals("102")) {
                plcCommand = stkProperty.getAddress();
            } else if (stkProperty.getPointType().equals("12")) {
                plcNulladdress = stkProperty.getAddress();
            } else if (stkProperty.getPointType().equals("4")) {
                Overonaddress = stkProperty.getAddress();
            }
        }
        WcsPlcConnect plcConnect = iWcsPlcConnectService.getById(plcId);
        //根据连接的plcId获取属性
        PLCReadAndWrite plcReadAndWriteD = new PLCReadAndWrite();
        Map<String, Object> pointDMap = plcReadAndWriteD.readPlcData(stkOperate, plcConnect.getPointTables());

        if (pointDMap.containsKey(plcNulladdress) && Boolean.valueOf(pointDMap.get(plcNulladdress).toString()) && (pointDMap.get(Overonaddress).equals("0"))) {
            //请求出库 给堆垛机下命令判断是否 加锁 加锁则返回
            if (ObjectUtils.isNotEmpty(redisTemplate.opsForValue().get("stackerLock:" + businDataTask.getTunnel()))
                    && redisTemplate.opsForValue().get("stackerLock:" + businDataTask.getTunnel()).toString().equals("true")) {
                return Result.err();
            } else {
                redisTemplate.opsForValue().set("stackerLock:" + businDataTask.getTunnel(), "true");
            }
            //给堆垛机写命令
            Map<String, Object> allMap = new HashMap<>(1);
            Map<String, Object> plcTaskIdMap = new HashMap<>(1);
            plcTaskIdMap.put("INTEGER", businDataTask.getId());
            allMap.put(plcTaskId, plcTaskIdMap);
            Map<String, Object> plcToRowMap = new HashMap<>(1);
            plcToRowMap.put("SHORT", fromRow);
            allMap.put(plcToRow, plcToRowMap);
            Map<String, Object> plcToColumnMap = new HashMap<>(1);
            plcToColumnMap.put("SHORT", fromColumn);
            allMap.put(plcToColumn, plcToColumnMap);
            Map<String, Object> plcToLayerMap = new HashMap<>(1);
            plcToLayerMap.put("SHORT", fromLayer);
            allMap.put(plcToLayer, plcToLayerMap);
            Map<String, Object> plcHsMap = new HashMap<>(1);
            plcHsMap.put("SHORT", 2);
            allMap.put(plcHs, plcHsMap);

            Map<String, Object> plcCommandMap = new HashMap<>(1);
            plcCommandMap.put("SHORT", 2);
            allMap.put(plcCommand, plcCommandMap);

            PLCReadAndWrite plcReadAndWrite = new PLCReadAndWrite();
            if (plcReadAndWrite.execWrite(stkOperate, JsonUtil.toJSONString(allMap))) {
                //解锁
                //redisTemplate.opsForValue().set("stackerLock", "false");
                return Result.ok();
            } else {
                //解锁
                //redisTemplate.opsForValue().set("stackerLock", "false");
                return Result.err();
            }
        } else {
            return Result.err();
        }
    }


    //检查当前物料号是否有出库任务（正常出库，紧急出库）
    public BusinDataTaskOutVo checkOutTaskData(String goods) {
        BusinDataTaskOutVo businDataTaskOutVo = null;
        BusinTaskQueryBo queryBo = new BusinTaskQueryBo();
//        queryBo.setTaskType("'4','5'");
        queryBo.setGoodsNo(goods);
        List<BusinDataTaskOutVo> businDataTaskOutVos = iBusinDataTaskService.selectOutBoundDataTask(goods);
        if (businDataTaskOutVos.size() > 0) {
            businDataTaskOutVo = businDataTaskOutVos.get(0);
        }
        return businDataTaskOutVo;
    }

    /**
     * 入库时有对应出库任务,将入库任务改为出库任务,直接将物料运往出库点位
     *
     * @param businDataTaskOutVo
     * @param businDataTaskVo
     */
    public void updateOutTask(BusinDataTaskOutVo businDataTaskOutVo, BusinDataTaskVo businDataTaskVo, String pointout) {
        Long taskId = businDataTaskVo.getId();
        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
        String outPoint = "";

        pointQueryBo.setGroupNo(pointout);
        BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
        if (pointDeviceout == null) {
            log.error("请维护紧急出库接驳点");
        }
        outPoint = pointDeviceout.getPointNo();
        int outtaskType = Integer.valueOf(pointDeviceout.getIsDown());


        //拿到机械手下料口上报取货完成点位
        String tepairGroupout = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point);
        BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
        pointQueryBoup.setGroupNo(tepairGroupout);

        BasePointDeviceVo pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);

        //更改紧急出库任务状态
        BusinDataTask businDataTaskout = iBusinDataTaskService.getById(businDataTaskOutVo.getTaskId());
        businDataTaskout.setTaskStatus("3");
        //更新入库任务对应信息
        String startPoint = businDataTaskVo.getTaskPath();
        Map<String, String> snPointMap = new HashMap<>(3);
        snPointMap.put("1", startPoint);
        snPointMap.put("2", pointDevice.getHandshakePoint());
        snPointMap.put("3", outPoint);
        List<String> points = new ArrayList<>();
        points.add(startPoint);
        points.add(pointDevice.getHandshakePoint());
        points.add(outPoint);
        businDataTaskVo.setPoints(JsonUtil.toJSONString(snPointMap));
        businDataTaskVo.setIsDown(String.valueOf(outtaskType));

        Result<Boolean> booleanResult = rcsUtil.callAGV(taskId, outtaskType, points);
        if (booleanResult.getCode() == HttpStatus.SUCCESS.getCode()) {
            businDataTaskVo.setTaskPath(outPoint);
            businDataTaskVo.setTaskType("5");
            businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
            iBusinDataTaskService.updateById(businDataTaskout);
            iBusinDataTaskService.updateById(BeanUtil.toBean(businDataTaskVo, BusinDataTask.class));
        }
    }
    //查询缓存区是否存在产品


    /**
     * 空治具出库流程
     */
   // @Scheduled(cron = "0/5 * * * * ? ")
    public void exeEmptyContainerFromWare() {
        if (ObjectUtils.isEmpty(redisTemplate.opsForValue().get(RedisConstant.out_empty_type))) {
            log.info("暂未设置空治具出库");
            return;
        }
        // 将redis 中的值转成字符串
        String outEmptyType = redisTemplate.opsForValue().get(RedisConstant.out_empty_type).toString();
        if ("开启".equals(outEmptyType)) {
            iBusinEnptyContainerService.emptyContainerFromWare();
        } else {
            log.info("暂未设置空治具 “开始” 出库");
        }

    }

    /**
     * 异常出库
     *
     * @author Comair
     * @date 2023/8/12 19:32
     */
//    @Scheduled(cron = "0 0/1 * * * ? ")
    public void abnormalDelivery() {
        //查询维修地点是否有空闲
        String repairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.tepair_group);
        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
        pointQueryBo.setGroupNo(repairGroup);
        BasePointDeviceVo basePointDeviceVo = null;
        List<BasePointDeviceVo> basePointDeviceVos = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
        // 查询是否有待出库的待维修保险杠
        Long abnormalArea = Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.abnormal_area));
        List<BaseLocationVo> baseLocationVos = baseLocationMapper.getOutLocationByAreaId(abnormalArea);
        // 判断是否符合生成任务
        if (ObjectUtils.isNotEmpty(basePointDeviceVos) && ObjectUtils.isNotEmpty(baseLocationVos.size())) {
            basePointDeviceVo = basePointDeviceVos.get(0);
            String toPointNo = basePointDeviceVo.getPointNo();

            //生成异常出库任务
            BusinDataTask task = new BusinDataTask();
            int randomoperands = (int) Math.round(Math.random() * 1000);
            String taskCode = "T_" + DateUtils.dateTimeNow() + randomoperands;
            task.setTaskCode(taskCode);
            task.setTaskType(TaskTypeEnum.abnormal_delivery.getValue());
            task.setBatch(DateUtils.getDate());
            task.setPriority("2");
            task.setIsTop("0");
            task.setIsUrgent("0");
            task.setCreateTime(DateUtils.getNowDate());
            task.setTaskPath(toPointNo);
            task.setTaskStatus("0");

            iBusinDataTaskService.insertBusinDataTask(task);

            BasePoint basePoint = iBasePointService.getById(basePointDeviceVo.getPointId());
            basePoint.setIsOccupy("1");
            iBasePointService.updateById(basePoint);
        }
    }

    /**
     * 冲孔出库
     *
     * @author Comair
     * @date 2023/8/12 19:33
     */
    @Scheduled(cron = "0 0/1 * * * ? ")
    public void punchingDelivery() {
        // 查询冲孔机是否符合并可以出库冲孔
        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
        BasePunchRecordVo basePunchRecordVos = iBasePunchService.selectBasePunchRecord(new BasePunch());
        // 查询是否有待出库的待冲孔保险杠
        Long punchingArea = Long.valueOf(sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.punching_area));
        List<BaseLocationVo> baseLocationVos = baseLocationMapper.getOutLocationByAreaId(punchingArea);
        // 判断是否符合生成任务
        if (ObjectUtils.isNotEmpty(basePunchRecordVos) && basePunchRecordVos.getRecordQty() < 5 && ObjectUtils.isNotEmpty(baseLocationVos)) {
            Long punchId = basePunchRecordVos.getId();
            //获取冲孔机设备对用的点位
            String punchingGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.punching_group);
            pointQueryBo.setGroupNo(punchingGroup);
            pointQueryBo.setDevCode(punchId);

            List<BasePointDeviceVo> tempList = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo);
            BasePointDeviceVo basePointDeviceVo = tempList.get(0);
            if (tempList.get(0).getPointNo().contains("KW11")) {
                basePointDeviceVo = tempList.get(1);
            }

            String toPointNo = basePointDeviceVo.getPointNo();

            //生成冲孔出库任务
            BusinDataTask task = new BusinDataTask();
            int randomoperands = (int) Math.round(Math.random() * 1000);
            String taskCode = "T_" + DateUtils.dateTimeNow() + randomoperands;
            task.setTaskCode(taskCode);
            task.setTaskType("21");
            task.setBatch(DateUtils.getDate());
            task.setPriority("2");
            task.setIsTop("0");
            task.setIsUrgent("0");
            task.setCreateTime(DateUtils.getNowDate());
            task.setTaskPath(toPointNo);
            task.setTaskStatus("0");

            iBusinDataTaskService.insertBusinDataTask(task);

            //记录冲孔机排队数量
            BasePunchRecordAddBo recordAddBo = new BasePunchRecordAddBo();
            recordAddBo.setTaskCode(task.getId());
            recordAddBo.setPunchNo(punchId);
            recordAddBo.setIsState("0");
            iBasePunchRecordService.insertBasePunchRecord(BeanUtil.toBean(recordAddBo, BasePunchRecord.class));
        }
    }

    /**
     * 返回任务数最少的巷道号
     *
     * @param tunnelAll
     * @return java.lang.String
     * @author Comair
     * @date 2023/8/12 20:57
     */
    public String quickSort(List<String> tunnelAll) {
        String tunnel = "";
        Map<String, Integer> tunnelmap = new HashMap<>();
        tunnelAll.stream().forEach(e -> {
            tunnelmap.put(e, tunnelTaskUtil.getTotalTaskNum(e, 1));
        });
        List<Integer> collect = tunnelmap.values().stream().sorted().collect(Collectors.toList());
        for (String key : tunnelmap.keySet()) {
            if (tunnelmap.get(key).equals(collect.get(0))) {
                tunnel = key;
            }
        }
        return tunnel;
    }


    public void inTask(Long taskId, Long containerId) {
        //获取待下发任务数据
        BusinDataTask businDataTaskVo = businDataTaskMapper.selectById(taskId);
        //获取要出入库的条码信息
        List<BusinDataTaskGoodsVo> businDataTaskGoodsVos = iBusinDataTaskGoodsService.selectBusinTaskGoodsByTaskCode(businDataTaskVo.getId());
        if (ObjectUtils.isEmpty(businDataTaskGoodsVos) || !businDataTaskVo.getTaskType().equals("0")) {
            return;
        }
        BasePointDeviceQueryBo pointQueryBo = new BasePointDeviceQueryBo();
        BusinDataTaskGoodsVo goodsVo = businDataTaskGoodsVos.get(0);
        String vehicheModel = goodsVo.getVehicheModel();
        String color = goodsVo.getColor();
        String goodsNo = goodsVo.getGoodsNo();
        String startPoint = businDataTaskVo.getTaskPath();


        BasePointDeviceVo pointDevice = new BasePointDeviceVo();
        BasePointDeviceVo basePointDeviceVo = new BasePointDeviceVo();
        //立库输送线接驳点-入
        String toLocation = "";
        int agvTaskType = 0;
        BusinTaskExeBo exeBo = new BusinTaskExeBo();
        Long plcId = null;
        Long stkPlcId = null;

        String agvno = null;
        //获取派生
        // TODO 由于逻辑区域换成与车型相匹配，不是与派生匹配，所以注释掉
//                Long dervieId = getLocationByDervie(vehicheModel, color);


        String randome = "P01";
        if (businDataTaskVo.getWarehouseType().equals("1")) {
            randome = "P01";
        } else if (businDataTaskVo.getWarehouseType().equals("2")) {
            randome = "P02";
        }
        if ("P01".equals(randome)) {
            //根据车型分配库位  先判断该任务是否已经分配了货位
            Result<BaseLocationVo> locationVoResult = null;
            if (ObjectUtils.isEmpty(businDataTaskVo.getToRow())) {
                //   locationVoResult = iBaseLocationService.assignEmptyLocation(vehicheModel, color,DateUtils.getDate(),businDataTaskGoodsVos);
                // TODO: 2024/6/28 zjx
                locationVoResult = iBaseLocationService.assignEmptyLocationByStock(goodsNo, vehicheModel, DateUtils.getDate(), businDataTaskGoodsVos);
            }

            if (ObjectUtils.isNotEmpty(locationVoResult) && locationVoResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                //如果是P01则设置randome为P02
                redisTemplate.opsForValue().set("randome", "P02");
                BaseLocationVo locationVo = locationVoResult.getData();
                String tunnel = locationVo.getTunnel();
                Long locationId = locationVo.getId();
                for (BusinDataTaskGoodsVo businDataTaskGoodsVo : businDataTaskGoodsVos) {
                    businDataTaskGoodsVo.setLocationId(locationId);
                }
                //回填任务的入行高列
                businDataTaskVo.setBatch(DateUtils.getDate());
                businDataTaskVo.setToColumn(locationVo.getLocationColumn());
                businDataTaskVo.setToLayer(locationVo.getLayer());
                businDataTaskVo.setToRow(locationVo.getLocationRow());
                businDataTaskVo.setTunnel(tunnel);
                //获取货位对应的巷道及巷道对应的设备信息
                pointQueryBo.setTunnel(tunnel);
                pointQueryBo.setDirection("0");
                basePointDeviceVo = baseLocationPlcMapper.selectBasePointByGroupno(pointQueryBo).get(0);

                if (basePointDeviceVo != null) {
                    toLocation = basePointDeviceVo.getPointNo();
                    //输送线PLCID
                    plcId = Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.LK_plc_id));
                }

                //获取巷道对应的堆垛机信息
                pointQueryBo.setDevType("1");
                BaseDevicePlcVo baseDevicePlcVo = baseLocationPlcMapper.selectBaseDevicePlc(pointQueryBo);
                stkPlcId = baseDevicePlcVo.getPlcId();

                exeBo.setTaskCode(taskId);
                exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
                exeBo.setContainerId(containerId);
                exeBo.setBaseLocationVo(locationVo);
                exeBo.setTransNo("1");
                exeBo.setTransQual("1");

                //根据取货时的的点位拿到对应的交互点用作取货完成点
                agvTaskType = Integer.valueOf(basePointDeviceVo.getIsDown());
                if (businDataTaskVo.getTaskType().equals("7")) {
                    if (businDataTaskVo.getTaskPath().contains("manMade")) {
                        agvTaskType = RCSTaskTypeEnum.TO_B_AND_PUT.getValue();
                        List agvtaskType = new ArrayList();
                        agvtaskType.add("15");
                        agvtaskType.add("12");
                        BusinDataTask manMade01 = iBusinDataTaskService.getOne(new LambdaQueryWrapper<BusinDataTask>()
                                .in(BusinDataTask::getTaskType, agvtaskType)
                                .eq(BusinDataTask::getContainerId, businDataTaskVo.getContainerId())
                                .eq(BusinDataTask::getTaskStatus, "2")
                                .orderByDesc(BusinDataTask::getId)
                                .last("limit 1"));
                        if (ObjectUtils.isNotEmpty(manMade01)) {
                            agvno = manMade01.getAgvNo();
                        }
                    } else if (businDataTaskVo.getTaskPath().contains("Artificial")) {
                        agvTaskType = RCSTaskTypeEnum.TO_B_AND_PUT.getValue();
                        String idArr = redisTemplate.opsForValue().get(RedisConstant.Replenishment).toString();
                        String[] idArrs = idArr.split("_");
                        agvno = idArrs[1];
                    }
                }
            }
            if (locationVoResult.getCode() == HttpStatus.ERROR.getCode()) {
                //如果是P02则设置randome为P01
                redisTemplate.opsForValue().set("randome", "P01");
                String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_in01);
                pointQueryBo.setGroupNo(tepairGroup);
                BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
                toLocation = pointDeviceout.getPointNo();
                agvTaskType = Integer.valueOf(pointDeviceout.getIsDown());
                exeBo.setTaskCode(taskId);
                exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
                exeBo.setContainerId(containerId);
                exeBo.setTransNo("1");
                exeBo.setTransQual("1");
            }

        }
        if ("P02".equals(randome)) {
            //如果是P02则设置randome为P01
            redisTemplate.opsForValue().set("randome", "P01");
            String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.P_in01);
            pointQueryBo.setGroupNo(tepairGroup);
            BasePointDeviceVo pointDeviceout = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBo);
            toLocation = pointDeviceout.getPointNo();
            agvTaskType = Integer.valueOf(pointDeviceout.getIsDown());
            exeBo.setTaskCode(taskId);
            exeBo.setBusinDataTaskGoodsVo(businDataTaskGoodsVos);
            exeBo.setContainerId(containerId);
            exeBo.setTransNo("1");
            exeBo.setTransQual("1");
        }


        List<String> points = new ArrayList<>();
        points.add(startPoint);

        String tepairGroup = sysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.putout_point);
        BasePointDeviceQueryBo pointQueryBoup = new BasePointDeviceQueryBo();
        pointQueryBoup.setGroupNo(tepairGroup);

        pointDevice = basePointDeviceMapper.selectBasePointByGroupno(pointQueryBoup);
        if (!businDataTaskVo.getTaskType().equals("7")) {
            points.add(pointDevice.getHandshakePoint());
        }

        points.add(toLocation);
        Map<String, String> snPointMap = new HashMap<>(3);
        snPointMap.put("1", startPoint);
        if (!businDataTaskVo.getTaskType().equals("7")) {
            snPointMap.put("2", pointDevice.getHandshakePoint());
            snPointMap.put("3", toLocation);
        } else {
            snPointMap.put("2", toLocation);
        }


        businDataTaskVo.setPoints(JsonUtil.toJSONString(snPointMap));
        businDataTaskVo.setIsDown(String.valueOf(agvTaskType));
        //呼叫AGV
        Result<Boolean> booleanResult = new Result<>();
        if (businDataTaskVo.getTaskType().equals("7")) {
            booleanResult = rcsUtil.callAGV(taskId, agvTaskType, points, businDataTaskVo.getToRow(), agvno);
        } else {
            booleanResult = rcsUtil.callAGV(taskId, agvTaskType, points, businDataTaskVo.getToRow());
            log.error("入库呼叫AGV任务号:" + taskId + "   结果:" + booleanResult.getCode() + "返回信息:" + booleanResult.getMsg());
        }
        if (booleanResult.getCode() == HttpStatus.ERROR.getCode()) {
            BusinDataTask businDataTask = new BusinDataTask();
            businDataTask.setId(businDataTaskVo.getId());
            businDataTask.setTaskStatus(TaskStatusEnum.wait_callback.getValue());
            iBusinDataTaskService.updateById(businDataTask);
            return;
        }

        //呼叫AGV成功
        if (booleanResult.getCode() == HttpStatus.SUCCESS.getCode()) {
            businDataTaskVo.setTaskPath(toLocation);
            businDataTaskVo.setTaskStatus(TaskStatusEnum.wait_callback.getValue());

            //生成入库单
            if (randome.equals("P01")) {
                Result<String> stringResult = iPutInOutStorageService.exeTaskPutinStorage(exeBo);

                //生成入库单成功
                if (stringResult.getCode() == HttpStatus.SUCCESS.getCode()) {
                    businDataTaskVo.setTransId(stringResult.getData());
                } else {
                    businDataTaskVo.setTaskStatus(TaskStatusEnum.err.getValue());
                    businDataTaskVo.setExceptionMsg("生成入库单失败");
                }
            }

        }
        //立库输送线PLCID
        businDataTaskVo.setDpsNoOne(plcId);
        //巷道堆垛机PLCID
        businDataTaskVo.setDpsNoTwo(stkPlcId);
        iBusinDataTaskService.updateById(BeanUtil.toBean(businDataTaskVo, BusinDataTask.class));
    }
}

