#
Junjie
20 小时以前 058d7bbb714634e42bff1dd71fdfca3a378421d3
#
2个文件已添加
4个文件已修改
199 ■■■■■ 已修改文件
src/main/java/com/zy/common/utils/NavigateUtils.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/station/StationSegmentExecutor.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/station/StationSegmentPlanner.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/zy/common/utils/NavigateUtilsTest.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/zy/core/thread/impl/station/StationSegmentExecutorTest.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/zy/core/thread/impl/station/StationSegmentPlannerTest.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/NavigateUtils.java
@@ -1994,8 +1994,8 @@
    }
    private List<NavigateNode> normalizeStationPath(List<NavigateNode> path) {
        HashSet<Integer> stationIdSet = new HashSet<>();
        List<NavigateNode> filterList = new ArrayList<>();
        Integer lastStationId = null;
        for (NavigateNode navigateNode : safeList(path)) {
            if (navigateNode == null) {
                continue;
@@ -2010,9 +2010,14 @@
                continue;
            }
            Integer stationId = valueObject.getInteger("stationId");
            if (stationId == null || !stationIdSet.add(stationId)) {
            if (stationId == null) {
                continue;
            }
            // 仅压缩连续重复站点,保留环线重算场景下后续再次经过的同一站点。
            if (lastStationId != null && lastStationId.equals(stationId)) {
                continue;
            }
            lastStationId = stationId;
            NavigateNode clonedNode = navigateNode.clone();
            if (clonedNode == null) {
                continue;
src/main/java/com/zy/core/thread/impl/station/StationSegmentExecutor.java
@@ -89,6 +89,7 @@
        long lastSeenAt = System.currentTimeMillis();
        int segCursor = 0;
        Integer lastCurrentStationId = null;
        int lastMatchedPathIndex = -1;
        boolean firstRun = true;
        while (true) {
            try {
@@ -144,12 +145,17 @@
                    break;
                }
                int currentIndex = effectiveFullPath.indexOf(currentStation.getStationId());
                int currentIndex = resolveCurrentPathIndex(
                        effectiveFullPath,
                        currentStation.getStationId(),
                        lastMatchedPathIndex
                );
                if (currentIndex < 0) {
                    Thread.sleep(500L);
                    firstRun = false;
                    continue;
                }
                lastMatchedPathIndex = currentIndex;
                int remaining = effectiveFullPath.size() - currentIndex - 1;
                if (remaining <= 0) {
@@ -192,6 +198,38 @@
        }
    }
    private int resolveCurrentPathIndex(List<Integer> fullPathStationIds,
                                        Integer currentStationId,
                                        int lastMatchedPathIndex) {
        if (fullPathStationIds == null || fullPathStationIds.isEmpty() || currentStationId == null) {
            return -1;
        }
        if (lastMatchedPathIndex >= 0
                && lastMatchedPathIndex < fullPathStationIds.size()
                && equalsInteger(currentStationId, fullPathStationIds.get(lastMatchedPathIndex))) {
            return lastMatchedPathIndex;
        }
        int nextIndex = findNextStationIndex(fullPathStationIds, currentStationId, Math.max(lastMatchedPathIndex + 1, 0));
        if (nextIndex >= 0) {
            return nextIndex;
        }
        return findNextStationIndex(fullPathStationIds, currentStationId, 0);
    }
    private int findNextStationIndex(List<Integer> path, Integer stationId, int fromIndex) {
        if (path == null || path.isEmpty() || stationId == null) {
            return -1;
        }
        int startIdx = Math.max(fromIndex, 0);
        for (int i = startIdx; i < path.size(); i++) {
            if (equalsInteger(stationId, path.get(i))) {
                return i;
            }
        }
        return -1;
    }
    private boolean sendSegmentWithRetry(StationCommand command,
                                         StationTaskTraceRegistry traceRegistry,
                                         Integer traceVersion,
src/main/java/com/zy/core/thread/impl/station/StationSegmentPlanner.java
@@ -34,8 +34,12 @@
        int total = path.size();
        List<Integer> segmentEndIndices = new ArrayList<>();
        if (liftTransferPath != null) {
            int searchStartIdx = 0;
            for (Integer liftTransferStationId : liftTransferPath) {
                int endIndex = path.indexOf(liftTransferStationId);
                int endIndex = findNextStationIndex(path, liftTransferStationId, searchStartIdx);
                if (endIndex >= 0) {
                    searchStartIdx = endIndex + 1;
                }
                if (endIndex <= 0) {
                    continue;
                }
@@ -87,6 +91,19 @@
        return plan;
    }
    private int findNextStationIndex(List<Integer> path, Integer stationId, int fromIndex) {
        if (path == null || path.isEmpty() || stationId == null) {
            return -1;
        }
        int startIdx = Math.max(fromIndex, 0);
        for (int i = startIdx; i < path.size(); i++) {
            if (stationId.equals(path.get(i))) {
                return i;
            }
        }
        return -1;
    }
    private List<Integer> copyIntegerList(List<Integer> source) {
        if (source == null) {
            return new ArrayList<>();
src/test/java/com/zy/common/utils/NavigateUtilsTest.java
New file
@@ -0,0 +1,49 @@
package com.zy.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.zy.common.model.NavigateNode;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
class NavigateUtilsTest {
    @Test
    void normalizeStationPath_keepsLoopRevisitStationsWhileCompressingAdjacentDuplicates() {
        NavigateUtils navigateUtils = new NavigateUtils();
        @SuppressWarnings("unchecked")
        List<NavigateNode> normalizedPath = (List<NavigateNode>) ReflectionTestUtils.invokeMethod(
                navigateUtils,
                "normalizeStationPath",
                List.of(
                        buildNode(121, 0, 0),
                        buildNode(121, 0, 1),
                        buildNode(124, 0, 2),
                        buildNode(186, 0, 3),
                        buildNode(189, 0, 4),
                        buildNode(121, 0, 5),
                        buildNode(124, 0, 6),
                        buildNode(124, 0, 7),
                        buildNode(125, 0, 8),
                        buildNode(127, 0, 9)
                )
        );
        List<Integer> stationIdList = normalizedPath.stream()
                .map(node -> JSONObject.parseObject(node.getNodeValue()).getInteger("stationId"))
                .collect(Collectors.toList());
        assertEquals(List.of(121, 124, 186, 189, 121, 124, 125, 127), stationIdList);
    }
    private NavigateNode buildNode(int stationId, int x, int y) {
        NavigateNode node = new NavigateNode(x, y);
        node.setNodeValue("{\"stationId\":" + stationId + "}");
        return node;
    }
}
src/test/java/com/zy/core/thread/impl/station/StationSegmentExecutorTest.java
@@ -14,9 +14,11 @@
import org.springframework.context.ApplicationContext;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.List;
import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -26,6 +28,37 @@
class StationSegmentExecutorTest {
    @Test
    void resolveCurrentPathIndex_prefersForwardOccurrenceForLoopRevisitStations() {
        StationSegmentExecutor executor = new StationSegmentExecutor(new DeviceConfig(), mock(RedisUtil.class), command -> null);
        Integer second121Index = ReflectionTestUtils.invokeMethod(
                executor,
                "resolveCurrentPathIndex",
                List.of(121, 124, 186, 189, 121, 124, 125, 127),
                121,
                3
        );
        Integer second124Index = ReflectionTestUtils.invokeMethod(
                executor,
                "resolveCurrentPathIndex",
                List.of(121, 124, 186, 189, 121, 124, 125, 127),
                124,
                4
        );
        Integer same124Index = ReflectionTestUtils.invokeMethod(
                executor,
                "resolveCurrentPathIndex",
                List.of(121, 124, 186, 189, 121, 124, 125, 127),
                124,
                5
        );
        assertEquals(Integer.valueOf(4), second121Index);
        assertEquals(Integer.valueOf(5), second124Index);
        assertEquals(Integer.valueOf(5), same124Index);
    }
    @Test
    void sendSegmentWithRetry_skipsWhenRouteIsCancelPending() {
        ApplicationContext applicationContext = mock(ApplicationContext.class);
        StationMoveCoordinator coordinator = new StationMoveCoordinator();
src/test/java/com/zy/core/thread/impl/station/StationSegmentPlannerTest.java
New file
@@ -0,0 +1,49 @@
package com.zy.core.thread.impl.station;
import com.zy.core.enums.StationCommandType;
import com.zy.core.model.command.StationCommand;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class StationSegmentPlannerTest {
    @Test
    void buildPlan_usesLaterLiftTransferOccurrencesWhenLoopPathRevisitsStations() {
        StationSegmentPlanner planner = new StationSegmentPlanner();
        StationCommand original = new StationCommand();
        original.setTaskNo(11017);
        original.setCommandType(StationCommandType.MOVE);
        original.setStationId(121);
        original.setTargetStaNo(127);
        original.setNavigatePath(List.of(121, 124, 186, 189, 121, 124, 125, 127));
        original.setLiftTransferPath(List.of(121, 124, 186, 189, 121, 124, 127));
        StationSegmentExecutionPlan plan = planner.buildPlan(original);
        assertEquals(
                List.of(
                        List.of(121, 124),
                        List.of(124, 186),
                        List.of(186, 189),
                        List.of(189, 121),
                        List.of(121, 124),
                        List.of(124, 125, 127)
                ),
                plan.getSegmentCommands().stream()
                        .map(StationCommand::getNavigatePath)
                        .collect(Collectors.toList())
        );
        assertEquals(List.of(1, 2, 3, 4, 5, 6),
                plan.getSegmentCommands().stream()
                        .map(StationCommand::getSegmentNo)
                        .collect(Collectors.toList()));
        assertTrue(plan.getSegmentCommands().stream()
                .allMatch(command -> Integer.valueOf(6).equals(command.getSegmentCount())));
    }
}