From a7e6761ba0cfccdf33ed552eb2d3b783c8e4ab4a Mon Sep 17 00:00:00 2001
From: shuishen <1109946754@qq.com>
Date: Wed, 16 Apr 2025 20:49:12 +0800
Subject: [PATCH] feat:事件弹窗显示调整

---
 src/views/Home/SearchBox.vue |  191 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 163 insertions(+), 28 deletions(-)

diff --git a/src/views/Home/SearchBox.vue b/src/views/Home/SearchBox.vue
index 3691bad..5af1e0e 100644
--- a/src/views/Home/SearchBox.vue
+++ b/src/views/Home/SearchBox.vue
@@ -1,7 +1,7 @@
 <template>
-  <div class="searchBox">
+  <div class="searchBox" ref="searchBoxRef">
     <div class="searchInput">
-      <el-select v-model="value" placeholder="请选择查询">
+      <el-select v-model="optionsValue" @change="optionChange" placeholder="请选择查询">
         <el-option
           v-for="item in options"
           :key="item.value"
@@ -10,50 +10,185 @@
         />
       </el-select>
 
-      <el-input v-model="input3" placeholder="请输入搜索关键字"></el-input>
+      <el-input v-model="searchKey"  @focus="handleFocus" placeholder="请输入搜索关键字"></el-input>
     </div>
-    <div class="searchBtn"></div>
+    <div class="searchBtn" @click="searchClick"></div>
     <div class="region">
-      <el-select v-model="value2" placeholder="请选择查询">
-        <el-option
-          v-for="item in options1"
-          :key="item.value"
-          :label="item.label"
-          :value="item.value"
-        />
-      </el-select>
+      <el-tree-select
+        v-model="treeValue"
+        check-strictly
+        lazy
+        :load="load"
+        :props="props"
+        style="width: 240px"
+        @node-click="handleNodeClick"
+      />
     </div>
+  </div>
+  <div class="select-down-list" ref="selectDownRef" v-show="isSelectDown">
+    <div class="item" v-for="item in downList" @click="selectedValue(item)">{{ item.nickname || item.name }}</div>
   </div>
 </template>
 <script setup>
-const input3 = ref('');
+import { getRegion } from '@/api/home';
+import { searchByKeyword, selectDeviceList } from '@/api/home/common';
+import { useStore } from 'vuex';
+import cesiumOperation from '@/utils/cesium-tsa'
 
-const value = ref('Option1');
-const value2 = ref('Optio44n1');
+const { flyTo } = cesiumOperation()
 
+const store = useStore();
+const searchKey = ref('');
+const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode);
+const selectedAreaCode = computed(() => store.state.user.selectedAreaCode);
+const areaValue = ref('江西省');
+const treeValue = ref(userAreaCode.value);
+let first = true;
+const searchBoxRef = ref(null);
+const selectDownRef = ref(null);
+
+function handleNodeClick(data) {
+  areaValue.value = data.name;
+  store.commit('setSelectedAreaCode', data.code);
+}
+
+const props = {
+  label: 'name',
+  value: 'code',
+  children: 'children',
+};
+const load = async (node, resolve) => {
+  if (first) {
+    first = false;
+    const res = await getRegion(userAreaCode.value);
+    const { provinceCode, provinceName } = res?.data?.data?.[0] || {};
+    resolve([{ code: provinceCode, name: provinceName }]);
+    return;
+  }
+  const code = node?.data?.code || userAreaCode.value;
+  if ((node?.data?.regionLevel || 0) > 2) return resolve([]);
+  getRegion(code).then(res => {
+    resolve(res?.data?.data || []);
+  });
+};
+
+const optionsValue = ref('1');
 const options = [
   {
-    value: 'Option1',
+    value: '1',
     label: '机巢',
   },
   {
-    value: 'Optio44n1',
-    label: '事件',
+    value: '2',
+    label: '地址',
   },
 ];
 
-const options1 = [
-  {
-    value: 'Option1',
-    label: '南昌市',
-  },
-  {
-    value: 'Optio44n1',
-    label: '抚州市',
-  },
-];
+const isSelectDown = ref(false);
+// 下拉数据列表
+const machineNestList = ref([]);
+// 地址搜索结果
+const downList = ref([]);
+const position = ref({});
+
+// 获取机巢搜索结果
+const getDeviceList = async () => {
+  const res = await selectDeviceList({
+    keyword: searchKey.value,
+  });
+  if (res.data.code !== 0) return;
+  machineNestList.value = res?.data?.data || [];
+  downList.value = res?.data?.data || [];
+};
+// 获取地址搜索结果
+const getAddressList = async () => {
+  const res = await searchByKeyword(encodeURIComponent(`${areaValue.value}+${searchKey.value}`));
+  if (res.data.code !== 0) return;
+  downList.value = res?.data?.data.tips || [];
+  if (downList.value.length > 0) {
+    isSelectDown.value = true;
+  }
+};
+// 搜索结果
+const searchClick = () => {
+	const longitude = Number(position.value.longitude)
+	const latitude = Number(position.value.latitude)
+	flyTo({ longitude, latitude }, 1, 1000)
+};
+
+// 地址和机巢的切换
+const optionChange = () => {
+  searchKey.value = '';
+  downList.value = [];
+};
+// 输入框获取焦点
+const handleFocus = () => {
+  if (optionsValue.value === '1') {
+    isSelectDown.value = true;
+    downList.value = machineNestList.value;
+  }
+};
+// 机巢下拉获取值
+const selectedValue = item => {
+  searchKey.value = item.nickname || item.name;
+  if (optionsValue.value === '1') {
+    position.value = item;
+  } else {
+    position.value = { longitude: item.location.split(',')[0], latitude: item.location.split(',')[1] };
+  }
+  
+  isSelectDown.value = false;
+};
+
+// 监听搜索关键字变化
+watch(searchKey, async (newVal) => {
+  if (optionsValue.value === '2') {
+    await getAddressList();
+  }
+}, { immediate: false });
+
+onMounted(() => {
+  getDeviceList();
+  document.addEventListener('click', handleClickOutside);
+});
+
+onUnmounted(() => {
+  document.removeEventListener('click', handleClickOutside);
+});
+
+const handleClickOutside = (event) => {
+  if (!searchBoxRef.value?.contains(event.target) && !selectDownRef.value?.contains(event.target)) {
+    isSelectDown.value = false;
+  }
+};
 </script>
 <style scoped lang="scss">
+.select-down-list {
+  position: absolute;
+  top: 188px;
+  left: 45%;
+  transform: translateX(-45%);
+  width: 220px;
+  height: 256px;
+  overflow-y: auto;
+  background: linear-gradient( 180deg, #0D3556 0%, #012350 100%);
+  border-radius: 0px 0px 8px 8px;
+  border: 1px solid;
+  border-image: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(115, 192, 255, 1)) 1 1;
+  &::-webkit-scrollbar {
+    width: 0;
+    display: none;
+  }
+  -ms-overflow-style: none;  /* IE and Edge */
+  scrollbar-width: none;  /* Firefox */
+  .item {
+    color: #FFFFFF;
+    height: 32px;
+    line-height: 32px;
+    text-align: center;
+    cursor: pointer;
+  }
+}
 .searchBox {
   width: 420px;
   height: 43px;

--
Gitblit v1.9.3