|  |  | 
 |  |  |      */ | 
 |  |  |     @Transactional(propagation = Propagation.REQUIRES_NEW) | 
 |  |  |     public void buildMajorTask(Long agvId, List<Task> taskList) { | 
 |  |  |         if (Cools.isEmpty(agvId, taskList)) { return; } | 
 |  |  |         if (Cools.isEmpty(agvId, taskList)) { | 
 |  |  |             return; | 
 |  |  |         } | 
 |  |  |         try { | 
 |  |  |             // valid ----------------------------------------------- | 
 |  |  |             Agv agv = agvService.getById(agvId); | 
 |  |  |             if (!agvService.judgeEnable(agv.getId(), false,  true)) { | 
 |  |  |             if (!agvService.judgeEnable(agv.getId(), false, true)) { | 
 |  |  |                 return; | 
 |  |  |             } | 
 |  |  |             if (!Cools.isEmpty(taskService.selectInSts(agvId, TaskStsType.ASSIGN, TaskStsType.PROGRESS))) { | 
 |  |  | 
 |  |  |              * val: new TaskPosDto(taskId, new Double[]{code.getX(), code.getY()}, posType) | 
 |  |  |              */ | 
 |  |  |             Map<String, List<TaskPosDto>> groups = new HashMap<>(); | 
 |  |  |             final String sameGroupXy = configService.getVal( "sameGroupXy", String.class); | 
 |  |  |             final String sameGroupXy = configService.getVal("sameGroupXy", String.class); | 
 |  |  |  | 
 |  |  |             int backpackLev = 0; | 
 |  |  |             for (Task task : taskList) { | 
 |  |  |  | 
 |  |  |                 backpackLev ++; | 
 |  |  |                 backpackLev++; | 
 |  |  |                 Code startCode = null; | 
 |  |  |                 Code endCode = null; | 
 |  |  |                 Loc oriLoc = null; Loc destLoc = null; | 
 |  |  |                 Sta oriSta = null; Sta destSta = null; | 
 |  |  |                 Loc oriLoc = null; | 
 |  |  |                 Loc destLoc = null; | 
 |  |  |                 Sta oriSta = null; | 
 |  |  |                 Sta destSta = null; | 
 |  |  |                 switch (Objects.requireNonNull(TaskTypeType.get(task.getTaskTypeEl()))) { | 
 |  |  |                     case LOC_TO_LOC: | 
 |  |  |                         oriLoc = locService.getById(task.getOriLoc()); | 
 |  |  | 
 |  |  |  | 
 |  |  |             // re-order by agv current position | 
 |  |  |             Code currCode = codeService.getCacheById(agvDetail.getRecentCode()); | 
 |  |  |             Double[] currPosition = new Double[] {currCode.getX(), currCode.getY()}; | 
 |  |  |             Double[] currPosition = new Double[]{currCode.getX(), currCode.getY()}; | 
 |  |  |  | 
 |  |  |             List<List<TaskPosDto>> pickGroups = new ArrayList<>(); | 
 |  |  |             List<List<TaskPosDto>> dropGroups = new ArrayList<>(); | 
 |  |  | 
 |  |  |             List<Segment> segmentList = new ArrayList<>(); | 
 |  |  |             for (List<TaskPosDto> dtoList : list) { | 
 |  |  |                 for (TaskPosDto taskPosDto : dtoList) { | 
 |  |  |                     segSerial ++; | 
 |  |  |                     segSerial++; | 
 |  |  |                     AgvBackpackType backpackType = AgvBackpackDto.find(backpackDtoList, taskPosDto.getTaskId()); | 
 |  |  |                     assert null != backpackType; | 
 |  |  |  | 
 |  |  | 
 |  |  |      * 充电 回待机位任务 | 
 |  |  |      * zc 新增了是否强制,强制说明由用户发起,小车在超过低电量就可以做移动充电去待机位 | 
 |  |  |      */ | 
 |  |  |     @Transactional(propagation = Propagation.REQUIRES_NEW) // although there is a Transactional here that the lock is isolated, but we can't join the caller's Transactional | 
 |  |  |     public boolean buildMinorTask(Long agvId, TaskTypeType taskType, String destination, Jam jam,boolean force) { | 
 |  |  |         if (Cools.isEmpty(agvId, taskType)) { return false; } | 
 |  |  |     @Transactional(propagation = Propagation.REQUIRES_NEW) | 
 |  |  |     // although there is a Transactional here that the lock is isolated, but we can't join the caller's Transactional | 
 |  |  |     public boolean buildMinorTask(Long agvId, TaskTypeType taskType, String destination, Jam jam, boolean force) { | 
 |  |  |         if (Cools.isEmpty(agvId, taskType)) { | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |         try { | 
 |  |  |             String agvNo = agvService.getAgvNo(agvId); | 
 |  |  |             if (!agvService.judgeEnable(agvId,false, force)) { | 
 |  |  |             if (!agvService.judgeEnable(agvId, false, force)) { | 
 |  |  |                 return false; | 
 |  |  |             } | 
 |  |  |             if (!Cools.isEmpty(taskService.selectInSts(agvId, TaskStsType.ASSIGN, TaskStsType.PROGRESS))) { | 
 |  |  | 
 |  |  |             task.setAgvId(agvId); | 
 |  |  |             task.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3)); | 
 |  |  |             List<Task> lastTasks = taskService.list(new LambdaQueryWrapper<Task>().orderByDesc(Task::getId)); | 
 |  |  |             task.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks)?null:lastTasks.get(0).getSeqNum())); | 
 |  |  |             task.setSeqNum(Utils.generateSeqNum(Cools.isEmpty(lastTasks) ? null : lastTasks.get(0).getSeqNum())); | 
 |  |  |             task.setOriCode(agvDetail.getCode()); | 
 |  |  |             task.setDestCode(endCode.getId()); | 
 |  |  |             // lane | 
 |  |  | 
 |  |  |             if (null != destLane) { | 
 |  |  |                 task.setDestLaneHash(destLane.getHashCode()); | 
 |  |  |             } | 
 |  |  |             task.setPriority(taskType.equals(TaskTypeType.TO_CHARGE)?2:1); | 
 |  |  |             task.setPriority(taskType.equals(TaskTypeType.TO_CHARGE) ? 2 : 1); | 
 |  |  |             task.setTaskSts(TaskStsType.ASSIGN.val()); | 
 |  |  |             task.setTaskType(taskType.val()); | 
 |  |  |             task.setIoTime(now); | 
 |  |  | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             // generate segment | 
 |  |  |             int segSerial = 0;     segSerial ++; | 
 |  |  |             int segSerial = 0; | 
 |  |  |             segSerial++; | 
 |  |  |             List<Segment> segmentList = new ArrayList<>(); | 
 |  |  |  | 
 |  |  |             String posType = ""; | 
 |  |  |             switch (taskType){ | 
 |  |  |             switch (taskType) { | 
 |  |  |                 case TO_CHARGE: | 
 |  |  |                     posType = TaskPosDto.PosType.TO_CHARGE.toString(); | 
 |  |  |                     break; | 
 |  |  | 
 |  |  |     @Transactional | 
 |  |  |     public synchronized void generateAction(Long agvId, List<Segment> segmentList, List<String> pathList, Date algoStartTime) { | 
 |  |  |         try { | 
 |  |  |             if (Cools.isEmpty(agvId, segmentList)) { return; } | 
 |  |  |             if (Cools.isEmpty(agvId, segmentList)) { | 
 |  |  |                 return; | 
 |  |  |             } | 
 |  |  |             Date now = new Date(); | 
 |  |  |             long actionPrepareSts = ActionStsType.PREPARE.val(); | 
 |  |  | //            JSONObject storeDirection = configService.getVal("storeDirection", JSONObject.class); | 
 |  |  | 
 |  |  |                     List<String> pathListPart = pathList.subList(pathList.indexOf(lastCode.getData()), pathList.indexOf(code.getData()) + 1); | 
 |  |  |  | 
 |  |  |                     for (int i = 0; i < pathListPart.size(); i++) { | 
 |  |  |                         if (i == 0) { continue; } | 
 |  |  |                         if (i == 0) { | 
 |  |  |                             continue; | 
 |  |  |                         } | 
 |  |  |  | 
 |  |  |                         String next = pathListPart.get(i); | 
 |  |  |  | 
 |  |  | 
 |  |  |                                 task.getBusId(),    // 总线 | 
 |  |  |                                 task.getId(),    // 任务 | 
 |  |  |                                 null,    // 动作号 | 
 |  |  |                                  null,    // 优先级 | 
 |  |  |                                 null,    // 优先级 | 
 |  |  |                                 ActionTypeType.ReadyReleaseToShelvesLoc.desc,    // 名称 | 
 |  |  |                                 (double) agvDirectionType.val,    // 属性值 | 
 |  |  |                                 lastCode.getData(),    // 地面码 | 
 |  |  | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |  | 
 |  |  |  | 
 |  |  |     @Transactional | 
 |  |  |     public void publishAction(String actionGroupId) { | 
 |  |  |         try { | 
 |  |  | 
 |  |  |             String agvNo = agvService.getAgvNo(agvId); | 
 |  |  |             if (!agvService.judgeOnline(agvId)) { | 
 |  |  |                 return; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             int lastActionIndex = actionSorter.findLastActionIndex(actionList, ActionTypeType.ReadyReleaseToAgvSite.val()); | 
 |  |  |             if (lastActionIndex != -1) { | 
 |  |  |                 List<Action> sortedList = new ArrayList<>(actionList.size()); | 
 |  |  |                 for (int i = 0; i < actionList.size(); i++) { | 
 |  |  |                     // 跳过动作本身 | 
 |  |  |                     if (i != lastActionIndex) { | 
 |  |  |                         sortedList.add(actionList.get(i)); | 
 |  |  |                     } | 
 |  |  |                 } | 
 |  |  |                 actionList = sortedList; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             Action shang = actionService.getOne(new LambdaQueryWrapper<Action>().eq(Action::getAgvId, agvId).eq(Action::getActionSts, ActionStsType.PREPARE.val()).eq(Action::getActionType, ActionTypeType.ReadyReleaseToAgvSite.val()).orderByDesc(Action::getId)); | 
 |  |  |             if (shang != null) { | 
 |  |  |                 int turnCornerIdx = actionSorter.findFirstActionIndex(actionList, ActionTypeType.TurnCorner.val()); | 
 |  |  |                 if (turnCornerIdx == -1) { | 
 |  |  |                     actionList.add(0, shang); | 
 |  |  |                 } else { | 
 |  |  |                     actionList.add(turnCornerIdx, shang); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             long actionIssuedSts = ActionStsType.ISSUED.val(); | 
 |  |  | 
 |  |  |  | 
 |  |  |                 // segment list | 
 |  |  |                 List<Segment> segmentList = segmentService.list(new LambdaQueryWrapper<Segment>() | 
 |  |  |                         .eq(Segment::getGroupId, serialNo) | 
 |  |  |                                 .eq(Segment::getGroupId, serialNo) | 
 |  |  | //                        .eq(Segment::getState, SegmentStateType.RUNNING.toString()) | 
 |  |  |                         .orderByAsc(Segment::getSerial) | 
 |  |  |                                 .orderByAsc(Segment::getSerial) | 
 |  |  |                 ); | 
 |  |  |  | 
 |  |  |                 // settlement | 
 |  |  | 
 |  |  |         for (Segment segment : segmentList) { | 
 |  |  |             boolean taskComplete = false; | 
 |  |  |  | 
 |  |  |             Task task = taskService.getById(segment.getTaskId());   assert null != task; | 
 |  |  |             TaskTypeType typeType = TaskTypeType.get(task.getTaskTypeEl());     assert null != typeType; | 
 |  |  |             Task task = taskService.getById(segment.getTaskId()); | 
 |  |  |             assert null != task; | 
 |  |  |             TaskTypeType typeType = TaskTypeType.get(task.getTaskTypeEl()); | 
 |  |  |             assert null != typeType; | 
 |  |  |  | 
 |  |  |             TaskPosDto.PosType posType = TaskPosDto.queryPosType(segment.getPosType()); | 
 |  |  |             switch (Objects.requireNonNull(posType)) { |