|
|
@@ -0,0 +1,155 @@
|
|
|
+import type { DeviceInstallItem, GoafOverviewItem, WarningRow } from './data';
|
|
|
+import type {
|
|
|
+ DeviceKindStatistic,
|
|
|
+ DeviceStatistics,
|
|
|
+ DeviceTypeStatistic,
|
|
|
+ GoafCountOverview,
|
|
|
+ GoafOverviewSummary,
|
|
|
+ SafetyEvaluationItem,
|
|
|
+ SensorAlarmItem,
|
|
|
+} from './goafOverview.api';
|
|
|
+
|
|
|
+export interface OverviewSummaryViewData {
|
|
|
+ overview: GoafOverviewItem[];
|
|
|
+ devices: DeviceInstallItem[];
|
|
|
+ warnings: WarningRow[];
|
|
|
+}
|
|
|
+
|
|
|
+interface DeviceBucket {
|
|
|
+ name: string;
|
|
|
+ typeKeywords: string[];
|
|
|
+ kindKeywords: string[];
|
|
|
+}
|
|
|
+
|
|
|
+const DEVICE_BUCKETS: DeviceBucket[] = [
|
|
|
+ { name: '束管监测', typeKeywords: ['束管', 'bundletube'], kindKeywords: ['束管', 'bundletube'] },
|
|
|
+ { name: '光纤测温', typeKeywords: ['光纤', 'fiber'], kindKeywords: ['光纤', 'fiber'] },
|
|
|
+ { name: '密闭监测', typeKeywords: ['密闭', 'sealed'], kindKeywords: ['密闭', 'sealed'] },
|
|
|
+];
|
|
|
+
|
|
|
+const ALARM_LEVEL_TEXT: Record<number, string> = {
|
|
|
+ 104: '高风险',
|
|
|
+ 103: '中等风险',
|
|
|
+ 102: '低风险',
|
|
|
+ 101: '一般风险',
|
|
|
+};
|
|
|
+
|
|
|
+function toNumber(value: unknown, fallback = 0) {
|
|
|
+ const result = Number(value);
|
|
|
+ return Number.isFinite(result) ? result : fallback;
|
|
|
+}
|
|
|
+
|
|
|
+function includesAny(text: string, keywords: string[]) {
|
|
|
+ const source = text.toLowerCase();
|
|
|
+ return keywords.some((keyword) => source.includes(keyword.toLowerCase()));
|
|
|
+}
|
|
|
+
|
|
|
+function buildOverview(counts: GoafCountOverview | undefined, fallback: GoafOverviewItem[]): GoafOverviewItem[] {
|
|
|
+ if (!counts) return fallback;
|
|
|
+
|
|
|
+ const fallbackMap = new Map(fallback.map((item) => [item.label, item.value]));
|
|
|
+ const pick = (value: number | undefined, label: string) =>
|
|
|
+ value === null || value === undefined ? (fallbackMap.get(label) ?? 0) : toNumber(value);
|
|
|
+
|
|
|
+ return [
|
|
|
+ { label: '矿井采空区总数', value: pick(counts.totalCount, '矿井采空区总数') },
|
|
|
+ { label: '已封闭采空区数', value: pick(counts.closedCount, '已封闭采空区数') },
|
|
|
+ { label: '回撤工作面采空区数', value: pick(counts.withdrawCount, '回撤工作面采空区数') },
|
|
|
+ { label: '回采工作面采空区数', value: pick(counts.miningCount, '回采工作面采空区数') },
|
|
|
+ { label: '停产工作面采空区数', value: pick(counts.stoppedCount, '停产工作面采空区数') },
|
|
|
+ ];
|
|
|
+}
|
|
|
+
|
|
|
+function sumTypeStatistics(statistics: DeviceTypeStatistic[], keywords: string[]) {
|
|
|
+ return statistics.reduce((total, item) => {
|
|
|
+ const text = `${item.deviceTypeName || ''} ${item.deviceType || ''}`;
|
|
|
+ return includesAny(text, keywords) ? total + toNumber(item.count) : total;
|
|
|
+ }, 0);
|
|
|
+}
|
|
|
+
|
|
|
+function sumKindStatistics(statistics: DeviceKindStatistic[], keywords: string[]) {
|
|
|
+ return statistics.reduce((total, item) => {
|
|
|
+ const text = `${item.deviceKindName || ''} ${item.deviceKind || ''}`;
|
|
|
+ return includesAny(text, keywords) ? total + toNumber(item.count) : total;
|
|
|
+ }, 0);
|
|
|
+}
|
|
|
+
|
|
|
+function buildDevices(statistics: DeviceStatistics | undefined, fallback: DeviceInstallItem[]): DeviceInstallItem[] {
|
|
|
+ if (!statistics) return fallback;
|
|
|
+
|
|
|
+ const typeStatistics = statistics.typeStatistics || [];
|
|
|
+ const kindStatistics = statistics.kindStatistics || [];
|
|
|
+ if (!typeStatistics.length && !kindStatistics.length) return fallback;
|
|
|
+
|
|
|
+ return DEVICE_BUCKETS.map((bucket) => {
|
|
|
+ const typeCount = sumTypeStatistics(typeStatistics, bucket.typeKeywords);
|
|
|
+ const count = typeCount || sumKindStatistics(kindStatistics, bucket.kindKeywords);
|
|
|
+ return {
|
|
|
+ name: bucket.name,
|
|
|
+ installed: count,
|
|
|
+ // 汇总接口只提供设备接入数量,运行数量暂按接入数量展示
|
|
|
+ running: count,
|
|
|
+ };
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function normalizeAlarmLevel(alarm: SensorAlarmItem | null) {
|
|
|
+ if (!alarm) return '未预警';
|
|
|
+
|
|
|
+ const name = alarm.alarmLevelName?.trim();
|
|
|
+ if (name) return name;
|
|
|
+
|
|
|
+ const code = Number(alarm.alarmLevel);
|
|
|
+ return ALARM_LEVEL_TEXT[code] || '未预警';
|
|
|
+}
|
|
|
+
|
|
|
+function pickAlarm(sceneId: string, alarms: SensorAlarmItem[]) {
|
|
|
+ const matched = alarms.filter((alarm) => String(alarm.sysId ?? '') === sceneId && alarm.isTriggered === true);
|
|
|
+ if (!matched.length) return null;
|
|
|
+
|
|
|
+ return matched.reduce((current, alarm) => (toNumber(alarm.alarmLevel) > toNumber(current.alarmLevel) ? alarm : current));
|
|
|
+}
|
|
|
+
|
|
|
+function normalizeRiskLevel(level: string | undefined) {
|
|
|
+ if (!level) return '未评价';
|
|
|
+ return level === '中风险' ? '中等风险' : level;
|
|
|
+}
|
|
|
+
|
|
|
+function pickSafetyLevel(sceneId: string, evaluations: SafetyEvaluationItem[]) {
|
|
|
+ const matched = evaluations
|
|
|
+ .filter((item) => String(item.manageSystemId ?? item.sysId ?? '') === sceneId)
|
|
|
+ .sort((a, b) => {
|
|
|
+ const timeCompare = (b.updateTime || b.latestEvalTime || '').localeCompare(a.updateTime || a.latestEvalTime || '');
|
|
|
+ return timeCompare || toNumber(b.evalType) - toNumber(a.evalType);
|
|
|
+ });
|
|
|
+ return normalizeRiskLevel(matched[0]?.currentRiskLevel);
|
|
|
+}
|
|
|
+
|
|
|
+function buildWarnings(summary: GoafOverviewSummary): WarningRow[] {
|
|
|
+ const scenes = summary.goafCountOverview?.goafList || [];
|
|
|
+ const alarms = summary.goafAlarmSummary?.sensorAlarmList || [];
|
|
|
+ const evaluations = summary.goafAlarmSummary?.safetyEvaluationList || [];
|
|
|
+
|
|
|
+ return scenes.map((scene, index) => {
|
|
|
+ const sceneId = String(scene.id ?? '');
|
|
|
+ const alarm = pickAlarm(sceneId, alarms);
|
|
|
+ return {
|
|
|
+ id: index + 1,
|
|
|
+ name: scene.systemName || scene.name || '--',
|
|
|
+ seam: scene.coalSeam || scene.properties?.coalSeam || '--',
|
|
|
+ level: normalizeAlarmLevel(alarm),
|
|
|
+ safetyLevel: pickSafetyLevel(sceneId, evaluations),
|
|
|
+ };
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/** 将综合汇总接口转换为系统概览页面的展示数据 */
|
|
|
+export function mapGoafSummaryData(summary: GoafOverviewSummary | undefined, fallback: OverviewSummaryViewData): OverviewSummaryViewData {
|
|
|
+ if (!summary) return fallback;
|
|
|
+
|
|
|
+ return {
|
|
|
+ overview: buildOverview(summary.goafCountOverview, fallback.overview),
|
|
|
+ devices: buildDevices(summary.deviceStatistics, fallback.devices),
|
|
|
+ warnings: buildWarnings(summary),
|
|
|
+ };
|
|
|
+}
|