ad9a0011a5
在摄像头、告警的Pinia存储中新增对应的数据记录与构建函数,并在渠道查询组合式函数中调用生成全局索引映射数据
176 lines
6.3 KiB
TypeScript
176 lines
6.3 KiB
TypeScript
import { defineStore } from 'pinia';
|
|
import type { VimpChannel, VimpSite } from '../apis';
|
|
import { shallowRef } from 'vue';
|
|
import type { AlarmMainAreaNodeOption, AlarmNodeOption, CodeLines, CodeSites, AlarmLineTabPane, AlarmSiteNodeOption, AlarmSubAreaNodeOption, CompiledCodeAreas } from '../types';
|
|
|
|
interface BuildLineTabPanesParams {
|
|
sites: VimpSite[];
|
|
siteCodeToAlarmsMap: Map<string, VimpChannel[]>;
|
|
codeLines: CodeLines;
|
|
codeSites: CodeSites;
|
|
compiledCodeAreas: CompiledCodeAreas;
|
|
}
|
|
|
|
const buildMainAreaNodeKey = (siteCode: string, mainAreaCode: string) => `${siteCode}${mainAreaCode}`;
|
|
const buildSubAreaNodeKey = (siteCode: string, areaCode: string) => `${siteCode}${areaCode}`;
|
|
|
|
export const useAlarmStore = defineStore('vimp-alarm-store', () => {
|
|
const lineTabPanes = shallowRef<AlarmLineTabPane[]>([]);
|
|
const alarmRecord = shallowRef<Record<string, VimpChannel>>({});
|
|
|
|
const buildLineTabPanes = (params: BuildLineTabPanesParams) => {
|
|
const { sites, siteCodeToAlarmsMap, codeLines, codeSites, compiledCodeAreas } = params;
|
|
|
|
const result: AlarmLineTabPane[] = [];
|
|
|
|
// 1. 线路索引 lineCode -> AlarmLineTabPane
|
|
const linePaneMap = new Map<string, AlarmLineTabPane>();
|
|
|
|
// 遍历所有站点
|
|
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, alarmTree: [] };
|
|
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: AlarmSiteNodeOption = {
|
|
key: siteCode,
|
|
label: siteName,
|
|
children: [],
|
|
stats: { online: 0, offline: 0, total: 0 },
|
|
online: site.online,
|
|
};
|
|
linePane.alarmTree.push(siteNode);
|
|
|
|
// 获取所有警报器
|
|
const alarms = siteCodeToAlarmsMap.get(siteCode);
|
|
if (!alarms) continue;
|
|
|
|
// 3. 1级区域索引 mainAreaNodeKey -> AlarmMainAreaNodeOption
|
|
// mainAreaNodeKey = ${siteCode}${alarmMainAreaCode}
|
|
const mainAreaNodeMap = new Map<string, AlarmMainAreaNodeOption>();
|
|
// 4. 2级区域索引 subAreaNodeKey -> AlarmSubAreaNodeOption
|
|
// subAreaNodeKey = ${siteCode}${alarmAreaCode}
|
|
const subAreaNodeMap = new Map<string, AlarmSubAreaNodeOption>();
|
|
// 5. 警报器索引 subAreaNodeKey -> Set<AlarmGbCode>
|
|
const subAreaNodeKeyToAlarmGbCodeSetMap = new Map<string, Set<string>>();
|
|
|
|
// 遍历警报器
|
|
for (const alarm of alarms) {
|
|
// 计算相关编码
|
|
const { code: alarmGbCode, name: alarmName } = alarm;
|
|
const alarmAreaCode = alarmGbCode.substring(6, 11);
|
|
const alarmMainAreaCode = alarmAreaCode.slice(0, mainAreaCodeLength);
|
|
|
|
// 查找1级区域,如果未找到则跳过该警报器
|
|
const mainArea = compiledCodeAreaMaps.mainAreaMap.get(alarmMainAreaCode);
|
|
if (!mainArea) continue;
|
|
|
|
// 尝试从索引中获取1级区域节点,若不存在则创建
|
|
const mainAreaNodeKey = buildMainAreaNodeKey(siteCode, alarmMainAreaCode);
|
|
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(alarmAreaCode);
|
|
if (!subArea) continue;
|
|
|
|
// 尝试从索引中获取2级区域节点,若不存在则创建
|
|
const subAreaNodeKey = buildSubAreaNodeKey(siteCode, alarmAreaCode);
|
|
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 alarmGbCodeSet = subAreaNodeKeyToAlarmGbCodeSetMap.get(subAreaNodeKey);
|
|
if (!alarmGbCodeSet) {
|
|
alarmGbCodeSet = new Set<string>();
|
|
subAreaNodeKeyToAlarmGbCodeSetMap.set(subAreaNodeKey, alarmGbCodeSet);
|
|
}
|
|
if (alarmGbCodeSet.has(alarmGbCode)) continue;
|
|
alarmGbCodeSet.add(alarmGbCode);
|
|
const alarmType = alarm.code.substring(11, 14);
|
|
const alarmNode: AlarmNodeOption = {
|
|
key: alarmGbCode,
|
|
label: alarmName,
|
|
type: alarmType,
|
|
alarm: alarm,
|
|
site: site,
|
|
};
|
|
subAreaNode.children?.push(alarmNode);
|
|
|
|
// 统计站点、区域、子区域的在线/离线/总警报器数量
|
|
siteNode.stats.total++;
|
|
mainAreaNode.stats.total++;
|
|
subAreaNode.stats.total++;
|
|
if (alarm.status === 1) {
|
|
siteNode.stats.online++;
|
|
mainAreaNode.stats.online++;
|
|
subAreaNode.stats.online++;
|
|
} else if (alarm.status === 0) {
|
|
siteNode.stats.offline++;
|
|
mainAreaNode.stats.offline++;
|
|
subAreaNode.stats.offline++;
|
|
}
|
|
}
|
|
}
|
|
lineTabPanes.value = result;
|
|
};
|
|
|
|
const buildAlarmRecord = (siteCodeToAlarmsMap: Map<string, VimpChannel[]>) => {
|
|
const record: Record<string, VimpChannel> = {};
|
|
for (const [, alarms] of siteCodeToAlarmsMap) {
|
|
for (const alarm of alarms) {
|
|
record[alarm.code] = alarm;
|
|
}
|
|
}
|
|
alarmRecord.value = record;
|
|
};
|
|
|
|
return {
|
|
lineTabPanes,
|
|
alarmRecord,
|
|
|
|
buildLineTabPanes,
|
|
buildAlarmRecord,
|
|
};
|
|
});
|