wangjuncheng
2025-05-19 d72bfc760302c524622e4484ad5175d03ca45ce7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<template>
  <div class="district">
    <div class="left-top">
      <span>监测位置</span>
    </div>
 
    <div class="left-content district-content">
      <div style="margin-left: 5px">
        <span style="color: white">重点沟:</span>
        <el-select @change="handleChange" v-model="selectValue" placeholder="Select" size="large" style="width: 240px">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </div>
 
      <!-- 滚动区域 -->
      <div style="overflow-y: auto; height: 95%">
        <!-- 加载遮罩层 -->
        <div v-if="loading" class="loading-overlay">
          <div class="spinner"></div>
        </div>
        <div v-else v-for="(item, key) in districtList" :key="key" class="district-item" @click="handleClick(item)">
          <div class="district-item-icon"></div>
          <div class="district-item-text">{{ item.hdName }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script setup>
import { ref, computed, onMounted } from "vue";
import { deviceDictList, getDictName } from "@/constant/dict.js";
 
// 定义一个响应式引用存储设备列表
const deviceListAll = ref([]);
 
// 当前选中的区域
const selectValue = ref("孙胡沟");
 
// 区域选项
const options = ref([
  { value: "孙胡沟", label: "孙胡沟" },
  { value: "鱼水洞后沟", label: "鱼水洞后沟" },
  // 其他选项...
]);
 
// 树形结构属性配置
const treeProps = {
  label: "deviceName",
  children: "children",
};
 
// 处理区域变化事件
const handleChange = (areaName) => {
  if (!areaName) {
    console.error("请选择一个区域");
    return;
  }
  selectValue.value = areaName; // 更新选中的区域值
  console.log(deviceListAll.value); // 这里已包含所有区域的数据
};
 
// 计算属性:将设备列表转换为树形结构,依据当前选中的区域
const deviceTree = computed(() => {
  const typeMap = {};
 
  // 过滤出属于当前选中区域的设备
  const filteredDevices = deviceListAll.value.filter(device =>
    device.deviceName.includes(selectValue.value)
  );
 
  // 按设备类型分组
  filteredDevices.forEach((device) => {
    const typeName = getDictName(deviceDictList, device.dictDeviceType);
 
    if (!typeName) {
      console.warn("未找到设备类型:", device);
      return;
    }
 
    if (!typeMap[typeName]) {
      typeMap[typeName] = [];
    }
    // 直接使用原始的设备名称,不进行任何替换操作
    typeMap[typeName].push({
      ...device,
      deviceName: device.deviceName.trim(), // 只去除首尾空格
    });
  });
 
  // 转换为树形结构
  return Object.keys(typeMap).map((typeName) => ({
    deviceName: typeName,
    children: typeMap[typeName],
  }));
});
 
// 假设在组件初始化之前,deviceListAll 已被填充了所有区域的数据
// 如果不是这样,则需要保留对 loadDeviceList 的调用,或者找到一种方法来预填充 deviceListAll
onMounted(() => {
  // 如果需要在此处加载全部数据,请取消注释以下行并确保 getDeviceInfo 返回所有区域的数据
  // loadDeviceList("");
});
</script>
 
<style lang="less" scoped>
.loading-overlay {
  position: absolute;
  top: 120px;
  left: 0px;
  right: 0px;
  bottom: 10px;
  background-color: rgba(236, 233, 233, 0.5);
  /* 半透明遮罩 */
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
}
 
.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #fff;
  border-top: 4px solid transparent;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}
 
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
 
.district {
  position: absolute;
  width: 345px;
  top: 100px;
  left: 30px;
  bottom: 55px;
  z-index: 99;
}
 
.district-item {
  height: 30px;
  cursor: pointer;
  margin-top: 10px;
}
 
.district-content {
  padding: 10px;
  box-sizing: border-box;
}
 
.district-item-icon {
  background: url("@/assets/img/menu/locationicon.png") no-repeat;
  background-position: 5px 5px;
  width: 30px;
  height: 30px;
  float: left;
}
 
.district-item-text {
  color: white;
  line-height: 30px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
 
.loading-text {
  color: white;
  font-size: 14px;
  text-align: center;
  margin-top: 20px;
}
 
/deep/ .el-select__placeholder {
  color: white;
}
 
/deep/ .el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  color: white !important;
  background-color: rgb(38, 124, 124, 0.5);
}
</style>