|
@@ -34,8 +34,8 @@ import { TIME_LABELS } from './fields.js'
|
|
|
import { SECTION_STATE, section } from './sectionState.js'
|
|
import { SECTION_STATE, section } from './sectionState.js'
|
|
|
import { WORK_ORDER_STATES, workOrderStateName } from './workOrder.js'
|
|
import { WORK_ORDER_STATES, workOrderStateName } from './workOrder.js'
|
|
|
import { tracksByOrder } from './workOrderTimeline.js'
|
|
import { tracksByOrder } from './workOrderTimeline.js'
|
|
|
-import { eventLevelTag, shortEventTime, eventStatusText, eventTypeText, eventNameText } from './eventList.js'
|
|
|
|
|
-import { statusVocabulary } from './eventStatusVocab.js'
|
|
|
|
|
|
|
+import { eventLevelTag, shortEventTime, formatEventTime, eventStatusText, eventTypeText, eventNameText } from './eventList.js'
|
|
|
|
|
+import { statusVocabulary, statusDisplayTone } from './eventStatusVocab.js'
|
|
|
import { pagedRows } from './pagination.js'
|
|
import { pagedRows } from './pagination.js'
|
|
|
import { detailEventLevel, collectionCellAssessment, collectionGroupAccent } from './equipmentDetailColors.js'
|
|
import { detailEventLevel, collectionCellAssessment, collectionGroupAccent } from './equipmentDetailColors.js'
|
|
|
|
|
|
|
@@ -369,6 +369,34 @@ function describeEvent(event) {
|
|
|
return type && type !== title ? type : ''
|
|
return type && type !== title ? type : ''
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/**
|
|
|
|
|
+ * 预警/报警描述(维护者 2026-11-13):
|
|
|
|
|
+ * 简单描述(指标 + 接近/超过上下限)+ 实际值 + 阈值,例:
|
|
|
|
|
+ * 化学需氧量(COD)预警接近上限
|
|
|
|
|
+ * 实际值:14.6 mg/L;阈值:上限 20 mg/L
|
|
|
|
|
+ *
|
|
|
|
|
+ * 缺值就少说一段,不编造、不补零;什么都没有时回空串(渲染层给占位符)。
|
|
|
|
|
+ */
|
|
|
|
|
+function eventDescriptionText(event) {
|
|
|
|
|
+ const metric = event && event.type ? eventTypeText(event.type) : ''
|
|
|
|
|
+ const value = typeof event?.value === 'number' && Number.isFinite(event.value) ? event.value : null
|
|
|
|
|
+ const unit = event?.unit || ''
|
|
|
|
|
+ const min = typeof event?.thresholdMinValue === 'number' ? event.thresholdMinValue : null
|
|
|
|
|
+ const max = typeof event?.thresholdMaxValue === 'number' ? event.thresholdMaxValue : null
|
|
|
|
|
+ let direction = ''
|
|
|
|
|
+ if (value !== null && max !== null) direction = value >= max ? '超过上限' : '接近上限'
|
|
|
|
|
+ else if (value !== null && min !== null) direction = value <= min ? '低于下限' : '接近下限'
|
|
|
|
|
+ const head = [metric, direction].filter(Boolean).join('')
|
|
|
|
|
+ const detail = []
|
|
|
|
|
+ if (value !== null) detail.push(`实际值:${value}${unit ? ' ' + unit : ''}`)
|
|
|
|
|
+ if (min !== null || max !== null) {
|
|
|
|
|
+ const scope = min !== null && max !== null ? `下限 ${min} / 上限 ${max}`
|
|
|
|
|
+ : max !== null ? `上限 ${max}` : `下限 ${min}`
|
|
|
|
|
+ detail.push(`阈值:${scope}${unit ? ' ' + unit : ''}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ return [head, detail.join(';')].filter(Boolean).join('\n')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function detailEventLevelLabel(event) {
|
|
function detailEventLevelLabel(event) {
|
|
|
const level = detailEventLevel(event).level
|
|
const level = detailEventLevel(event).level
|
|
|
return level ? `${level} 级` : '未分级'
|
|
return level ? `${level} 级` : '未分级'
|
|
@@ -394,6 +422,7 @@ export function eventRows(data) {
|
|
|
// 等级名称取后端字典(alert_level / alarm_level)下发的标签;
|
|
// 等级名称取后端字典(alert_level / alarm_level)下发的标签;
|
|
|
// 缺失时明确说「未提供」,不拿「N 级」冒充字典口径。
|
|
// 缺失时明确说「未提供」,不拿「N 级」冒充字典口径。
|
|
|
levelText: eventNameText(event.levelName) || detailEventLevelLabel(event),
|
|
levelText: eventNameText(event.levelName) || detailEventLevelLabel(event),
|
|
|
|
|
+ levelTone: level.tone,
|
|
|
levelLabelSource: eventNameText(event.levelName) ? 'dictionary' : 'fallback',
|
|
levelLabelSource: eventNameText(event.levelName) ? 'dictionary' : 'fallback',
|
|
|
activeColor: level.color,
|
|
activeColor: level.color,
|
|
|
levelColor: event.levelColor || '',
|
|
levelColor: event.levelColor || '',
|
|
@@ -404,7 +433,12 @@ export function eventRows(data) {
|
|
|
levelTag: { tone: levelTag.tone, label: levelTag.label },
|
|
levelTag: { tone: levelTag.tone, label: levelTag.label },
|
|
|
categoryKey: levelNumber === null ? 'level:unknown' : `level:${levelNumber}`,
|
|
categoryKey: levelNumber === null ? 'level:unknown' : `level:${levelNumber}`,
|
|
|
categoryLabel: levelNumber === null ? '等级未知' : levelTag.label,
|
|
categoryLabel: levelNumber === null ? '等级未知' : levelTag.label,
|
|
|
- timeText: shortEventTime(event.eventTime),
|
|
|
|
|
|
|
+ // 维护者 2026-11-13:列表与详情统一用 yyyy-MM-dd HH:mm:ss。
|
|
|
|
|
+ timeText: formatEventTime(event.eventTime),
|
|
|
|
|
+ family: String(event.family || '').toUpperCase(),
|
|
|
|
|
+ // 状态徽标高亮色(待接收/已接收黄、处置中蓝、已处置紫、已解除绿)。
|
|
|
|
|
+ statusTone: statusDisplayTone(event.family, event.status),
|
|
|
|
|
+ descriptionText: eventDescriptionText(event),
|
|
|
type: eventTypeText(event.type),
|
|
type: eventTypeText(event.type),
|
|
|
deviceCode: event.deviceCode || '',
|
|
deviceCode: event.deviceCode || '',
|
|
|
deviceName: event.deviceName || '',
|
|
deviceName: event.deviceName || '',
|
|
@@ -592,22 +626,24 @@ export function categoryNote(chips, categoryKey) {
|
|
|
* `keepEmpty` 的项是票 46 范围第 3 条点名要**始终保留**的四件事:
|
|
* `keepEmpty` 的项是票 46 范围第 3 条点名要**始终保留**的四件事:
|
|
|
* 事件时间 / 状态 / 来源 / 关联对象;其余项有值才画(不铺一排 `—` 噪音)。
|
|
* 事件时间 / 状态 / 来源 / 关联对象;其余项有值才画(不铺一排 `—` 噪音)。
|
|
|
*/
|
|
*/
|
|
|
-function detailRow(label, value, keepEmpty = false) {
|
|
|
|
|
|
|
+function detailRow(label, value, keepEmpty = false, tone = '') {
|
|
|
const text = valueText(value)
|
|
const text = valueText(value)
|
|
|
if (!keepEmpty && text === DETAIL_PLACEHOLDER) return null
|
|
if (!keepEmpty && text === DETAIL_PLACEHOLDER) return null
|
|
|
- return { label, value: text }
|
|
|
|
|
|
|
+ return { label, value: text, tone }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 一条预警/报警 → 展开后的详情行(时间、状态、来源、关联设备都在,缺值给占位符)。 */
|
|
/** 一条预警/报警 → 展开后的详情行(时间、状态、来源、关联设备都在,缺值给占位符)。 */
|
|
|
export function eventDetailRows(row) {
|
|
export function eventDetailRows(row) {
|
|
|
const current = row || {}
|
|
const current = row || {}
|
|
|
return detailRowList([
|
|
return detailRowList([
|
|
|
- detailRow(TIME_LABELS.event, current.eventTime, true),
|
|
|
|
|
|
|
+ detailRow(TIME_LABELS.event, formatEventTime(current.eventTime), true),
|
|
|
detailRow('状态', current.status, true),
|
|
detailRow('状态', current.status, true),
|
|
|
- detailRow('来源', current.type, true),
|
|
|
|
|
|
|
+ // 维护者 2026-11-13:原「来源」改为「预警描述 / 报警描述」,内容含简单描述与实际值、阈值。
|
|
|
|
|
+ detailRow(current.family === 'ALARM' ? '报警描述' : '预警描述', current.descriptionText, true),
|
|
|
detailRow('关联设备', current.deviceName || current.deviceCode, true),
|
|
detailRow('关联设备', current.deviceName || current.deviceCode, true),
|
|
|
detailRow('编码', current.codeText || '编码未提供'),
|
|
detailRow('编码', current.codeText || '编码未提供'),
|
|
|
- detailRow('等级', current.levelText),
|
|
|
|
|
|
|
+ // 等级文字颜色与等级色一致(维护者 2026-11-13 第 4 条)。
|
|
|
|
|
+ detailRow('等级', current.levelText, false, current.levelTone),
|
|
|
detailRow('量值', current.quantity),
|
|
detailRow('量值', current.quantity),
|
|
|
detailRow('位置', current.location),
|
|
detailRow('位置', current.location),
|
|
|
])
|
|
])
|