From a71d7a7a4b437a718e68ec41dcecd30ee7ff55e7 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期日, 04 一月 2026 09:45:30 +0800
Subject: [PATCH] #

---
 zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java |  100 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 92 insertions(+), 8 deletions(-)

diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
index ad7a709..513df59 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/MainService.java
@@ -276,6 +276,9 @@
                             int backpackLev = 0;
                             int backpack = agvService.getBackpack(agvId);
                             List<Integer> usedBackpacks = segmentService.selectUsedBackpacks(currSeg.getTravelId(), agvId);
+                            if (usedBackpacks.size() >= backpack) {
+                                throw new CoolException("[Agv:" + agvNo + "] allocate inbound segment failed: no idle backpack to use");
+                            }
                             for (int lev = 1; lev <= backpack; lev++) {
                                 if (!usedBackpacks.contains(lev)) {
                                     backpackLev = lev;
@@ -290,7 +293,8 @@
                             currSeg.setState(SegmentStateType.INIT.toString());
                             currSeg.setUpdateTime(now);
                             if (!segmentService.updateById(currSeg)) {
-                                log.error("Segment [{}] failed to update 锛侊紒锛�", currSeg.getGroupId() + " - " + currSeg.getSerial());
+//                                log.error("Segment [{}] failed to update 锛侊紒锛�", currSeg.getGroupId() + " - " + currSeg.getSerial());
+                                throw new CoolException("failed to update segment [" + currSeg.getGroupId() + "-" + currSeg.getSerial() + "] failed");
                             }
 
                             // new oriSta seg
@@ -307,42 +311,122 @@
                             loadSeg.setCreateTime(now);
                             loadSeg.setUpdateTime(now);
                             if (!segmentService.save(loadSeg)) {
-                                log.error("Segment [{}] failed to save 锛侊紒锛�", loadSeg.getTravelId() + " - " + loadSeg.getSerial());
+//                                log.error("Segment [{}] failed to save 锛侊紒锛�", loadSeg.getTravelId() + " - " + loadSeg.getSerial());
+                                throw new CoolException("failed to save segment [" + loadSeg.getGroupId() + "-" + loadSeg.getSerial() + "] failed");
                             }
 
                             // place segment
                             TaskTypeType taskType = Objects.requireNonNull(TaskTypeType.get(task.getTaskTypeEl()));
                             TaskPosDto.PosType posType;
-                            Long endCodeId;
+                            Code endCode;
                             switch (taskType) {
                                 case STA_TO_LOC:
                                     posType = TaskPosDto.PosType.DEST_LOC;
                                     Loc destLoc = locService.getById(task.getDestLoc());
-                                    endCodeId = destLoc.getCode();
+                                    endCode = codeService.getCacheById(destLoc.getCode());
                                     break;
                                 case STA_TO_STA:
                                     posType = TaskPosDto.PosType.DEST_STA;
                                     Sta destSta = staService.getById(task.getDestSta());
-                                    endCodeId = destSta.getCode();
+                                    endCode = codeService.getCacheById(destSta.getCode());
                                     break;
                                 default:
                                     throw new BusinessException("[Agv:" + agvNo + "] allocate inbound only supports STA_TO_LOC/STA_TO_STA");
                             }
 
+                            // calc placeSeg serial, through code position
+                            List<Segment> destSegList = segmentService.list(new LambdaQueryWrapper<Segment>()
+                                    .eq(Segment::getAgvId, agvId)
+                                    .eq(Segment::getTravelId, currSeg.getTravelId())
+                                    .ne(Segment::getState, SegmentStateType.FINISH.toString())
+                                    .in(Segment::getPosType,
+                                            TaskPosDto.PosType.DEST_LOC.toString(),
+                                            TaskPosDto.PosType.DEST_STA.toString())
+                                    .orderByAsc(Segment::getSerial)
+                            );
+
+                            // build destPosList and sort
+                            List<TaskPosDto> destPosList = new ArrayList<>();
+                            for (Segment destSeg : destSegList) {
+                                Code code = codeService.getCacheById(destSeg.getEndNode());
+                                if (code == null) continue;
+
+                                TaskPosDto dto = new TaskPosDto(destSeg.getTaskId(), new Double[]{code.getX(), code.getY()}, TaskPosDto.PosType.DEST_LOC);
+                                dto.setCodeId(code.getId());
+                                dto.setSegId(destSeg.getId());
+                                destPosList.add(dto);
+                            }
+                            TaskPosDto newDto = new TaskPosDto(task.getId(), new Double[]{endCode.getX(), endCode.getY()}, TaskPosDto.PosType.DEST_LOC);
+                            newDto.setCodeId(endCode.getId());
+                            destPosList.add(newDto);
+
+                            destPosList.sort((a, b) -> {
+                                int c1 = Double.compare(a.getXy()[0], b.getXy()[0]); // X
+                                if (c1 != 0) return c1;
+                                int c2 = Double.compare(a.getXy()[1], b.getXy()[1]); // Y
+                                if (c2 != 0) return c2;
+                                // 鍚屽潗鏍囨椂鐢� taskId 鎵撴暎锛堥伩鍏嶆帓搴忎笉绋冲畾锛�
+                                return Long.compare(a.getTaskId(), b.getTaskId());
+                            });
+
+                            // get placeSeg serial
+                            int placeSegSerial;
+                            // query placeSeg idx
+                            int idx = -1;
+                            for (int i = 0; i < destPosList.size(); i++) {
+                                if (Objects.equals(destPosList.get(i).getCodeId(), newDto.getCodeId())
+                                        && Objects.equals(destPosList.get(i).getTaskId(), newDto.getTaskId())) {
+                                    idx = i;
+                                    break;
+                                }
+                            }
+                            if (idx < 0) {
+                                throw new BusinessException("failed to locate new destination in sorted list");
+                            }
+
+                            // 鍚庣户鐐�
+                            if (idx + 1 == destPosList.size()) {
+                                placeSegSerial = destSegList.get(destSegList.size() - 1).getSerial() + 1;
+                            } else {
+                                TaskPosDto afterTaskPos = destPosList.get(idx + 1);
+                                Segment afterSeg = destSegList.stream()
+                                        .filter(destSeg -> Objects.equals(destSeg.getId(), afterTaskPos.getSegId()))
+                                        .findFirst()
+                                        .orElse(null);
+                                if (null == afterSeg) {
+                                    placeSegSerial = destSegList.get(destSegList.size() - 1).getSerial() + 1;
+                                } else {
+                                    placeSegSerial = afterSeg.getSerial();
+                                }
+                            }
+//                            placeSegSerial = Math.max(placeSegSerial, currSeg.getSerial() + 1);
+
+                            // shift serial after
+                            segmentService.update(new LambdaUpdateWrapper<Segment>()
+                                    .eq(Segment::getAgvId, agvId)
+                                    .eq(Segment::getTravelId, currSeg.getTravelId())
+                                    .ge(Segment::getSerial, placeSegSerial)
+                                    .ne(Segment::getState, SegmentStateType.FINISH.toString())
+                                    .setSql("serial = serial + 1")
+                                    .set(Segment::getUpdateTime, now)
+                            );
+
+                            // save place segment
                             Segment placeSeg = new Segment();
                             placeSeg.setUuid(String.valueOf(snowflakeIdWorker.nextId()).substring(3));
                             placeSeg.setTravelId(currSeg.getTravelId());
                             placeSeg.setAgvId(agvId);
                             placeSeg.setTaskId(task.getId());
-                            placeSeg.setSerial();
-                            placeSeg.setEndNode(endCodeId);
+                            placeSeg.setSerial(placeSegSerial);
+                            placeSeg.setEndNode(endCode.getId());
                             placeSeg.setPosType(posType.toString());
                             placeSeg.setState(SegmentStateType.INIT.toString());
                             placeSeg.setBackpack(backpackLev);
                             placeSeg.setCreateTime(now);
                             placeSeg.setUpdateTime(now);
                             if (!segmentService.save(placeSeg)) {
-                                log.error("Segment [{}] failed to save 锛侊紒锛�", placeSeg.getTravelId() + " - " + placeSeg.getSerial());
+//                                log.error("Segment [{}] failed to save 锛侊紒锛�", placeSeg.getTravelId() + " - " + placeSeg.getSerial());
+                                throw new CoolException("failed to save segment [" + placeSeg.getGroupId() + "-" + placeSeg.getSerial() + "] failed");
                             }
 
                             // update task

--
Gitblit v1.9.1