Переглянути джерело

fix(water): normalize monitoring subtype labels

Kazerin 1 тиждень тому
батько
коміт
9f658a32b7

+ 7 - 2
src/utils/waterSupplyModel.js

@@ -13,7 +13,12 @@ export function normalizePage(response) {
   }
 }
 
-export function normalizeMonitoringRecord(record = {}, metric = 'value') {
+export function normalizeMonitoringTypeName(record = {}, fallback = '-') {
+  const candidate = record.equipmentTypeName ?? record.typeName ?? record.deviceType ?? record.equipmentType
+  const normalized = candidate == null ? '' : String(candidate).trim()
+  return normalized || String(fallback || '-').trim() || '-'
+}
+export function normalizeMonitoringRecord(record = {}, metric = 'value', monitorType = '') {
   const metricValue = metric === 'flow'
     ? record.instantFlow
     : metric === 'pressure'
@@ -25,7 +30,7 @@ export function normalizeMonitoringRecord(record = {}, metric = 'value') {
     id: record.id ?? record.equipmentId ?? record.pointId,
     equipmentName: record.equipmentName ?? record.name ?? record.deviceName ?? '未命名设备',
     equipmentCode: record.equipmentCode ?? record.deviceCode ?? record.code ?? '-',
-    equipmentTypeName: record.equipmentTypeName ?? record.typeName ?? record.deviceType ?? record.equipmentType ?? '-',
+    equipmentTypeName: normalizeMonitoringTypeName(record, monitorType),
     location: record.equipmentLocation ?? record.location ?? record.address ?? '-',
     value: value == null || value === '' ? null : Number(value),
     unit: record.unit ?? (metric === 'pressure' ? 'MPa' : metric === 'power' ? 'kW' : 'm³/h'),

+ 3 - 3
src/views/subSystem/waterSupply/components/WaterMonitoringPage.vue

@@ -36,7 +36,7 @@
       </el-table>
       <el-pagination v-model:current-page="query.pageNum" v-model:page-size="query.pageSize" :total="page.total" layout="total, sizes, prev, pager, next" :page-sizes="[10, 20, 50]" @change="loadData" />
     </el-card>
-    <el-drawer v-model="trendVisible" :title="`${current?.equipmentName || ''} - ${title}趋势`" size="520px">
+    <el-drawer v-model="trendVisible" class="detail-drawer" direction="rtl" :title="`${current?.equipmentName || ''} - ${title}趋势`" size="520px">
       <div ref="chartRef" class="trend-chart"></div>
       <el-descriptions v-if="current" :column="1" border><el-descriptions-item label="设备编码">{{ current.equipmentCode }}</el-descriptions-item><el-descriptions-item label="安装位置">{{ current.location }}</el-descriptions-item><el-descriptions-item label="当前值">{{ current.value ?? '-' }} {{ current.unit }}</el-descriptions-item></el-descriptions>
     </el-drawer>
@@ -59,14 +59,14 @@ const current = ref(null)
 const trendVisible = ref(false)
 const chartRef = ref(null)
 let chart
-const loadData = async () => { loading.value = true; try { const response = await props.load({ ...query.value }); const normalized = normalizePage(response); normalized.records = normalized.records.map(row => normalizeMonitoringRecord(row, props.metric)); page.value = normalized } catch (error) { page.value = { records: [], total: 0 }; console.warn(`[${props.title}] 数据加载失败`, error) } finally { loading.value = false } }
+const loadData = async () => { loading.value = true; try { const response = await props.load({ ...query.value }); const normalized = normalizePage(response); normalized.records = normalized.records.map(row => normalizeMonitoringRecord(row, props.metric, props.monitorType)); page.value = normalized } catch (error) { page.value = { records: [], total: 0 }; console.warn(`[${props.title}] 数据加载失败`, error) } finally { loading.value = false } }
 const resetQuery = () => { query.value = { pageNum: 1, pageSize: 10, equipmentName: '', equipmentCode: '', equipmentLocation: '', [props.minKey]: undefined, [props.maxKey]: undefined }; loadData() }
 const averageValue = computed(() => { const values = page.value.records.map(item => item.value).filter(value => Number.isFinite(value)); return values.length ? (values.reduce((a, b) => a + b, 0) / values.length).toFixed(2) : '-' })
 const abnormalCount = computed(() => page.value.records.filter(item => item.status === 1 || item.status === '1' || item.value == null).length)
 const latestTime = computed(() => page.value.records.map(item => item.updateTime).filter(Boolean).sort().at(-1) || '-')
 const statusText = row => row.status === 1 || row.status === '1' ? '异常' : row.status === 0 || row.status === '0' ? '正常' : row.status ? '在线' : '未知'
 const statusType = row => statusText(row) === '异常' ? 'danger' : statusText(row) === '正常' || statusText(row) === '在线' ? 'success' : 'info'
-const showTrend = async row => { current.value = row; trendVisible.value = true; await nextTick(); const response = await props.trend(row.id); const data = unwrapResponse(response); const records = Array.isArray(data) ? data : data?.records || []; const labels = records.map(item => item.time || item.monitorTime || item.createTime || ''); const values = records.map(item => normalizeMonitoringRecord(item, props.metric).value ?? 0); chart?.dispose(); chart = echarts.init(chartRef.value); chart.setOption({ tooltip: { trigger: 'axis' }, grid: { left: 40, right: 18, top: 20, bottom: 35 }, xAxis: { type: 'category', data: labels }, yAxis: { type: 'value', name: props.unit }, series: [{ type: 'line', smooth: true, data: values, areaStyle: { opacity: 0.12 }, itemStyle: { color: '#2563eb' } }] }) }
+const showTrend = async row => { current.value = row; trendVisible.value = true; await nextTick(); const response = await props.trend(row.id); const data = unwrapResponse(response); const records = Array.isArray(data) ? data : data?.records || []; const labels = records.map(item => item.time || item.monitorTime || item.createTime || ''); const values = records.map(item => normalizeMonitoringRecord(item, props.metric, props.monitorType).value ?? 0); chart?.dispose(); chart = echarts.init(chartRef.value); chart.setOption({ tooltip: { trigger: 'axis' }, grid: { left: 40, right: 18, top: 20, bottom: 35 }, xAxis: { type: 'category', data: labels }, yAxis: { type: 'value', name: props.unit }, series: [{ type: 'line', smooth: true, data: values, areaStyle: { opacity: 0.12 }, itemStyle: { color: '#2563eb' } }] }) }
 const exportData = async () => { try { await props.exportApi({ ...query.value }); ElMessage.success('导出请求已提交') } catch (error) { ElMessage.warning('当前接口暂不支持文件流导出') } }
 onMounted(loadData)
 </script>

+ 5 - 1
tests/waterSupplyModel.test.mjs

@@ -1,5 +1,5 @@
 import assert from 'node:assert/strict'
-import { normalizePage, normalizeMonitoringRecord, normalizeGeoJson, normalizeMapPoints } from '../src/utils/waterSupplyModel.js'
+import { normalizePage, normalizeMonitoringRecord, normalizeMonitoringTypeName, normalizeGeoJson, normalizeMapPoints } from '../src/utils/waterSupplyModel.js'
 
 const page = normalizePage({ data: { records: [{ id: 1 }], total: 4, current: 2, size: 10 } })
 assert.equal(page.records.length, 1)
@@ -20,6 +20,10 @@ assert.equal(pressureRecord.value, 0.42)
 const typedRecord = normalizeMonitoringRecord({ equipmentId: 'flow-2', typeName: '流量监测(测试)', instantFlow: 8.2 }, 'flow')
 assert.equal(typedRecord.equipmentTypeName, '流量监测(测试)')
 
+const fallbackTypeRecord = normalizeMonitoringRecord({ equipmentId: 'flow-3', equipmentTypeName: '  ', instantFlow: 1.2 }, 'flow', 'Flow Monitor')
+assert.equal(fallbackTypeRecord.equipmentTypeName, 'Flow Monitor')
+assert.equal(normalizeMonitoringTypeName({ typeName: 'Pressure Monitor' }, 'Flow Monitor'), 'Pressure Monitor')
+
 assert.equal(normalizeGeoJson({ data: { type: 'FeatureCollection', features: [] } }).type, 'FeatureCollection')
 assert.equal(normalizeGeoJson({ data: [] }).features.length, 0)