package com.zy.ai.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.zy.ai.domain.autotune.AutoTuneFlowTopologyItem;
|
import com.zy.ai.domain.autotune.AutoTuneStationRuntimeItem;
|
import com.zy.ai.service.FlowTopologySnapshotService;
|
import com.zy.asrs.entity.StationFlowCapacity;
|
import com.zy.asrs.service.StationFlowCapacityService;
|
import com.zy.common.utils.NavigateUtils;
|
import lombok.Data;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.Comparator;
|
import java.util.LinkedHashSet;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Objects;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
@Service("flowTopologySnapshotService")
|
public class FlowTopologySnapshotServiceImpl implements FlowTopologySnapshotService {
|
|
@Autowired
|
private StationFlowCapacityService stationFlowCapacityService;
|
|
@Autowired
|
private NavigateUtils navigateUtils;
|
|
@Override
|
public List<AutoTuneFlowTopologyItem> buildSnapshot(List<AutoTuneStationRuntimeItem> stationRuntimeSnapshot) {
|
List<StationFlowCapacity> capacities = loadCapacityList();
|
Map<Integer, List<Integer>> adjacencyMap = loadSortedAdjacencyMap();
|
List<AutoTuneFlowTopologyItem> itemList = new ArrayList<>();
|
for (StationFlowCapacity capacity : capacities) {
|
if (capacity == null || capacity.getStationId() == null) {
|
continue;
|
}
|
itemList.add(buildTopologyItem(capacity, adjacencyMap, stationRuntimeSnapshot));
|
}
|
return itemList;
|
}
|
|
public AutoTuneFlowTopologyItem buildTopologyItem(StationFlowCapacity capacity,
|
Map<Integer, List<Integer>> adjacencyMap,
|
List<AutoTuneStationRuntimeItem> stationRuntimeSnapshot) {
|
Integer targetStationId = capacity.getStationId();
|
Integer bufferCapacity = defaultInt(capacity.getBufferCapacity());
|
List<Integer> adjacentStationIds = sortedList(adjacencyMap == null ? null : adjacencyMap.get(targetStationId));
|
List<Integer> flowStationIds = buildFlowStationIds(targetStationId, adjacentStationIds);
|
List<AutoTuneStationRuntimeItem> flowRuntimeItems = filterRuntimeByStationIds(stationRuntimeSnapshot, flowStationIds);
|
RuntimeCount runtimeCount = calculateRuntimeCount(flowRuntimeItems);
|
|
AutoTuneFlowTopologyItem item = new AutoTuneFlowTopologyItem();
|
item.setTargetStationId(targetStationId);
|
item.setDirection(capacity.getDirectionCode());
|
// 当前只有后端无向站点图可用,保守地把排序相邻站同时作为上下游候选。
|
item.setUpstreamStationIds(adjacentStationIds);
|
item.setDownstreamStationIds(adjacentStationIds);
|
item.setFlowStationIds(flowStationIds);
|
item.setBufferCapacity(bufferCapacity);
|
item.setOccupiedCount(runtimeCount.getOccupiedCount());
|
item.setFreeCount(Math.max(0, bufferCapacity - runtimeCount.getOccupiedCount()));
|
item.setNonAutoingCount(runtimeCount.getNonAutoingCount());
|
item.setLoadingCount(runtimeCount.getLoadingCount());
|
item.setTaskHoldingCount(runtimeCount.getTaskHoldingCount());
|
return item;
|
}
|
|
public RuntimeCount calculateRuntimeCount(List<AutoTuneStationRuntimeItem> runtimeItems) {
|
RuntimeCount count = new RuntimeCount();
|
if (runtimeItems == null || runtimeItems.isEmpty()) {
|
return count;
|
}
|
for (AutoTuneStationRuntimeItem runtimeItem : runtimeItems) {
|
if (runtimeItem == null) {
|
continue;
|
}
|
boolean autoing = Objects.equals(runtimeItem.getAutoing(), 1);
|
boolean loading = Objects.equals(runtimeItem.getLoading(), 1);
|
boolean taskHolding = runtimeItem.getTaskNo() != null && runtimeItem.getTaskNo() > 0;
|
if (!autoing) {
|
count.nonAutoingCount++;
|
}
|
if (loading) {
|
count.loadingCount++;
|
}
|
if (taskHolding) {
|
count.taskHoldingCount++;
|
}
|
if (loading || taskHolding) {
|
count.occupiedCount++;
|
}
|
}
|
return count;
|
}
|
|
public StationFlowCapacity findCapacity(List<StationFlowCapacity> capacities,
|
Integer stationId,
|
String directionCode) {
|
if (capacities == null || stationId == null || directionCode == null) {
|
return null;
|
}
|
for (StationFlowCapacity capacity : capacities) {
|
if (capacity == null) {
|
continue;
|
}
|
if (Objects.equals(capacity.getStationId(), stationId)
|
&& directionCode.equals(capacity.getDirectionCode())) {
|
return capacity;
|
}
|
}
|
return null;
|
}
|
|
private List<StationFlowCapacity> loadCapacityList() {
|
if (stationFlowCapacityService == null) {
|
return Collections.emptyList();
|
}
|
QueryWrapper<StationFlowCapacity> wrapper = new QueryWrapper<>();
|
wrapper.orderByAsc("station_id", "direction_code");
|
List<StationFlowCapacity> capacityList = stationFlowCapacityService.list(wrapper);
|
return capacityList == null ? Collections.emptyList() : capacityList;
|
}
|
|
private Map<Integer, List<Integer>> loadSortedAdjacencyMap() {
|
if (navigateUtils == null) {
|
return Collections.emptyMap();
|
}
|
Map<Integer, Set<Integer>> graph = navigateUtils.loadUndirectedStationGraphSnapshot();
|
if (graph == null || graph.isEmpty()) {
|
return Collections.emptyMap();
|
}
|
return graph.entrySet().stream()
|
.filter(entry -> entry.getKey() != null)
|
.collect(Collectors.toMap(
|
Map.Entry::getKey,
|
entry -> sortedList(entry.getValue())
|
));
|
}
|
|
private List<Integer> buildFlowStationIds(Integer targetStationId,
|
List<Integer> adjacentStationIds) {
|
LinkedHashSet<Integer> stationIds = new LinkedHashSet<>();
|
if (targetStationId != null) {
|
stationIds.add(targetStationId);
|
}
|
stationIds.addAll(sortedList(adjacentStationIds));
|
return new ArrayList<>(stationIds);
|
}
|
|
private List<AutoTuneStationRuntimeItem> filterRuntimeByStationIds(List<AutoTuneStationRuntimeItem> runtimeItems,
|
List<Integer> stationIds) {
|
if (runtimeItems == null || runtimeItems.isEmpty() || stationIds == null || stationIds.isEmpty()) {
|
return Collections.emptyList();
|
}
|
Set<Integer> stationIdSet = new LinkedHashSet<>(stationIds);
|
return runtimeItems.stream()
|
.filter(item -> item != null && stationIdSet.contains(item.getStationId()))
|
.collect(Collectors.toList());
|
}
|
|
private static List<Integer> sortedList(Iterable<Integer> values) {
|
if (values == null) {
|
return new ArrayList<>();
|
}
|
List<Integer> result = new ArrayList<>();
|
for (Integer value : values) {
|
if (value != null) {
|
result.add(value);
|
}
|
}
|
result.sort(Comparator.naturalOrder());
|
return result;
|
}
|
|
private int defaultInt(Integer value) {
|
return value == null ? 0 : value;
|
}
|
|
@Data
|
public static class RuntimeCount {
|
private int occupiedCount;
|
private int nonAutoingCount;
|
private int loadingCount;
|
private int taskHoldingCount;
|
}
|
}
|