yeg
2026-09-05 68156d14934ffb7d7b6e0dca63d3dcf3ed43c995
battery-business/src/main/java/com/battery/business/service/impl/TDetectionCabinetServiceImpl.java
@@ -101,7 +101,7 @@
    }
    /**
     * 读取 Redis 在线候选供原选择设备弹窗展示,不生成模拟设备。
     * 读取未过期且未登记的候选,离线设备仍保留身份并可选择。
     * 测试占用状态由实时通道工作状态聚合;测试归属留待后续绑定闭环确认。
     *
     * @return 可供选择的检测柜设备摘要
@@ -111,13 +111,12 @@
    {
        Set<String> registeredCodes = Set.copyOf(detectionCabinetMapper.selectRegisteredCabinetCodes());
        return candidateStore.snapshot(Instant.now()).cabinets().stream()
                .filter(CabinetCandidate::online)
                .filter(candidate -> !registeredCodes.contains(candidate.deviceCode()))
                .map(candidate -> {
                    boolean active = isActive(candidate);
                    boolean active = candidate.online() && isActive(candidate);
                    return new DiscoveredCabinetVo(
                            candidate.deviceCode(), candidate.ip(), candidate.mac(), candidate.name(),
                            candidate.manufacturer(), candidate.model(), candidate.channels().size(), "在线",
                            candidate.manufacturer(), candidate.model(), candidate.channels().size(), candidate.online() ? "在线" : "离线",
                            active ? "测试中" : "空闲",
                            active ? "待确认" : "-");
                })
@@ -136,8 +135,7 @@
    {
        normalizeBasicFields(detectionCabinet);
        CabinetCandidate candidate = candidateStore.findCabinet(detectionCabinet.getCabinetCode(), Instant.now())
                .filter(CabinetCandidate::online)
                .orElseThrow(() -> new ServiceException("请先选择在线的发现候选设备"));
                .orElseThrow(() -> new ServiceException("请先选择有效的发现候选设备"));
        detectionCabinet.setAdapterId(candidate.adapterId());
        detectionCabinet.setAdapterCode(candidate.adapterCode());
        detectionCabinet.setVendorDeviceType(candidate.devtype());
@@ -169,7 +167,7 @@
                value.setLastSeenAtUtc(null);
                detectionCabinetMapper.insertDetectionChannel(value);
            }
            // 登记瞬间的候选也是一次有效观测,立即写入正式事实,避免等待下一轮轮询才显示在线。
            // 登记只确认来源身份,在线与离线事实都按候选原样同步。
            detectionCabinetMapper.updateRegisteredCabinetObservation(candidate.adapterCode(), candidate.devtype(),
                    candidate.devid(), candidate.online() ? "ONLINE" : "OFFLINE", candidate.observedAt(),
                    candidate.online());