更新api url
This commit is contained in:
@@ -91,13 +91,13 @@ const fetchFromBackend = async (
|
||||
.join(",");
|
||||
|
||||
// 监测值数据接口(use_cleaned=false)
|
||||
const rawDataUrl = `${config.BACKEND_URL}/timescaledb/composite/element-scada?element_id=${feature_ids}&start_time=${start_time}&end_time=${end_time}&use_cleaned=false`;
|
||||
const rawDataUrl = `${config.BACKEND_URL}/api/v1/composite/element-scada?element_id=${feature_ids}&start_time=${start_time}&end_time=${end_time}&use_cleaned=false`;
|
||||
// 清洗数据接口(use_cleaned=true)
|
||||
const cleanedDataUrl = `${config.BACKEND_URL}/timescaledb/composite/element-scada?element_id=${feature_ids}&start_time=${start_time}&end_time=${end_time}&use_cleaned=true`;
|
||||
const cleanedDataUrl = `${config.BACKEND_URL}/api/v1/composite/element-scada?element_id=${feature_ids}&start_time=${start_time}&end_time=${end_time}&use_cleaned=true`;
|
||||
// 模拟数据接口
|
||||
const simulationDataUrl = `${config.BACKEND_URL}/timescaledb/composite/element-simulation?feature_infos=${feature_infos}&start_time=${start_time}&end_time=${end_time}`;
|
||||
const simulationDataUrl = `${config.BACKEND_URL}/api/v1/composite/element-simulation?feature_infos=${feature_infos}&start_time=${start_time}&end_time=${end_time}`;
|
||||
// 策略模拟数据接口
|
||||
const schemeSimulationDataUrl = `${config.BACKEND_URL}/timescaledb/composite/element-simulation?feature_infos=${feature_infos}&start_time=${start_time}&end_time=${end_time}&scheme_type=${scheme_type}&scheme_name=${scheme_name}`;
|
||||
const schemeSimulationDataUrl = `${config.BACKEND_URL}/api/v1/composite/element-simulation?feature_infos=${feature_infos}&start_time=${start_time}&end_time=${end_time}&scheme_type=${scheme_type}&scheme_name=${scheme_name}`;
|
||||
|
||||
try {
|
||||
if (type === "none") {
|
||||
|
||||
@@ -29,7 +29,6 @@ import { FiSkipBack, FiSkipForward } from "react-icons/fi";
|
||||
import { useData } from "../MapComponent";
|
||||
import { config, NETWORK_NAME } from "@/config/config";
|
||||
import { useMap } from "../MapComponent";
|
||||
const backendUrl = config.BACKEND_URL;
|
||||
|
||||
interface TimelineProps {
|
||||
schemeDate?: Date;
|
||||
@@ -103,7 +102,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
junctionProperties: string,
|
||||
pipeProperties: string,
|
||||
schemeName: string,
|
||||
schemeType: string
|
||||
schemeType: string,
|
||||
) => {
|
||||
const query_time = queryTime.toISOString();
|
||||
let nodeRecords: any = { results: [] };
|
||||
@@ -119,12 +118,12 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
} else {
|
||||
disableDateSelection && schemeName
|
||||
? (nodePromise = fetch(
|
||||
// `${backendUrl}/queryallschemerecordsbytimeproperty/?querytime=${query_time}&type=node&property=${junctionProperties}&schemename=${schemeName}`
|
||||
`${backendUrl}/timescaledb/scheme/query/by-scheme-time-property?scheme_type=${schemeType}&scheme_name=${schemeName}&query_time=${query_time}&type=node&property=${junctionProperties}`
|
||||
// `${config.BACKEND_URL}/queryallschemerecordsbytimeproperty/?querytime=${query_time}&type=node&property=${junctionProperties}&schemename=${schemeName}`
|
||||
`${config.BACKEND_URL}/api/v1/scheme/query/by-scheme-time-property?scheme_type=${schemeType}&scheme_name=${schemeName}&query_time=${query_time}&type=node&property=${junctionProperties}`,
|
||||
))
|
||||
: (nodePromise = fetch(
|
||||
// `${backendUrl}/queryallrecordsbytimeproperty/?querytime=${query_time}&type=node&property=${junctionProperties}`
|
||||
`${backendUrl}/timescaledb/realtime/query/by-time-property?query_time=${query_time}&type=node&property=${junctionProperties}`
|
||||
// `${config.BACKEND_URL}/queryallrecordsbytimeproperty/?querytime=${query_time}&type=node&property=${junctionProperties}`
|
||||
`${config.BACKEND_URL}/api/v1/realtime/query/by-time-property?query_time=${query_time}&type=node&property=${junctionProperties}`,
|
||||
));
|
||||
requests.push(nodePromise);
|
||||
}
|
||||
@@ -140,12 +139,12 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
} else {
|
||||
disableDateSelection && schemeName
|
||||
? (linkPromise = fetch(
|
||||
// `${backendUrl}/queryallschemerecordsbytimeproperty/?querytime=${query_time}&type=link&property=${pipeProperties}&schemename=${schemeName}`
|
||||
`${backendUrl}/timescaledb/scheme/query/by-scheme-time-property?scheme_type=${schemeType}&scheme_name=${schemeName}&query_time=${query_time}&type=link&property=${pipeProperties}`
|
||||
// `${config.BACKEND_URL}/queryallschemerecordsbytimeproperty/?querytime=${query_time}&type=link&property=${pipeProperties}&schemename=${schemeName}`
|
||||
`${config.BACKEND_URL}/api/v1/scheme/query/by-scheme-time-property?scheme_type=${schemeType}&scheme_name=${schemeName}&query_time=${query_time}&type=link&property=${pipeProperties}`,
|
||||
))
|
||||
: (linkPromise = fetch(
|
||||
// `${backendUrl}/queryallrecordsbytimeproperty/?querytime=${query_time}&type=link&property=${pipeProperties}`
|
||||
`${backendUrl}/timescaledb/realtime/query/by-time-property?query_time=${query_time}&type=link&property=${pipeProperties}`
|
||||
// `${config.BACKEND_URL}/queryallrecordsbytimeproperty/?querytime=${query_time}&type=link&property=${pipeProperties}`
|
||||
`${config.BACKEND_URL}/api/v1/realtime/query/by-time-property?query_time=${query_time}&type=link&property=${pipeProperties}`,
|
||||
));
|
||||
requests.push(linkPromise);
|
||||
}
|
||||
@@ -162,7 +161,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
// 缓存数据(修复键以包含 schemeName)
|
||||
nodeCacheRef.current.set(
|
||||
`${query_time}_${junctionProperties}_${schemeName}_${schemeType}`,
|
||||
nodeRecords || []
|
||||
nodeRecords || [],
|
||||
);
|
||||
}
|
||||
if (linkPromise) {
|
||||
@@ -173,7 +172,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
// 缓存数据(修复键以包含 schemeName)
|
||||
linkCacheRef.current.set(
|
||||
`${query_time}_${pipeProperties}_${schemeName}_${schemeType}`,
|
||||
linkRecords || []
|
||||
linkRecords || [],
|
||||
);
|
||||
}
|
||||
// 更新状态
|
||||
@@ -249,7 +248,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
setCurrentTime(value);
|
||||
}, 500); // 500ms 防抖延迟
|
||||
},
|
||||
[timeRange, minTime, maxTime]
|
||||
[timeRange, minTime, maxTime],
|
||||
);
|
||||
|
||||
// 播放控制
|
||||
@@ -366,7 +365,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
}, newInterval);
|
||||
}
|
||||
},
|
||||
[isPlaying]
|
||||
[isPlaying],
|
||||
);
|
||||
// 计算时间段改变处理
|
||||
const handleCalculatedIntervalChange = useCallback((event: any) => {
|
||||
@@ -393,10 +392,17 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
junctionText,
|
||||
pipeText,
|
||||
schemeName,
|
||||
schemeType
|
||||
schemeType,
|
||||
);
|
||||
}
|
||||
}, [junctionText, pipeText, currentTime, selectedDate, schemeName, schemeType]);
|
||||
}, [
|
||||
junctionText,
|
||||
pipeText,
|
||||
currentTime,
|
||||
selectedDate,
|
||||
schemeName,
|
||||
schemeType,
|
||||
]);
|
||||
|
||||
// 组件卸载时清理定时器和防抖
|
||||
useEffect(() => {
|
||||
@@ -445,7 +451,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
const dateStr = date.toISOString().split("T")[0];
|
||||
|
||||
const clearCache = (
|
||||
cacheRef: ReturnType<typeof useRef<Map<string, any[]>>>
|
||||
cacheRef: ReturnType<typeof useRef<Map<string, any[]>>>,
|
||||
) => {
|
||||
if (!cacheRef.current) return;
|
||||
const cacheKeys = Array.from(cacheRef.current.keys());
|
||||
@@ -474,7 +480,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
junctionText,
|
||||
pipeText,
|
||||
schemeName,
|
||||
schemeType
|
||||
schemeType,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -508,14 +514,14 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
};
|
||||
|
||||
const response = await fetch(
|
||||
`${backendUrl}/runsimulationmanuallybydate/`,
|
||||
`${config.BACKEND_URL}/api/v1/runsimulationmanuallybydate/`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(body),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
|
||||
@@ -20,7 +20,6 @@ import { handleMapClickSelectFeatures as mapClickSelectFeatures } from "@/utils/
|
||||
import { useNotification } from "@refinedev/core";
|
||||
|
||||
import { config } from "@/config/config";
|
||||
const backendUrl = config.BACKEND_URL;
|
||||
|
||||
// 添加接口定义隐藏按钮的props
|
||||
interface ToolbarProps {
|
||||
@@ -229,7 +228,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
if (getBaseType(layerId) !== getBaseType(firstLayerId)) {
|
||||
// 如果点击的是已选中的要素(为了取消选中),则不报错
|
||||
const isAlreadySelected = highlightFeatures.some(
|
||||
(f) => f.getProperties().id === featureId
|
||||
(f) => f.getProperties().id === featureId,
|
||||
);
|
||||
if (!isAlreadySelected) {
|
||||
open?.({
|
||||
@@ -243,7 +242,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
|
||||
setHighlightFeatures((prev) => {
|
||||
const existingIndex = prev.findIndex(
|
||||
(f) => f.getProperties().id === featureId
|
||||
(f) => f.getProperties().id === featureId,
|
||||
);
|
||||
|
||||
if (existingIndex !== -1) {
|
||||
@@ -259,7 +258,7 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
setHighlightFeatures([feature]);
|
||||
}
|
||||
},
|
||||
[map, activeTools, highlightFeatures, open]
|
||||
[map, activeTools, highlightFeatures, open],
|
||||
);
|
||||
// 添加矢量属性查询事件监听器
|
||||
useEffect(() => {
|
||||
@@ -388,13 +387,13 @@ const Toolbar: React.FC<ToolbarProps> = ({
|
||||
let response;
|
||||
if (queryType === "scheme") {
|
||||
response = await fetch(
|
||||
// `${backendUrl}/queryschemesimulationrecordsbyidtime/?scheme_name=${schemeName}&id=${id}&querytime=${querytime}&type=${type}`
|
||||
`${backendUrl}/timescaledb/scheme/query/by-id-time?scheme_name=${schemeName}&id=${id}&type=${type}&query_time=${querytime}`
|
||||
// `${config.BACKEND_URL}/queryschemesimulationrecordsbyidtime/?scheme_name=${schemeName}&id=${id}&querytime=${querytime}&type=${type}`
|
||||
`${config.BACKEND_URL}/api/v1/scheme/query/by-id-time?scheme_name=${schemeName}&id=${id}&type=${type}&query_time=${querytime}`,
|
||||
);
|
||||
} else {
|
||||
response = await fetch(
|
||||
// `${backendUrl}/querysimulationrecordsbyidtime/?id=${id}&querytime=${querytime}&type=${type}`
|
||||
`${backendUrl}/timescaledb/realtime/query/by-id-time?id=${id}&type=${type}&query_time=${querytime}`
|
||||
// `${config.BACKEND_URL}/querysimulationrecordsbyidtime/?id=${id}&querytime=${querytime}&type=${type}`
|
||||
`${config.BACKEND_URL}/api/v1/realtime/query/by-id-time?id=${id}&type=${type}&query_time=${querytime}`,
|
||||
);
|
||||
}
|
||||
if (!response.ok) {
|
||||
|
||||
@@ -154,11 +154,11 @@ const App = (props: React.PropsWithChildren<AppProps>) => {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "爆管分析定位",
|
||||
list: "/burst-pipe-analysis",
|
||||
name: "风险分析定位",
|
||||
list: "/risk-analysis-location",
|
||||
meta: {
|
||||
icon: <TbLocationPin className="w-6 h-6" />,
|
||||
label: "爆管分析定位",
|
||||
label: "风险分析定位",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -283,7 +283,7 @@ const AnalysisParameters: React.FC = () => {
|
||||
};
|
||||
|
||||
try {
|
||||
await axios.post(`${config.BACKEND_URL}/burst_analysis/`, body, {
|
||||
await axios.post(`${config.BACKEND_URL}/api/v1/burst_analysis/`, body, {
|
||||
headers: {
|
||||
"Accept-Encoding": "gzip",
|
||||
"Content-Type": "application/json",
|
||||
|
||||
@@ -129,7 +129,7 @@ const BurstPipeAnalysisPanel: React.FC<BurstPipeAnalysisPanelProps> = ({
|
||||
const handleLocateScheme = async (scheme: SchemeRecord) => {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`${config.BACKEND_URL}/postgresql/burst-locate-result/${scheme.schemeName}`
|
||||
`${config.BACKEND_URL}/api/v1/burst-locate-result/${scheme.schemeName}`
|
||||
);
|
||||
setLocationResults(response.data);
|
||||
setCurrentTab(2); // 切换到定位结果标签页
|
||||
|
||||
@@ -133,7 +133,7 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`${config.BACKEND_URL}/getallschemes/?network=${network}`
|
||||
`${config.BACKEND_URL}/api/v1/getallschemes/?network=${network}`
|
||||
);
|
||||
let filteredResults = response.data;
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ const AnalysisParameters: React.FC = () => {
|
||||
pattern: pattern || undefined,
|
||||
};
|
||||
|
||||
await axios.get(`${config.BACKEND_URL}/contaminant_simulation/`, {
|
||||
await axios.get(`${config.BACKEND_URL}/api/v1/contaminant_simulation/`, {
|
||||
params,
|
||||
});
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`${config.BACKEND_URL}/getallschemes/?network=${network}`
|
||||
`${config.BACKEND_URL}/api/v1/getallschemes/?network=${network}`
|
||||
);
|
||||
let filteredResults = response.data;
|
||||
|
||||
|
||||
@@ -38,8 +38,6 @@ import {
|
||||
RISK_BREAKS,
|
||||
} from "./types";
|
||||
|
||||
const backendUrl = config.BACKEND_URL;
|
||||
|
||||
// 辅助函数:将日期向下取整到最近的15分钟
|
||||
const getRoundedDate = (date: Date): Date => {
|
||||
const minutes = date.getHours() * 60 + date.getMinutes();
|
||||
@@ -49,7 +47,7 @@ const getRoundedDate = (date: Date): Date => {
|
||||
Math.floor(roundedMinutes / 60),
|
||||
roundedMinutes % 60,
|
||||
0,
|
||||
0
|
||||
0,
|
||||
);
|
||||
return roundedDate;
|
||||
};
|
||||
@@ -124,7 +122,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
setCurrentYear(value);
|
||||
}, 500); // 500ms 防抖延迟
|
||||
},
|
||||
[minTime, maxTime]
|
||||
[minTime, maxTime],
|
||||
);
|
||||
|
||||
// 播放控制
|
||||
@@ -215,7 +213,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
}, newInterval);
|
||||
}
|
||||
},
|
||||
[isPlaying]
|
||||
[isPlaying],
|
||||
);
|
||||
|
||||
// 组件加载时设置初始时间为当前时间的最近15分钟
|
||||
@@ -245,7 +243,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
const safeIndex = Math.max(0, Math.min(index, y.length - 1));
|
||||
return y[safeIndex];
|
||||
},
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
// 更新管道图层中的 healthRisk 属性
|
||||
@@ -270,7 +268,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
});
|
||||
});
|
||||
},
|
||||
[pipeLayer]
|
||||
[pipeLayer],
|
||||
);
|
||||
|
||||
// 监听瓦片加载,为新瓦片设置 healthRisk 属性
|
||||
@@ -313,7 +311,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
predictionResults.forEach((result) => {
|
||||
const probability = getSurvivalProbabilityAtYear(
|
||||
result.survival_function,
|
||||
currentYear - 4 // 使用索引 (0-based)
|
||||
currentYear - 4, // 使用索引 (0-based)
|
||||
);
|
||||
pipeHealthData.set(result.link_id, probability);
|
||||
});
|
||||
@@ -347,7 +345,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
widthCases.push(["<=", ["get", "healthRisk"], breakValue], width);
|
||||
});
|
||||
console.log(
|
||||
`应用健康风险样式,年份: ${currentYear}, 分段: ${breaks.length}`
|
||||
`应用健康风险样式,年份: ${currentYear}, 分段: ${breaks.length}`,
|
||||
);
|
||||
console.log("颜色表达式:", colorCases);
|
||||
console.log("宽度表达式:", widthCases);
|
||||
@@ -371,7 +369,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
const layers = map.getLayers().getArray();
|
||||
const pipesLayer = layers.find(
|
||||
(layer) =>
|
||||
layer instanceof WebGLVectorTileLayer && layer.get("value") === "pipes"
|
||||
layer instanceof WebGLVectorTileLayer && layer.get("value") === "pipes",
|
||||
) as WebGLVectorTileLayer | undefined;
|
||||
|
||||
if (pipesLayer) {
|
||||
@@ -426,7 +424,7 @@ const Timeline: React.FC<TimelineProps> = ({
|
||||
});
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${backendUrl}/timescaledb/composite/pipeline-health-prediction?query_time=${query_time}&network_name=${NETWORK_NAME}`
|
||||
`${config.BACKEND_URL}/api/v1/composite/pipeline-health-prediction?query_time=${query_time}&network_name=${NETWORK_NAME}`,
|
||||
);
|
||||
|
||||
if (response.ok) {
|
||||
|
||||
@@ -94,7 +94,7 @@ const OptimizationParameters: React.FC = () => {
|
||||
try {
|
||||
// 发送优化请求
|
||||
const response = await axios.post(
|
||||
`${config.BACKEND_URL}/sensorplacementscheme/create`,
|
||||
`${config.BACKEND_URL}/api/v1/sensorplacementscheme/create`,
|
||||
null,
|
||||
{
|
||||
params: {
|
||||
|
||||
@@ -148,7 +148,7 @@ const SchemeQuery: React.FC<SchemeQueryProps> = ({
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`${config.BACKEND_URL}/getallsensorplacements/?network=${network}`
|
||||
`${config.BACKEND_URL}/api/v1/getallsensorplacements/?network=${network}`
|
||||
);
|
||||
|
||||
let filteredResults = response.data;
|
||||
|
||||
@@ -78,7 +78,7 @@ type LoadingState = "idle" | "loading" | "success" | "error";
|
||||
*/
|
||||
const fetchFromBackend = async (
|
||||
deviceIds: string[],
|
||||
range: { from: Date; to: Date }
|
||||
range: { from: Date; to: Date },
|
||||
): Promise<TimeSeriesPoint[]> => {
|
||||
if (deviceIds.length === 0) {
|
||||
return [];
|
||||
@@ -88,12 +88,11 @@ const fetchFromBackend = async (
|
||||
const start_time = dayjs(range.from).toISOString();
|
||||
const end_time = dayjs(range.to).toISOString();
|
||||
// 清洗数据接口
|
||||
const cleaningDataUrl = `${config.BACKEND_URL}/timescaledb/scada/by-ids-field-time-range?device_ids=${device_ids}&field=cleaned_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
const cleaningDataUrl = `${config.BACKEND_URL}/api/v1/scada/by-ids-field-time-range?device_ids=${device_ids}&field=cleaned_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
// 原始数据
|
||||
const rawDataUrl = `${config.BACKEND_URL}/timescaledb/scada/by-ids-field-time-range?device_ids=${device_ids}&field=monitored_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
const rawDataUrl = `${config.BACKEND_URL}/api/v1/scada/by-ids-field-time-range?device_ids=${device_ids}&field=monitored_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
// 模拟数据接口
|
||||
const simulationDataUrl = `${config.BACKEND_URL}/timescaledb/composite/scada-simulation?device_ids=${device_ids}&start_time=${start_time}&end_time=${end_time}`;
|
||||
|
||||
const simulationDataUrl = `${config.BACKEND_URL}/api/v1/composite/scada-simulation?device_ids=${device_ids}&start_time=${start_time}&end_time=${end_time}`;
|
||||
try {
|
||||
// 优先查询清洗数据和模拟数据
|
||||
const [cleaningRes, simulationRes] = await Promise.all([
|
||||
@@ -115,7 +114,7 @@ const fetchFromBackend = async (
|
||||
simulationData,
|
||||
deviceIds,
|
||||
"clean",
|
||||
"sim"
|
||||
"sim",
|
||||
);
|
||||
} else {
|
||||
// 如果清洗数据没有数据,查询原始数据,返回模拟和原始数据
|
||||
@@ -128,7 +127,7 @@ const fetchFromBackend = async (
|
||||
rawData,
|
||||
deviceIds,
|
||||
"sim",
|
||||
"raw"
|
||||
"raw",
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -143,7 +142,7 @@ const fetchFromBackend = async (
|
||||
*/
|
||||
const transformBackendData = (
|
||||
backendData: any,
|
||||
deviceIds: string[]
|
||||
deviceIds: string[],
|
||||
): TimeSeriesPoint[] => {
|
||||
// 处理后端返回的对象格式: { deviceId: [{time: "...", value: ...}] }
|
||||
if (backendData && !Array.isArray(backendData)) {
|
||||
@@ -176,12 +175,12 @@ const transformBackendData = (
|
||||
([timestamp, values]) => ({
|
||||
timestamp,
|
||||
values,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
result.sort(
|
||||
(a, b) =>
|
||||
new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
||||
new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
|
||||
);
|
||||
|
||||
return result;
|
||||
@@ -200,7 +199,7 @@ const mergeTimeSeriesData = (
|
||||
data2: TimeSeriesPoint[],
|
||||
deviceIds: string[],
|
||||
suffix1: string,
|
||||
suffix2: string
|
||||
suffix2: string,
|
||||
): TimeSeriesPoint[] => {
|
||||
const timeMap = new Map<string, Record<string, number | null>>();
|
||||
|
||||
@@ -228,7 +227,7 @@ const mergeTimeSeriesData = (
|
||||
}));
|
||||
|
||||
result.sort(
|
||||
(a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
||||
(a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
|
||||
);
|
||||
|
||||
return result;
|
||||
@@ -239,7 +238,7 @@ const formatTimestamp = (timestamp: string) =>
|
||||
|
||||
const ensureValidRange = (
|
||||
from: Dayjs,
|
||||
to: Dayjs
|
||||
to: Dayjs,
|
||||
): { from: Dayjs; to: Dayjs } => {
|
||||
if (from.isAfter(to)) {
|
||||
return { from: to, to: from };
|
||||
@@ -251,7 +250,7 @@ const buildDataset = (
|
||||
points: TimeSeriesPoint[],
|
||||
deviceIds: string[],
|
||||
fractionDigits: number,
|
||||
showCleaning: boolean
|
||||
showCleaning: boolean,
|
||||
) => {
|
||||
return points.map((point) => {
|
||||
const entry: Record<string, any> = {
|
||||
@@ -325,19 +324,18 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
|
||||
return async (
|
||||
deviceIds: string[],
|
||||
range: { from: Date; to: Date }
|
||||
range: { from: Date; to: Date },
|
||||
): Promise<TimeSeriesPoint[]> => {
|
||||
const device_ids = deviceIds.join(",");
|
||||
const start_time = dayjs(range.from).toISOString();
|
||||
const end_time = dayjs(range.to).toISOString();
|
||||
|
||||
// 清洗数据接口
|
||||
const cleaningDataUrl = `${config.BACKEND_URL}/timescaledb/scada/by-ids-field-time-range?device_ids=${device_ids}&field=cleaned_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
const cleaningDataUrl = `${config.BACKEND_URL}/api/v1/scada/by-ids-field-time-range?device_ids=${device_ids}&field=cleaned_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
// 原始数据
|
||||
const rawDataUrl = `${config.BACKEND_URL}/timescaledb/scada/by-ids-field-time-range?device_ids=${device_ids}&field=monitored_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
const rawDataUrl = `${config.BACKEND_URL}/api/v1/scada/by-ids-field-time-range?device_ids=${device_ids}&field=monitored_value&start_time=${start_time}&end_time=${end_time}`;
|
||||
// 模拟数据接口
|
||||
const simulationDataUrl = `${config.BACKEND_URL}/timescaledb/composite/scada-simulation?device_ids=${device_ids}&start_time=${start_time}&end_time=${end_time}`;
|
||||
|
||||
const simulationDataUrl = `${config.BACKEND_URL}/api/v1/composite/scada-simulation?device_ids=${device_ids}&start_time=${start_time}&end_time=${end_time}`;
|
||||
try {
|
||||
const [cleanRes, rawRes, simRes] = await Promise.all([
|
||||
fetch(cleaningDataUrl)
|
||||
@@ -381,12 +379,12 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
([timestamp, values]) => ({
|
||||
timestamp,
|
||||
values,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
result.sort(
|
||||
(a, b) =>
|
||||
new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
||||
new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
|
||||
);
|
||||
|
||||
return result;
|
||||
@@ -420,7 +418,7 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
|
||||
const dataset = useMemo(
|
||||
() => buildDataset(timeSeries, deviceIds, fractionDigits, showCleaning),
|
||||
[timeSeries, deviceIds, fractionDigits, showCleaning]
|
||||
[timeSeries, deviceIds, fractionDigits, showCleaning],
|
||||
);
|
||||
|
||||
const handleFetch = useCallback(
|
||||
@@ -447,7 +445,7 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
setLoadingState("error");
|
||||
}
|
||||
},
|
||||
[deviceIds, customFetcher, hasDevices, normalizedRange]
|
||||
[deviceIds, customFetcher, hasDevices, normalizedRange],
|
||||
);
|
||||
|
||||
// 处理数据清洗
|
||||
@@ -479,9 +477,9 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
const response = await axios.post(
|
||||
`${
|
||||
config.BACKEND_URL
|
||||
}/timescaledb/composite/clean-scada?device_ids=${deviceIds.join(
|
||||
","
|
||||
)}&start_time=${startTime}&end_time=${endTime}`
|
||||
}/api/v1/composite/clean-scada?device_ids=${deviceIds.join(
|
||||
",",
|
||||
)}&start_time=${startTime}&end_time=${endTime}`,
|
||||
);
|
||||
|
||||
console.log("[SCADADataPanel] 清洗响应:", response.data);
|
||||
@@ -627,7 +625,7 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
const fieldKey = `${id}_${key}`;
|
||||
// 检查是否有该字段的数据
|
||||
const hasData = dataset.some(
|
||||
(item) => item[fieldKey] !== null && item[fieldKey] !== undefined
|
||||
(item) => item[fieldKey] !== null && item[fieldKey] !== undefined,
|
||||
);
|
||||
|
||||
if (hasData) {
|
||||
@@ -663,7 +661,7 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
}-${index}`,
|
||||
...item,
|
||||
})),
|
||||
[dataset]
|
||||
[dataset],
|
||||
);
|
||||
|
||||
const renderEmpty = () => {
|
||||
@@ -760,7 +758,7 @@ const SCADADataPanel: React.FC<SCADADataPanelProps> = ({
|
||||
["raw", "clean", "sim"].forEach((suffix, sIndex) => {
|
||||
const key = `${id}_${suffix}`;
|
||||
const hasData = dataset.some(
|
||||
(item) => item[key] !== null && item[key] !== undefined
|
||||
(item) => item[key] !== null && item[key] !== undefined,
|
||||
);
|
||||
if (hasData) {
|
||||
series.push({
|
||||
|
||||
@@ -617,7 +617,7 @@ const SCADADeviceList: React.FC<SCADADeviceListProps> = ({
|
||||
|
||||
// 调用后端清洗接口
|
||||
const response = await axios.post(
|
||||
`${config.BACKEND_URL}/timescaledb/composite/clean-scada?device_ids=all&start_time=${startTime}&end_time=${endTime}`
|
||||
`${config.BACKEND_URL}/api/v1/composite/clean-scada?device_ids=all&start_time=${startTime}&end_time=${endTime}`
|
||||
);
|
||||
|
||||
// 处理成功响应
|
||||
|
||||
@@ -23,7 +23,7 @@ export const config = {
|
||||
},
|
||||
MAP_AVAILABLE_LAYERS: process.env.NEXT_PUBLIC_MAP_AVAILABLE_LAYERS
|
||||
? process.env.NEXT_PUBLIC_MAP_AVAILABLE_LAYERS.split(",").map((item) =>
|
||||
item.trim().toLowerCase()
|
||||
item.trim().toLowerCase(),
|
||||
)
|
||||
: ["junctions", "pipes", "valves", "reservoirs", "pumps", "tanks", "scada"],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user