From 75cdd3cdcec1fc22bddebd6352e5e87e0a8d5d33 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Fri, 18 Apr 2025 10:57:41 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
src/views/Home/SearchBox.vue | 442 +++++++++++++++++++++++++++---------------------------
1 files changed, 223 insertions(+), 219 deletions(-)
diff --git a/src/views/Home/SearchBox.vue b/src/views/Home/SearchBox.vue
index 46d23e7..fb3b28c 100644
--- a/src/views/Home/SearchBox.vue
+++ b/src/views/Home/SearchBox.vue
@@ -1,277 +1,281 @@
<template>
- <div class="searchBox" ref="searchBoxRef">
- <div class="searchInput">
- <el-select v-model="optionsValue" @change="optionChange" placeholder="请选择查询">
- <el-option
- v-for="item in options"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
+ <div class="searchBox" ref="searchBoxRef">
+ <div class="searchInput">
+ <el-select v-model="optionsValue" @change="optionChange" placeholder="请选择查询">
+ <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+ </el-select>
- <el-input v-model="searchKey" @focus="handleFocus" placeholder="请输入搜索关键字"></el-input>
- </div>
- <div class="searchBtn" @click="searchClick"></div>
- <div class="region">
- <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>
+ <el-input
+ v-model="searchKey"
+ @input="handlerInput"
+ @focus="handleFocus"
+ placeholder="请输入搜索关键字"
+ ></el-input>
+ </div>
+ <div class="searchBtn" @click="searchClick"></div>
+ <div class="region">
+ <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>
-import { getRegion } from '@/api/home';
-import { searchByKeyword, selectDeviceList } from '@/api/home/common';
-import { useStore } from 'vuex';
+import _ from 'lodash'
+import { getRegion } from '@/api/home'
+import { searchByKeyword, selectDeviceList } from '@/api/home/common'
+import { useStore } from 'vuex'
import cesiumOperation from '@/utils/cesium-tsa'
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);
+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);
+ areaValue.value = data.name
+ store.commit('setSelectedAreaCode', data.code)
}
const props = {
- label: 'name',
- value: 'code',
- children: 'children',
-};
+ 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 || []);
- });
-};
+ 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 optionsValue = ref('1')
const options = [
- {
- value: '1',
- label: '机巢',
- },
- {
- value: '2',
- label: '地址',
- },
-];
+ {
+ value: '1',
+ label: '机巢',
+ },
+ {
+ value: '2',
+ label: '地址',
+ },
+]
-const isSelectDown = ref(false);
-// 下拉数据列表
-const machineNestList = ref([]);
+const isSelectDown = ref(false)
+
// 地址搜索结果
-const downList = ref([]);
-const position = ref({});
+const downList = ref([])
+const position = ref({})
// 获取机巢搜索结果
const getDeviceList = async () => {
- const res = await selectDeviceList({nickname: searchKey.value});
- if (res.data.code !== 0) return;
- machineNestList.value = res?.data?.data || [];
- downList.value = res?.data?.data || [];
-};
+ const res = await selectDeviceList({ nickname: searchKey.value })
+ if (res.data.code !== 0) return
+ 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 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 = [];
-};
+ searchKey.value = ''
+ downList.value = []
+
+ inputSelect()
+}
+
+// input对应下拉数据初始化
+const inputSelect = () => {
+ if (optionsValue.value === '2') {
+ getAddressList()
+ } else {
+ getDeviceList()
+ }
+}
+
+inputSelect()
+
+// 输入框input事件
+const handlerInput = _.debounce(inputSelect, 1000)
+
// 输入框获取焦点
const handleFocus = () => {
- if (optionsValue.value === '1') {
- isSelectDown.value = true;
- downList.value = machineNestList.value;
- }
-};
+ isSelectDown.value = true
+}
// 机巢下拉获取值
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;
-};
+ 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] }
+ }
-// 监听搜索关键字变化
-watch(searchKey, async (newVal) => {
- if (optionsValue.value === '2') {
- await getAddressList();
- } else {
- await getDeviceList();
- }
-}, { immediate: false });
+ isSelectDown.value = false
+}
onMounted(() => {
- document.addEventListener('click', handleClickOutside);
-});
+ document.addEventListener('click', handleClickOutside)
+})
onUnmounted(() => {
- document.removeEventListener('click', handleClickOutside);
-});
+ document.removeEventListener('click', handleClickOutside)
+})
-const handleClickOutside = (event) => {
- if (!searchBoxRef.value?.contains(event.target) && !selectDownRef.value?.contains(event.target)) {
- isSelectDown.value = false;
- }
-};
+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: 44%;
- transform: translateX(-40%);
- 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;
- opacity: 0.8;
- &::-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;
- &:hover {
- background: linear-gradient( 90deg, rgba(0,122,255,0) 0%, rgba(0,98,204,0.6) 50%, rgba(0,73,153,0) 100%);
- border: 1px solid;
- border-image: linear-gradient(90deg, rgba(0, 199, 190, 0), rgba(48, 176, 199, 1), rgba(0, 199, 190, 0)) 1 1;
- }
- }
+ position: absolute;
+ top: 188px;
+ left: 44%;
+ transform: translateX(-40%);
+ 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;
+ opacity: 0.8;
+ &::-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;
+ &:hover {
+ background: linear-gradient(90deg, rgba(0, 122, 255, 0) 0%, rgba(0, 98, 204, 0.6) 50%, rgba(0, 73, 153, 0) 100%);
+ border: 1px solid;
+ border-image: linear-gradient(90deg, rgba(0, 199, 190, 0), rgba(48, 176, 199, 1), rgba(0, 199, 190, 0)) 1 1;
+ }
+ }
}
.searchBox {
- width: 420px;
- height: 43px;
- position: absolute;
- top: 145px;
- left: 50%;
- transform: translateX(-50%);
- display: flex;
+ width: 420px;
+ height: 43px;
+ position: absolute;
+ top: 145px;
+ left: 50%;
+ transform: translateX(-50%);
+ display: flex;
- .el-select {
- width: 130px;
- height: 100%;
+ .el-select {
+ width: 130px;
+ height: 100%;
- :deep() {
- .el-select__wrapper {
- background: transparent;
- border: none;
- box-shadow: none;
- height: 100%;
- padding-left: 20px;
- }
+ :deep() {
+ .el-select__wrapper {
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ height: 100%;
+ padding-left: 20px;
+ }
- .el-select__selected-item {
- font-family: Source Han Sans CN, Source Han Sans CN, serif;
- font-weight: 400;
- font-size: 14px;
- color: #ffffff;
- line-height: 18px;
- }
- }
- }
+ .el-select__selected-item {
+ font-family: Source Han Sans CN, Source Han Sans CN, serif;
+ font-weight: 400;
+ font-size: 14px;
+ color: #ffffff;
+ line-height: 18px;
+ }
+ }
+ }
- .searchInput {
- width: 243px;
- height: 100%;
- background: url('@/assets/images/home/searchBox/searchBg1.png') no-repeat center / 100% 100%;
- display: flex;
+ .searchInput {
+ width: 243px;
+ height: 100%;
+ background: url('@/assets/images/home/searchBox/searchBg1.png') no-repeat center / 100% 100%;
+ display: flex;
- .el-input {
- height: 100%;
+ .el-input {
+ height: 100%;
- :deep() {
- .el-input__wrapper {
- background: transparent;
- border: none;
- box-shadow: none;
- height: 100%;
- }
+ :deep() {
+ .el-input__wrapper {
+ background: transparent;
+ border: none;
+ box-shadow: none;
+ height: 100%;
+ }
- .el-input__inner {
- font-family: Source Han Sans CN, Source Han Sans CN, serif;
- font-weight: 400;
- font-size: 14px;
- color: #ffffff;
- line-height: 18px;
- }
- }
- }
- }
+ .el-input__inner {
+ font-family: Source Han Sans CN, Source Han Sans CN, serif;
+ font-weight: 400;
+ font-size: 14px;
+ color: #ffffff;
+ line-height: 18px;
+ }
+ }
+ }
+ }
- .searchBtn {
- width: 67px;
- height: 100%;
- background: url('@/assets/images/home/searchBox/searchBg2.png') no-repeat center / 100% 100%;
- cursor: pointer;
- }
+ .searchBtn {
+ width: 67px;
+ height: 100%;
+ background: url('@/assets/images/home/searchBox/searchBg2.png') no-repeat center / 100% 100%;
+ cursor: pointer;
+ }
- .region {
- width: 0;
- flex-grow: 1;
- background: url('@/assets/images/home/searchBox/searchBg3.png') no-repeat center / 100% 100%;
+ .region {
+ width: 0;
+ flex-grow: 1;
+ background: url('@/assets/images/home/searchBox/searchBg3.png') no-repeat center / 100% 100%;
- :deep() {
- .el-select__wrapper {
- width: 100px;
- padding-left: 20px;
- }
- }
- }
+ :deep() {
+ .el-select__wrapper {
+ width: 100px;
+ padding-left: 20px;
+ }
+ }
+ }
}
</style>
--
Gitblit v1.9.3