diff --git a/src/api/iot/device/index.ts b/src/api/iot/device/index.ts index d8ec18d2..235ab29f 100644 --- a/src/api/iot/device/index.ts +++ b/src/api/iot/device/index.ts @@ -150,6 +150,10 @@ export const DeviceApi = { return await request.get({ url: `/iot/device/singleDevice`, params }) }, + getSingleDeviceFrom: async (params: SingleDeviceParams) => { + return await request.get({ url: `/iot/device/singleDeviceFrom`, params }) + }, + getHistoryRecord: async (params: HistoryRecordParams) => { return await request.get({ url: `/iot/device/historyRecord`, diff --git a/src/locales/en.ts b/src/locales/en.ts index 5c7a1810..803dec7d 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -4230,6 +4230,8 @@ export default { dialogTitlePrefix: 'History: ', dialogCollectionTimeLabel: 'Collection Time', + dialogPointFilterLabel:'Point Filter', + dialogPointFilterPlaceholder: 'Please enter point name', dialogCollectionTimeStartPlaceholder: 'Start Time', dialogCollectionTimeEndPlaceholder: 'End Time', dialogSearchButtonText: 'Search', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 8b896efa..b139997a 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -4073,6 +4073,8 @@ export default { dialogTitlePrefix: '历史记录:', dialogCollectionTimeLabel: '采集时间', + dialogPointFilterLabel: '点位筛选', + dialogPointFilterPlaceholder: '请输入点位名称', dialogCollectionTimeStartPlaceholder: '开始时间', dialogCollectionTimeEndPlaceholder: '结束时间', dialogSearchButtonText: '查询', @@ -4445,6 +4447,8 @@ export default { dialogTitlePrefix: '历史记录:', dialogCollectionTimeLabel: '采集时间', + dialogPointFilterLabel: '点位筛选', + dialogPointFilterPlaceholder: '请输入点位名称', dialogCollectionTimeStartPlaceholder: '开始时间', dialogCollectionTimeEndPlaceholder: '结束时间', dialogSearchButtonText: '查询', diff --git a/src/views/iot/realTimeMonitoring/SingleDeviceMonitorDialog.vue b/src/views/iot/realTimeMonitoring/SingleDeviceMonitorDialog.vue index 2fe7cb1c..d1db069a 100644 --- a/src/views/iot/realTimeMonitoring/SingleDeviceMonitorDialog.vue +++ b/src/views/iot/realTimeMonitoring/SingleDeviceMonitorDialog.vue @@ -7,15 +7,15 @@
-
+ + + +
+

{{ section.title }}

+ +
+
+
{{ item.label }}:
+
{{ formatCellTwo(item.value) }}
+
+
+
+
type Section = { - key: string - title: string - columns: SectionColumn[] - rows: SectionRow[] + id: number + title?: string + items: FormItem[] +} +interface FormItem { + prop: string + label: string + value: any } const { t } = useI18n() @@ -83,8 +101,44 @@ const dialogTitle = computed(() => { const loading = ref(false) const deviceName = computed(() => props.deviceName) -const sections = ref([]) +const sections = ref([ + { + id: 1, + title: '工艺参数监控', + items: [ + { prop: 'addressValue', label: '系统运行', value: 1, unit: '℃' }, + { prop: 'attributeName', label: '烘干湿度', value: 2, unit: '%' }, + { prop: 'attributeName', label: '输送速度', value: 3, unit: 'm/min' }, + { prop: 'attributeName', label: '回风温度', value: 4, unit: '℃' }, + { prop: 'attributeName', label: '排风温度', value: 5, unit: '℃' }, + { prop: 'attributeName', label: '呼叫状态', value: 6 }, + { prop: 'attributeName', label: '在线状态', value: 7 }, + { prop: 'attributeName', label: '运行状态', value: 3 }, + { prop: 'attributeName', label: '主缸速度', value: 0, unit: '%' }, + { prop: 'attributeName', label: '提布辊速度', value: 0 }, + { prop: 'fanSpeed', label: '风机速度', value: '暂无数据' }, + { prop: 'mainLevel', label: '主缸水位', value: 1, unit: '%' }, + { prop: 'mainWater', label: '主缸水量', value: 145, unit: 'L' }, + { prop: 'setTemp', label: '设定温度', value: 0.0, unit: '℃' }, + { prop: 'actualTemp', label: '实际温度', value: 0.0, unit: '℃' }, + ], + }, +]) + +const formatValue = (item: FormItem) => { + let value = item.value + if (value === null || value === undefined) return '--' + + if (typeof value === 'number') { + value = Number.isInteger(value) ? value.toString() : value.toFixed(2) + } + + if (item.unit) { + value += ` ${item.unit}` + } + return value +} const toGroupMap = (value: any): Record => { if (!value || typeof value !== 'object' || Array.isArray(value)) { return {} @@ -136,6 +190,14 @@ const formatCell = (value: string | number | null | undefined) => { return value } +const formatCellTwo = (value: any) => { + // 示例:如果是数字保留两位小数,否则原样返回 + if (typeof value === 'number') { + return value.toFixed(2) + } + return value +} + const buildSectionsFromGroups = (groups: Record): Section[] => { const result: Section[] = [] for (const [key, list] of Object.entries(groups)) { @@ -150,12 +212,12 @@ const buildSectionsFromGroups = (groups: Record): Section[] => { row[prop] = item?.addressValue ?? '-' }) } - result.push({ +/* result.push({ key, title: key, columns, rows: columns.length ? [row] : [] - }) + })*/ } return result } @@ -167,15 +229,16 @@ const fetchList = async () => { } loading.value = true try { - const res: any = await DeviceApi.getSingleDevice({ deviceId: props.deviceId }) - const groups = Array.isArray(res) + const res: any = await DeviceApi.getSingleDeviceFrom({ deviceId: props.deviceId }) + /* const groups = Array.isArray(res) ? { [t('DataCollection.RealTimeMonitoring.defaultGroupName')]: res } : { ...toGroupMap(res?.data), ...toGroupMap(res?.data?.data), ...toGroupMap(res) } - sections.value = buildSectionsFromGroups(groups) + //sections.value = buildSectionsFromGroups(groups)*/ + sections.value = res } finally { loading.value = false } @@ -222,4 +285,84 @@ watch( .single-device-dialog__section :deep(.el-table__inner-wrapper) { border-radius: 0; } + +/* 表单容器 */ +.form-section { + margin-bottom: 24px; +} + +/* 标题样式 */ +.section-title { + font-size: 13px; + font-weight: bold; + margin-bottom: 12px; + color: var(--el-text-color-primary); +} + +/* 三列网格容器 */ +.form-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); /* 三列等宽 */ + /*gap: 16px;*/ /* 列间距和行间距 */ + /* padding: 8px;*/ + background-color: #fff; +/* border: 1px solid #dcdfe6; !* 外边框 *!*/ + border-radius: 4px; + min-height: 35px; +} + +/* 表单项:标签 + 值 */ +.form-item { + display: flex; + align-items: center; + justify-content: space-between; + height: 100%; + min-height: 35px; + /* padding: 8px 0;*/ + border: 1px solid #dcdfe6; + /* border-right: 1px solid #dcdfe6; !* 右边框 *! + border-bottom: 1px solid #dcdfe6; !* 下边框 *!*/ +} + +/* 标签样式 */ +.form-label { + font-size: 14px; + display: flex; + align-items: center; + justify-content: center; + color: #666; + height: 100%; + min-height: 35px; + width: 150px; /* 固定标签宽度,避免错位 */ + background-color: #f5f7fa; /* 背景色 */ +} + +/* 值样式 */ +.form-value { + flex: 1; + display: flex; + align-items: center; + justify-content: center; + height: 100%; + padding: 6px 12px; + background: white; + min-height: 35px; + box-sizing: border-box; + overflow: hidden; + cursor: default; + transition: all 0.2s; +} + +/* 响应式:小屏幕下改为两列或单列 */ +@media (max-width: 768px) { + .form-grid { + grid-template-columns: repeat(2, 1fr); /* 平板改为两列 */ + } +} + +@media (max-width: 480px) { + .form-grid { + grid-template-columns: 1fr; /* 手机改为单列 */ + } +}