yeg
2026-09-02 4220194f54535388daad46136f8da0452441b806
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TestConsoleDataServiceImpl.java
@@ -4,7 +4,6 @@
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashSet;
import com.alibaba.fastjson2.JSON;
import org.springframework.beans.factory.annotation.Autowired;
@@ -114,42 +113,8 @@
                mapper.upsertDataOverride(item);
            }
        }
        if ("DELETE".equals(action.getOperationType()) && overrides != null)
        {
            List<Long> resolvedIds = new ArrayList<>();
            for (TTestDataOverride item : overrides)
            {
                Long[] identity = parseDeleteIdentity(item.getStableIdentity(), action.getDataType());
                if (identity == null) throw new ServiceException("删除数据稳定身份无效");
                switch (action.getDataType())
                {
                    case "REALTIME" -> {
                        Long sampleId = mapper.selectBtsSampleIdByDeviceChannelSequence(action.getTestId(),
                                identity[0], identity[1], identity[2]);
                        if (sampleId != null) resolvedIds.add(sampleId);
                    }
                    case "STEP" -> resolvedIds.addAll(mapper.selectBtsSampleIdsByDeviceChannelStep(action.getTestId(),
                            identity[0], identity[1], identity[2].intValue(), identity[3].intValue()));
                    case "CYCLE" -> resolvedIds.addAll(mapper.selectBtsSampleIdsByDeviceChannelCycle(action.getTestId(),
                            identity[0], identity[1], identity[2].intValue()));
                    default -> throw new ServiceException("控制台数据类型无效");
                }
            }
            if (!resolvedIds.isEmpty())
            {
                resolvedIds = new ArrayList<>(new HashSet<>(resolvedIds));
                // 工步和循环是采样聚合视图,物理删除需在同一事务内清理对应底层采样。
                mapper.deleteBtsMeasurementsBySampleIds(resolvedIds);
                mapper.deleteBtsSamplesByIds(action.getTestId(), resolvedIds);
            }
        }
        if (btsSampleIds != null && !btsSampleIds.isEmpty())
        {
            // 采样明细受外键保护,必须在主采样物理删除前清理。
            mapper.deleteBtsMeasurementsBySampleIds(btsSampleIds);
            mapper.deleteBtsSamplesByIds(action.getTestId(), btsSampleIds);
        }
        if (collectorSampleIds != null && !collectorSampleIds.isEmpty()) mapper.deleteCollectorSamplesByIds(action.getTestId(), collectorSampleIds);
        // 删除仅写入 deleted 覆盖,保留设备原始采样和采集器事实供追溯。
        // btsSampleIds/collectorSampleIds 保留在接口中兼容旧调用方,但不再执行物理删除。
        return action.getActionId();
    }
@@ -196,6 +161,8 @@
    private void validateOverride(TTestDataOverride item, String operation, String dataType)
    {
        if ("DELETE".equals(operation) && parseDeleteIdentity(item.getStableIdentity(), dataType) == null)
            throw new ServiceException("删除数据稳定身份无效");
        if (!"EDIT".equals(operation) || item.getFieldValues() == null || item.getFieldValues().isBlank()) return;
        try
        {
@@ -260,16 +227,25 @@
    private Long[] parseDeleteIdentity(String value, String dataType)
    {
        String[] parts = value.split(":", -1);
        int expectedLength = "STEP".equals(dataType) ? 5 : "CYCLE".equals(dataType) ? 4 : 3;
        if (parts.length != expectedLength) return null;
        int expectedLength = "STEP".equals(dataType) ? 8 : "CYCLE".equals(dataType) ? 7 : 6;
        int legacyLength = "STEP".equals(dataType) ? 5 : "CYCLE".equals(dataType) ? 4 : 3;
        if (parts.length != expectedLength && parts.length != legacyLength) return null;
        int offset = "REALTIME".equals(dataType) ? 0 : 1;
        try
        {
            if (parts.length == legacyLength && "STEP".equals(dataType))
                return new Long[] { Long.valueOf(parts[1]), Long.valueOf(parts[2]),
                        Long.valueOf(parts[3]), Long.valueOf(parts[4]) };
            if (parts.length == legacyLength)
                return new Long[] { Long.valueOf(parts[0]), Long.valueOf(parts[1]), Long.valueOf(parts[2]) };
            if ("STEP".equals(dataType))
                return new Long[] { Long.valueOf(parts[offset]), Long.valueOf(parts[offset + 1]),
                        Long.valueOf(parts[offset + 2]), Long.valueOf(parts[offset + 3]) };
                        Long.valueOf(parts[offset + 2]), Long.valueOf(parts[offset + 3]),
                        Long.valueOf(parts[offset + 4]), Long.valueOf(parts[offset + 5]),
                        Long.valueOf(parts[offset + 6]) };
            return new Long[] { Long.valueOf(parts[offset]), Long.valueOf(parts[offset + 1]),
                    Long.valueOf(parts[offset + 2]) };
                    Long.valueOf(parts[offset + 2]), Long.valueOf(parts[offset + 3]),
                    Long.valueOf(parts[offset + 4]), Long.valueOf(parts[offset + 5]) };
        }
        catch (NumberFormatException exception) { return null; }
    }