131 lines
5.3 KiB
TypeScript
131 lines
5.3 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 });
|
||
|
||
const siteCamerasMapFromApi = new Map<string, VimpChannel[]>();
|
||
const siteAlarmsMapFromApi = new Map<string, VimpChannel[]>();
|
||
for (const site of sitesFromApi ?? []) {
|
||
const channels = await catalogChannelApi(site.code, { signal });
|
||
if (!channels || channels.length === 0) continue;
|
||
const cameras: VimpChannel[] = [];
|
||
const alarms: VimpChannel[] = [];
|
||
channels.forEach((channel) => {
|
||
const typeCode = Number(channel.code.substring(11, 14));
|
||
if (typeCode >= 4 && typeCode <= 6) {
|
||
cameras.push(channel);
|
||
} else if ((typeCode >= 101 && typeCode <= 108) || (typeCode >= 810 && typeCode <= 815)) {
|
||
alarms.push(channel);
|
||
}
|
||
});
|
||
const siteCode = site.code.substring(0, 6);
|
||
siteCamerasMapFromApi.set(siteCode, cameras);
|
||
siteAlarmsMapFromApi.set(siteCode, alarms);
|
||
}
|
||
// 从 /allDevice 接口获取的站点信息并不保证真实性和完整性,
|
||
// 例如有一个站点的编码是 010699 开头,但是其下的通道是 010199 和 010599 开头,
|
||
// 而 010699 是一个不存在的站点编码,所以需要基于通道的编码来确定所有的站点。
|
||
const sites: VimpStation[] = [];
|
||
const siteCamerasMap = new Map<string, VimpChannel[]>();
|
||
const siteOnlineMap = new Map<string, boolean>();
|
||
(sitesFromApi ?? []).forEach((site) => siteOnlineMap.set(site.code.substring(0, 6), site.online));
|
||
const builtSitesSet = new Set<string>();
|
||
siteCamerasMapFromApi.forEach((cameras, siteCode) => {
|
||
for (const camera of cameras) {
|
||
const { code: cameraGbCode } = camera;
|
||
const cameraSiteCode = cameraGbCode.substring(0, 6);
|
||
// 聚合同一站点的摄像机
|
||
if (!siteCamerasMap.has(cameraSiteCode)) {
|
||
siteCamerasMap.set(cameraSiteCode, []);
|
||
}
|
||
siteCamerasMap.get(cameraSiteCode)!.push(camera);
|
||
// 如果码表中不存在该站点则跳过
|
||
if (!(cameraSiteCode in codeSites)) continue;
|
||
// 如果该站点已被添加则跳过
|
||
if (builtSitesSet.has(cameraSiteCode)) continue;
|
||
// 添加该站点到站点列表
|
||
sites.push({
|
||
code: cameraSiteCode,
|
||
name: codeSites[cameraSiteCode]?.name ?? '',
|
||
// 要用 siteCode,而不是 cameraSiteCode,
|
||
// 因为 siteCode 是 010699,cameraSiteCode 是 010199 和 010599,
|
||
// 我们要将 010699 的状态分派给 010199 和 010599
|
||
online: siteOnlineMap.get(siteCode) ?? false,
|
||
});
|
||
// 标记该站点已被添加
|
||
builtSitesSet.add(cameraSiteCode);
|
||
}
|
||
});
|
||
|
||
cameraStore.buildLineTabPanes({
|
||
sites,
|
||
siteCamerasMap,
|
||
codeLines,
|
||
codeSites,
|
||
codeStationAreas,
|
||
codeParkingAreas,
|
||
codeOccAreas,
|
||
codeTrainAreas,
|
||
});
|
||
|
||
// alarmStore.buildLineTabPanes({
|
||
// sitesFromApi,
|
||
// siteAlarmsMapFromApi,
|
||
// codeLines,
|
||
// codeSites,
|
||
// codeStationAreas,
|
||
// codeParkingAreas,
|
||
// codeOccAreas,
|
||
// codeTrainAreas,
|
||
// });
|
||
|
||
return null;
|
||
},
|
||
});
|
||
};
|