wujingjing
2025-02-19 cc43f08bbbc5e501c63844516ae41a15358c6ce5
src/components/chat/chatComponents/summaryCom/components/recordSetTable/map/Search.vue
@@ -1,24 +1,187 @@
<template>
   <div class="w-[320px]">
      <div class="search flex-items-center">
         <el-input v-model="searchText" clearable placeholder="查找对象"> </el-input>
         <div class="bg-blue-400 flex-center px-4 h-[32px] cursor-pointer hover:bg-blue-500 active:bg-blue-400">
            <span class="ywifont ywicon-sousuo text-white"></span>
         </div>
      </div>
   <div class="h-full">
      <AdvanceSearch v-if="isAdvanceSearch" class="h-full" :ol-map="olMap" @close="advanceSearchClose" :propertyMap="propertyMap" :propertyConfigMap="propertyConfigMap" />
      <div v-else class="simple-search mt-3">
         <div class="search flex-items-center">
            <el-input class="w-[320px]" v-model="searchText" clearable placeholder="查找对象" @input="searchInput" @clear="clearSearch">
               <template #prefix>
                  <el-switch v-model="isSearchObj" inline-prompt active-text="对象" inactive-text="道路" @change="changeSearchType" />
      <div class="search-result w-min-[340px] bg-white px-2">
         <div class="flex-items-center gap-2 hover:bg-[#ebebeb] cursor-pointer text-gray-500">
            <span class="ywifont ywicon-sousuo text-gray-400 !text-[12px]"></span>
            <span>测试aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</span>
                  <el-button
                     class="bg-white flex-center px-2 cursor-pointer hover:bg-[#f5f5f5] active:bg-[#f5f5f5]"
                     text
                     title="高级搜索"
                     @click="handleAdvanceSearchClick"
                  >
                     <span class="ywifont ywicon-liebiao text-black !text-[22px]"></span>
                  </el-button>
               </template>
            </el-input>
            <div
               class="bg-blue-400 flex-center px-4 h-[32px] search-btn cursor-pointer hover:bg-blue-500 active:bg-blue-400"
               @click="searchClick(searchText)"
            >
               <span v-if="isLoading" class="ywifont ywicon-loading1 text-white animate-spin"></span>
               <span v-else class="ywifont ywicon-sousuo text-white"></span>
            </div>
         </div>
         <div class="search-result w-[320px] bg-white text-sm">
            <div
               class="flex-items-center gap-2 hover:bg-[#ebebeb] cursor-pointer text-gray-500 w-full py-2 px-2"
               v-for="item in searchResultList"
               @click="searchResultClick(item)"
               :key="item.name"
            >
               <span class="ywifont ywicon-sousuo text-gray-400 !text-[12px]"></span>
               <span class="over-ellipsis"
                  >{{ item.name }}
                  <span class="text-gray-400 text-[12px]">{{ item.cityname }} {{ item.adname }}</span>
               </span>
            </div>
         </div>
      </div>
   </div>
</template>
<script setup lang="ts" name="Search">
import { debounce } from 'lodash-es';
import Feature from 'ol/Feature';
import Circle from 'ol/geom/Circle';
import { fromLonLat } from 'ol/proj';
import type { PropType } from 'vue';
import { ref } from 'vue';
import { getSearchMapElement } from '/@/api/map';
import type { OLMap } from '/@/model/map/OLMap';
import { formatDate } from '/@/utils/formatTime';
import AdvanceSearch from './advanceSearch/index.vue';
const props = defineProps({
   olMap: {
      type: Object as PropType<OLMap>,
   },
   propertyMap: {
      type: Object as PropType<Record<string, any>>,
   },
   propertyConfigMap: {
      type: Object as PropType<Record<string, any>>,
   },
});
const isLoading = ref(false);
const searchText = ref('');
const isSearchObj = ref(true);
const searchInput = (e) => {
   debounceSearch(e);
};
const changeSearchType = () => {
   clearSearch(!isSearchObj.value);
   searchClick(searchText.value);
};
const searchResultList = ref([]);
const searchResultClick = (item) => {
   if (item.isSearchObj) {
      props.olMap.displaySearchResult(item.model);
   } else {
      if (!item.location) return;
      const [lon, lat] = item.location.split(',').map(Number);
      const point = fromLonLat([lon, lat]);
      const WKT = `SRID=3857;POINT(${point[0]} ${point[1]})`;
      props.olMap.displaySearchResult({ WKT });
   }
};
const debounceSearch = debounce((text) => {
   searchClick(text);
}, 500);
const searchClick = async (text) => {
   if (!text.trim()) {
      clearSearch(isSearchObj.value);
      return;
   }
   try {
      isLoading.value = true;
      if (isSearchObj.value) {
         const res = await getSearchMapElement({
            search_text: text,
            max_count: 10,
            time: formatDate(new Date()),
         });
         searchResultList.value = (res?.values ?? []).map((item) => {
            return {
               name: item.ONAME,
               model: item,
               isSearchObj: true,
               // address: item.ADDRESS,
            };
         });
         // props.olMap.displaySearchResult(res?.values ?? []);
      } else {
         const result = await props.olMap.gaodeAddressSearch(text);
         const pois = result?.pois ?? [];
         searchResultList.value =
            pois
               .map((item) => {
                  return {
                     name: item.name,
                     // address: item.address,
                     cityname: item.cityname,
                     adname: item.adname,
                     model: item,
                     isSearchObj: false,
                     location: item.location,
                  };
               })
               ?.slice(0, 5) ?? [];
      }
   } finally {
      isLoading.value = false;
   }
};
const clearSearch = (isSearchObj = true) => {
   searchResultList.value = [];
   if (isSearchObj) {
      props.olMap.clearObjectSearch();
   } else {
      props.olMap.clearObjectSearch();
   }
};
//#region ====================== 高级搜索 ======================
const isAdvanceSearch = ref(false);
const handleAdvanceSearchClick = () => {
   isAdvanceSearch.value = true;
};
const advanceSearchClose = () => {
   isAdvanceSearch.value = false;
};
//#endregion
</script>
<style scoped lang="scss"></style>
<style scoped lang="scss">
.search {
   --radius-size: 8px;
   --search-height: 35px;
   :deep(.el-input__wrapper) {
      border-top-right-radius: 0;
      border-bottom-right-radius: 0;
      border-top-left-radius: var(--radius-size);
      border-bottom-left-radius: var(--radius-size);
      .el-input__inner {
         --el-input-inner-height: calc(var(--search-height) - 2px);
      }
   }
   .search-btn {
      height: var(--search-height);
      border-bottom-right-radius: var(--radius-size);
      border-top-right-radius: var(--radius-size);
   }
   .el-switch {
      --el-switch-on-color: #1676fc;
   }
}
</style>