bd1cc0483b
- 将设备中心查询逻辑从API层抽取至composables目录,封装为useDeviceCenterQuery组合式函数 - 拆分camera、alarm的状态管理为独立store文件,新增资源面板搜索状态store - 更新相关组件的依赖导入路径,清理冗余导出并调整导出列表
184 lines
7.5 KiB
TypeScript
184 lines
7.5 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import type { VimpChannel, VimpStation } from '../apis';
|
|
import { h, ref } from 'vue';
|
|
import type { CameraMainAreaNodeOption, CameraNodeOption, CodeArea, CodeLines, CodeSites, CameraLineTabPane, CameraSiteNodeOption, CameraSubAreaNodeOption } from '../types';
|
|
|
|
interface BuildLineTabPanesParams {
|
|
sites: VimpStation[] | null;
|
|
siteCamerasMap: Record<string, VimpChannel[]>;
|
|
codeLines: CodeLines;
|
|
codeSites: CodeSites;
|
|
codeStationAreas: CodeArea[];
|
|
codeParkingAreas: CodeArea[];
|
|
codeOccAreas: CodeArea[];
|
|
codeTrainAreas: CodeArea[];
|
|
}
|
|
|
|
export const useCameraStore = defineStore('vimp-camera-store', () => {
|
|
const lineTabPanes = ref<CameraLineTabPane[]>([]);
|
|
|
|
const buildLineTabPanes = (params: BuildLineTabPanesParams) => {
|
|
const { sites, siteCamerasMap, codeLines, codeSites, codeStationAreas, codeParkingAreas, codeOccAreas, codeTrainAreas } = params;
|
|
if (!sites) {
|
|
lineTabPanes.value = [];
|
|
return;
|
|
}
|
|
// 构造线路TabPane
|
|
const _lineTabPanes: CameraLineTabPane[] = [];
|
|
const lineCode = sites.at(0)?.code.substring(0, 3) ?? '';
|
|
const lineName = codeLines[lineCode]?.name ?? '';
|
|
if (!_lineTabPanes.some((lineNode) => lineNode.lineCode === lineCode)) {
|
|
_lineTabPanes.push({
|
|
lineCode,
|
|
lineName,
|
|
cameraTree: [],
|
|
});
|
|
}
|
|
|
|
// 遍历所有站点
|
|
for (const site of sites) {
|
|
const siteCode = site.code.substring(0, 6);
|
|
const siteName = codeSites[siteCode]?.name;
|
|
if (!siteName) continue;
|
|
|
|
// 构造站点节点
|
|
const siteNode: CameraSiteNodeOption = {
|
|
key: siteCode,
|
|
label: siteName,
|
|
children: [],
|
|
stats: { online: 0, offline: 0, total: 0 },
|
|
online: site.online,
|
|
};
|
|
_lineTabPanes.find((lineTabPane) => lineTabPane.lineCode === lineCode)?.cameraTree.push(siteNode);
|
|
|
|
// 获取所有摄像机
|
|
const cameras = siteCamerasMap[site.code];
|
|
if (!cameras || cameras.length === 0) continue;
|
|
|
|
// 遍历摄像机
|
|
for (const camera of cameras) {
|
|
// 计算相关编码
|
|
const { code: cameraGbCode, name: cameraName } = camera;
|
|
const cameraSiteCode = cameraGbCode.substring(0, 6);
|
|
const cameraSiteType = codeSites[cameraSiteCode]?.type;
|
|
const cameraAreaCode = cameraGbCode.substring(6, 11);
|
|
const cameraMainAreaCode = cameraAreaCode.slice(0, 2);
|
|
|
|
// 构造车站/基地/OCC/车次区域
|
|
let siteArea: CodeArea | undefined = undefined;
|
|
if (cameraSiteType === 'station') {
|
|
siteArea = codeStationAreas.find((area) => area.code === cameraMainAreaCode);
|
|
} else if (cameraSiteType === 'parking') {
|
|
siteArea = codeParkingAreas.find((area) => area.code === cameraMainAreaCode);
|
|
} else if (cameraSiteType === 'occ') {
|
|
siteArea = codeOccAreas.find((area) => area.code === cameraMainAreaCode);
|
|
} else if (cameraSiteType === 'train') {
|
|
siteArea = codeTrainAreas.find((area) => area.code === cameraMainAreaCode);
|
|
} else {
|
|
continue;
|
|
}
|
|
if (!siteArea) continue; // 如果还是未找到区域,则跳过该摄像机
|
|
|
|
// 构造1级区域节点
|
|
if (!siteNode.children?.find((areaNode) => areaNode.key === `${cameraSiteCode}${cameraMainAreaCode}`)) {
|
|
const mainAreaNode: CameraMainAreaNodeOption = {
|
|
key: `${cameraSiteCode}${cameraMainAreaCode}`,
|
|
label: siteArea.name,
|
|
children: [],
|
|
stats: { online: 0, offline: 0, total: 0 },
|
|
site: site,
|
|
};
|
|
siteNode.children?.push(mainAreaNode);
|
|
}
|
|
const targetMainAreaNode = siteNode.children?.find((areaNode) => areaNode.key === `${cameraSiteCode}${cameraMainAreaCode}`);
|
|
if (!targetMainAreaNode) continue; // 如果1级区域节点不存在,则跳过该摄像机
|
|
|
|
// 构造2级区域节点
|
|
if (!targetMainAreaNode.children?.find((subAreaNode) => subAreaNode.key === `${cameraSiteCode}${cameraAreaCode}`)) {
|
|
let subArea: CodeArea['subs'][number] | undefined = undefined;
|
|
if (cameraSiteType === 'station') {
|
|
subArea = codeStationAreas.find((area) => area.code === cameraMainAreaCode)?.subs.find((subArea) => subArea.code === cameraAreaCode);
|
|
} else if (cameraSiteType === 'parking') {
|
|
subArea = codeParkingAreas.find((area) => area.code === cameraMainAreaCode)?.subs.find((subArea) => subArea.code === cameraAreaCode);
|
|
} else if (cameraSiteType === 'occ') {
|
|
subArea = codeOccAreas.find((area) => area.code === cameraMainAreaCode)?.subs.find((subArea) => subArea.code === cameraAreaCode);
|
|
} else if (cameraSiteType === 'train') {
|
|
subArea = codeTrainAreas.find((area) => area.code === cameraMainAreaCode)?.subs.find((subArea) => subArea.code === cameraAreaCode);
|
|
} else {
|
|
continue;
|
|
}
|
|
if (!subArea) continue; // 如果还是未找到2级区域,则跳过该摄像机
|
|
|
|
const subAreaNode: CameraSubAreaNodeOption = {
|
|
key: `${cameraSiteCode}${cameraAreaCode}`,
|
|
label: subArea.name,
|
|
children: [],
|
|
stats: { online: 0, offline: 0, total: 0 },
|
|
site: site,
|
|
};
|
|
targetMainAreaNode.children?.push(subAreaNode);
|
|
}
|
|
const subAreaNode = targetMainAreaNode.children?.find((subAreaNode) => subAreaNode.key === `${cameraSiteCode}${cameraAreaCode}`);
|
|
if (!subAreaNode) continue; // 如果子区域节点不存在,则跳过该摄像机
|
|
|
|
// 构造摄像机节点
|
|
const cameraType = camera.code.substring(11, 14);
|
|
const cameraNode: CameraNodeOption = {
|
|
key: cameraGbCode,
|
|
label: cameraName,
|
|
type: cameraType,
|
|
camera: camera,
|
|
site: site,
|
|
prefix: () => {
|
|
if (cameraType === '004') return `[枪机]`;
|
|
if (cameraType === '005') return `[半球]`;
|
|
if (cameraType === '006') return `[球机]`;
|
|
},
|
|
};
|
|
|
|
// 添加摄像机节点到子区域节点
|
|
if (!subAreaNode.children?.find((cameraNode) => cameraNode.key === cameraGbCode)) {
|
|
subAreaNode.children?.push(cameraNode);
|
|
}
|
|
|
|
// 统计站点、区域、子区域的在线/离线/总摄像机数量
|
|
siteNode.stats.total++;
|
|
targetMainAreaNode.stats.total++;
|
|
subAreaNode.stats.total++;
|
|
if (camera.status === 1) {
|
|
siteNode.stats.online++;
|
|
targetMainAreaNode.stats.online++;
|
|
subAreaNode.stats.online++;
|
|
}
|
|
if (camera.status === 0) {
|
|
siteNode.stats.offline++;
|
|
targetMainAreaNode.stats.offline++;
|
|
subAreaNode.stats.offline++;
|
|
}
|
|
}
|
|
siteNode.suffix = () => {
|
|
const { online, offline, total } = siteNode.stats;
|
|
return `(${online}/${offline}/${total})`;
|
|
};
|
|
siteNode.children?.forEach((areaNode) => {
|
|
areaNode.suffix = () => {
|
|
const { online, offline, total } = areaNode.stats;
|
|
return h('div', { style: { marginRight: '8px', opacity: 0.6 } }, `(${online}/${offline}/${total})`);
|
|
};
|
|
areaNode.children?.forEach((subAreaNode) => {
|
|
subAreaNode.suffix = () => {
|
|
const { online, offline, total } = subAreaNode.stats;
|
|
return h('div', { style: { marginRight: '16px', opacity: 0.4 } }, `(${online}/${offline}/${total})`);
|
|
};
|
|
});
|
|
});
|
|
}
|
|
lineTabPanes.value = _lineTabPanes;
|
|
};
|
|
|
|
return {
|
|
lineTabPanes,
|
|
buildLineTabPanes,
|
|
};
|
|
});
|