Bladeren bron

驾驶舱-多级筛选

wanglt 5 maanden geleden
bovenliggende
commit
2bebdfb26d

+ 12 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/controller/GxtEquipmentController.java

@@ -46,6 +46,18 @@ public class GxtEquipmentController extends BaseController
         return getDataTable(list);
     }
 
+    /**
+     * 驾驶舱获取设备数据筛选树状图
+     * @param gxtEquipment
+     * @return
+     */
+    @GetMapping("/listAll")
+    public TableDataInfo listAll(GxtEquipment gxtEquipment)
+    {
+        List<GxtEquipment> list = gxtEquipmentService.selectGxtEquipmentList(gxtEquipment);
+        return getDataTable(list);
+    }
+
     /**
      * 获取所有品牌列表(去重)
      */

+ 9 - 7
ygtx-gxt/src/main/java/com/ygtx/gxt/controller/GxtWorkOrderController.java

@@ -5,6 +5,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 import java.lang.reflect.Field;
 
+import com.github.pagehelper.util.StringUtil;
 import com.ygtx.common.constant.HttpStatus;
 import com.ygtx.common.core.page.PageDomain;
 import com.ygtx.common.core.page.TableSupport;
@@ -355,9 +356,13 @@ public class GxtWorkOrderController extends BaseController
     public void exportHomePageOrderList(HttpServletResponse response, GxtOrderData gxtOrderData)
     {
         List<GxtOrderData> list = gxtWorkOrderService.selectHomePageWorkOrderList(gxtOrderData);
-        
+
         // 获取有值的字段名称
-        List<String> nonNullFields = getNonNullFields(gxtOrderData);
+        List<String> nonNullFields = new ArrayList<>();
+        if (!list.isEmpty() && StringUtil.isNotEmpty(list.get(0).getOrderCode())) {
+            nonNullFields.add("orderCode");
+        }
+        getNonNullFields(gxtOrderData,nonNullFields);
         
         // 创建Excel工具类实例
         ExcelUtil<GxtOrderData> util = new ExcelUtil<GxtOrderData>(GxtOrderData.class);
@@ -386,10 +391,9 @@ public class GxtWorkOrderController extends BaseController
      * @param obj 对象实例
      * @return 非空字段名称列表
      */
-    private List<String> getNonNullFields(GxtOrderData obj) {
-        List<String> nonNullFields = new ArrayList<>();
+    private void getNonNullFields(GxtOrderData obj,List<String> nonNullFields) {
         if (obj == null) {
-            return nonNullFields;
+            return;
         }
         
         Field[] fields = GxtOrderData.class.getDeclaredFields();
@@ -408,7 +412,5 @@ public class GxtWorkOrderController extends BaseController
                 // 忽略访问异常
             }
         }
-        
-        return nonNullFields;
     }
 }

+ 13 - 2
ygtx-gxt/src/main/java/com/ygtx/gxt/domain/GxtOrderData.java

@@ -18,6 +18,9 @@ public class GxtOrderData extends BaseEntity
 {
     private static final long serialVersionUID = 1L;
 
+    @Excel(name = "工单编码")
+    private String orderCode;
+
     /** 开始时间 */
     private Date startTime;
 
@@ -167,10 +170,18 @@ public class GxtOrderData extends BaseEntity
 
     private String hasCenter;
 
-    private String orderCode;
-
     private Integer restartNum;
 
+    private String devices;
+
+    public String getDevices() {
+        return devices;
+    }
+
+    public void setDevices(String devices) {
+        this.devices = devices;
+    }
+
     public Integer getRestartNum() {
         return restartNum;
     }

+ 4 - 4
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtMonthScoreServiceImpl.java

@@ -271,8 +271,8 @@ public class GxtMonthScoreServiceImpl implements IGxtMonthScoreService
                     List<GxtWorkOrderPerson> personList = gxtWorkOrderPersonMapper.selectGxtWorkOrderPersonListByScore(gxtWorkOrderPerson);
                     if (!personList.isEmpty()) {
                         for (GxtWorkOrderPerson person:personList) {
-                            if (person.getFinalScore()!=null) {
-                                workOrderScore = workOrderScore.add(BigDecimal.valueOf(person.getFinalScore()));
+                            if (person.getScore()!=null) {
+                                workOrderScore = workOrderScore.add(person.getScore());
                             }
                         }
                     }
@@ -287,8 +287,8 @@ public class GxtMonthScoreServiceImpl implements IGxtMonthScoreService
                     List<GxtRepairOrderPerson> personList1 = gxtRepairOrderPersonMapper.selectGxtRepairOrderPersonListByScore(repairOrderPerson);
                     if (!personList1.isEmpty()) {
                         for (GxtRepairOrderPerson person:personList1) {
-                            if (person.getFinalScore()!=null) {
-                                repairOrderScore = repairOrderScore.add(BigDecimal.valueOf(person.getFinalScore()));
+                            if (person.getScore()!=null) {
+                                repairOrderScore = repairOrderScore.add(person.getScore());
                             }
                         }
                     }

+ 0 - 1
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtWorkOrderServiceImpl.java

@@ -1794,7 +1794,6 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
 
     @Override
     public List<GxtOrderData> selectHomePageWorkOrderList(GxtOrderData gxtOrderData) {
-        System.out.println(gxtOrderData);
         Long deptId = null;
         SysDept dept = deptMapper.selectDeptById(SecurityUtils.getDeptId());
         if (dept!=null && dept.getStatus().equals("0") && dept.getLevel().equals("3")) {

+ 15 - 2
ygtx-gxt/src/main/resources/mapper/gxt/GxtWorkOrderMapper.xml

@@ -95,6 +95,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="repairOrderNum"    column="repairOrderNum" />
         <result property="orderCode"    column="order_code" />
         <result property="restartNum"    column="restart_num" />
+        <result property="devices"    column="devices" />
     </resultMap>
 
     <sql id="selectGxtWorkOrderVo">
@@ -569,7 +570,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 p.dept_name AS center,
                 '维保工单' AS orderType,
                 m.nick_name AS chargePerson,
-                <if test="repairPerson != null and repairPerson == 'true'">u.nick_name AS repairPerson,ROUND(wop.final_score,2) AS score,</if>
+                <if test="repairPerson != null and repairPerson == 'true'">u.nick_name AS repairPerson,ROUND(wop.score,2) AS score,</if>
                 <if test="repairPerson == null or repairPerson == '' or repairPerson == 'false'">ROUND(wo.score,2) AS score,</if>
                 ROUND(TIMESTAMPDIFF( MINUTE, wo.create_time, wo.assign_time ) / 60,2) AS xfsc,
                 ROUND(TIMESTAMPDIFF( MINUTE, wo.assign_time, wo.accept_time ) / 60,2) AS xysc,
@@ -610,6 +611,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                     OR p.dept_name LIKE concat('%', #{remark}, '%')
                     )
                 </if>
+                <if test="devices != null and devices != ''">
+                    AND wo.pcs_device_id IN
+                    <foreach item="item" collection="devices.split(',')" open="(" separator="," close=")">
+                        #{item, jdbcType=BIGINT}  <!-- 指定 Long 类型 -->
+                    </foreach>
+                </if>
                 <if test="dataPermission != null and dataPermission != ''">${dataPermission}</if>
                 AND p.dept_name IS NOT NULL
             </where>
@@ -628,7 +635,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 p.dept_name AS center,
                 '维修工单' AS orderType,
                 m.nick_name AS chargePerson,
-                <if test="repairPerson != null and repairPerson == 'true'">u.nick_name AS repairPerson,ROUND(wop.final_score,2) AS score,</if>
+                <if test="repairPerson != null and repairPerson == 'true'">u.nick_name AS repairPerson,ROUND(wop.score,2) AS score,</if>
                 <if test="repairPerson == null or repairPerson == '' or repairPerson == 'false'">ROUND(wo.score,2) AS score,</if>
                 ROUND(TIMESTAMPDIFF( MINUTE, wo.occur_time, wo.assign_time ) / 60,2) AS xfsc,
                 ROUND(TIMESTAMPDIFF( MINUTE, wo.assign_time, wo.accept_time ) / 60,2) AS xysc,
@@ -669,6 +676,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                     OR p.dept_name LIKE concat('%', #{remark}, '%')
                     )
                 </if>
+                <if test="devices != null and devices != ''">
+                    AND wo.pcs_device_id IN
+                    <foreach item="item" collection="devices.split(',')" open="(" separator="," close=")">
+                        #{item, jdbcType=BIGINT}  <!-- 指定 Long 类型 -->
+                    </foreach>
+                </if>
                 <if test="dataPermission != null and dataPermission != ''">${dataPermission}</if>
                 AND p.dept_name IS NOT NULL
             </where>

+ 606 - 3
ygtx-ui/src/views/index4.vue

@@ -56,6 +56,61 @@
             </h2>
             <i class="fa fa-chevron-up text-neutral-400 transition-transform duration-300" :class="{'rotate-180': dimensionExpanded}" id="dimension-toggle"></i>
           </div>
+          <!-- 多级筛选下拉框 -->
+          <div class="filter-select">
+            <el-cascader
+              v-model="selectedFilterCombination"
+              :options="filterOptions"
+              :props="cascaderProps"
+              placeholder="请选择筛选条件组合"
+              clearable
+              style="width: 100%;"
+              @change="handleCascaderChange"
+            ></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"
+            >
+              <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>
+            </el-cascader>
+          </div>
           <div id="dimension-content" class="filter-content" :class="{'hidden': !dimensionExpanded}">
             <!-- 地点纬度 - 树状选择 -->
             <div class="tree-select">
@@ -385,6 +440,7 @@
 import { ref, reactive } from 'vue';
 import { getHomePageOrderListData } from '@/api/gxt/gxtOrder';
 import { selectHomePageData } from '@/api/gxt/repairOrder';
+import { listAllEquipment } from '@/api/gxt/equipment';
 
 export default {
   name: 'Index4',
@@ -485,7 +541,8 @@ export default {
         qjbwsc: false,
         gqsc: false,
         score: null,
-        remark: null
+        remark: null,
+        devices: null,
       },
       orderList: [],
       // 添加首页统计数据
@@ -502,15 +559,470 @@ export default {
         workPending: 0,
         pendingNum: 0,
         hasCenter: null
-      }
+      },
+      // 多级筛选数据
+      selectedFilterCombination: [],
+      cascaderProps: {
+        checkStrictly: true,
+        expandTrigger: 'hover',
+        multiple: false
+      },
+      filterOptions: [
+        {
+          value: 'center',
+          label: '中心',
+          children: [
+            {
+              value: 'station',
+              label: '场站',
+              children: [
+                {
+                  value: 'brand',
+                  label: '品牌',
+                  children: [
+                    {
+                      value: 'model',
+                      label: '机型'
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        },
+        {
+          value: 'brand',
+          label: '品牌',
+          children: [
+            {
+              value: 'center',
+              label: '中心',
+              children: [
+                {
+                  value: 'station',
+                  label: '场站',
+                  children: [
+                    {
+                      value: 'model',
+                      label: '机型'
+                    }
+                  ]
+                }
+              ]
+            },
+            {
+              value: 'area',
+              label: '区域',
+              children: [
+                {
+                  value: 'model',
+                  label: '机型'
+                }
+              ]
+            }
+          ]
+        },
+        {
+          value: 'model',
+          label: '机型',
+          children: [
+            {
+              value: 'brand',
+              label: '品牌',
+              children: [
+                {
+                  value: 'area',
+                  label: '区域'
+                }
+              ]
+            }
+          ]
+        }
+      ],
+      // 设备筛选数据
+      selectedEquipment: [],
+      equipmentOptions: [],
+      equipmentCascaderProps: {
+        checkStrictly: false, // 改为false,允许级联选择
+        expandTrigger: 'hover',
+        multiple: true,  // 多选
+        showAllLevels: true,  // 显示所有层级的路径
+        emitPath: true,       // 返回完整路径
+        emitPathValue: true,   // 发出路径值
+        leafOnly: false       // 不仅叶子节点可选
+      },
+      equipmentKeyword: '',
+      originalEquipmentOptions: null,
+      filteredEquipmentOptions: null
     }
   },
   created() {
     this.selectPeriod('本月');
     this.loadHomePageData(); // 加载首页统计数据
+    this.loadEquipmentData(); // 加载设备数据
     this.applyFilter();
   },
   methods: {
+    handleCascaderChange(val) {
+      console.log('选中的节点值:', val);
+      
+      // 重置所有维度筛选条件
+      this.dimensionFilters.location.center = false;
+      this.dimensionFilters.location.station = false;
+      this.dimensionFilters.fan.brand = false;
+      this.dimensionFilters.fan.model = false;
+      
+      // 如果没有选择任何值,直接返回
+      if (!val || val.length === 0) {
+        return;
+      }
+      
+      // 遍历选中的值
+      val.forEach(item => {
+        if (item === 'center') {
+          this.dimensionFilters.location.center = true;
+        } else if (item === 'station') {
+          this.dimensionFilters.location.station = true;
+        } else if (item === 'area') {
+          this.dimensionFilters.location.center = true;
+          this.dimensionFilters.location.station = true;
+        } else if (item === 'brand') {
+          this.dimensionFilters.fan.brand = true;
+        } else if (item === 'model') {
+          this.dimensionFilters.fan.model = true;
+        }
+      });
+      
+      // 根据val的内容和顺序来构建设备级联选项
+      this.buildEquipmentOptionsByVal(val);
+    },
+
+    // 根据val的内容和顺序来构建设备级联选项
+    buildEquipmentOptionsByVal(val) {
+      // 重置设备选项
+      this.equipmentOptions = [];
+      
+      // 如果没有选择任何值,直接返回
+      if (!val || val.length === 0) {
+        return;
+      }
+      
+      // 根据选择的维度动态构建设备级联选项
+      // 获取所有设备数据
+      listAllEquipment().then(response => {
+        if (response.code === 200) {
+          const equipmentList = response.rows;
+          
+          // 创建根级别的选项映射
+          const rootOptions = {};
+          
+          // 根据val中的值来过滤和构建设备选项
+          const filteredEquipment = equipmentList.filter(item => {
+            // 检查是否符合选中的维度条件
+            let match = true;
+            
+            if (val.includes('center') && !item.maintenanceCenter) match = false;
+            if (val.includes('station') && !item.station) match = false;
+            if (val.includes('brand') && !item.brand) match = false;
+            if (val.includes('model') && !item.model) match = false;
+            
+            return match;
+          });
+          
+          // 遍历过滤后的设备列表,根据val的顺序构建层级结构
+          filteredEquipment.forEach(item => {
+            // 根据val的顺序构建值数组
+            const values = [];
+            
+            val.forEach(level => {
+              switch (level) {
+                case 'center':
+                  if (item.maintenanceCenter) {
+                    values.push({ value: item.maintenanceCenter, label: item.maintenanceCenter });
+                  }
+                  break;
+                case 'station':
+                  if (item.station) {
+                    values.push({ value: item.station, label: item.station });
+                  }
+                  break;
+                case 'brand':
+                  if (item.brand) {
+                    values.push({ value: item.brand, label: item.brand });
+                  }
+                  break;
+                case 'model':
+                  if (item.model) {
+                    values.push({ value: item.model, label: item.model });
+                  }
+                  break;
+                case 'area':
+                  // area表示同时选择center和station两个层级
+                  if (item.maintenanceCenter) {
+                    values.push({ value: item.maintenanceCenter, label: item.maintenanceCenter });
+                  }
+                  if (item.station) {
+                    values.push({ value: item.station, label: item.station });
+                  }
+                  break;
+              }
+            });
+            
+            // 添加设备编号作为最终层级
+            // 显示为equipmentCode,但值为equipmentId
+            if (item.equipmentCode && item.equipmentId) {
+              values.push({ 
+                value: item.equipmentId,     // 值为equipmentId
+                label: item.equipmentCode    // 显示为equipmentCode
+              });
+            }
+            
+            // 构建层级结构
+            this.buildHierarchy(rootOptions, values);
+          });
+          
+          // 在第一个选项中添加标记
+          const convertedOptions = this.convertToCascaderOptions(rootOptions);
+          if (convertedOptions.length > 0) {
+            convertedOptions[0].isFirst = true;
+          }
+          
+          // 将构建好的选项转换为级联选择器需要的格式
+          this.equipmentOptions = convertedOptions;
+        }
+      }).catch(error => {
+        console.error('加载设备数据失败:', error);
+      });
+    },
+    
+    // 根据值数组构建层级结构
+    buildHierarchy(optionsMap, values) {
+      if (!values || values.length === 0) return;
+      
+      let currentLevel = optionsMap;
+      
+      values.forEach((value, index) => {
+        // 生成当前层级的唯一键
+        const key = value.value;
+        
+        // 如果当前层级不存在,则创建
+        if (!currentLevel[key]) {
+          currentLevel[key] = {
+            value: value.value,
+            label: value.label,
+            children: {}
+          };
+        }
+        
+        // 如果是最后一级,确保children是数组
+        if (index === values.length - 1) {
+          currentLevel[key].children = [];
+        }
+        
+        // 移动到下一级
+        currentLevel = currentLevel[key].children;
+      });
+    },
+    
+    // 生成唯一键值
+    generateKey(values, index) {
+      return values.slice(0, index + 1).map(v => v.value).join('-');
+    },
+    
+    // 将层级结构转换为级联选择器需要的格式
+    convertToCascaderOptions(optionsMap) {
+      const result = [];
+      
+      Object.values(optionsMap).forEach((item, index) => {
+        const option = {
+          value: item.value,
+          label: item.label
+        };
+        
+        // 添加isFirst标记(仅第一个选项)
+        if (index === 0 && item.isFirst) {
+          option.isFirst = true;
+        }
+        
+        // 如果有子级且不为空,递归转换
+        if (item.children && Object.keys(item.children).length > 0) {
+          option.children = this.convertToCascaderOptions(item.children);
+        } else {
+          // 如果是叶子节点,确保children是空数组
+          option.children = [];
+        }
+        
+        result.push(option);
+      });
+      
+      return result;
+    },
+    
+    // 加载设备数据并构建级联选择器选项
+    async loadEquipmentData() {
+      try {
+        const response = await listAllEquipment();
+        if (response.code === 200) {
+          // �建设备级联选项
+          this.buildEquipmentOptions(response.rows);
+        }
+      } catch (error) {
+        console.error('加载设备数据失败:', error);
+      }
+    },
+
+    // 构建设备级联选项
+    buildEquipmentOptions(equipmentList) {
+      // 初始化选项数组
+      this.equipmentOptions = [];
+      
+      // 创建映射对象来存储不同层级的数据
+      const centers = {};
+      const stations = {};
+      const brands = {};
+      const models = {};
+      
+      // 遍历设备列表,构建层级结构
+      equipmentList.forEach(item => {
+        const center = item.maintenanceCenter;
+        const station = item.station;
+        const brand = item.brand;
+        const model = item.model;
+        const equipmentCode = item.equipmentCode;
+        const equipmentId = item.equipmentId; // 获取设备ID
+        
+        // 维保中心层级
+        if (center && !centers[center]) {
+          centers[center] = {
+            value: center,
+            label: center,
+            children: []
+          };
+        }
+        
+        // 场站层级
+        if (center && station && !stations[`${center}-${station}`]) {
+          stations[`${center}-${station}`] = {
+            value: station,
+            label: station,
+            children: []
+          };
+          
+          // 将场站添加到对应的维保中心下
+          if (centers[center] && !centers[center].children.some(child => child.value === station)) {
+            centers[center].children.push(stations[`${center}-${station}`]);
+          }
+        }
+        
+        // 品牌层级
+        if (center && station && brand && !brands[`${center}-${station}-${brand}`]) {
+          brands[`${center}-${station}-${brand}`] = {
+            value: brand,
+            label: brand,
+            children: []
+          };
+          
+          // 将品牌添加到对应的场站下
+          if (stations[`${center}-${station}`] && !stations[`${center}-${station}`].children.some(child => child.value === brand)) {
+            stations[`${center}-${station}`].children.push(brands[`${center}-${station}-${brand}`]);
+          }
+        }
+        
+        // 机型层级
+        if (center && station && brand && model && !models[`${center}-${station}-${brand}-${model}`]) {
+          models[`${center}-${station}-${brand}-${model}`] = {
+            value: model,
+            label: model,
+            children: []
+          };
+          
+          // 将机型添加到对应的品牌下
+          if (brands[`${center}-${station}-${brand}`] && !brands[`${center}-${station}-${brand}`].children.some(child => child.value === model)) {
+            brands[`${center}-${station}-${brand}`].children.push(models[`${center}-${station}-${brand}-${model}`]);
+          }
+        }
+        
+        // 风机编号层级(最终层级)
+        // 显示为equipmentCode,但值为equipmentId
+        if (center && station && brand && model && equipmentCode && equipmentId) {
+          const equipmentOption = {
+            value: equipmentId,        // 值为equipmentId
+            label: equipmentCode,      // 显示为equipmentCode
+            equipmentId: equipmentId   // 保存设备ID
+          };
+          
+          // 将风机编号添加到对应的机型下
+          if (models[`${center}-${station}-${brand}-${model}`] && !models[`${center}-${station}-${brand}-${model}`].children.some(child => child.value === equipmentId)) {
+            models[`${center}-${station}-${brand}-${model}`].children.push(equipmentOption);
+          }
+        }
+      });
+      
+      // 将维保中心添加到设备选项中
+      this.equipmentOptions = Object.values(centers);
+    },
+
+    // 处理设备级联选择器变化
+    handleEquipmentCascaderChange(val) {
+      console.log('选中的设备节点值:', val);
+      // 这里可以添加处理选中设备的逻辑
+      // 例如:将选中的设备编号存储到查询参数中
+      if (val && val.length > 0) {
+        // 由于是多选且支持级联选择,val是一个数组,每个元素是一个路径数组
+        // 提取所有选中的设备ID
+        const selectedEquipmentIds = [];
+        
+        val.forEach(path => {
+          if (Array.isArray(path)) {
+            // 获取路径中的最后一个节点
+            const lastNode = path[path.length - 1];
+            // 保存设备ID(现在值就是equipmentId)
+            if (lastNode) {
+              // 如果lastNode是一个对象,取其value或equipmentId属性
+              if (typeof lastNode === 'object') {
+                selectedEquipmentIds.push(lastNode.value || lastNode.equipmentId || lastNode);
+              } else {
+                // 如果是字符串或其他基本类型,直接使用
+                selectedEquipmentIds.push(lastNode);
+              }
+            }
+          }
+        });
+        
+        // 将设备ID用逗号拼接成字符串存储到this.queryParams.devices
+        this.queryParams.devices = selectedEquipmentIds.join(',');
+      } else {
+        // 清空设备编号
+        this.queryParams.devices = null;
+      }
+    },
+
+    // 获取显示标签,只显示第一个选中项,其余用省略号表示
+    getDisplayLabel(value) {
+      if (!value || value.length === 0) {
+        return '';
+      }
+      
+      // 如果只有一个选中项,直接显示
+      if (value.length === 1) {
+        const firstItem = value[0];
+        if (Array.isArray(firstItem)) {
+          // 如果是路径数组,显示最后一个元素
+          return firstItem[firstItem.length - 1];
+        } else {
+          return firstItem;
+        }
+      }
+      
+      // 如果有多个选中项,显示第一个项 + 省略号
+      const firstItem = value[0];
+      if (Array.isArray(firstItem)) {
+        // 如果是路径数组,显示最后一个元素
+        return firstItem[firstItem.length - 1] + '...';
+      } else {
+        return firstItem + '...';
+      }
+    },
 
     resetFilter() {
       this.leftFormData.field1 = '';
@@ -543,6 +1055,14 @@ export default {
           manager: false
         }
       };
+      // 重置设备筛选
+      this.selectedEquipment = [];
+      this.queryParams.devices = null;
+      this.equipmentKeyword = '';
+      // 恢复原始选项
+      if (this.originalEquipmentOptions) {
+        this.equipmentOptions = JSON.parse(JSON.stringify(this.originalEquipmentOptions));
+      }
       // 重置指标筛选
       this.indicatorFilters = {
         workorder: {
@@ -711,6 +1231,7 @@ export default {
       });
     },
     handleQuery() {
+    console.log(this.queryParams.devices);
       this.queryParams.pageNum = 1;
       this.applyFilter();
     },
@@ -871,6 +1392,52 @@ export default {
         return true;
       }
       return false;
+    },
+    filterEquipmentOptions() {
+      // 根据关键字筛选设备选项
+      if (!this.equipmentKeyword) {
+        // 如果关键字为空,显示所有选项
+        this.filteredEquipmentOptions = null;
+        return;
+      }
+      
+      // 保存原始选项
+      if (!this.originalEquipmentOptions) {
+        this.originalEquipmentOptions = JSON.parse(JSON.stringify(this.equipmentOptions));
+      }
+      
+      // 根据关键字过滤选项
+      this.filteredEquipmentOptions = this.filterOptionsByKeyword(this.originalEquipmentOptions, this.equipmentKeyword);
+    },
+    
+    // 递归过滤选项
+    filterOptionsByKeyword(options, keyword) {
+      const filtered = [];
+      
+      options.forEach(option => {
+        // 检查当前选项是否匹配关键字
+        if (option.label.toLowerCase().includes(keyword.toLowerCase())) {
+          // 如果匹配,直接添加整个选项(包括子项)
+          filtered.push(option);
+        } else if (option.children && option.children.length > 0) {
+          // 如果当前选项不匹配,但有子项,递归过滤子项
+          const filteredChildren = this.filterOptionsByKeyword(option.children, keyword);
+          if (filteredChildren.length > 0) {
+            // 如果子项中有匹配的,添加当前选项并更新子项
+            const newOption = { ...option, children: filteredChildren };
+            filtered.push(newOption);
+          }
+        }
+      });
+      
+      return filtered;
+    },
+    
+    resetEquipmentFilter() {
+      // 重置设备筛选
+      this.equipmentKeyword = '';
+      this.filteredEquipmentOptions = null;
+      this.selectedEquipment = [];
     }
   }
 }
@@ -1316,4 +1883,40 @@ export default {
 .flex-1 {
   flex: 1 1 0%;
 }
-</style>
+
+/* 设备级联选择器标签显示样式 */
+.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;
+}
+
+.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;
+}
+</style>