Преглед на файлове

🎨 优化村社搜索

快乐的梦鱼 преди 3 седмици
родител
ревизия
3ac5dc7f9c
променени са 4 файла, в които са добавени 59 реда и са изтрити 59 реда
  1. 4 1
      src/api/light/LightVillageApi.ts
  2. 6 42
      src/pages/home/components/LightMap.vue
  3. 2 0
      src/pages/home/light/map.vue
  4. 47 16
      src/pages/home/search/index.vue

+ 4 - 1
src/api/light/LightVillageApi.ts

@@ -299,6 +299,7 @@ export class VillageMapItem extends DataModel<VillageMapItem> {
   }
 
 
+  id!: number|null;
   villageId!: number|null;
   villageName = '';
   isLight = false;
@@ -469,10 +470,12 @@ export class LightVillageApi extends AppServerRequestModule<DataModel> {
    */
   async getMapVillage(params: {
     /** 地区code */
-    areaCode: number;
+    areaCode?: number;
+    keywords?: string;
   }) {
     const res = await this.post<KeyValue[]>('/village/village/mapVillage', '村社地图', {
       area_code: params.areaCode,
+      keywords: params.keywords,
     });
     return transformArrayDataModel<VillageMapItem>(VillageMapItem, res.requireData(), '村社地图条目', true);
   }

+ 6 - 42
src/pages/home/components/LightMap.vue

@@ -95,7 +95,7 @@
             />
             
             <FrameButton
-              :icon="searchKeyword ? 'close' : 'search'" 
+              icon="search" 
               size="small"
               @click="showSearch" 
             />
@@ -130,19 +130,6 @@
       color1="transparent"
       color2="white"
     />
-
-    <!-- 搜索村社 -->
-    <Dialog 
-      v-model:show="searchDialogShow" 
-      title="搜索村社"
-      showCancel
-      :maskClosable="false"
-      :onConfirm="searchConfirm"
-    >
-      <template #content>
-        <Field v-model="searchKeyword" placeholder="请输入村社名称进行搜索" />
-      </template>
-    </Dialog>
   </div>
 </template>
 
@@ -171,6 +158,7 @@ import FrameButton from '@/common/components/FrameButton.vue';
 import BoxMid from '@/common/components/box/BoxMid.vue';
 import Width from '@/components/layout/space/Width.vue';
 import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
+import { navTo } from '@/components/utils/PageAction';
 
 const instance = getCurrentInstance();
 const mapCtx = uni.createMapContext('prevMap', instance);
@@ -181,9 +169,6 @@ const villageData = new Map<number, VillageMapItem>();
 const ready = ref(false);
 const hasResItems = ref(false);
 
-const searchDialogShow = ref(false);
-const searchKeyword = ref('');
-
 const emit = defineEmits([
   'getCurrentLonlat',
   'update:isLightMode', 
@@ -233,11 +218,8 @@ const mapLoader = useSimpleDataLoader<MapMarker[]>(async () => {
     return [];
   await waitTimeOut(100);
   let res = (await LightVillageApi.getMapVillage({
-    areaCode: selectedRegion.value,
+    areaCode: selectedRegion.value
   }));
-  if (searchKeyword.value) {
-    res = res.filter(p => p.name.includes(searchKeyword.value));
-  }
   //如果为空则尝试获取子级
   hasResItems.value = res.length > 0;
   const list = res
@@ -414,26 +396,8 @@ function loadFirstRegion() {
 }
 
 function showSearch() {
-  if (searchKeyword.value) {
-    searchKeyword.value = '';
-    mapLoader.reload();
-  } else {
-    searchDialogShow.value = true;
-    searchKeyword.value = '';
-  }
-}
-async function searchConfirm() {
-  searchDialogShow.value = false;
-  if (searchKeyword.value.trim() === '') {
-    toast('请输入搜索关键词');
-    return;
-  }
-  await mapLoader.reload();
-  if (mapLoader.content.value?.length === 0) {
-    toast('未搜索到相关村社,换个关键词再试试吧');
-    return;
-  }
-}
+  navTo('/pages/home/search/index');
+} 
 
 watch(() => props.cityCode, async () => {
   await regionLoader.reload();
@@ -482,7 +446,7 @@ defineExpose({
   reload: async () => {
     await regionLoader.reload();
     loadFirstRegion();
-  }
+  },
 });
 </script>
 

+ 2 - 0
src/pages/home/light/map.vue

@@ -171,6 +171,8 @@ defineExpose({
       }
       joinCurrentVillageId.value = params.id;
       joinDialog.value?.show();
+    } else if (name === 'goVillage') {
+      callPrevOnPageBack('goVillage', params, 1);
     }
   }
 })

+ 47 - 16
src/pages/home/search/index.vue

@@ -1,9 +1,19 @@
 <template>
   <CommonTopBanner title="搜索">
     <FlexCol padding="padding.md">
-      <SimplePageListLoader :loader="listLoader">
+      <SearchBar
+        v-model="searchKeywords" 
+        leftIcon=""
+        searchState="show"
+        cancelState="hidden"
+        placeholder="搜索村社" 
+        @search="listLoader.reload()"
+      />
+      <Height :height="20" />
+      <SimplePageListLoader :loader="listLoader" :emptyView="{
+        text: searchKeywords ? '暂无搜索结果,换个关键词试试吧!' : '请输入搜索关键词搜索村社',
+      }">
         <FlexCol gap="gap.md">
-          <Empty v-if="listLoader.list.value.length === 0" description="暂无搜索结果,换个关键词试试吧" />
           <FlexRow 
             v-for="(item, i) in listLoader.list.value"
             :key="i"
@@ -11,16 +21,17 @@
           >
             <ImageBlock3
               backgroundColor="transparent"
-              :src="item.image"
+              :src="(item.image as '')"
               defaultImage="https://xy.wenlvti.net/app_static/images/village/PlaceholderVillage.jpg"
               :title="item.name"
-              :desc="item.address"
+              :desc="item.mergerName || ''"
               :imageRadius="15"
               :imageWidth="200"
               :imageHeight="140"
-              @click="onGoDetails(item as VillageListItem)"
+              @click="onGoDetails(item)"
             />
             <FlexRow justify="flex-end" align="center" gap="gap.md" width="200rpx">
+              <Tag :text="item.isLight ? '已点亮' : '未点亮'" size="small" />
               <Tag v-if="item.isFollow" text="已关注" size="small" />
               <Tag v-if="item.isJoined" text="已加入" size="small" type="primary" />
             </FlexRow>
@@ -34,34 +45,54 @@
 <script setup lang="ts">
 import { useSimplePageListLoader } from '@/components/composeabe/loader/SimplePageListLoader';
 import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
+import { backAndCallOnPageBack, navTo } from '@/components/utils/PageAction';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import ImageBlock3 from '@/components/display/block/ImageBlock3.vue';
-import LightVillageApi, { type VillageListItem } from '@/api/light/LightVillageApi';
+import LightVillageApi, { type VillageMapItem } from '@/api/light/LightVillageApi';
 import SimplePageListLoader from '@/components/loader/SimplePageListLoader.vue';
-import Empty from '@/components/feedback/Empty.vue';
 import Tag from '@/components/display/Tag.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
-import { backAndCallOnPageBack } from '@/components/utils/PageAction';
+import SearchBar from '@/components/form/SearchBar.vue';
+import { ref } from 'vue';
+import Height from '@/components/layout/space/Height.vue';
 
 const { querys } = useLoadQuerys({
   searchValue: '',
   cityCode: 0,
 }, () => {
+  searchKeywords.value = querys.value.searchValue;
   listLoader.load();
 });
 
+const searchKeywords = ref('');
+
 const listLoader = useSimplePageListLoader(16, async (page, pageSize) => {
-  return await LightVillageApi.getVillageList({
-    keyword: querys.value.searchValue,
-    //areaCode: querys.value.cityCode,
-    page,
-    pageSize,
-  });
+  if (!searchKeywords.value)
+    return {
+      total: 0,
+      list: [],
+    };
+  const list = (await LightVillageApi.getMapVillage({
+    keywords: searchKeywords.value,
+  }));
+  return {
+    total: list.length,
+    list,
+  }
 }, false);
 
-function onGoDetails(item: VillageListItem) {
-  backAndCallOnPageBack('goVillage', { id: item.id });
+function onGoDetails(item: VillageMapItem) {
+  if (!item.villageId) 
+    navTo('/pages/home/light/create-village', { 
+      villageName: item.name,
+      mergerName: item.mergerName || '',
+      areaCode: item.areaCode,
+      longitude: item.longitude,
+      latitude: item.latitude,
+    });
+  else
+    backAndCallOnPageBack('goVillage', { id: item.villageId });
 }