package org.nl.acs.instruction.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.nl.acs.AcsConfig;
import org.nl.acs.agv.server.MagicAgvService;
import org.nl.acs.agv.server.NDCAgvService;
import org.nl.acs.agv.server.ZheDaAgvService;
import org.nl.acs.auto.initial.ApplicationAutoInitial;
import org.nl.acs.common.base.PageInfo;
import org.nl.acs.common.base.QueryHelpMybatisPlus;
import org.nl.acs.common.base.impl.CommonServiceImpl;
import org.nl.acs.device.domain.Device;
import org.nl.acs.device.service.DeviceService;
import org.nl.acs.device.service.impl.DeviceServiceImpl;
import org.nl.acs.device_driver.DeviceDriver;
import org.nl.acs.device_driver.basedriver.hongxiang_device.HongXiangConveyorDeviceDriver;
import org.nl.acs.device_driver.basedriver.siemens_conveyor.SiemensConveyorDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_conveyor_control_with_scanner.StandardCoveyorControlWithScannerDeviceDriver;
import org.nl.acs.device_driver.basedriver.standard_inspect_site.StandardInspectSiteDeviceDriver;
import org.nl.acs.ext.wms.liKuData.*;
import org.nl.acs.ext.wms.service.AcsToLiKuService;
import org.nl.acs.instruction.domain.Instruction;
import org.nl.acs.instruction.domain.InstructionMybatis;
import org.nl.acs.instruction.service.InstructionService;
import org.nl.acs.instruction.service.dto.InstructionDto;
import org.nl.acs.instruction.service.dto.InstructionQueryParam;
import org.nl.acs.instruction.service.mapper.InstructionMapper;
import org.nl.acs.opc.DeviceAppService;
import org.nl.acs.opc.DeviceAppServiceImpl;
import org.nl.acs.route.service.RouteLineService;
import org.nl.acs.route.service.dto.RouteLineDto;
import org.nl.acs.task.TaskInstructionLock;
import org.nl.acs.task.domain.Task;
import org.nl.acs.task.service.TaskService;
import org.nl.acs.task.service.dto.TaskDto;
import org.nl.acs.task.service.mapper.TaskMapper;
import org.nl.acs.utils.ConvertUtil;
import org.nl.acs.utils.PageUtil;
import org.nl.common.exception.BadRequestException;
import org.nl.common.utils.CodeUtil;
import org.nl.common.utils.FileUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.config.SpringContextHolder;
import org.nl.system.service.param.ISysParamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;

/**
 * @author jiaolm
 * @date 2023-05-09
 */
@Service
@Slf4j
// @CacheConfig(cacheNames = InstructionService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class InstructionServiceImpl extends CommonServiceImpl<InstructionMapper, InstructionMybatis> implements InstructionService, ApplicationAutoInitial {

    // private final RedisUtils redisUtils;
    @Autowired
    InstructionMapper instructionMapper;
    @Autowired
    TaskMapper taskMapper;
    List<Instruction> instructions = new CopyOnWriteArrayList();
    //    List<InstructionMybatis> instructions_mybatis = new CopyOnWriteArrayList();
    @Autowired
    DeviceAppService deviceAppService;
    @Autowired
    NDCAgvService ndcAgvService;
    @Autowired
    ISysParamService paramService;
    @Autowired
    RouteLineService routeLineService;
    @Autowired
    TaskService taskService;
    @Autowired
    AcsToLiKuService acsToLiKuService;

    @Override
    public PageInfo<InstructionDto> queryAll(InstructionQueryParam query, Pageable pageable) {
        IPage<InstructionMybatis> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<InstructionMybatis> page = instructionMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, InstructionDto.class);
    }

    @Override
    public List<InstructionDto> queryAll(InstructionQueryParam query) {
        return ConvertUtil.convertList(instructionMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), InstructionDto.class);
    }

    @Override
    public InstructionMybatis getById(String id) {
        return instructionMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public InstructionDto findById(String id) {
        return ConvertUtil.convert(getById(id), InstructionDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(InstructionDto resources) {
        InstructionMybatis entity = ConvertUtil.convert(resources, InstructionMybatis.class);
        int ret = instructionMapper.updateById(entity);
        // delCaches(resources.id);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<String> ids) {
        // delCaches(ids);
        return instructionMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(String id) {
        Set<String> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(String id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<String> ids) {
        for (String id: ids) {
            delCaches(id);
        }
    }*/

    /**
     * 加载指令数据
     */
    @Override
    public void autoInitial() {
        this.reload();
    }

    @Override
    public synchronized void reload() {
        List<InstructionMybatis> list = new LambdaQueryChainWrapper<InstructionMybatis>(instructionMapper)
                .lt(InstructionMybatis::getInstruction_status, "2")
                .eq(InstructionMybatis::getIs_delete, "0")
                .list();
//        List list = this.queryAll("instruction_status <2 and is_delete =0");
        this.instructions = new CopyOnWriteArrayList<>(ConvertUtil.convertList(list, Instruction.class));
    }

    @Override
    public Map<String, Object> queryAll(Map whereJson, Pageable page) {
        String code = (String) whereJson.get("code");
        String vehicle_code = (String) whereJson.get("vehicle_code");
        String material_type = (String) whereJson.get("material_type");
        String status = (String) whereJson.get("status");
        String point_code = (String) whereJson.get("point_code");
        String is_over = (String) whereJson.get("is_over");
        String instruction_type = (String) whereJson.get("instruction_type");

        IPage<InstructionMybatis> queryPage = PageUtil.toMybatisPage(page);
        LambdaQueryWrapper<InstructionMybatis> wrapper = new LambdaQueryWrapper<>();
        //        wrapper.eq(InstructionMybatis::getIs_delete,0);
        wrapper.and(StringUtils.isNotBlank(code), instructionMybatis -> instructionMybatis.like(InstructionMybatis::getInstruction_code, code).or().like(InstructionMybatis::getTask_code, code));
        wrapper.like(StringUtils.isNotBlank(vehicle_code), InstructionMybatis::getVehicle_code, vehicle_code);
        wrapper.eq(StringUtils.isNotBlank(material_type), InstructionMybatis::getMaterial, material_type);
        wrapper.and(StringUtils.isNotBlank(point_code), instructionMybatis -> instructionMybatis.like(InstructionMybatis::getStart_point_code, point_code).or().like(InstructionMybatis::getNext_point_code, point_code));
        wrapper.eq(StringUtils.isNotBlank(instruction_type), InstructionMybatis::getInstruction_type, instruction_type);
        if (!StrUtil.isEmpty(is_over)) {
            if (StrUtil.equals(is_over, "1")) {
                wrapper.ge(InstructionMybatis::getInstruction_status, 2);
            } else {
                wrapper.lt(InstructionMybatis::getInstruction_status, 2);
            }
        }
        if (!StrUtil.isEmpty(status)) {
            wrapper.eq(InstructionMybatis::getInstruction_status, status);
        } else {
            wrapper.lt(InstructionMybatis::getInstruction_status, 2);
        }
        IPage<InstructionMybatis> insPage = instructionMapper.selectPage(queryPage, wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(insPage, InstructionDto.class));
        return json;
    }

    @Override
    public Map<String, Object> getAll(Map whereJson, Pageable page) {
        String code = (String) whereJson.get("code");
        String vehicle_code = (String) whereJson.get("vehicle_code");
        String material_type = (String) whereJson.get("material_type");
        String status = (String) whereJson.get("status");
        String point_code = (String) whereJson.get("point_code");
        String create_time = (String) whereJson.get("createTime");
        String end_time = (String) whereJson.get("end_time");

        IPage<InstructionMybatis> queryPage = PageUtil.toMybatisPage(page);
        LambdaQueryWrapper<InstructionMybatis> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(InstructionMybatis::getIs_delete,"0");
        if (!StrUtil.isEmpty(code)) {
            wrapper.and(instructionMybatis -> instructionMybatis.like(InstructionMybatis::getInstruction_code, code).or().like(InstructionMybatis::getTask_code, code));
        }
        if (!StrUtil.isEmpty(vehicle_code)) {
            wrapper.like(InstructionMybatis::getVehicle_code, vehicle_code);
        }
        if (!StrUtil.isEmpty(material_type)) {
            wrapper.eq(InstructionMybatis::getMaterial, material_type);
        }
        if (!StrUtil.isEmpty(status)) {
            wrapper.eq(InstructionMybatis::getInstruction_status, status);
        }
        if (!StrUtil.isEmpty(point_code)) {
            wrapper.and(instructionMybatis -> instructionMybatis.like(InstructionMybatis::getStart_point_code, point_code).or().like(InstructionMybatis::getNext_point_code, point_code));
        }
        if (!StrUtil.isEmpty(create_time) && !StrUtil.isEmpty(end_time)) {
            wrapper.between(InstructionMybatis::getCreate_time, create_time, end_time);
        }
        wrapper.orderByDesc(InstructionMybatis::getCreate_time);
        IPage<InstructionMybatis> insPage = instructionMapper.selectPage(queryPage, wrapper);
        final JSONObject json = (JSONObject) JSON.toJSON(ConvertUtil.convertPage(insPage, InstructionDto.class));
        return json;
    }

    @Override
    public Map<String, Object> getByTaskId(String id) {
        List<InstructionMybatis> insList = new LambdaQueryChainWrapper<>(instructionMapper)
                .eq(InstructionMybatis::getTask_id, id)
                .list();
        JSONObject jsonObject = new JSONObject();
        JSONArray content = JSONArray.parseArray(JSON.toJSONString(insList));
        JSONArray array = new JSONArray();
        for (int i = 0; i < content.size(); i++) {
            JSONObject jo = (JSONObject) content.get(i);
            JSONObject ins = new JSONObject();
            ins.put("task_id", jo.get("instruction_id"));
            ins.put("task_code", jo.get("instruction_code"));
            ins.put("task_status", jo.get("instruction_status"));
            ins.put("start_point_code", jo.get("start_point_code"));
            ins.put("next_point_code", jo.get("next_point_code"));
            ins.put("matarial", jo.get("matarial"));
            ins.put("remark", jo.get("remark"));
            ins.put("create_by", jo.get("create_by"));
            ins.put("create_time", jo.get("create_time"));
            array.add(ins);
        }
        jsonObject.put("content", array);
        return jsonObject;
    }

    @Override
    public List<Instruction> queryAll(Map whereJson) {
        List<InstructionMybatis> insList = new LambdaQueryChainWrapper<>(instructionMapper)
                .list();
        return ConvertUtil.convertList(insList, Instruction.class);
    }

    @Override
    public List queryAll(String whereJson) {
//        WQLObject wo = WQLObject.getWQLObject("acs_instruction");
//        JSONArray arr = wo.query(whereJson, "create_time").getResultJSONArray(0);
//        List<Instruction> list = arr.toJavaList(Instruction.class);
        List<InstructionMybatis> insList = new LambdaQueryChainWrapper<>(instructionMapper)
                .lt(InstructionMybatis::getInstruction_status, "2")
                .list();
        return ConvertUtil.convertList(insList, Instruction.class);
    }


    @Override
    public Instruction findByCode(String code) {
//        WQLObject wo = WQLObject.getWQLObject("acs_instruction");
//        JSONObject json = wo.query("instruction_code ='" + code + "'").uniqueResult(0);
//        if (ObjectUtil.isEmpty(json)) {
//            return null;
//        }
//        final Instruction obj = json.toJavaObject(Instruction.class);
//        return obj;

        InstructionMybatis ins = new LambdaQueryChainWrapper<>(instructionMapper)
                .eq(InstructionMybatis::getInstruction_code, code)
                .one();
        if (ObjectUtil.isEmpty(ins)) {
            return null;
        }
        return ConvertUtil.convert(ins, Instruction.class);
    }

    @Override
    public Instruction findByTaskcode(String code) {
        List<InstructionMybatis> instructList= instructionMapper.selectList(new LambdaQueryWrapper<InstructionMybatis>()
                .eq(InstructionMybatis::getTask_code, code));
        if (ObjectUtil.isEmpty(instructList)) {
            return null;
        }
        return ConvertUtil.convert(instructList.get(0), Instruction.class);
    }

    @Override
    public Instruction findByTaskcodeAndStatus(String code) {
        Iterator var3 = instructions.iterator();
        while (var3.hasNext()) {
            Instruction instruction = (Instruction) var3.next();
            if (StrUtil.equals(instruction.getTask_code(), code)
                    && StrUtil.equals(instruction.getInstruction_status(), "0")) {
                return instruction;
            }
        }
        return null;
    }

    @Override
    public Instruction findByTaskid(String id, String wherecaluse) {
        LambdaQueryWrapper<InstructionMybatis> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InstructionMybatis::getTask_id, id);
        wrapper.apply(StringUtils.isNotBlank(wherecaluse), wherecaluse);
        List<InstructionMybatis> insList = instructionMapper.selectList(wrapper);
        if (ObjectUtil.isNotEmpty(insList)) {
            return ConvertUtil.convert(insList.get(0), Instruction.class);
        }
        return null;
    }

    @Override
    public void create(Instruction dto) {
        dto = foramte(dto);
        String task_code = dto.getTask_code();
        TaskDto task = taskService.findByCodeFromCache(task_code);
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        if (StrUtil.isEmpty(dto.getRoute_plan_code())) {
            dto.setRoute_plan_code(task.getRoute_plan_code());
        }
        if (StrUtil.isEmpty(dto.getPriority())) {
            dto.setPriority(task.getPriority());
        }
        if (StrUtil.isEmpty(dto.getInstruction_code())) {
            dto.setInstruction_code(CodeUtil.getNewCode("INSTRUCT_NO"));
        }
        if (StrUtil.isEmpty(dto.getInstruction_id())) {
            dto.setInstruction_id(IdUtil.simpleUUID());
        }
        if (StrUtil.isEmpty(dto.getIs_send())) {
            dto.setIs_send(task.getIs_send());
        }
        if (StrUtil.isEmpty(dto.getLink_num())) {
            dto.setIs_send(task.getLink_num());
        }
        //        if (task.getTask_type().equals("1") || task.getTask_type().equals("2")) {
        dto.setInstruction_type(task.getTask_type());
        //        } else if (false) {
        //
        //        } else {
        //            dto.setInstruction_type("3");
        //        }
        // 查询是否存在相同指令号
        //            if (!StrUtil.isEmpty(dto.getVehicle_code() )) {
        //                Instruction inst_dto = findByContainer(dto.getVehicle_code());
        //                if (inst_dto != null) {
        //                    log.error("存在相同载具号任务,载具号"+dto.getVehicle_code());
        //                    throw new BadRequestException("存在相同载具号任务！");
        //                }
        //            }
        // 起点设备与终点设备相同则为初始指令
        if (StrUtil.equals(task.getStart_device_code(), dto.getStart_device_code())) {
            if (!StrUtil.equals(dto.getCompound_inst(), "0")
                    && StrUtil.equals(task.getCompound_task(), "1")) {
                dto.setCompound_inst("1");
                dto.setCompound_inst_data(task.getCompound_task_data());
            }
        }
        dto.setExt_task_id(task.getExt_task_id());
        dto.setCreate_by(ObjectUtil.isNotEmpty(currentUsername) ? currentUsername : "admin");
        dto.setUpdate_by(ObjectUtil.isNotEmpty(currentUsername) ? currentUsername : "admin");
        dto.setUpdate_time(now);
        dto.setCreate_time(now);
        dto.setStart_parent_code(task.getStart_parent_code());
        dto.setNext_parent_code(task.getNext_parent_code());
        if (ObjectUtil.isNotEmpty(task.getTask_type())) {
            dto.setInstruction_type(task.getTask_type());
        }
        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        try {
            //            String start_device_code = dto.getStart_device_code();
            //            String next_device_code = dto.getNext_device_code();
            //            String route_plan_code = task.getRoute_plan_code();
            //            List<RouteLineDto> shortPathsList =
            //                    routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code);
            //            RouteLineDto route = null;
            //            for (int i = 0; i < shortPathsList.size(); i++) {
            //                RouteLineDto routeLineDto = shortPathsList.get(i);
            //                String route_device = routeLineDto.getDevice_code();
            //                String route_next_device = routeLineDto.getNext_device_code();
            //                if (route_device.equals(dto.getStart_device_code())
            //                        && route_next_device.equals(dto.getNext_device_code())) {
            //                    route = routeLineDto;
            //                    break;
            //                }
            //            }
            //            if (ObjectUtil.isEmpty(route)) {
            //                throw new BadRequestException("未查询到相关路由！");
            //            }
            //            if (StrUtil.equals(shortPathsList.get(0).getType(), "1")) {
            NDCAgvService ndcAgvService = SpringContextHolder.getBean(NDCAgvService.class);
            try {
                ndcAgvService.sendAgvInstToNDC(task.getAgv_system_type(), dto);
            } catch (Exception e) {
                log.error("tofix下发agv数据失败，失败原因：" + e.getMessage());
            }
            //            } else if (StrUtil.equals(shortPathsList.get(0).getType(), "2")) {
            //                ZheDaAgvService zheDaAgvService = SpringContextHolder.getBean(ZheDaAgvService.class);
            //                HttpResponse result = zheDaAgvService.sendAgvInstToAgv(dto);
            //                if (!ObjectUtils.isEmpty(result)) {
            //                    JSONObject jo = JSON.parseObject(result.body());
            //                    if (jo.getInteger("status") != 200) {
            //                        dto.setSend_status("2");
            //                        dto.setRemark("失败原因:" + jo.getString("message"));
            //                        log.error("创建指令,下发AGV/RGV任务失败！任务id为:{},指令号为:{}，失败原因{}", task.getTask_id(), dto.getInstruction_code(), jo.getString("message"));
            //                        if (task != null) {
            //                            task.setRemark("创建指令,下发AGV/RGV任务失败！失败原因{}" + jo.getString("message"));
            //                            taskService.update(task);
            //                        }
            //                    } else {
            //                        dto.setSend_status("1");
            //                    }
            //                } else {
            //                    dto.setSend_status("2");
            //                    dto.setRemark("失败原因:AGV/RGV未响应！");
            //                    log.error("创建指令,下发AGV/RGV任务失败！任务id为:{},指令号为:{}，失败原因{}", task.getTask_id(), dto.getInstruction_code(), "AGV/RGV未响应！");
            //                    if (task != null) {
            //                        task.setRemark("创建指令,下发AGV/RGV任务失败！失败原因: AGV/RGV未响应！");
            //                        taskService.update(task);
            //                    }
            //                }
            //  }
        } catch (Exception e) {
            String msg = e.getMessage()==null?"连接失败！":e.getMessage();
            dto.setSend_status("2");
            dto.setRemark("失败原因:" + msg);
            log.error("创建指令失败，任务id为：" + task.getTask_id(), "失败原因：" + msg);
            if (task != null) {
                task.setRemark("自动创建指令失败，失败原因:"+msg);
                taskService.update(task);
            }
        }
        InstructionMybatis entity = ConvertUtil.convert(dto, InstructionMybatis.class);
        instructionMapper.insert(entity);
        instructions.add(dto);
    }

    public void create1(Instruction dto) {
        dto = foramte(dto);
        String task_code = dto.getTask_code();
        TaskDto task = taskService.findByCodeFromCache(task_code);

        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        if (StrUtil.isEmpty(dto.getRoute_plan_code())) {
            dto.setRoute_plan_code(task.getRoute_plan_code());
        }
        if (StrUtil.isEmpty(dto.getPriority())) {
            dto.setPriority(task.getPriority());
        }
        if (StrUtil.isEmpty(dto.getInstruction_code())) {
            dto.setInstruction_code(CodeUtil.getNewCode("INSTRUCT_NO"));
        }
        if (StrUtil.isEmpty(dto.getInstruction_id())) {
            dto.setInstruction_id(IdUtil.simpleUUID());
        }
        if (StrUtil.isEmpty(dto.getIs_send())) {
            dto.setIs_send(task.getIs_send());
        }
        if (StrUtil.isEmpty(dto.getLink_num())) {
            dto.setIs_send(task.getLink_num());
        }
//        if (task.getTask_type().equals("1") || task.getTask_type().equals("2")) {
        dto.setInstruction_type(task.getTask_type());
//        } else if (false) {
//
//        } else {
//            dto.setInstruction_type("3");
//        }

        // 查询是否存在相同指令号
        //            if (!StrUtil.isEmpty(dto.getVehicle_code() )) {
        //                Instruction inst_dto = findByContainer(dto.getVehicle_code());
        //                if (inst_dto != null) {
        //                    log.error("存在相同载具号任务,载具号"+dto.getVehicle_code());
        //                    throw new BadRequestException("存在相同载具号任务！");
        //                }
        //            }
        // 起点设备与终点设备相同则为初始指令
        if (StrUtil.equals(task.getStart_device_code(), dto.getStart_device_code())) {
            if (!StrUtil.equals(dto.getCompound_inst(), "0")
                    && StrUtil.equals(task.getCompound_task(), "1")) {
                dto.setCompound_inst("1");
                dto.setCompound_inst_data(task.getCompound_task_data());
            }
        }

        dto.setCreate_by(ObjectUtil.isNotEmpty(currentUsername) ? currentUsername : "admin");
        dto.setUpdate_by(ObjectUtil.isNotEmpty(currentUsername) ? currentUsername : "admin");
        dto.setUpdate_time(now);
        dto.setCreate_time(now);
        dto.setStart_parent_code(task.getStart_parent_code());
        dto.setNext_parent_code(task.getNext_parent_code());

        if (ObjectUtil.isNotEmpty(task.getTask_type())) {
            dto.setInstruction_type(task.getTask_type());
        }

        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        Device startdevice = appService.findDeviceByCode(dto.getStart_device_code());

        HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
        StandardCoveyorControlWithScannerDeviceDriver standardCoveyorControlWithScannerDeviceDriver;

        try {
            String start_device_code = dto.getStart_device_code();
            String next_device_code = dto.getNext_device_code();
            String route_plan_code = task.getRoute_plan_code();
            List<RouteLineDto> shortPathsList =
                    routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code);
            RouteLineDto route = null;
            for (int i = 0; i < shortPathsList.size(); i++) {
                RouteLineDto routeLineDto = shortPathsList.get(i);
                String route_device = routeLineDto.getDevice_code();
                String route_next_device = routeLineDto.getNext_device_code();
                if (route_device.equals(dto.getStart_device_code())
                        && route_next_device.equals(dto.getNext_device_code())) {
                    route = routeLineDto;
                    break;
                }
            }
            if (ObjectUtil.isEmpty(route)) {
                throw new BadRequestException("未查询到相关路由！");
            }
            if (StrUtil.equals(shortPathsList.get(0).getType(), "1")) {
                NDCAgvService ndcAgvService = SpringContextHolder.getBean(NDCAgvService.class);
                ndcAgvService.sendAgvInstToNDC(task.getAgv_system_type(), dto);
            } else if (StrUtil.equals(shortPathsList.get(0).getType(), "2")) {
                ZheDaAgvService zheDaAgvService = SpringContextHolder.getBean(ZheDaAgvService.class);
                HttpResponse result = zheDaAgvService.sendAgvInstToAgv(dto);
                if (!ObjectUtils.isEmpty(result)) {
                    JSONObject jo = JSON.parseObject(result.body());
                    if (jo.getInteger("status") != 200) {
                        dto.setSend_status("2");
                    } else {
                        dto.setSend_status("1");
                    }
                } else {
                    dto.setSend_status("2");
                }
            }
        } catch (Exception e) {
            dto.setSend_status("2");
            e.printStackTrace();
            log.error("");
        }
        InstructionMybatis entity = ConvertUtil.convert(dto, InstructionMybatis.class);
        instructionMapper.insert(entity);
        instructions.add(dto);
    }

    @Override
    public void create2(Instruction dto) throws Exception {
        dto = foramte(dto);
        String task_code = dto.getTask_code();
        TaskDto task = taskService.findByCodeFromCache(task_code);
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        if (StrUtil.isEmpty(dto.getRoute_plan_code())) {
            dto.setRoute_plan_code(task.getRoute_plan_code());
        }
        if (StrUtil.isEmpty(dto.getPriority())) {
            dto.setPriority(task.getPriority());
        }
        if (StrUtil.isEmpty(dto.getInstruction_code())) {
            dto.setInstruction_code(CodeUtil.getNewCode("INSTRUCT_NO"));
        }
        if (StrUtil.isEmpty(dto.getInstruction_id())) {
            dto.setInstruction_id(IdUtil.simpleUUID());
        }
        if (StrUtil.isEmpty(dto.getIs_send())) {
            dto.setIs_send(task.getIs_send());
        }
        if (StrUtil.isEmpty(dto.getLink_num())) {
            dto.setIs_send(task.getLink_num());
        }
        if (task.getTask_type().equals("1") || task.getTask_type().equals("2")) {
            dto.setInstruction_type(task.getTask_type());
        } else if (false) {

        } else {
            dto.setInstruction_type("3");
        }

        // 起点设备与终点设备相同则为初始指令
        if (StrUtil.equals(task.getStart_device_code(), dto.getStart_device_code())) {
            if (!StrUtil.equals(dto.getCompound_inst(), "0")
                    && StrUtil.equals(task.getCompound_task(), "1")) {
                dto.setCompound_inst("1");
                dto.setCompound_inst_data(task.getCompound_task_data());
            }
        }

        dto.setCreate_by(currentUsername);
        dto.setUpdate_by(currentUsername);
        dto.setUpdate_time(now);
        dto.setCreate_time(now);
        dto.setStart_parent_code(task.getStart_parent_code());
        dto.setNext_parent_code(task.getNext_parent_code());

        if (ObjectUtil.isNotEmpty(task.getTask_type())) {
            dto.setInstruction_type(task.getTask_type());
        }
        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        Device startdevice = appService.findDeviceByCode(dto.getStart_device_code());
        HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
        StandardCoveyorControlWithScannerDeviceDriver standardCoveyorControlWithScannerDeviceDriver;

        if (startdevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
            hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) startdevice.getDeviceDriver();
            hongXiangConveyorDeviceDriver.writing(3, Integer.valueOf(dto.getInstruction_code()));
        }

        try {
//            String start_device_code = dto.getStart_device_code();
//            String next_device_code = dto.getNext_device_code();
//            String route_plan_code = task.getRoute_plan_code();
//            List<RouteLineDto> shortPathsList =
//                    routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code);
//            RouteLineDto route = null;
//            for (int i = 0; i < shortPathsList.size(); i++) {
//                RouteLineDto routeLineDto = shortPathsList.get(i);
//                String route_device = routeLineDto.getDevice_code();
//                String route_next_device = routeLineDto.getNext_device_code();
//                if (route_device.equals(dto.getStart_device_code())
//                        && route_next_device.equals(dto.getNext_device_code())) {
//                    route = routeLineDto;
//                    break;
//                }
//            }
//            if (ObjectUtil.isEmpty(route)) {
//                throw new BadRequestException("未查询到相关路由！");
//            }
//            if (StrUtil.equals(shortPathsList.get(0).getType(), "1")) {
            try {
                ndcAgvService.sendAgvInstToNDC(task.getAgv_system_type(), dto);
            } catch (Exception e) {
                log.error("tofix下发agv数据失败，失败原因：" + e.getMessage());
            }
//            } else if (StrUtil.equals(shortPathsList.get(0).getType(), "2")) {
//                ZheDaAgvService zheDaAgvService = SpringContextHolder.getBean(ZheDaAgvService.class);
//                HttpResponse result = zheDaAgvService.sendAgvInstToAgv(dto);
//                if (!ObjectUtils.isEmpty(result)) {
//                    JSONObject jo = JSON.parseObject(result.body());
//                    if (jo.getInteger("status") != 200) {
//                        dto.setSend_status("2");
//                        dto.setRemark("失败原因:" + jo.getString("message"));
//                        log.error("创建指令,下发AGV/RGV任务失败！任务id为:{},指令号为:{}，失败原因{}", task.getTask_id(), dto.getInstruction_code(), jo.getString("message"));
//                        task.setRemark("创建指令,下发AGV/RGV任务失败！失败原因{}" + jo.getString("message"));
//                    } else {
//                        dto.setSend_status("1");
//                        task.setRemark("");
//                    }
//                } else {
//                    dto.setSend_status("2");
//                    dto.setRemark("失败原因:AGV/RGV未响应！");
//                    log.error("创建指令,下发AGV/RGV任务失败！任务id为:{},指令号为:{}，失败原因{}", task.getTask_id(), dto.getInstruction_code(), "AGV/RGV未响应！");
//                    task.setRemark("创建指令,下发AGV/RGV任务失败！失败原因: AGV/RGV未响应！");
//                }
            taskService.update(task);
            //   }
        } catch (Exception e) {
            if (e.getMessage() == null) {
                dto.setRemark("失败原因:连接异常！");
            } else {
                dto.setRemark("失败原因:" + e.getMessage());
            }
            dto.setSend_status("2");
            log.error("创建指令失败，下发AGV/RGV任务失败！任务id为:{},指令号为:{}，失败原因{}", task.getTask_id(), dto.getInstruction_code(), e.getMessage());
        }
        InstructionMybatis entity = ConvertUtil.convert(dto, InstructionMybatis.class);
        instructionMapper.insert(entity);
        instructions.add(dto);
    }

    public void create3(Instruction dto) throws Exception {
        dto = foramte(dto);
        String task_code = dto.getTask_code();
        TaskDto task = taskService.findByCodeFromCache(task_code);
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        if (StrUtil.isEmpty(dto.getRoute_plan_code())) {
            dto.setRoute_plan_code(task.getRoute_plan_code());
        }
        if (StrUtil.isEmpty(dto.getPriority())) {
            dto.setPriority(task.getPriority());
        }
        if (StrUtil.isEmpty(dto.getInstruction_code())) {
            dto.setInstruction_code(CodeUtil.getNewCode("INSTRUCT_NO"));
        }
        if (StrUtil.isEmpty(dto.getInstruction_id())) {
            dto.setInstruction_id(IdUtil.simpleUUID());
        }
        if (StrUtil.isEmpty(dto.getIs_send())) {
            dto.setIs_send(task.getIs_send());
        }
        if (StrUtil.isEmpty(dto.getLink_num())) {
            dto.setIs_send(task.getLink_num());
        }
        if (task.getTask_type().equals("1") || task.getTask_type().equals("2")) {
            dto.setInstruction_type(task.getTask_type());
        } else if (false) {

        } else {
            dto.setInstruction_type("3");
        }
        // 起点设备与终点设备相同则为初始指令
        if (StrUtil.equals(task.getStart_device_code(), dto.getStart_device_code())) {
            if (!StrUtil.equals(dto.getCompound_inst(), "0")
                    && StrUtil.equals(task.getCompound_task(), "1")) {
                dto.setCompound_inst("1");
                dto.setCompound_inst_data(task.getCompound_task_data());
            }
        }
        dto.setCreate_by(currentUsername);
        dto.setUpdate_by(currentUsername);
        dto.setUpdate_time(now);
        dto.setCreate_time(now);
        dto.setStart_parent_code(task.getStart_parent_code());
        dto.setNext_parent_code(task.getNext_parent_code());

        if (ObjectUtil.isNotEmpty(task.getTask_type())) {
            dto.setInstruction_type(task.getTask_type());
        }

        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        Device startdevice = appService.findDeviceByCode(dto.getStart_device_code());
        Device nextdevice = appService.findDeviceByCode(dto.getNext_device_code());

        HongXiangConveyorDeviceDriver hongXiangConveyorDeviceDriver;
        StandardCoveyorControlWithScannerDeviceDriver standardCoveyorControlWithScannerDeviceDriver;

        if (startdevice.getDeviceDriver() instanceof HongXiangConveyorDeviceDriver) {
            hongXiangConveyorDeviceDriver = (HongXiangConveyorDeviceDriver) startdevice.getDeviceDriver();
            hongXiangConveyorDeviceDriver.writing(3, Integer.valueOf(dto.getInstruction_code()));
        }

        try {
            String start_device_code = dto.getStart_device_code();
            String next_device_code = dto.getNext_device_code();
            String route_plan_code = task.getRoute_plan_code();
            List<RouteLineDto> shortPathsList =
                    routeLineService.getShortPathLines(start_device_code, next_device_code, route_plan_code);
            RouteLineDto route = null;
            for (int i = 0; i < shortPathsList.size(); i++) {
                RouteLineDto routeLineDto = shortPathsList.get(i);
                String route_device = routeLineDto.getDevice_code();
                String route_next_device = routeLineDto.getNext_device_code();
                if (route_device.equals(dto.getStart_device_code())
                        && route_next_device.equals(dto.getNext_device_code())) {
                    route = routeLineDto;
                    break;
                }
            }
            if (ObjectUtil.isEmpty(route)) {
                throw new BadRequestException("未查询到相关路由！");
            }
            if (StrUtil.equals(shortPathsList.get(0).getType(), "1")) {
                NDCAgvService ndcAgvService = SpringContextHolder.getBean(NDCAgvService.class);
                ndcAgvService.sendAgvInstToNDC(task.getAgv_system_type(), dto);
            } else if (StrUtil.equals(shortPathsList.get(0).getType(), "2")) {
                ZheDaAgvService zheDaAgvService = SpringContextHolder.getBean(ZheDaAgvService.class);
                HttpResponse result = zheDaAgvService.sendAgvInstToAgv(dto);
                if (!ObjectUtils.isEmpty(result)) {
                    JSONObject jo = JSON.parseObject(result.body());
                    if (jo.getInteger("status") != 200) {
                        dto.setSend_status("2");
                    } else {
                        dto.setSend_status("1");
                    }
                } else {
                    dto.setSend_status("2");
                }
            }
        } catch (Exception e) {
            dto.setSend_status("2");
            e.printStackTrace();
        }

        InstructionMybatis entity = ConvertUtil.convert(dto, InstructionMybatis.class);
        instructionMapper.insert(entity);
        instructions.add(dto);
    }

    @Override
    public void createAgain(Instruction dto) throws Exception {
        String task_code = dto.getTask_code();
        TaskDto task = taskService.findByCodeFromCache(task_code);
//        WQLObject instwo = WQLObject.getWQLObject("acs_instruction");
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        if (StrUtil.isEmpty(dto.getRoute_plan_code())) {
            dto.setRoute_plan_code(task.getRoute_plan_code());
        }
        if (StrUtil.isEmpty(dto.getInstruction_code())) {
            dto.setInstruction_code(CodeUtil.getNewCode("INSTRUCT_NO"));
        }
        if (StrUtil.isEmpty(dto.getInstruction_id())) {
            dto.setInstruction_id(IdUtil.simpleUUID());
        }
//        List<RouteLineDto> shortPathsList =
//                routeLineService.getShortPathLines(
//                        dto.getStart_device_code(), dto.getNext_device_code(), dto.getRoute_plan_code());
//        if (ObjectUtils.isEmpty(shortPathsList)) {
//            throw new Exception(dto.getStart_device_code() + "->" + dto.getNext_device_code() + "路由不通");
//        }
//        String type = shortPathsList.get(0).getType();
//        if (!StrUtil.equals(type, "0")) {
        //            JSONObject instcheckjson =
        //                    instwo
        //                            .query(
        //                                    " instruction_status <3 and next_point_code= '"
        //                                            + dto.getNext_point_code()
        //                                            + "'"
        //                                            + " and start_point_code = '"
        //                                            + dto.getStart_point_code()
        //                                            + "'"
        //                                            + " and task_id = '"
        //                                            + dto.getTask_id()
        //                                            + "'")
        //                            .uniqueResult(0);
        InstructionMybatis ins = new LambdaQueryChainWrapper<>(instructionMapper)
                .lt(InstructionMybatis::getInstruction_status, 3)
                .eq(InstructionMybatis::getNext_point_code, dto.getNext_point_code())
                .eq(InstructionMybatis::getStart_point_code, dto.getStart_point_code())
                .eq(InstructionMybatis::getTask_id, dto.getTask_id())
                .one();


        if (ins != null) {
            throw new Exception(dto.getTask_code() + ":该任务已存在待完成指令!");
        }
        //  }

        if (!StrUtil.equals(dto.getCompound_inst(), "0")
                && StrUtil.equals(task.getCompound_task(), "1")) {
            dto.setCompound_inst("1");
            dto.setCompound_inst_data(task.getCompound_task_data());
        }

        dto.setCreate_by(currentUsername);
        dto.setUpdate_by(currentUsername);
        dto.setUpdate_time(now);
        dto.setCreate_time(now);

//        WQLObject wo = WQLObject.getWQLObject("acs_instruction");
//        JSONObject json = (JSONObject) JSONObject.toJSON(dto);
//
//        wo.insert(json);

        InstructionMybatis entity = ConvertUtil.convert(dto, InstructionMybatis.class);
        instructionMapper.insert(entity);

        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        Device startdevice = appService.findDeviceByCode(dto.getStart_device_code());
        Device nextdevice = appService.findDeviceByCode(dto.getNext_device_code());

        StandardInspectSiteDeviceDriver standardInspectSiteDeviceDriver;
        StandardCoveyorControlWithScannerDeviceDriver standardCoveyorControlWithScannerDeviceDriver;

        if (!ObjectUtils.isEmpty(nextdevice.getExtraValue().get("link_three_lamp"))) {
            String lamd_device = nextdevice.getExtraValue().get("link_three_lamp").toString();
            Device lamddevice = appService.findDeviceByCode(lamd_device);
        }

        // != 0 为agv任务
        //        if(!StrUtil.equals(type,"0")){
        //            if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(), "1"))
        // {
        //                agvService.sendAgvInstToMagic(dto);
        //            } else if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(),
        // "2")) {
        //                agvService.sendAgvInstToNDC(dto);
        //            } else if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(),
        // "3")) {
        //                agvService.addOrderSequences(dto);
        //            }
        //        }
        instructions.add(dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Instruction dto) {
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        dto.setUpdate_time(now);
        dto.setUpdate_by(currentUsername);
        InstructionMybatis entity = ConvertUtil.convert(dto, InstructionMybatis.class);
        instructionMapper.updateById(entity);
        removeByCodeFromCache(dto.getInstruction_code());
        instructions.add(dto);
//        this.reload();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(String[] ids) throws Exception {
        for (String instruction_id : ids) {
            this.cancel(instruction_id);
        }
    }

    @Override
    public void download(List<Instruction> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (Instruction instruction : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("任务标识", instruction.getTask_id());
            map.put("指令编码", instruction.getInstruction_code());
            map.put("指令由哪台设备做", instruction.getExecute_device_code());
            map.put("执行状态", instruction.getExecute_status());
            map.put("执行状态描述", instruction.getExecute_status_description());
            map.put("下一条指令由哪台设备做", instruction.getFollow_device_code());
            map.put("指令类型", instruction.getInstruction_type());
            map.put("指令状态", instruction.getInstruction_status());
            map.put("创建类型", instruction.getCreate_type());
            map.put("完成类型", instruction.getFinish_type());
            map.put("优先级", instruction.getPriority());
            map.put("执行编码", instruction.getExecute_code());
            map.put("执行信息", instruction.getExecute_message());
            map.put("起始点位编码", instruction.getStart_point_code());
            map.put("起始设备编码", instruction.getStart_device_code());
            map.put("目标点位编码", instruction.getNext_point_code());
            map.put("目标设备编码", instruction.getNext_device_code());
            map.put("排", instruction.getFrom_x());
            map.put("列", instruction.getFrom_y());
            map.put("层", instruction.getFrom_z());
            map.put("排", instruction.getTo_x());
            map.put("列", instruction.getTo_y());
            map.put("层", instruction.getTo_z());
            map.put("最后一条指令标识", instruction.getLast_instruction_id());
            map.put("是否允许修改", instruction.getCan_modify());
            map.put("备注", instruction.getRemark());
            map.put("是否启用", instruction.getIs_active());
            map.put("是否删除", instruction.getIs_delete());
            map.put("创建者", instruction.getCreate_by());
            map.put("创建时间", instruction.getCreate_time());
            map.put("修改者", instruction.getUpdate_by());
            map.put("修改时间", instruction.getUpdate_time());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finish(String id) {
        InstructionDto entity = this.findById(id);
        if (ObjectUtil.isEmpty(entity)||"3".equals(entity.getInstruction_status())) {
            log.error("指令{}被删除或无权限，操作失败!",id);
            return;
        }
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        entity.setUpdate_time(now);
        entity.setUpdate_by(currentUsername);
        entity.setInstruction_status("2");
        String instnextdevice = entity.getNext_device_code();
        String insttaskid = entity.getTask_id();
        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        Device startdevice = appService.findDeviceByCode(entity.getStart_device_code());
        if (ObjectUtils.isEmpty(startdevice)) {
            log.debug("地址对应设备未找到");
            throw new BadRequestException("地址对应设备未找到");
        }
        if (instnextdevice.indexOf(".") != -1) {
            instnextdevice = instnextdevice.substring(0, instnextdevice.indexOf("."));
        }
        Device device = appService.findDeviceByCode(instnextdevice);
        if (device == null) {
            log.debug("地址对应设备未找到");
            throw new BadRequestException("地址对应设备未找到");
        }
        DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class);

        JSONObject jo1 = new JSONObject();
        jo1.put("device_code", instnextdevice);

        String start_device_code = entity.getStart_device_code();

        Device deviceByCode = deviceAppService.findDeviceByCode(start_device_code);
        if (deviceByCode == null) {
            log.debug("地址对应设备未找到");
            throw new BadRequestException("地址对应设备未找到");
        }

        jo1.put("hasGoodStatus", "1");
        jo1.put("material_type", startdevice.getMaterial_type());

        jo1.put("quantity", startdevice.getQuantity());
        jo1.put("remark", startdevice.getRemark());
        jo1.put("batch", startdevice.getBatch());
        jo1.put("vehicle_code", entity.getVehicle_code());
        jo1.put("islock", "0");
        jo1.put("barrels_code", startdevice.getBarrels_code());
        jo1.put("cooperate_code", startdevice.getCooperate_code());
        jo1.put("powder_name", startdevice.getPowder_name());
        jo1.put("barrels_status", startdevice.getBarrels_status());
        deviceService.changeDeviceStatus(jo1);
        // 如果是无光电的设备 指令完成变更起点、终点状态
        JSONObject jo = new JSONObject();
        jo.put("device_code", entity.getStart_device_code());
        jo.put("hasGoodStatus", "0");
        jo.put("material_type", "");
        jo.put("quantity", "");
        jo.put("remark", "");
        jo.put("batch", "");
        jo.put("islock", "0");
        deviceService.changeDeviceStatus(jo);



        InstructionMybatis ins = ConvertUtil.convert(entity, InstructionMybatis.class);
        instructionMapper.updateById(ins);


        Task task = new LambdaQueryChainWrapper<>(taskMapper)
                .eq(Task::getTask_id, insttaskid)
                .one();
        // =0 则不用再次请求
        if (StrUtil.equals(task.getRequest_again(), "0")) {
            if (StrUtil.equals(task.getNext_device_code(), instnextdevice)) {
                taskService.finish(task.getTask_id());
            } else {
                finishAndCreateNextInst(new Instruction(entity));
            }
        }

        removeByCodeFromCache(entity.getInstruction_code());
//        this.reload();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finish(Instruction dto) {
        String now = DateUtil.now();
        dto.setInstruction_status("2");
//        WQLObject wo = WQLObject.getWQLObject("acs_instruction");
//        JSONObject json = (JSONObject) JSONObject.toJSON(dto);
//
//        wo.update(json);

        InstructionMybatis ins = ConvertUtil.convert(dto, InstructionMybatis.class);
        instructionMapper.updateById(ins);

        String instnextdevice = dto.getNext_device_code();
        String insttaskid = dto.getTask_id();
//        WQLObject taskwo = WQLObject.getWQLObject("acs_task");
//        JSONObject taskjson = taskwo.query("task_id ='" + insttaskid + "'").uniqueResult(0);
//        TaskDto obj = taskjson.toJavaObject(TaskDto.class);

        Task task = new LambdaQueryChainWrapper<>(taskMapper)
                .eq(Task::getTask_id, insttaskid)
                .one();
        // =0 则不用再次请求
        if (StrUtil.equals(task.getRequest_again(), "0")) {
            if (StrUtil.equals(task.getNext_device_code(), instnextdevice)) {
                taskService.finish(task.getTask_id());
            } else {
                finishAndCreateNextInst(dto);
            }
        }

        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class);
        Device device = appService.findDeviceByCode(instnextdevice);
        if (device == null) {
            log.debug("地址对应设备未找到");
            return;
        }
        // 如果是无光电的设备 放货任务完成需要变更有货状态
        //        StandardOrdinarySiteDeviceDriver standardOrdinarySiteDeviceDriver;
        //        if(device.getDeviceDriver() instanceof StandardOrdinarySiteDeviceDriver) {
        //            standardOrdinarySiteDeviceDriver = (StandardOrdinarySiteDeviceDriver)
        // device.getDeviceDriver();
        //            standardOrdinarySiteDeviceDriver.setMove(2);
        //        }

        // 如果是无光电的设备 指令完成变更起点、终点状态
        JSONObject jo = new JSONObject();
        jo.put("device_code", dto.getStart_point_code());
        jo.put("hasGoodStatus", "0");
        jo.put("material_type", "");
        jo.put("batch", "");
        deviceService.changeDeviceStatus(jo);

        JSONObject jo1 = new JSONObject();
        jo1.put("device_code", dto.getNext_point_code());
        jo1.put("hasGoodStatus", "1");
        jo1.put("material_type", dto.getMaterial());
        jo1.put("batch", dto.getBatch());
        deviceService.changeDeviceStatus(jo1);

        removeByCodeFromCache(dto.getInstruction_code());
        //            this.reload();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishAndCreateNextInst(Instruction dto) {
        dto = foramte(dto);
        String device_code = dto.getNext_device_code();
        Task acsTask = new LambdaQueryChainWrapper<>(taskMapper)
                .eq(Task::getTask_id, dto.getTask_id())
                .one();
        //        RouteLineService routeLineService = SpringContextHolder.getBean(RouteLineServiceImpl.class);
        //        List<RouteLineDto> list =
        //                routeLineService.getShortPathLines(
        //                        dto.getNext_device_code(), acsTask.getNext_device_code(), acsTask.getRoute_plan_code());
        //        if (ObjectUtils.isEmpty(list)) {
        //            throw new BadRequestException("路由不通");
        //        }
        // RouteLineDto routeLineDto = (RouteLineDto) list.get(0);
        //  String[] path = routeLineDto.getPath().split("->");
        //  List<String> pathlist = Arrays.asList(path);
        //        int index = 0;
        //        for (int m = 0; m < pathlist.size(); m++) {
        //            if (pathlist.get(m).equals(dto.getNext_device_code())) {
        //                index = m + 1;
        //                break;
        //            }
        //        }
        String next_device_code = dto.getNext_device_code();
        String start_device_code = dto.getNext_device_code();
        String start_point_code = null;
        String next_point_code = null;
        String start_device =
                deviceAppService
                        .findDeviceByCode(start_device_code)
                        .getDeviceDriverDefination()
                        .getFitDeviceTypes()
                        .get(0)
                        .name();
        String next_device =
                deviceAppService
                        .findDeviceByCode(next_device_code)
                        .getDeviceDriverDefination()
                        .getFitDeviceTypes()
                        .get(0)
                        .name();
        if (StrUtil.equals("storage", start_device)) {
            start_point_code = start_device_code + "-" + acsTask.getFrom_y() + "-" + acsTask.getFrom_z();
        } else {
            start_point_code = start_device_code;
        }
        if (StrUtil.equals("storage", next_device)) {
            next_point_code = next_device_code + "-" + acsTask.getTo_y() + "-" + acsTask.getTo_z();
        } else {
            next_point_code = next_device_code;
        }
        Instruction instdto = new Instruction();
        instdto.setInstruction_id(IdUtil.simpleUUID());
        instdto.setRoute_plan_code(acsTask.getRoute_plan_code());
        instdto.setRemark(acsTask.getRemark());
        instdto.setMaterial(acsTask.getMaterial());
        instdto.setQuantity(acsTask.getQuantity().toPlainString());
        instdto.setTask_id(acsTask.getTask_id());
        instdto.setTask_code(acsTask.getTask_code());
        instdto.setVehicle_code(acsTask.getVehicle_code());
        String now = DateUtil.now();
        instdto.setCreate_time(now);
        instdto.setCreate_by("auto");
        instdto.setStart_device_code(start_device_code);
        instdto.setNext_device_code(next_device_code);
        instdto.setStart_point_code(start_point_code);
        instdto.setNext_point_code(next_point_code);
        instdto.setPriority(acsTask.getPriority());
        instdto.setInstruction_status("0");
        instdto.setExecute_device_code(dto.getNext_device_code());
        try {
            this.create(instdto);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("完成并创建下一条指令", e.getMessage());
        }
    }

    @Override
    public void cancel(String id) throws Exception {
        // flag= true时取消指令
        boolean flag = false;
        InstructionDto entity = this.findById(id);
        if (entity == null) {
            List<InstructionMybatis> entities = this.list(new LambdaQueryWrapper<InstructionMybatis>().eq(InstructionMybatis::getTask_id, id).lt(InstructionMybatis::getInstruction_status, 2));
            if (CollectionUtils.isNotEmpty(entities)) {
                entity = BeanUtil.copyProperties(entities.get(0), InstructionDto.class);
            } else {
                return;
            }
        }
        TaskDto task = taskService.findByCodeFromCache(entity.getTask_code());
        if (StrUtil.isEmpty(entity.getRoute_plan_code())) {
            entity.setRoute_plan_code(task.getRoute_plan_code());
        }
        // != 0 为agv任务 1=magic 2=NDC 3=XZ,4=ZHEDA
        if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(), "1")
                && !StrUtil.equals(entity.getSend_status(), "2")) {
            MagicAgvService magicAgvService = SpringContextHolder.getBean(MagicAgvService.class);
            magicAgvService.deleteAgvInst(entity.getInstruction_code());
            flag = true;

        } else if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(), "2")) {
            // NDC agv指令不当场取消指令,需要等agv上报
            if (StrUtil.isEmpty(entity.getAgv_jobno())) {
                throw new BadRequestException("该任务已下发NDC，等待NDC反馈任务号，暂时无法取消！");
            } else {
                ndcAgvService.deleteAgvInstToNDC(new Instruction(entity));
                flag = true;
            }
        } else {
            flag = true;
        }
        if (StrUtil.equals(entity.getInstruction_type(), "4") ||
                StrUtil.equals(entity.getInstruction_type(), "3")) {
            ZheDaAgvService zheDaAgvService = SpringContextHolder.getBean(ZheDaAgvService.class);
            zheDaAgvService.deleteZDAgvInst(entity.getInstruction_code());
            flag = true;
        }
        if (flag) {
            String currentUsername = SecurityUtils.getCurrentUsername();
            String now = DateUtil.now();
            entity.setUpdate_time(now);
            entity.setUpdate_by(currentUsername);
            entity.setInstruction_status("3");
            InstructionMybatis ins = ConvertUtil.convert(entity, InstructionMybatis.class);
            instructionMapper.updateById(ins);
            DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
            DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class);
            // 如果是无光电的设备 指令完成变更起点、终点状态
            JSONObject jo = new JSONObject();
            jo.put("device_code", entity.getStart_device_code());
            if (StrUtil.equals(entity.getMaterial(), "1")) {
                jo.put("hasGoodStatus", "1");
            } else if (!StrUtil.equals(entity.getMaterial(), "1")
                    && !StrUtil.isEmpty(entity.getMaterial())) {
                jo.put("hasGoodStatus", "2");
            } else {
                jo.put("hasGoodStatus", "0");
            }
            jo.put("material_type", entity.getMaterial());
            jo.put("batch", entity.getBatch());
            jo.put("islock", "false");
            deviceService.changeDeviceStatus(jo);
            JSONObject jo1 = new JSONObject();
            jo1.put("device_code", entity.getNext_device_code());
            jo.put("hasGoodStatus", "0");
            jo.put("material_type", "");
            jo.put("batch", "");
            jo1.put("islock", "false");
            deviceService.changeDeviceStatus(jo1);
            String instnextdevice = entity.getNext_device_code();
            Device device = appService.findDeviceByCode(instnextdevice);
            if (device == null) {
                log.debug("地址对应设备未找到");
                return;
            }
            removeByCodeFromCache(entity.getInstruction_code());
            //            taskService.cancel(entity.getTask_id());
        }
        //        this.reload();
    }

    @Override
    public void forceCancel(String id) throws Exception {
        // flag= true时取消指令
        boolean flag = false;
        InstructionDto entity = this.findById(id);
        if (entity == null) {
            throw new BadRequestException("被删除或无权限，操作失败!");
        }
        TaskDto task = taskService.findByCodeFromCache(entity.getTask_code());
        if (StrUtil.isEmpty(entity.getRoute_plan_code())) {
            entity.setRoute_plan_code(task.getRoute_plan_code());
        }
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        entity.setUpdate_time(now);
        entity.setUpdate_by(currentUsername);
        entity.setInstruction_status("3");
//        WQLObject wo = WQLObject.getWQLObject("acs_instruction");
//        JSONObject json = (JSONObject) JSONObject.toJSON(entity);
//        wo.update(json);
        InstructionMybatis ins = ConvertUtil.convert(entity, InstructionMybatis.class);
        instructionMapper.updateById(ins);
        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class);
        // 如果是无光电的设备 指令完成变更起点、终点状态
        JSONObject jo = new JSONObject();
        jo.put("device_code", entity.getStart_device_code());
        if (StrUtil.equals(entity.getMaterial(), "1")) {
            jo.put("hasGoodStatus", "1");
        } else if (!StrUtil.equals(entity.getMaterial(), "1")
                && !StrUtil.isEmpty(entity.getMaterial())) {
            jo.put("hasGoodStatus", "2");
        } else {
            jo.put("hasGoodStatus", "0");
        }
        jo.put("material_type", entity.getMaterial());
        jo.put("batch", entity.getBatch());
        jo.put("islock", "false");
        deviceService.changeDeviceStatus(jo);

        JSONObject jo1 = new JSONObject();
        jo1.put("device_code", entity.getNext_device_code());
        jo.put("hasGoodStatus", "0");
        jo.put("material_type", "");
        jo.put("batch", "");
        jo1.put("islock", "false");
        deviceService.changeDeviceStatus(jo1);

        String instnextdevice = entity.getNext_device_code();
        Device device = appService.findDeviceByCode(instnextdevice);
        if (device == null) {
            log.debug("地址对应设备未找到");
            return;
        }
        removeByCodeFromCache(entity.getInstruction_code());
    }

    @Override
    public void cancelNOSendAgv(String id) throws Exception {
        // flag= true时取消指令
        boolean flag = false;
        InstructionDto entity = this.findById(id);
        if (entity == null) {
            throw new BadRequestException("被删除或无权限，操作失败!");
        }
        TaskDto task = taskService.findByCodeFromCache(entity.getTask_code());
        if (StrUtil.isEmpty(entity.getRoute_plan_code())) {
            entity.setRoute_plan_code(task.getRoute_plan_code());
        }
        String currentUsername = SecurityUtils.getCurrentUsername();
        String now = DateUtil.now();
        entity.setUpdate_time(now);
        entity.setUpdate_by(currentUsername);
        entity.setInstruction_status("3");
//            WQLObject wo = WQLObject.getWQLObject("acs_instruction");
//            JSONObject json = (JSONObject) JSONObject.toJSON(entity);
//            wo.update(json);
        InstructionMybatis ins = ConvertUtil.convert(entity, InstructionMybatis.class);
        instructionMapper.updateById(ins);
        DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
        DeviceService deviceService = SpringContextHolder.getBean(DeviceServiceImpl.class);

        // 如果是无光电的设备 指令完成变更起点、终点状态
        JSONObject jo = new JSONObject();
        jo.put("device_code", entity.getStart_device_code());
        if (StrUtil.equals(entity.getMaterial(), "1")) {
            jo.put("hasGoodStatus", "1");
        } else if (!StrUtil.equals(entity.getMaterial(), "1")
                && !StrUtil.isEmpty(entity.getMaterial())) {
            jo.put("hasGoodStatus", "2");
        } else {
            jo.put("hasGoodStatus", "0");
        }
        jo.put("material_type", entity.getMaterial());
        jo.put("batch", entity.getBatch());
        jo.put("islock", "false");
        deviceService.changeDeviceStatus(jo);

        JSONObject jo1 = new JSONObject();
        jo1.put("device_code", entity.getNext_device_code());
        jo.put("hasGoodStatus", "0");
        jo.put("material_type", "");
        jo.put("batch", "");
        jo1.put("islock", "false");
        deviceService.changeDeviceStatus(jo1);

        String instnextdevice = entity.getNext_device_code();
        Device device = appService.findDeviceByCode(instnextdevice);
        if (device == null) {
            log.debug("地址对应设备未找到");
            return;
        }
        removeByCodeFromCache(entity.getInstruction_code());
//        taskService.cancel(entity.getTask_id());
    }

    @Override
    public Instruction findByLinkNumSend(String code) {
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(code, inst.getLink_num()) && StrUtil.equals(inst.getIs_send(), "1")) {
                return inst;
            }
        }

        return null;
    }

    @Override
    public List<Instruction> findByLinkNum(String code) {
        List<Instruction> list = new ArrayList<>();
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(code, inst.getLink_num()) && StrUtil.equals(inst.getIs_send(), "0")) {
                list.add(inst);
            }
        }
        return list;
    }

    @Override
    public Instruction findByLinkNumNoSend(String code) {
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(code, inst.getLink_num()) && StrUtil.equals(inst.getIs_send(), "0")) {
                return inst;
            }
        }

        return null;
    }

    @Override
    public Instruction findByCodeFromCache(String code) {
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(code, inst.getInstruction_code())) {
                return inst;
            }
        }
        return null;
    }

    @Override
    public Instruction findByBarcodeFromCache(String barcode) {
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(barcode, inst.getVehicle_code())) {
                return inst;
            }
        }
        return null;
    }

    @Override
    public Instruction findByIdFromCache(String id) {
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(id, inst.getInstruction_id())) {
                return inst;
            }
        }
        return null;
    }

    @Override
    public Instruction foramte(Instruction inst) {
        String start_point_code = inst.getStart_point_code();
        String next_point_code = inst.getNext_point_code();
        String start_device_code = "";
        String next_device_code = "";
        if (StrUtil.contains(start_point_code, ".")) {
            String[] point = start_point_code.split("\\.");
            start_device_code = point[0];
        } else {
            start_device_code = start_point_code;
        }
        if (StrUtil.contains(next_point_code, ".")) {
            String[] point = next_point_code.split("\\.");
            next_device_code = point[0];
        } else {
            next_device_code = next_point_code;
        }
        if (StrUtil.contains(start_point_code, "-") && StrUtil.count(start_point_code, "-") == 2) {
            String[] start_point = start_point_code.split("-");
            inst.setFrom_x(start_point[0]);
            inst.setStart_device_code(start_point[0]);
            inst.setFrom_y(start_point[1]);
            inst.setFrom_z(start_point[2]);
        } else {
            String start_device =
                    deviceAppService
                            .findDeviceByCode(start_device_code)
                            .getDeviceDriverDefination()
                            .getFitDeviceTypes()
                            .get(0)
                            .name();
            if (StrUtil.equals("storage", start_device)) {
                String[] start_point = start_point_code.split("-");
                inst.setFrom_x(start_point[0]);
                inst.setStart_device_code(start_point[0]);
                inst.setFrom_y(start_point[1]);
                inst.setFrom_z(start_point[2]);
            } else {
                inst.setStart_device_code(start_device_code);
            }
        }

        if (StrUtil.contains(next_point_code, "-") && StrUtil.count(next_point_code, "-") == 2) {
            String[] next_point = next_point_code.split("-");
            inst.setTo_x(next_point[0]);
            inst.setNext_device_code(next_point[0]);
            inst.setTo_y(next_point[1]);
            inst.setTo_z(next_point[2]);
        } else {

            String next_device =
                    deviceAppService
                            .findDeviceByCode(next_device_code)
                            .getDeviceDriverDefination()
                            .getFitDeviceTypes()
                            .get(0)
                            .name();
            if (StrUtil.equals("storage", next_device)) {
                String[] next_point = start_point_code.split("-");
                inst.setTo_x(next_point[0]);
                inst.setNext_device_code(next_point[0]);
                inst.setTo_y(next_point[1]);
                inst.setTo_z(next_point[2]);
            } else {
                inst.setNext_device_code(next_device_code);
            }
        }
        return inst;
    }

    @Override
    public Instruction findByDeviceCodeFromCache(String devicecode) {
        List<Instruction> instructionList = instructions;
        ListUtil.sort(
                instructionList,
                new Comparator<Instruction>() {
                    @Override
                    public int compare(Instruction o1, Instruction o2) {
                        return o1.getCreate_time().compareTo(o2.getCreate_time());
                    }
                });
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(devicecode, inst.getStart_device_code())
                    && inst.getInstruction_status().equals("0")) {
                return inst;
            }
        }

        return null;
    }

    @Override
    public List<Instruction> findAllInstFromCache() {
        return instructions;
    }

    @Override
    public Integer querySameDestinationInst(String devicecode) {
        int num = 0;
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            // 处理空盘位站点
            String next_code = inst.getNext_point_code();
            if (next_code.indexOf(".") != -1) {
                next_code = next_code.substring(0, next_code.indexOf("."));
            }
            if (StrUtil.equals(devicecode, next_code)) {
                num = num + 1;
            }
        }

        return num;
    }

    @Override
    public Integer querySameInstType(String inst_type) {
        int num = 0;
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            if (StrUtil.equals(inst.getInstruction_type(), inst_type)) {
                num = num + 1;
            }
        }
        return num;
    }

    @Override
    public Integer querySameOriginInst(String devicecode) {
        int num = 0;
        Iterator<Instruction> it = instructions.iterator();
        while (it.hasNext()) {
            Instruction inst = it.next();
            // 处理空盘位站点
            String start_code = inst.getStart_point_code();
            if (start_code.indexOf(".") != -1) {
                start_code = start_code.substring(0, start_code.indexOf("."));
            }
            if (StrUtil.equals(devicecode, start_code)) {
                num = num + 1;
            }
        }
        return num;
    }

    @Override
    public boolean removeByCodeFromCache(String code) {
        CopyOnWriteArrayList<Instruction> instructions = (CopyOnWriteArrayList<Instruction>) this.instructions;
        instructions.removeIf((inst) -> {
            return inst.getInstruction_code().equals(code);
        });
//      while (iterator.hasNext()) {
//        Instruction instruction = iterator.next();
//        if (instruction.getInstruction_code().equals(code)) {
//          iterator.remove();
//          return true;
//        }
//      }
        return true;
    }

    @Override
    public boolean createLkInst(String type, Instruction dto) {
        Class var3 = TaskInstructionLock.class;
        synchronized (TaskInstructionLock.class) {
            // 入库
            AcsToLiKuService acsToLiKuService = SpringContextHolder.getBean(AcsToLiKuService.class);
            Resp resp = null;
            if (StrUtil.equals(type, "1")) {
                InStoreRequest request = new InStoreRequest();
                request.setFloorNo(Integer.parseInt(dto.getTo_z()));
                request.setType(1);
                request.setPalletCode(dto.getVehicle_code());
                request.setOrderId(dto.getInstruction_code());
                request.setSrcLocation(dto.getStart_point_code());
                request.setDestLocation(dto.getNext_point_code());
                resp = acsToLiKuService.inStore(request);
                // 空托入库
            } else if (StrUtil.equals(type, "2")) {
                InStoreRequest request = new InStoreRequest();
                request.setFloorNo(Integer.parseInt(dto.getTo_z()));
                request.setType(2);
                request.setPalletCode(dto.getVehicle_code());
                request.setOrderId(dto.getInstruction_code());
                request.setSrcLocation(dto.getStart_point_code());
                request.setDestLocation(dto.getNext_point_code());
                resp = acsToLiKuService.inStore(request);
                // 出库
            } else if (StrUtil.equals(type, "3")) {
                OutStoreRequest outStore = new OutStoreRequest();
                BaseStoreRequest baseReq = new BaseStoreRequest();
                List<BaseStoreRequest> list = new ArrayList();
                baseReq.setOrderId(dto.getInstruction_code());
                baseReq.setSrcLocation(dto.getStart_point_code());
                baseReq.setDestLocation(dto.getNext_point_code());
                baseReq.setFloorNo(Integer.parseInt(dto.getFrom_z()));
                baseReq.setPalletCode(dto.getVehicle_code());
                list.add(baseReq);
                outStore.setOrderInfos(list);
                outStore.setGroupId(dto.getInstruction_code());
                resp = acsToLiKuService.outStore(outStore);
                // 空托出库
            } else if (StrUtil.equals(type, "4")) {
                EmptyVehicleOutStoreRequest emptyVehicleOutStoreRequest = new EmptyVehicleOutStoreRequest();
                emptyVehicleOutStoreRequest.setOrderId(dto.getInstruction_code());
                emptyVehicleOutStoreRequest.setFloorNo(Integer.parseInt(dto.getFrom_z()));
                emptyVehicleOutStoreRequest.setSrcLocation(dto.getStart_point_code());
                emptyVehicleOutStoreRequest.setDestLocation(dto.getNext_point_code());
                emptyVehicleOutStoreRequest.setPalletCode(dto.getVehicle_code());
                resp = acsToLiKuService.emptyVehicleOutStore(emptyVehicleOutStoreRequest);
                // 转库
            } else if (StrUtil.equals(type, "5")) {
                MoveStoreRequest moveStoreRequest = new MoveStoreRequest();
                BaseStoreRequest baseReq = new BaseStoreRequest();
                List<BaseStoreRequest> list = new ArrayList();
                baseReq.setFloorNo(Integer.parseInt(dto.getFrom_z()));
                baseReq.setPalletCode(dto.getVehicle_code());
                baseReq.setOrderId(dto.getInstruction_code());
                baseReq.setSrcLocation(dto.getStart_point_code());
                baseReq.setDestLocation(dto.getNext_point_code());
                list.add(baseReq);
                moveStoreRequest.setGroupId(dto.getInstruction_code());
                moveStoreRequest.setOrderInfos(list);
                resp = acsToLiKuService.moveStore(moveStoreRequest);
            }

            if (ObjectUtil.isNotEmpty(resp)) {
                if (StrUtil.equals(resp.getResult(), "true")) {
                    dto.setSend_status("1");
                } else {
                    dto.setSend_status("2");
                    dto.setRemark(resp.getData().toString());
                    return false;
                }
            } else {
                dto.setSend_status("2");
                dto.setRemark("ERROR");
                return false;
            }
            return true;
        }
    }

    /*
     * 判断是否为整数
     * @param str 传入的字符串
     * @return 是整数返回true,否则返回false
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    @Override
    public void init(String id) {
        InstructionDto inst = this.findById(id);
        if (inst == null) {
            throw new BadRequestException("指令不存在或已删除");
        }
        if ("2".equals(inst.getInstruction_status())) {
            throw new BadRequestException("指令已经完成");
        }

        Device startDevice = deviceAppService.findDeviceByCode(inst.getStart_device_code());
        DeviceDriver startDeviceDriver = startDevice.getDeviceDriver();
        if (startDeviceDriver instanceof SiemensConveyorDeviceDriver) {
            Device nextDevice = deviceAppService.findDeviceByCode(inst.getNext_device_code());

            List<Map<String, String>> list = new ArrayList<>();
            Map<String, String> map = new HashMap<>();
            map.put("code", "to_target");
            map.put("value", nextDevice.getExtraValue().get("address").toString());
            list.add(map);
            Map<String, String> map2 = new HashMap<>();
            map2.put("code", "to_task");
            map2.put("value", inst.getInstruction_code());
            list.add(map2);
            Map<String, String> map3 = new HashMap<>();
            map3.put("code", "to_command");
            map3.put("value", "1");
            list.add(map3);
            ((SiemensConveyorDeviceDriver) startDeviceDriver).writing(list);
        }
    }
}
