wanglt 4 месяцев назад
Родитель
Сommit
6d07802beb
1 измененных файлов с 103 добавлено и 96 удалено
  1. 103 96
      ygtx-ui/src/views/index4.vue

+ 103 - 96
ygtx-ui/src/views/index4.vue

@@ -69,47 +69,64 @@
             ></el-cascader>
           </div>
           
-          <!-- 设备选择级联下拉框 -->
+          <!-- 设备选择树形下拉框 -->
           <div class="filter-select" style="margin-top: 15px;">
-            <el-cascader
-              v-model="selectedEquipment"
-              :options="filteredEquipmentOptions || equipmentOptions"
-              :props="equipmentCascaderProps"
-              placeholder="请选择设备"
-              clearable
-              style="width: 100%;"
-              @change="handleEquipmentCascaderChange"
+            <el-popover
+              placement="bottom-start"
+              :width="250"
+              trigger="click"
+              popper-class="equipment-tree-popover"
             >
-              <template #default="{ node, data }">
-                <span>{{ data.label }}</span>
-              </template>
-              <template #header>
-                <div style="display: flex; padding: 5px; border-bottom: 1px solid #eee; margin-bottom: 5px;">
-                  <el-input 
-                    v-model="equipmentKeyword" 
-                    placeholder="请输入关键字筛选" 
-                    size="small"
-                    style="width: 200px;"
-                    @keyup.enter="filterEquipmentOptions"
-                  />
-                  <el-button 
-                    type="primary" 
-                    size="small"
-                    style="width: 50px; margin-left: 5px;"
-                    @click="filterEquipmentOptions"
-                  >
-                    筛选
-                  </el-button>
-                  <el-button 
-                    size="small"
-                    style="width: 50px; margin-left: 5px;"
-                    @click="resetEquipmentFilter"
-                  >
-                    重置
-                  </el-button>
-                </div>
+              <template #reference>
+                <el-input 
+                  readonly
+                  :model-value="getDisplayLabel(selectedEquipmentNodes)"
+                  placeholder="请选择设备"
+                  style="width: 100%; cursor: pointer;"
+                  clearable
+                >
+                  <template #suffix>
+                    <i class="el-input__icon el-icon-arrow-down"></i>
+                  </template>
+                </el-input>
               </template>
-            </el-cascader>
+              
+              <div style="padding: 5px; border-bottom: 1px solid #eee; margin-bottom: 5px; display: flex; align-items: center;">
+                <el-input 
+                  v-model="equipmentKeyword" 
+                  placeholder="请输入关键字筛选" 
+                  size="small"
+                  style="width: 120px;"
+                  @keyup.enter="filterEquipmentOptions"
+                />
+                <el-button 
+                  type="primary" 
+                  size="small"
+                  style="width: 50px; margin-left: 5px;"
+                  @click="filterEquipmentOptions"
+                >
+                  筛选
+                </el-button>
+                <el-button 
+                  size="small"
+                  style="width: 50px; margin-left: 5px;"
+                  @click="resetEquipmentFilter"
+                >
+                  重置
+                </el-button>
+              </div>
+              
+              <el-tree
+                ref="equipmentTree"
+                :data="filteredEquipmentOptions || equipmentOptions"
+                show-checkbox
+                node-key="value"
+                :props="equipmentTreeProps"
+                :default-checked-keys="selectedEquipment"
+                @check="handleEquipmentTreeCheck"
+                style="max-height: 300px; overflow-y: auto;"
+              />
+            </el-popover>
           </div>
           <div id="dimension-content" class="filter-content" :class="{'hidden': !dimensionExpanded}">
             <!-- 地点纬度 - 树状选择 -->
@@ -640,16 +657,13 @@ export default {
         }
       ],
       // 设备筛选数据
-      selectedEquipment: [],
+      selectedEquipment: [], // 存储选中的设备ID
+      selectedEquipmentNodes: [], // 存储选中的设备节点信息
       equipmentOptions: [],
-      equipmentCascaderProps: {
-        checkStrictly: false, // 改为false,允许级联选择
-        expandTrigger: 'hover',
-        multiple: true,  // 多选
-        showAllLevels: true,  // 显示所有层级的路径
-        emitPath: true,       // 返回完整路径
-        emitPathValue: true,   // 发出路径值
-        leafOnly: false       // 不仅叶子节点可选
+      equipmentTreeProps: {
+        label: 'label',
+        children: 'children',
+        disabled: 'disabled'
       },
       equipmentKeyword: '',
       originalEquipmentOptions: null,
@@ -998,30 +1012,18 @@ export default {
     },
 
     // 获取显示标签,只显示第一个选中项,其余用省略号表示
-    getDisplayLabel(value) {
-      if (!value || value.length === 0) {
+    getDisplayLabel(nodes) {
+      if (!nodes || nodes.length === 0) {
         return '';
       }
       
       // 如果只有一个选中项,直接显示
-      if (value.length === 1) {
-        const firstItem = value[0];
-        if (Array.isArray(firstItem)) {
-          // 如果是路径数组,显示最后一个元素
-          return firstItem[firstItem.length - 1];
-        } else {
-          return firstItem;
-        }
+      if (nodes.length === 1) {
+        return nodes[0].label;
       }
       
       // 如果有多个选中项,显示第一个项 + 省略号
-      const firstItem = value[0];
-      if (Array.isArray(firstItem)) {
-        // 如果是路径数组,显示最后一个元素
-        return firstItem[firstItem.length - 1] + '...';
-      } else {
-        return firstItem + '...';
-      }
+      return nodes[0].label + '...';
     },
 
     resetFilter() {
@@ -1433,11 +1435,41 @@ export default {
       return filtered;
     },
     
+    // 处理设备树形选择器选中变化
+    handleEquipmentTreeCheck(data, checkedInfo) {
+      // 保存选中的节点信息
+      this.selectedEquipmentNodes = checkedInfo.checkedNodes;
+    },
+    
+    // 确认设备选择
+    confirmEquipmentSelection() {
+      // 提取选中节点的值(设备ID)
+      const selectedIds = this.selectedEquipmentNodes.map(node => node.value);
+      
+      // 更新selectedEquipment以保持与原逻辑兼容
+      this.selectedEquipment = selectedIds;
+      
+      // 将设备ID用逗号拼接成字符串存储到this.queryParams.devices
+      this.queryParams.devices = selectedIds.length > 0 ? selectedIds.join(',') : null;
+      
+      // 关闭弹出框(如果需要)
+      // 注意:这里可能需要通过ref控制popover的显示/隐藏
+    },
+    
     resetEquipmentFilter() {
       // 重置设备筛选
       this.equipmentKeyword = '';
       this.filteredEquipmentOptions = null;
       this.selectedEquipment = [];
+      this.selectedEquipmentNodes = []; // 同时重置选中的节点信息
+      
+      // 清空设备查询参数
+      this.queryParams.devices = null;
+      
+      // 如果有设备树引用,清除选中状态
+      if (this.$refs.equipmentTree) {
+        this.$refs.equipmentTree.setCheckedKeys([]);
+      }
     }
   }
 }
@@ -1884,39 +1916,14 @@ export default {
   flex: 1 1 0%;
 }
 
-/* 设备级联选择器标签显示样式 */
-.filter-select :deep(.el-cascader__tags) {
-  flex-wrap: nowrap;
-  overflow: hidden;
-}
-
-.filter-select :deep(.el-cascader__tags .el-tag) {
-  display: none;
-}
-
-.filter-select :deep(.el-cascader__tags .el-tag:first-child) {
-  display: inline-flex;
-  max-width: 100%;
-  overflow: hidden;
+/* 设备树形选择器弹出框样式 */
+.equipment-tree-popover {
+  padding: 0;
 }
 
-.filter-select :deep(.el-cascader__tags .el-tag:first-child .el-tag__content) {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.filter-select :deep(.el-cascader__tags .el-tag:nth-child(2)) {
-  display: inline-block;
-  margin-left: 5px;
-}
-
-.filter-select :deep(.el-cascader__tags .el-tag:nth-child(2)::before) {
-  content: '...';
-}
-
-/* 隐藏级联选择器标签的关闭按钮 */
-.filter-select :deep(.el-cascader__tags .el-tag .el-tag__close) {
-  display: none;
+/* 设备树形选择器输入框样式 */
+.filter-select :deep(.el-input.is-disabled .el-input__inner) {
+  background-color: #fff;
+  cursor: pointer;
 }
 </style>