| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- /**
- * 监测**设备**自身状态 → 视觉表现(票 44;决策票 07)。
- *
- * ── 为什么必须是**平行**于 `pointStatus.js` 的另一张表,而不是复用它 ──
- * 两张表的业务对象不同、状态来源也不同:
- * · `pointStatus.js` 表达**监测点聚合状态**(后端解析并发布,六个取值含 `EMPTY`「无设备」);
- * · 本表表达**监测设备自身状态**(五个取值,**没有 `EMPTY`** —— 那是点位聚合态专有)。
- * 早先 `detailFlow.js` 正拿点位那张表给设备配色配形(即"把设备猜成点位状态"在代码里已经发生),
- * 那是越界;本票把它改到本表(见 `domain/detailFlow.js` 的 `deviceStatusView`)。
- *
- * ── 三条纪律(与 `pointStatus.js` 同源,但取值集不同)──
- * 1. **前端不重算**:只接收后端 `deviceStatus` 字符串;认不出的落 `UNKNOWN`(「状态未发布」),
- * 宁可如实说不知道,**不猜成 NORMAL** —— 猜成正常是最危险的一种谎话。
- * 2. **颜色不是唯一线索**:每态同时有 `tone`(色键)+ `shape`(形状)+ `label`(文字)。
- * 色键**只写键名**,色值仍只在 `styles/tokens.css` 声明(票 06 的单一口径)。
- * 3. **色键可同、语义不混**:点位与设备可用同一组 `--lv1..--neutral` 调色板,
- * 但两表的键位含义各自成立,不得互相推导。
- *
- * 五态与中文标签照抄后端 `CockpitMonitoringPointDeviceCard.deviceStatus` 的取值
- * (`ALARM`/`WARNING`/`WORK_ORDER`/`NORMAL`/`OFFLINE`),不另造业务词汇。
- * 本票只交付**静态**色/形/文字;动效(扩散脉冲/闪烁/旋转环)归票 47。
- */
- import { SHAPES } from './pointStatus.js'
- /** 后端设备自身状态的五个取值(原样字符串,不改名、不缩写)。 */
- export const DEVICE_STATUS = {
- ALARM: 'ALARM',
- WARNING: 'WARNING',
- WORK_ORDER: 'WORK_ORDER',
- NORMAL: 'NORMAL',
- OFFLINE: 'OFFLINE',
- }
- /**
- * 设备状态视觉词表。
- *
- * 形状**复用** `pointStatus.js` 的 `SHAPES` 片段(同风格、同一份 SVG 来源,避免两套图形定义),
- * 但**键与语义在本表独立成立**:例如点位表的 `EMPTY`(无设备)在这里根本不存在。
- * `priority` 数值沿用后端给的状态优先级(1 最紧急),前端不自定序。
- */
- export const DEVICE_STATUS_VISUALS = {
- ALARM: { key: 'ALARM', tone: 'lv1', shape: 'triangle', label: '报警', priority: 1, effect: 'pulse' },
- WARNING: { key: 'WARNING', tone: 'lv2', shape: 'diamond', label: '预警', priority: 2, effect: 'blink' },
- WORK_ORDER: { key: 'WORK_ORDER', tone: 'lv3', shape: 'square', label: '工单处置', priority: 3, effect: 'spin' },
- NORMAL: { key: 'NORMAL', tone: 'lv4', shape: 'circle', label: '正常', priority: 4, effect: null },
- OFFLINE: { key: 'OFFLINE', tone: 'point-offline', shape: 'ring', label: '离线', priority: 5, effect: null },
- }
- /**
- * 认不出的设备状态:如实说「不知道」,**不落到任何一个真实状态上**(尤其不猜 NORMAL)。
- * `effect: null` —— 状态都不知道,**更不能给它编一个动效**(那会把"未知"画成"正在报警")。
- */
- export const DEVICE_UNKNOWN_VISUAL = { key: 'UNKNOWN', tone: 'point-unknown', shape: 'hollowDiamond', label: '状态未发布', priority: 6, effect: null }
- /** 设备状态字符串 → 视觉词条;认不出的一律 `DEVICE_UNKNOWN_VISUAL`。 */
- export function deviceVisualForStatus(status) {
- return DEVICE_STATUS_VISUALS[status] || DEVICE_UNKNOWN_VISUAL
- }
- /** 一条设备的视觉词条 → 地图标记要的形状名(引擎只认形状,不认业务状态)。 */
- export function deviceShapeOf(device) {
- return deviceVisualForStatus(device && device.status).shape
- }
- /**
- * 设备状态图例行(**独立于监测点摘要图例**,规格与票 09 的边界都要求分开)。
- *
- * `count` = 当前模式实际绘制的该状态设备数(由调用方给,本层只负责行与顺序)。
- * 0 不隐藏行(形状的含义要能查到)。
- * @param {object} [byStatus] `{ [visualKey]: count }`
- */
- export function deviceLegend(byStatus = {}) {
- const rows = [...Object.keys(DEVICE_STATUS_VISUALS).map((key) => DEVICE_STATUS_VISUALS[key]), DEVICE_UNKNOWN_VISUAL]
- return rows
- .sort((a, b) => a.priority - b.priority)
- .map((visual) => ({
- key: visual.key,
- tone: visual.tone,
- shape: visual.shape,
- label: visual.label,
- count: byStatus[visual.key] || 0,
- }))
- }
- /** 该形状名在本表(及其复用的 `SHAPES`)里是否存在;供静态守卫与降级判据用。 */
- export function isKnownDeviceShape(shape) {
- return Object.prototype.hasOwnProperty.call(SHAPES, shape)
- }
|