更改 SCADA 设备列表条目关键词;样式设置中新增彩虹色带;强制计算后清除计算范围内的缓存;

This commit is contained in:
JIANG
2025-10-31 15:24:23 +08:00
parent fe797c1bf3
commit b332a6437d
6 changed files with 331 additions and 29 deletions

View File

@@ -286,7 +286,7 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
}
return styles;
};
// 创建高亮图层 - 爆管管段标识样式
// 创建高亮图层
const highlightLayer = new VectorLayer({
source: new VectorSource(),
style: burstPipeStyle,

View File

@@ -103,7 +103,7 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
anchor: [0.5, 1],
}),
});
// 创建高亮图层 - 爆管管段标识样式
// 创建高亮图层
const highlightLayer = new VectorLayer({
source: new VectorSource(),
style: sensorStyle,

View File

@@ -336,7 +336,7 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
} else {
setTimeSeries([]);
}
}, [deviceIds.join(","), hasDevices]);
}, [deviceIds.join(",")]); // 移除 hasDevices因为它由 deviceIds 决定,避免潜在的依赖循环
const columns: GridColDef[] = useMemo(() => {
const base: GridColDef[] = [

View File

@@ -42,8 +42,13 @@ import { FixedSizeList } from "react-window";
import { useMap } from "@app/OlMap/MapComponent";
import { GeoJSON } from "ol/format";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Stroke, Style, Circle } from "ol/style";
import Feature from "ol/Feature";
import { Point } from "ol/geom";
import config from "@/config/config";
import { get } from "http";
const STATUS_OPTIONS: {
value: "online" | "offline" | "warning" | "error";
@@ -57,12 +62,14 @@ const STATUS_OPTIONS: {
interface SCADADevice {
id: string;
name: string;
transmission_frequency: string;
reliability: number;
type: string;
coordinates: [number, number];
status: {
value: "online" | "offline" | "warning" | "error";
name: "在线" | "离线" | "警告" | "错误";
};
coordinates: [number, number];
properties?: Record<string, any>;
}
@@ -85,6 +92,7 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
const [searchQuery, setSearchQuery] = useState<string>("");
const [selectedType, setSelectedType] = useState<string>("all");
const [selectedStatus, setSelectedStatus] = useState<string>("all");
const [selectedReliability, setSelectedReliability] = useState<string>("all");
const [isExpanded, setIsExpanded] = useState<boolean>(true);
const [internalSelection, setInternalSelection] = useState<string[]>([]);
const [pendingSelection, setPendingSelection] = useState<string[] | null>(
@@ -94,6 +102,10 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
const [loading, setLoading] = useState<boolean>(true);
const [inputValue, setInputValue] = useState<string>("");
const [highlightLayer, setHighlightLayer] =
useState<VectorLayer<VectorSource> | null>(null);
const [highlightFeatures, setHighlightFeatures] = useState<Feature[]>([]);
const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);
// 防抖更新搜索查询
@@ -139,6 +151,8 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
const data = features.map((feature) => ({
id: feature.get("id") || feature.getId(),
name: feature.get("id") || feature.getId(),
transmission_frequency: feature.get("transmission_frequency"),
reliability: feature.get("reliability"),
type: feature.get("type") === "pipe_flow" ? "流量" : "压力",
status: STATUS_OPTIONS[Math.floor(Math.random() * 4)],
coordinates: (feature.getGeometry() as Point)?.getCoordinates() as [
@@ -170,6 +184,20 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
// 获取设备状态列表
const deviceStatuses = STATUS_OPTIONS;
// 可靠度文字映射
const getReliability = (reliability: number) => {
switch (reliability) {
case 1:
return "高";
case 2:
return "中";
case 3:
return "低";
default:
return "未知";
}
};
// 过滤设备列表
const filteredDevices = useMemo(() => {
return effectiveDevices.filter((device) => {
@@ -186,10 +214,21 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
selectedType === "all" || device.type === selectedType;
const matchesStatus =
selectedStatus === "all" || device.status.value === selectedStatus;
const matchesReliability =
selectedReliability === "all" ||
getReliability(device.reliability) === selectedReliability;
return matchesSearch && matchesType && matchesStatus;
return (
matchesSearch && matchesType && matchesStatus && matchesReliability
);
});
}, [effectiveDevices, searchQuery, selectedType, selectedStatus]);
}, [
effectiveDevices,
searchQuery,
selectedType,
selectedStatus,
selectedReliability,
]);
// 状态颜色映射
const getStatusColor = (status: string) => {
@@ -222,6 +261,17 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
return "●";
}
};
// 传输频率文字对应
const getTransmissionFrequency = (transmission_frequency: string) => {
// 传输频率文本00:01:0000:05:0000:10:0000:30:0001:00:00转换为分钟数
const parts = transmission_frequency.split(":");
if (parts.length !== 3) return transmission_frequency;
const hours = parseInt(parts[0], 10);
const minutes = parseInt(parts[1], 10);
const seconds = parseInt(parts[2], 10);
const totalMinutes = hours * 60 + minutes + (seconds >= 30 ? 1 : 0);
return totalMinutes;
};
// 处理设备点击
const handleDeviceClick = (device: SCADADevice, event?: React.MouseEvent) => {
@@ -264,6 +314,7 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
setSearchQuery("");
setSelectedType("all");
setSelectedStatus("all");
setSelectedReliability("all");
});
}, []);
@@ -273,6 +324,56 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
setPendingSelection([]);
}, []);
// 初始化管道图层和高亮图层
useEffect(() => {
if (!map) return;
// 获取地图的目标容器
const SCADASelectedStyle = () => {
return new Style({
image: new Circle({
stroke: new Stroke({ color: "yellow", width: 2 }),
radius: 15,
}),
});
};
// 创建高亮图层
const highlightLayer = new VectorLayer({
source: new VectorSource(),
style: SCADASelectedStyle,
maxZoom: 24,
minZoom: 12,
properties: {
name: "SCADA 选中高亮",
value: "scada_selected_highlight",
},
});
map.addLayer(highlightLayer);
setHighlightLayer(highlightLayer);
return () => {
map.removeLayer(highlightLayer);
};
}, [map]);
// 高亮要素的函数
useEffect(() => {
if (!highlightLayer) {
return;
}
const source = highlightLayer.getSource();
if (!source) {
return;
}
// 清除之前的高亮
source.clear();
// 添加新的高亮要素
highlightFeatures.forEach((feature) => {
if (feature instanceof Feature) {
source.addFeature(feature);
}
});
}, [selectedDeviceIds, highlightFeatures]);
// 清理定时器
useEffect(() => {
return () => {
@@ -364,14 +465,14 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
{/* 筛选器 */}
<Stack direction="row" spacing={2}>
<FormControl size="small" sx={{ minWidth: 120 }}>
<FormControl size="small" sx={{ minWidth: 80 }}>
<InputLabel></InputLabel>
<Select
value={selectedType}
label="设备类型"
onChange={(e) => setSelectedType(e.target.value)}
>
<MenuItem value="all"></MenuItem>
<MenuItem value="all"></MenuItem>
{deviceTypes.map((type) => (
<MenuItem key={type} value={type}>
{type}
@@ -380,14 +481,14 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
</Select>
</FormControl>
<FormControl size="small" sx={{ minWidth: 100 }}>
<FormControl size="small" sx={{ minWidth: 80 }}>
<InputLabel></InputLabel>
<Select
value={selectedStatus}
label="状态"
onChange={(e) => setSelectedStatus(e.target.value)}
>
<MenuItem value="all"></MenuItem>
<MenuItem value="all"></MenuItem>
{deviceStatuses.map((status) => (
<MenuItem key={status.value} value={status.value}>
{status.name}
@@ -396,6 +497,20 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
</Select>
</FormControl>
<FormControl size="small" sx={{ minWidth: 80 }}>
<InputLabel></InputLabel>
<Select
value={selectedReliability}
label="可靠度"
onChange={(e) => setSelectedReliability(e.target.value)}
>
<MenuItem value="all"></MenuItem>
<MenuItem value="高"></MenuItem>
<MenuItem value="中"></MenuItem>
<MenuItem value="低"></MenuItem>
</Select>
</FormControl>
<Tooltip title="重置筛选条件">
<IconButton onClick={handleResetFilters}>
<FilterList />
@@ -523,6 +638,14 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
variant="outlined"
sx={{ fontSize: "0.7rem", height: 20 }}
/>
<Chip
label={
"可靠度" + getReliability(device.reliability)
}
size="small"
variant="outlined"
sx={{ fontSize: "0.7rem", height: 20 }}
/>
</Stack>
}
secondary={
@@ -537,8 +660,11 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
variant="caption"
color="text.secondary"
>
: {device.coordinates[0].toFixed(6)},{" "}
{device.coordinates[1].toFixed(6)}
:{" "}
{getTransmissionFrequency(
device.transmission_frequency
)}{" "}
</Typography>
</Stack>
}