Эх сурвалжийг харах

设备属性支持表格展示

learshaw 1 долоо хоног өмнө
parent
commit
0a5c6d9f99

+ 65 - 10
ems-ui-cloud/src/views/basecfg/device/index.vue

@@ -370,6 +370,20 @@
 
         <!-- 详情弹框 -->
         <el-dialog :visible.sync="showDrawer" title="设备详情" width="65%" custom-class="detail-dialog">
+
+        <!-- 表格属性详情弹框 -->
+        <el-dialog :visible.sync="showTableDetail" title="表格数据详情" width="70%" append-to-body :modal-append-to-body="true">
+          <el-table :data="tableDetailData" style="width: 100%">
+            <el-table-column type="index" label="序号" width="50"></el-table-column>
+            <el-table-column prop="name" label="名称"></el-table-column>
+            <el-table-column prop="key" label="键"></el-table-column>
+            <el-table-column prop="value" label="值"></el-table-column>
+            <el-table-column prop="updateTime" label="更新时间"></el-table-column>
+          </el-table>
+          <div slot="footer" class="dialog-footer">
+            <el-button @click="showTableDetail = false">关闭</el-button>
+          </div>
+        </el-dialog>
           <div v-if="curRow">
             <!-- 分页导航 -->
             <el-tabs v-model="activeTab">
@@ -422,20 +436,26 @@
             <div v-if="activeTab === 'attr'">
               <el-card class="box-card">
                 <div v-for="(tableData, tableName) in attrTables" :key="tableName">
-                  <p class="section-title">{{ tableData.title }}</p>
-                  <el-table :data="tableData.data" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
+                  <p class="section-title" @click="toggleCollapse(tableName)" style="cursor: pointer;">
+                    <i :class="collapsed[tableName] ? 'el-icon-arrow-right' : 'el-icon-arrow-down'" style="margin-right: 8px;"></i>
+                    {{ tableData.title }} ({{ tableData.data.length }})
+                  </p>
+                  <el-table v-if="!collapsed[tableName]" :data="tableData.data" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
                     <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
                     <el-table-column label="属性名称" prop="attrName"></el-table-column>
                     <el-table-column label="属性标识" prop="attrKey"></el-table-column>
                     <!-- 动态显示属性值 -->
                     <el-table-column label="属性值" align="center">
                       <template slot-scope="scope">
-                        <span v-if="tableData.title === '状态属性'">
-                       {{ scope.row.attrValueName || getAttrValueText(scope.row.attrValue) }}
-                        <span v-if="scope.row.attrUnit">{{ scope.row.attrUnit }}</span>
+                        <span v-if="scope.row.attrValueType === 'Table'">
+                          <el-button type="text" size="small" @click="handleTableAttrDetail(scope.row)">详情</el-button>
+                        </span>
+                        <span v-else-if="tableData.title === '状态属性'">
+                          {{ scope.row.attrValueName || getAttrValueText(scope.row.attrValue) }}
+                          <span v-if="scope.row.attrUnit">{{ scope.row.attrUnit }}</span>
                         </span>
                         <span v-else>
-                        {{ scope.row.attrValue }}
+                          {{ scope.row.attrValue }}
                         </span>
                       </template>
                     </el-table-column>
@@ -684,8 +704,12 @@ export default {
   components: { Treeselect },
   data() {
     return {
-      // 归属区域下拉选项
-      areaOptions: [],
+        // 表格属性详情弹窗状态
+        showTableDetail: false,
+        // 表格详情数据
+        tableDetailData: [],
+        // 归属区域下拉选项
+        areaOptions: [],
       // 归属子区下拉选项
       subAreaOptions: [],
       abilityDialogVisible: false,
@@ -825,12 +849,23 @@ export default {
       ProtocolData: [],
       StateData: [],
       MeasureData: [],
+      // 折叠状态,默认全部折叠
+      collapsed: {
+        Base: true,
+        Protocol: true,
+        State: true,
+        Measure: true
+      },
       attrTables: {
         Base: { title: '基础属性', data: [] },
         Protocol: { title: '协议属性', data: [] },
         State: { title: '状态属性', data: [] },
         Measure: { title: '计量属性', data: [] }
       },
+      // 控制表格显示的方法
+      toggleCollapse(tableName) {
+        this.collapsed[tableName] = !this.collapsed[tableName];
+      },
       // 表单参数
       form: {
         customAttrs: []
@@ -907,8 +942,28 @@ export default {
     this.logDaterangeTime = [this.formatDate(startOfDay), this.formatDate(endOfDay)]
     this.loadAreaOptions() // 加载归属区域数据
   },
-  methods: {
-    // 根据区域代码获取区域名称
+    methods: {
+      // 处理表格属性详情点击事件
+      handleTableAttrDetail(row) {
+        try {
+          // 解析JSON格式的属性值
+          const tableData = JSON.parse(row.attrValue);
+          // 格式化表格数据,确保包含所需字段
+          this.tableDetailData = tableData.map((item, index) => ({
+            ...item,
+            name: item.name || `项目${index + 1}`,
+            key: item.key || '',
+            value: item.value || '',
+            updateTime: item.updateTime || ''
+          }));
+          // 显示弹窗
+          this.showTableDetail = true;
+        } catch (error) {
+          this.$message.error('解析表格数据失败,请检查数据格式');
+          console.error('解析表格数据失败:', error);
+        }
+      },
+      // 根据区域代码获取区域名称
     buildRefAreaName(curRow) {
       const area = this.areaOptions.find(a => a.id === curRow.areaCode);
       const areaName = area ? area.label : '未知区域';

+ 69 - 21
ems-ui-cloud/src/views/devmgr/attr/index.vue

@@ -150,7 +150,7 @@
         </el-dialog>
 
        <!--详情 -->
-        <el-dialog :visible.sync="open" title="设备状态详情" custom-class="detail-dialog">
+        <el-dialog :visible.sync="open" title="设备详情" custom-class="detail-dialog">
           <div v-if="curRow">
             <el-tabs v-model="activeTab">
               <el-tab-pane label="设备基本信息" name="basic"></el-tab-pane>
@@ -188,17 +188,23 @@
             <div v-if="activeTab === 'attr'">
               <el-card class="box-card">
                 <div v-for="(tableData, tableName) in attrTables" :key="tableName">
-                  <p class="section-title">{{ tableData.title }}</p>
-                  <el-table :data="tableData.data" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
+                    <p class="section-title" @click="toggleCollapse(tableName)" style="cursor: pointer;">
+                      <i :class="collapsed[tableName] ? 'el-icon-arrow-right' : 'el-icon-arrow-down'" style="margin-right: 8px;"></i>
+                    {{ tableData.title }} ({{ tableData.data.length }})
+                    </p>
+                    <el-table v-if="!collapsed[tableName]" :data="tableData.data" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
                     <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
                     <el-table-column label="属性名称" prop="attrName"></el-table-column>
                     <el-table-column label="属性标识" prop="attrKey"></el-table-column>
                     <el-table-column label="属性值" align="center">
                       <template slot-scope="scope">
-                <span v-if="tableData.title === '状态属性'">
-                  {{ scope.row.attrValueName || getAttrValueText(scope.row.attrValue) }}
-                  <span v-if="scope.row.attrUnit">{{ scope.row.attrUnit }}</span>
-                </span>
+                        <span v-if="scope.row.attrValueType === 'Table'">
+                          <el-button size="mini" type="text" @click="handleTableAttrDetail(scope.row)">详情</el-button>
+                        </span>
+                        <span v-else-if="tableData.title === '状态属性'">
+                           {{ scope.row.attrValueName || getAttrValueText(scope.row.attrValue) }}
+                        <span v-if="scope.row.attrUnit">{{ scope.row.attrUnit }}</span>
+                        </span>
                         <span v-else>
                   {{ scope.row.attrValue }}
                 </span>
@@ -382,6 +388,18 @@
 
           </div>
         </el-dialog>
+
+        <!-- 表格属性详情弹窗 -->
+        <el-dialog :visible.sync="tableAttrDetailDialog" :title="tableAttrDetailTitle" width="60%">
+          <el-table :data="tableAttrDetailData" style="width: 100%" :show-header="true" :empty-text="'暂无数据'">
+            <el-table-column type="index" label="序号" width="50" align="center"></el-table-column>
+            <el-table-column label="名称" prop="name"></el-table-column>
+            <el-table-column label="键" prop="key"></el-table-column>
+            <el-table-column label="值" prop="value"></el-table-column>
+            <el-table-column label="更新时间" prop="updateTime"></el-table-column>
+          </el-table>
+        </el-dialog>
+
       </el-col>
     </el-row>
   </div>
@@ -444,15 +462,26 @@ export default {
       abilityDevice: [],
       eventData: [],
       BaseData: [],
-      ProtocolData: [],
-      StateData: [],
-      MeasureData: [],
-      attrTables: {
-        Base: { title: '基础属性', data: [] },
-        Protocol: { title: '协议属性', data: [] },
-        State: { title: '状态属性', data: [] },
-        Measure: { title: '计量属性', data: [] }
-      },
+        ProtocolData: [],
+        StateData: [],
+        MeasureData: [],
+        // 折叠状态,默认全部折叠
+        collapsed: {
+          Base: true,
+          Protocol: true,
+          State: true,
+          Measure: true
+        },
+        attrTables: {
+          Base: { title: '基础属性', data: [] },
+          Protocol: { title: '协议属性', data: [] },
+          State: { title: '状态属性', data: [] },
+          Measure: { title: '计量属性', data: [] }
+        },
+        // 控制表格显示的方法
+        toggleCollapse(tableName) {
+          this.collapsed[tableName] = !this.collapsed[tableName];
+        },
       // 查询参数
       queryParams: {
         pageNum: 1,
@@ -506,7 +535,11 @@ export default {
       callLog: false,
       reportLog: false,
       callLogData: [],
-      reportLogData: []
+      reportLogData: [],
+      // 表格属性详情弹窗
+      tableAttrDetailDialog: false,
+      tableAttrDetailData: [],
+      tableAttrDetailTitle: ''
 
     }
   },
@@ -822,6 +855,17 @@ export default {
       })
       this.activeTab = 'basic'
     },
+    // 处理表格类型属性详情
+    handleTableAttrDetail(row) {
+      this.tableAttrDetailTitle = row.attrName
+      try {
+        this.tableAttrDetailData = JSON.parse(row.attrValue)
+      } catch (e) {
+        this.tableAttrDetailData = []
+        this.$message.error('解析表格数据失败')
+      }
+      this.tableAttrDetailDialog = true
+    },
     getFacsOptions() {
       const getFacsParams = {
         facsCategory: this.queryParams.deviceCategory,
@@ -866,11 +910,11 @@ export default {
 }
 
 .section-title {
-  font-size: 18px;
+  font-size: 16px;
   font-weight: bold;
-  margin-top: 20px;
-  margin-bottom: 10px;
-
+  margin: 10px 0;
+  padding: 5px 0;
+  border-bottom: 1px solid #ebeef5;
 }
 
 .status-highlight {
@@ -894,4 +938,8 @@ export default {
   border-radius: 4px;
 }
 
+.table-detail-dialog .el-dialog {
+  width: 70%;
+}
+
 </style>