Files
ndm-web-platform/src/pages/vimp/composables/query/use-device-center-query.ts
T
yangsy 176e35609f fix(device-center-query): 简化并修正设备站点与通道的处理逻辑
原先的逻辑先按API返回的站点分组通道,再通过通道编码重建站点列表,存在冗余且可能出错。现在改为单次循环直接基于通道编码生成正确的站点,并按站点分组相机和告警通道,同时完善了相关注释说明。
2026-05-30 22:02:52 +08:00

112 lines
4.2 KiB
TypeScript

import { useQuery } from '@tanstack/vue-query';
import { computed } from 'vue';
import type { AxiosRequestConfig } from 'axios';
import axios from 'axios';
import type { CodeArea, CodeLines, CodeSites } from '../../types';
import { useCameraStore, useAlarmStore } from '../../stores';
import { catalogAllDeviceApi, catalogChannelApi, type VimpChannel, type VimpStation } from '../../apis';
const config: AxiosRequestConfig = {
headers: {
'Cache-Control': 'no-store',
},
};
const buildTrainAreas = () => {
const codeTrainAreas: CodeArea[] = [];
for (let i = 0; i < 999; i++) {
const codeTrain = i.toString().padStart(3, '0');
// 市域线name为车组,改造线name为车次
const area: CodeArea = { code: codeTrain, name: '车次' + codeTrain, subs: [] };
for (let j = 0; j <= 99; j++) {
const codeCarriage = j.toString().padStart(2, '0');
const subArea: CodeArea['subs'][number] = { code: codeTrain + codeCarriage, name: '车厢' + codeCarriage };
area.subs.push(subArea);
}
// const areaPreserve: CodeArea['subs'][number] = { code: codeTrain + '51', name: '预留' };
// area.subs.push(areaPreserve);
codeTrainAreas.push(area);
}
return codeTrainAreas;
};
export const useDeviceCenterQuery = () => {
const cameraStore = useCameraStore();
const alarmStore = useAlarmStore();
return useQuery({
queryKey: computed(() => ['vimp-device']),
refetchInterval: 10 * 1000,
refetchOnWindowFocus: false,
queryFn: async ({ signal }) => {
const codeLines = (await axios.get<CodeLines>('/cdn/vimp/codes/codeLines.json', config)).data;
const codeSites = (await axios.get<CodeSites>('/cdn/vimp/codes/codeStations.json', config)).data;
const codeStationAreas = (await axios.get<CodeArea[]>('/cdn/vimp/codes/codeStationAreas.json', config)).data;
const codeParkingAreas = (await axios.get<CodeArea[]>('/cdn/vimp/codes/codeParkingAreas.json', config)).data;
const codeOccAreas = (await axios.get<CodeArea[]>('/cdn/vimp/codes/codeOccAreas.json', config)).data;
const codeTrainAreas = buildTrainAreas();
const sitesFromApi = await catalogAllDeviceApi({ signal });
// 从 /allDevice 接口获取的站点信息并不保证真实性和完整性,
// 例如有一个站点的编码是 010699 开头,但是其下的通道是 010199 和 010599 开头,
// 而 010699 是一个不存在的站点编码,所以需要基于通道的编码来确定所有的站点。
const sites: VimpStation[] = [];
const siteCamerasMap = new Map<string, VimpChannel[]>();
const siteAlarmsMap = new Map<string, VimpChannel[]>();
for (const siteFromApi of sitesFromApi ?? []) {
const channels = await catalogChannelApi(siteFromApi.code, { signal });
if (!channels || channels.length === 0) continue;
channels.forEach((channel) => {
const siteCode = channel.code.substring(0, 6);
if (siteCode in codeSites && !sites.some((site) => site.code === siteCode)) {
sites.push({
code: siteCode,
name: codeSites[siteCode]?.name ?? '',
online: siteFromApi.online,
});
}
const typeCode = Number(channel.code.substring(11, 14));
if (typeCode >= 4 && typeCode <= 6) {
if (!siteCamerasMap.has(siteCode)) {
siteCamerasMap.set(siteCode, []);
}
siteCamerasMap.get(siteCode)!.push(channel);
} else if ((typeCode >= 101 && typeCode <= 108) || (typeCode >= 810 && typeCode <= 815)) {
if (!siteAlarmsMap.has(siteCode)) {
siteAlarmsMap.set(siteCode, []);
}
siteAlarmsMap.get(siteCode)!.push(channel);
}
});
}
cameraStore.buildLineTabPanes({
sites,
siteCamerasMap,
codeLines,
codeSites,
codeStationAreas,
codeParkingAreas,
codeOccAreas,
codeTrainAreas,
});
// alarmStore.buildLineTabPanes({
// sitesFromApi,
// siteAlarmsMapFromApi,
// codeLines,
// codeSites,
// codeStationAreas,
// codeParkingAreas,
// codeOccAreas,
// codeTrainAreas,
// });
return null;
},
});
};