import { defineStore } from 'pinia'; import type { VimpChannel, VimpStation } from '../apis'; import { shallowRef } from 'vue'; import type { CameraMainAreaNodeOption, CameraNodeOption, CodeLines, CodeSites, CameraLineTabPane, CameraSiteNodeOption, CameraSubAreaNodeOption, CompiledCodeAreas } from '../types'; interface BuildLineTabPanesParams { sites: VimpStation[]; siteCodeToCamerasMap: Map; codeLines: CodeLines; codeSites: CodeSites; compiledCodeAreas: CompiledCodeAreas; } const buildMainAreaNodeKey = (siteCode: string, mainAreaCode: string) => `${siteCode}${mainAreaCode}`; const buildSubAreaNodeKey = (siteCode: string, areaCode: string) => `${siteCode}${areaCode}`; export const useCameraStore = defineStore('vimp-camera-store', () => { const lineTabPanes = shallowRef([]); const buildLineTabPanes = (params: BuildLineTabPanesParams) => { const { sites, siteCodeToCamerasMap, codeLines, codeSites, compiledCodeAreas } = params; const result: CameraLineTabPane[] = []; // 1. 线路索引 lineCode -> CameraLineTabPane const linePaneMap = new Map(); // 遍历所有站点 for (const site of sites) { // 2. 站点节点 siteNode 只在当前轮次中顺序创建,不需要建立索引 const lineCode = site.code.substring(0, 3); const lineName = codeLines[lineCode]?.name ?? ''; let linePane = linePaneMap.get(lineCode); if (!linePane) { linePane = { lineCode, lineName, cameraTree: [] }; linePaneMap.set(lineCode, linePane); result.push(linePane); } const siteCode = site.code; const siteMeta = codeSites[siteCode]; if (!siteMeta) continue; const siteName = siteMeta.name; const siteType = siteMeta.type; const compiledCodeAreaMaps = compiledCodeAreas[siteType]; const mainAreaCodeLength = siteType === 'train' ? 3 : 2; // 构造站点节点 const siteNode: CameraSiteNodeOption = { key: siteCode, label: siteName, children: [], stats: { online: 0, offline: 0, total: 0 }, online: site.online, }; linePane.cameraTree.push(siteNode); // 获取所有摄像机 const cameras = siteCodeToCamerasMap.get(siteCode); if (!cameras) continue; // 3. 1级区域索引 mainAreaNodeKey -> CameraMainAreaNodeOption // mainAreaNodeKey = ${siteCode}${cameraMainAreaCode} const mainAreaNodeMap = new Map(); // 4. 2级区域索引 subAreaNodeKey -> CameraSubAreaNodeOption // subAreaNodeKey = ${siteCode}${cameraAreaCode} const subAreaNodeMap = new Map(); // 5. 摄像机索引 subAreaNodeKey -> Set const subAreaNodeKeyToCameraGbCodeSetMap = new Map>(); // 遍历摄像机 for (const camera of cameras) { // 计算相关编码 const { code: cameraGbCode, name: cameraName } = camera; const cameraAreaCode = cameraGbCode.substring(6, 11); const cameraMainAreaCode = cameraAreaCode.slice(0, mainAreaCodeLength); // 查找1级区域,如果未找到则跳过该摄像机 const mainArea = compiledCodeAreaMaps.mainAreaMap.get(cameraMainAreaCode); if (!mainArea) continue; // 尝试从索引中获取1级区域节点,若不存在则创建 const mainAreaNodeKey = buildMainAreaNodeKey(siteCode, cameraMainAreaCode); let mainAreaNode = mainAreaNodeMap.get(mainAreaNodeKey); if (!mainAreaNode) { mainAreaNode = { key: mainAreaNodeKey, label: mainArea.name, children: [], stats: { online: 0, offline: 0, total: 0 }, site: site, areaLevel: 1, }; mainAreaNodeMap.set(mainAreaNodeKey, mainAreaNode); siteNode.children?.push(mainAreaNode); } // 查找2级区域,如果未找到则跳过该摄像机 const subArea = compiledCodeAreaMaps.subAreaMap.get(cameraAreaCode); if (!subArea) continue; // 尝试从索引中获取2级区域节点,若不存在则创建 const subAreaNodeKey = buildSubAreaNodeKey(siteCode, cameraAreaCode); let subAreaNode = subAreaNodeMap.get(subAreaNodeKey); if (!subAreaNode) { subAreaNode = { key: subAreaNodeKey, label: subArea.name, children: [], stats: { online: 0, offline: 0, total: 0 }, site: site, areaLevel: 2, }; subAreaNodeMap.set(subAreaNodeKey, subAreaNode); mainAreaNode.children?.push(subAreaNode); } // 构造摄像机节点 let cameraGbCodeSet = subAreaNodeKeyToCameraGbCodeSetMap.get(subAreaNodeKey); if (!cameraGbCodeSet) { cameraGbCodeSet = new Set(); subAreaNodeKeyToCameraGbCodeSetMap.set(subAreaNodeKey, cameraGbCodeSet); } if (cameraGbCodeSet.has(cameraGbCode)) continue; cameraGbCodeSet.add(cameraGbCode); const cameraType = cameraGbCode.substring(11, 14); const cameraNode: CameraNodeOption = { key: cameraGbCode, label: cameraName, type: cameraType, camera: camera, site: site, }; subAreaNode.children?.push(cameraNode); // 统计站点、区域、子区域的在线/离线/总摄像机数量 siteNode.stats.total++; mainAreaNode.stats.total++; subAreaNode.stats.total++; if (camera.status === 1) { siteNode.stats.online++; mainAreaNode.stats.online++; subAreaNode.stats.online++; } else if (camera.status === 0) { siteNode.stats.offline++; mainAreaNode.stats.offline++; subAreaNode.stats.offline++; } } } lineTabPanes.value = result; }; return { lineTabPanes, buildLineTabPanes, }; });