refactor(vimp): 拆分站点模型为 VimpRawSite / VimpSite 并归一化 online 字段

- 将 VimpStation 重命名为 VimpSite,统一"站点"语义贯穿全模块
- 新增 VimpRawSite 表示 /catalog/allDevice 接口原样数据,online 字段可选
- 抽离 normalizeVimpSite 纯函数,集中处理 online 字段缺失时的默认值
- catalogAllDeviceApi 入参改为 VimpRawSite[],出参统一归一化为 VimpSite[] | null
- 下游 store、composable、树节点类型同步从 VimpStation 切换到 VimpSite
- 内部业务模型保持 online: boolean 必填,避免缺失字段沿调用链向下传播
This commit is contained in:
yangsy
2026-06-08 13:38:38 +08:00
parent 6fed499d78
commit 6f14370751
8 changed files with 36 additions and 24 deletions
+1 -1
View File
@@ -1,2 +1,2 @@
export * from './vimp-channel'; export * from './vimp-channel';
export * from './vimp-station'; export * from './vimp-site';
+17
View File
@@ -0,0 +1,17 @@
export interface VimpRawSite {
code: string;
name: string;
online?: boolean;
}
export interface VimpSite {
code: string;
name: string;
online: boolean;
}
export const normalizeVimpSite = (site: VimpRawSite): VimpSite => ({
code: site.code,
name: site.name,
online: site.online ?? true,
});
@@ -1,5 +0,0 @@
export interface VimpStation {
code: string;
name: string;
online: boolean;
}
@@ -1,11 +1,11 @@
import { unwrapVimpResponse, vimpClient } from '../client'; import { unwrapVimpResponse, vimpClient } from '../client';
import type { VimpStation } from '../model'; import { normalizeVimpSite, type VimpRawSite } from '../model';
export const catalogAllDeviceApi = async (options?: { signal?: AbortSignal }) => { export const catalogAllDeviceApi = async (options?: { signal?: AbortSignal }) => {
const { signal } = options ?? {}; const { signal } = options ?? {};
const client = vimpClient; const client = vimpClient;
const endpoint = `/catalog/allDevice`; const endpoint = `/catalog/allDevice`;
const resp = await client.post<VimpStation[]>(endpoint, {}, { signal }); const resp = await client.post<VimpRawSite[]>(endpoint, {}, { signal });
const data = unwrapVimpResponse(resp); const data = unwrapVimpResponse(resp);
return data; return data?.map(normalizeVimpSite) ?? null;
}; };
@@ -4,7 +4,7 @@ import type { AxiosRequestConfig } from 'axios';
import axios from 'axios'; import axios from 'axios';
import { compileCodeAreas, type CodeArea, type CodeLines, type CodeSites } from '../../types'; import { compileCodeAreas, type CodeArea, type CodeLines, type CodeSites } from '../../types';
import { useCameraStore, useAlarmStore } from '../../stores'; import { useCameraStore, useAlarmStore } from '../../stores';
import { catalogAllDeviceApi, catalogChannelApi, type VimpChannel, type VimpStation } from '../../apis'; import { catalogAllDeviceApi, catalogChannelApi, type VimpChannel, type VimpSite } from '../../apis';
const config: AxiosRequestConfig = { const config: AxiosRequestConfig = {
headers: { headers: {
@@ -35,7 +35,7 @@ const compareByCode = <T extends { code: string }>(a: T, b: T) => {
if (a.code > b.code) return 1; if (a.code > b.code) return 1;
return 0; return 0;
}; };
const sortSitesByCode = (sites: VimpStation[]) => { const sortSitesByCode = (sites: VimpSite[]) => {
sites.sort(compareByCode); sites.sort(compareByCode);
}; };
const sortChannelsMapByCode = (siteCodeToChannelsMap: Map<string, VimpChannel[]>) => { const sortChannelsMapByCode = (siteCodeToChannelsMap: Map<string, VimpChannel[]>) => {
@@ -73,8 +73,8 @@ export const useDeviceCenterQuery = () => {
// 从 /allDevice 接口获取的站点信息并不保证真实性和完整性, // 从 /allDevice 接口获取的站点信息并不保证真实性和完整性,
// 例如有一个站点的编码是 010699 开头,但是其下的通道是 010199 和 010599 开头, // 例如有一个站点的编码是 010699 开头,但是其下的通道是 010199 和 010599 开头,
// 而 010699 是一个不存在的站点编码,所以需要基于通道的编码来确定所有的站点。 // 而 010699 是一个不存在的站点编码,所以需要基于通道的编码来确定所有的站点。
const cameraSites: VimpStation[] = []; const cameraSites: VimpSite[] = [];
const alarmSites: VimpStation[] = []; const alarmSites: VimpSite[] = [];
const cameraBuiltSitesSet = new Set<string>(); const cameraBuiltSitesSet = new Set<string>();
const alarmBuiltSitesSet = new Set<string>(); const alarmBuiltSitesSet = new Set<string>();
const siteCodeToCamerasMap = new Map<string, VimpChannel[]>(); const siteCodeToCamerasMap = new Map<string, VimpChannel[]>();
+2 -2
View File
@@ -1,10 +1,10 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import type { VimpChannel, VimpStation } from '../apis'; import type { VimpChannel, VimpSite } from '../apis';
import { shallowRef } from 'vue'; import { shallowRef } from 'vue';
import type { AlarmMainAreaNodeOption, AlarmNodeOption, CodeLines, CodeSites, AlarmLineTabPane, AlarmSiteNodeOption, AlarmSubAreaNodeOption, CompiledCodeAreas } from '../types'; import type { AlarmMainAreaNodeOption, AlarmNodeOption, CodeLines, CodeSites, AlarmLineTabPane, AlarmSiteNodeOption, AlarmSubAreaNodeOption, CompiledCodeAreas } from '../types';
interface BuildLineTabPanesParams { interface BuildLineTabPanesParams {
sites: VimpStation[]; sites: VimpSite[];
siteCodeToAlarmsMap: Map<string, VimpChannel[]>; siteCodeToAlarmsMap: Map<string, VimpChannel[]>;
codeLines: CodeLines; codeLines: CodeLines;
codeSites: CodeSites; codeSites: CodeSites;
+2 -2
View File
@@ -1,10 +1,10 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import type { VimpChannel, VimpStation } from '../apis'; import type { VimpChannel, VimpSite } from '../apis';
import { shallowRef } from 'vue'; import { shallowRef } from 'vue';
import type { CameraMainAreaNodeOption, CameraNodeOption, CodeLines, CodeSites, CameraLineTabPane, CameraSiteNodeOption, CameraSubAreaNodeOption, CompiledCodeAreas } from '../types'; import type { CameraMainAreaNodeOption, CameraNodeOption, CodeLines, CodeSites, CameraLineTabPane, CameraSiteNodeOption, CameraSubAreaNodeOption, CompiledCodeAreas } from '../types';
interface BuildLineTabPanesParams { interface BuildLineTabPanesParams {
sites: VimpStation[]; sites: VimpSite[];
siteCodeToCamerasMap: Map<string, VimpChannel[]>; siteCodeToCamerasMap: Map<string, VimpChannel[]>;
codeLines: CodeLines; codeLines: CodeLines;
codeSites: CodeSites; codeSites: CodeSites;
+7 -7
View File
@@ -1,5 +1,5 @@
import type { TabPaneProps, TreeOption } from 'naive-ui'; import type { TabPaneProps, TreeOption } from 'naive-ui';
import type { VimpChannel, VimpStation } from '../apis/model'; import type { VimpChannel, VimpSite } from '../apis/model';
export type SiteType = 'station' | 'parking' | 'occ' | 'train'; export type SiteType = 'station' | 'parking' | 'occ' | 'train';
export type CodeLines = Record<string, { name: string; color: string }>; export type CodeLines = Record<string, { name: string; color: string }>;
@@ -57,20 +57,20 @@ export interface CountStats {
export interface CameraNodeOption extends TreeOption { export interface CameraNodeOption extends TreeOption {
camera: VimpChannel; camera: VimpChannel;
type: string; type: string;
site: VimpStation; site: VimpSite;
} }
export interface CameraSubAreaNodeOption extends TreeOption { export interface CameraSubAreaNodeOption extends TreeOption {
children?: CameraNodeOption[]; children?: CameraNodeOption[];
stats: CountStats; stats: CountStats;
site: VimpStation; site: VimpSite;
areaLevel: 2; areaLevel: 2;
} }
export interface CameraMainAreaNodeOption extends TreeOption { export interface CameraMainAreaNodeOption extends TreeOption {
children?: CameraSubAreaNodeOption[]; children?: CameraSubAreaNodeOption[];
stats: CountStats; stats: CountStats;
site: VimpStation; site: VimpSite;
areaLevel: 1; areaLevel: 1;
} }
@@ -104,20 +104,20 @@ export interface CameraLineTabPane extends TabPaneProps {
export interface AlarmNodeOption extends TreeOption { export interface AlarmNodeOption extends TreeOption {
alarm: VimpChannel; alarm: VimpChannel;
type: string; type: string;
site: VimpStation; site: VimpSite;
} }
export interface AlarmSubAreaNodeOption extends TreeOption { export interface AlarmSubAreaNodeOption extends TreeOption {
children?: AlarmNodeOption[]; children?: AlarmNodeOption[];
stats: CountStats; stats: CountStats;
site: VimpStation; site: VimpSite;
areaLevel: 2; areaLevel: 2;
} }
export interface AlarmMainAreaNodeOption extends TreeOption { export interface AlarmMainAreaNodeOption extends TreeOption {
children?: AlarmSubAreaNodeOption[]; children?: AlarmSubAreaNodeOption[];
stats: CountStats; stats: CountStats;
site: VimpStation; site: VimpSite;
areaLevel: 1; areaLevel: 1;
} }