Просмотр исходного кода

fix(s8): normalize dashboard module tricolor metrics

YY968XX 1 месяц назад
Родитель
Сommit
64afad2175

+ 3 - 1
Web/src/views/aidop/s8/monitoring/S8MonitoringDeliveryPage.vue

@@ -132,7 +132,7 @@ import S8MonitoringCategoryGrid, { type CategoryGridCardData } from './component
 import S8MonitoringEditToolbar from './components/S8MonitoringEditToolbar.vue';
 import S8MonitoringStageConfigDrawer from './components/S8MonitoringStageConfigDrawer.vue';
 import { useS8UnsavedLayoutEditGuard } from './useS8UnsavedLayoutEditGuard';
-import { useS8StageConfig } from './useS8StageConfig';
+import { useS8StageConfig, buildModuleTriColorStats } from './useS8StageConfig';
 import { useS8CategoryConfig } from './useS8CategoryConfig';
 import { useS8PageConfigDriver } from './useS8PageConfigDriver';
 
@@ -286,6 +286,8 @@ const stageCards = computed(() =>
 			icon: meta.icon,
 			metricLabel: meta.metricLabel,
 			value: formatInteger(total),
+			// S8-DASHBOARD-MODULE-TRICOLOR-SEMANTICS-1:三色数字(绿正常 / 黄关注 / 红严重)
+			values: buildModuleTriColorStats({ total: red + yellow, red, yellow }),
 			healthRate,
 			statusLabel: `${red + yellow} 异常`,
 			progress: total > 0

+ 4 - 1
Web/src/views/aidop/s8/monitoring/S8MonitoringOverviewPage.vue

@@ -182,7 +182,7 @@ import S8MonitoringModulesGrid from './components/S8MonitoringModulesGrid.vue';
 import S8MonitoringCategoryGrid, { type CategoryGridCardData } from './components/S8MonitoringCategoryGrid.vue';
 import S8MonitoringEditToolbar from './components/S8MonitoringEditToolbar.vue';
 import S8MonitoringStageConfigDrawer from './components/S8MonitoringStageConfigDrawer.vue';
-import { useS8StageConfig } from './useS8StageConfig';
+import { useS8StageConfig, buildModuleTriColorStats } from './useS8StageConfig';
 import { useS8CategoryConfig } from './useS8CategoryConfig';
 import { useS9DeptConfig } from './useS9DeptConfig';
 import { useS8UnsavedLayoutEditGuard } from './useS8UnsavedLayoutEditGuard';
@@ -518,6 +518,9 @@ function buildStageCard(
 		icon: meta.icon,
 		metricLabel: meta.metricLabel,
 		value: formatStageValue(meta.valueMode, { total, frequency, avgProcessHours, closeRate }),
+		// S8-DASHBOARD-MODULE-TRICOLOR-SEMANTICS-1:三色数字(绿正常 / 黄关注 / 红严重)
+		// 全部为自然数;warning + serious = 异常总数;绿色暂用 DEFAULT_NORMAL_WORK_ORDER_COUNT。
+		values: buildModuleTriColorStats({ total: anomalyCount, red, yellow }),
 		healthRate,
 		statusLabel: timeout > 0 ? `${timeout} 超时` : `${anomalyCount} 异常`,
 		progress: toProgress(green, yellow, red, total),

+ 3 - 1
Web/src/views/aidop/s8/monitoring/S8MonitoringProductionPage.vue

@@ -132,7 +132,7 @@ import S8MonitoringCategoryGrid, { type CategoryGridCardData } from './component
 import S8MonitoringEditToolbar from './components/S8MonitoringEditToolbar.vue';
 import S8MonitoringStageConfigDrawer from './components/S8MonitoringStageConfigDrawer.vue';
 import { useS8UnsavedLayoutEditGuard } from './useS8UnsavedLayoutEditGuard';
-import { useS8StageConfig } from './useS8StageConfig';
+import { useS8StageConfig, buildModuleTriColorStats } from './useS8StageConfig';
 import { useS8CategoryConfig } from './useS8CategoryConfig';
 import { useS8PageConfigDriver } from './useS8PageConfigDriver';
 
@@ -287,6 +287,8 @@ const stageCards = computed(() =>
 			icon: meta.icon,
 			metricLabel: meta.metricLabel,
 			value,
+			// S8-DASHBOARD-MODULE-TRICOLOR-SEMANTICS-1:三色数字(绿正常 / 黄关注 / 红严重)
+			values: buildModuleTriColorStats({ total: red + yellow, red, yellow }),
 			healthRate,
 			statusLabel: `${red + yellow} 异常`,
 			progress: total > 0

+ 3 - 1
Web/src/views/aidop/s8/monitoring/S8MonitoringSupplyPage.vue

@@ -132,7 +132,7 @@ import S8MonitoringCategoryGrid, { type CategoryGridCardData } from './component
 import S8MonitoringEditToolbar from './components/S8MonitoringEditToolbar.vue';
 import S8MonitoringStageConfigDrawer from './components/S8MonitoringStageConfigDrawer.vue';
 import { useS8UnsavedLayoutEditGuard } from './useS8UnsavedLayoutEditGuard';
-import { useS8StageConfig } from './useS8StageConfig';
+import { useS8StageConfig, buildModuleTriColorStats } from './useS8StageConfig';
 import { useS8CategoryConfig } from './useS8CategoryConfig';
 import { useS8PageConfigDriver } from './useS8PageConfigDriver';
 
@@ -306,6 +306,8 @@ const stageCards = computed(() =>
 			icon: meta.icon,
 			metricLabel: meta.metricLabel,
 			value,
+			// S8-DASHBOARD-MODULE-TRICOLOR-SEMANTICS-1:三色数字(绿正常 / 黄关注 / 红严重)
+			values: buildModuleTriColorStats({ total: red + yellow, red, yellow }),
 			healthRate,
 			statusLabel: `${red + yellow} 异常`,
 			progress: total > 0

+ 54 - 6
Web/src/views/aidop/s8/monitoring/useS8StageConfig.ts

@@ -101,6 +101,50 @@ export const STAGE_ICON_OPTIONS = [
 
 const STORAGE_KEY = 'aidop_s8_stage_config';
 
+/**
+ * 模块卡「正常」绿色默认显示值(自然数)。
+ * 当后端尚未提供真实"正常工单 / 运行中工单"字段时使用。
+ * 任务来源:S8-DASHBOARD-MODULE-TRICOLOR-SEMANTICS-1
+ */
+export const DEFAULT_NORMAL_WORK_ORDER_COUNT = 20;
+
+/**
+ * 从模块原始指标派生三色业务数字(自然数字符串)。
+ * 语义恒等:warningCount + seriousCount = totalExceptionCount。
+ * 绿色 = 正常工单数(暂用集中默认值兜底)。
+ *
+ * 兜底策略:
+ *  1. total / red / yellow 均经过 safeNonNegInt 归一;
+ *  2. red 不超过 total;
+ *  3. 当 yellow + red 不等于 total(API 缺字段或脏数据)→ yellow 改为 total - red;
+ *  4. 全部缺失 → red=0, yellow=0;
+ *  5. 绿色统一使用 DEFAULT_NORMAL_WORK_ORDER_COUNT,待后端返回真实正常工单数后再接入。
+ */
+export function buildModuleTriColorStats(input: {
+	total?: number | null;
+	red?: number | null;
+	yellow?: number | null;
+}): { green: string; yellow: string; red: string } {
+	const total = safeNonNegInt(input.total);
+	let red = Math.min(safeNonNegInt(input.red), total);
+	let yellow = safeNonNegInt(input.yellow);
+	if (yellow + red !== total) {
+		yellow = Math.max(0, total - red);
+	}
+	return {
+		green: String(DEFAULT_NORMAL_WORK_ORDER_COUNT),
+		yellow: String(yellow),
+		red: String(red),
+	};
+}
+
+function safeNonNegInt(value: number | null | undefined): number {
+	if (value === null || value === undefined) return 0;
+	const n = Number(value);
+	if (!Number.isFinite(n) || n < 0) return 0;
+	return Math.floor(n);
+}
+
 function deepClone<T>(value: T): T {
 	return JSON.parse(JSON.stringify(value));
 }
@@ -146,11 +190,13 @@ function defaultConfigFromCard(card: StageCardPreviewData): StageCardConfigItem
 		statusLabel: card.statusLabel,
 		showStatusLabel: card.showStatusLabel ?? true,
 		showProgress: card.showProgress ?? true,
-		values: {
-			green: card.value,
-			yellow: card.value,
-			red: card.value,
-		},
+		values: card.values
+			? { ...card.values }
+			: {
+					green: card.value,
+					yellow: card.value,
+					red: card.value,
+				},
 		valueLabels: {
 			green: '正常',
 			yellow: '关注',
@@ -257,7 +303,9 @@ export function useS8StageConfig() {
 			title: config.title,
 			icon,
 			value: config.values[tone] || card.value,
-			values: { ...config.values },
+			// S8-DASHBOARD-MODULE-TRICOLOR-SEMANTICS-1:实时业务三色数字(card.values)优先于
+			// localStorage 中可能残留的旧 stage 配置(10.0 / 0% / 3.2h),保证「关注 + 严重 = 异常总数」。
+			values: card.values ? { ...card.values } : { ...config.values },
 			valueLabels: config.valueLabels ? { ...config.valueLabels } : { green: '正常', yellow: '关注', red: '严重' },
 			metricLabel: config.metricLabel,
 			healthRate: clampPercent(config.healthRates[tone] ?? card.healthRate),