Просмотр исходного кода

📦 发现页排名优化,乡源好物补充

快乐的梦鱼 1 месяц назад
Родитель
Сommit
d7a11c40f3

+ 66 - 39
src/pages/home/discover/index.vue

@@ -14,50 +14,62 @@
 
 
     <HomeTitle title="乡村排名" showMore @moreClicked="navTo('/pages/home/village/rank/village')" />
     <HomeTitle title="乡村排名" showMore @moreClicked="navTo('/pages/home/village/rank/village')" />
     <FlexCol gap="gap.lg">
     <FlexCol gap="gap.lg">
-      <Touchable
-        v-for="item in villageRankListLoader.content.value" :key="item.id"
-        backgroundColor="background.tertiary"
-        radius="radius.md"
-        :padding="[20, 30]"
-        gap="gap.lg"
-        align="center"
+      <RankVillageItem
+        v-for="item in villageRankListLoader.content.value"
+        :key="item.id"
+        :id="item.id"
+        :image="item.image"
+        :rank="item.rank"
+        :title="item.title"
+        :points="item.points"
         @click="handleGoVillageDetails(item as any)"
         @click="handleGoVillageDetails(item as any)"
-      > 
-        <Image
-          :src="item.image"
-          defaultImage="https://xy.wenlvti.net/app_static/images/village/PlaceholderVillage.jpg"
-          :width="280"
-          :height="80"
-          :round="false"
-          :radius="10"
-        />
-        <Text :text="item.title" fontConfig="contentText" :innerStyle="{ flex: 1 }" />
-      </Touchable>
+      />
     </FlexCol>
     </FlexCol>
 
 
     <HomeTitle title="志愿者排名" showMore :lightCount="3" @moreClicked="navTo('/pages/home/village/rank/volunteer')" />
     <HomeTitle title="志愿者排名" showMore :lightCount="3" @moreClicked="navTo('/pages/home/village/rank/volunteer')" />
     <FlexCol gap="gap.lg">
     <FlexCol gap="gap.lg">
-      <Touchable
-        v-for="item in villageRankListLoader.content.value" :key="item.id"
-        backgroundColor="background.tertiary"
-        radius="radius.md"
-        :padding="[20, 30]"
-        gap="gap.lg"
-        align="center"
-        @click="navTo('/pages/home/village/volunteer/detail', { id: $event.id })"
-      > 
-        <Image
-          :src="item.image"
-          defaultImage="https://xy.wenlvti.net/app_static/images/village/PlaceholderVolunteer.jpg"
-          :width="80"
-          :height="80"
-          :round="true"
-        />
-        <Text :text="item.title" fontConfig="contentText" :innerStyle="{ flex: 1 }" />
-      </Touchable>
+      <RankVolunteerItem
+        v-for="(item, index) in villageUserRankListLoader.content.value" :key="item.id"
+        :id="item.id"
+        :image="item.image"
+        :rank="index + 1"
+        :title="item.title"
+        :score="item.score"
+        :isAdmin="false"
+        @click="navTo('/pages/home/village/volunteer/detail', { id: item.id })"
+      />
     </FlexCol>
     </FlexCol>
 
 
-    <HomeTitle title="乡源好物" showMore @moreClicked="navTo('/pages/home/village/rank/village')" />
+    <HomeTitle title="乡源好物" showMore @moreClicked="navTo('/pages/home/village/goods/index')" />
+    <SimplePageListLoader :loader="goodsLoader">
+      <FlexRow wrap justify="space-around" gap="gap.sm">
+        <BoxMid
+          v-for="good in goodsLoader.list.value" :key="good.id"
+          :innerStyle="{
+            width: 'calc(50% - 80rpx)',
+          }"
+        >
+          <Touchable direction="column" gap="gap.lg" @click="handleGoodDetail(good)">
+            <Image 
+              :src="good.image"
+              :radius="20"
+              width="100%"
+              height="300rpx"
+              mode="aspectFill"
+            />
+            <Text :text="good.title" fontConfig="titleText" />
+            <FlexRow align="center" gap="gap.md">
+              <Avatar 
+                :src="good.villageVolunteerAvatar"
+                :size="40"
+              />
+              <Text :text="`发布人: ${good.villageVolunteerName}`" fontConfig="contentText" />
+            </FlexRow>
+          </Touchable>
+        </BoxMid>
+        <FlexCol v-if="goodsLoader.list.value.length % 2 !== 0" width="calc(50% - 40rpx)" />
+      </FlexRow>
+    </SimplePageListLoader>
 
 
     <HomeTitle title="最新推荐" />
     <HomeTitle title="最新推荐" />
     <SimplePageListLoader :loader="discoverLoader">
     <SimplePageListLoader :loader="discoverLoader">
@@ -108,6 +120,10 @@ import Touchable from '@/components/feedback/Touchable.vue';
 import Text from '@/components/basic/Text.vue';
 import Text from '@/components/basic/Text.vue';
 import Image from '@/components/basic/Image.vue';
 import Image from '@/components/basic/Image.vue';
 import { waitTimeOut } from '@imengyu/imengyu-utils';
 import { waitTimeOut } from '@imengyu/imengyu-utils';
+import FlexRow from '@/components/layout/FlexRow.vue';
+import BoxMid from '@/common/components/box/BoxMid.vue';
+import RankVolunteerItem from '../village/rank/components/RankVolunteerItem.vue';
+import RankVillageItem from '../village/rank/components/RankVillageItem.vue';
 
 
 const emit = defineEmits([ 'goVillage' ]);
 const emit = defineEmits([ 'goVillage' ]);
 
 
@@ -123,10 +139,11 @@ const villageRankListLoader = useSimpleDataLoader(async () => {
     title: item.name,
     title: item.name,
     rank: i + 1,
     rank: i + 1,
     id: item.id,
     id: item.id,
+    points: item.points,
   }));
   }));
 });
 });
 const villageUserRankListLoader = useSimpleDataLoader(async () => {
 const villageUserRankListLoader = useSimpleDataLoader(async () => {
-  const res = (await LightVillageApi.getVolunteerRankList({ num: 10 }))
+  const res = (await LightVillageApi.getVolunteerRankList({ num: 6 }))
     .map((item, i) => ({
     .map((item, i) => ({
       id: item.id,
       id: item.id,
       image: item.image ?? '',
       image: item.image ?? '',
@@ -136,8 +153,18 @@ const villageUserRankListLoader = useSimpleDataLoader(async () => {
     }));
     }));
   return res
   return res
 });
 });
+const goodsLoader = useSimplePageListLoader(20, async (page, pageSize, params) => {
+  return await VillageInfoApi.getList({
+    collectModuleId: 24,
+    page, pageSize,
+  });
+});
 
 
-
+function handleGoodDetail(good: { id: number }) {
+  navTo('/pages/home/village/goods/detail', {
+    id: good.id,
+  });
+};
 function handleGoRecommendDetails(item: CommonInfoModel) {
 function handleGoRecommendDetails(item: CommonInfoModel) {
   navTo(`/pages/home/discover/details`, { id: item.id });
   navTo(`/pages/home/discover/details`, { id: item.id });
 }
 }

+ 1 - 1
src/pages/home/village/introd/card.vue

@@ -102,7 +102,7 @@
         </FlexCol>
         </FlexCol>
         <Divider type="vertical" />
         <Divider type="vertical" />
         <FlexCol center gap="gap.sm" flexBasis="25%">
         <FlexCol center gap="gap.sm" flexBasis="25%">
-          <Touchable direction="column" center @click="navTo('/pages/home/village/volunteer/list')">
+          <Touchable direction="column" center @click="navTo('/pages/home/village/volunteer/list', { villageId: villageStore.currentVillage?.id ?? undefined })">
             <Text text="乡源人数" fontConfig="contentText" />
             <Text text="乡源人数" fontConfig="contentText" />
             <Text :text="villageInfoLoader.content.value?.memberCount" fontConfig="importantTitle" />
             <Text :text="villageInfoLoader.content.value?.memberCount" fontConfig="importantTitle" />
           </Touchable>
           </Touchable>

+ 71 - 0
src/pages/home/village/rank/components/RankVillageItem.vue

@@ -0,0 +1,71 @@
+<template>
+  <BackgroundBox
+    backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxDark.png"
+    :backgroundCutBorder="[6,6,6,6]"
+    :backgroundCutBorderSize="[10,10,10,10]"
+  >
+    <Touchable
+      direction="row"
+      justify="space-between"
+      align="center"
+      gap="gap.md"
+      :padding="[25,25]"
+      @click="emit('click')"
+    >
+      <FlexRow align="center" gap="gap.lg">
+        <BackgroundBox
+          backgroundImage="https://xy.wenlvti.net/app_static/images/village/ImageBlessingCount.png"
+          width="60rpx"
+          height="60rpx"
+          center
+        >
+          <Text :text="rank" fontConfig="h4" color="white" />
+        </BackgroundBox>
+        <Image 
+          :src="image" 
+          defaultImage="https://xy.wenlvti.net/app_static/images/village/PlaceholderVillage.jpg"
+          width="170rpx"
+          height="120rpx"
+          mode="aspectFill"
+          radius="radius.md"
+        />
+        <Text :text="title" fontConfig="contentText" />
+      </FlexRow>
+      <FlexRow center gap="gap.md">
+        <BackgroundBox
+          backgroundImage="https://xy.wenlvti.net/app_static/images/village/TagNormal.png"
+          :backgroundCutBorder="[10,10,10,10]"
+          :backgroundCutBorderSize="[10,10,10,10]"
+          :padding="[15,10]"
+          center
+          direction="row"
+          gap="gap.md"
+          width="100"
+        >
+          <Image src="https://xy.wenlvti.net/app_static/images/village/IconLight.png" width="30rpx" height="30rpx" mode="aspectFill" />
+          <Text :text="points" fontConfig="contentText" />
+        </BackgroundBox>
+      </FlexRow>
+    </Touchable>
+  </BackgroundBox>
+</template>
+
+<script setup lang="ts">  
+import Touchable from '@/components/feedback/Touchable.vue';
+import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
+import Text from '@/components/basic/Text.vue';
+import Image from '@/components/basic/Image.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+
+const props = defineProps<{
+  id: number;
+  image: string;
+  rank: number;
+  title: string;
+  points: number;
+}>();
+
+const emit = defineEmits<{
+  (e: 'click'): void;
+}>();
+</script>

+ 75 - 0
src/pages/home/village/rank/components/RankVolunteerItem.vue

@@ -0,0 +1,75 @@
+<template>
+  <Touchable
+    direction="column"
+    @click="$emit('click')"
+  >
+    <BackgroundBox
+      backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxDark.png"
+      :backgroundCutBorder="[6,6,6,6]"
+      :backgroundCutBorderSize="[10,10,10,10]"
+      :padding="[25,25]"
+      direction="row"
+      justify="space-between"
+      align="center"
+      gap="gap.md"
+    >
+      <FlexRow align="center" gap="gap.lg">
+        <BackgroundBox
+          backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxOrder.png"
+          width="120rpx"
+          height="90rpx"
+          center
+        >
+          <Text :text="rank" fontConfig="h5" color="white" />
+        </BackgroundBox>
+        <Avatar 
+          :url="image" 
+          defaultAvatar="https://xy.wenlvti.net/app_static/images/village/PlaceholderVolunteer.png"
+          :size="70" 
+          mode="aspectFill" 
+          radius="radius.md" 
+        />
+        <Text :text="title" fontConfig="contentText" />
+      </FlexRow>
+      <FlexRow center gap="gap.md">
+        <Tag v-if="isAdmin" text="管理员" size="small" />
+        <BackgroundBox
+          backgroundImage="https://xy.wenlvti.net/app_static/images/village/TagNormal.png"
+          :backgroundCutBorder="[10,10,10,10]"
+          :backgroundCutBorderSize="[10,10,10,10]"
+          :padding="[15,10]"
+          center
+          direction="row"
+          gap="gap.md"
+          width="100"
+        >
+          <Image src="https://xy.wenlvti.net/app_static/images/village/IconFruit.png" width="30rpx" height="30rpx" mode="aspectFill" />
+          <Text :text="score" fontConfig="contentText" />
+        </BackgroundBox>
+      </FlexRow>
+    </BackgroundBox>
+  </Touchable>
+</template>
+
+<script setup lang="ts">  
+import Touchable from '@/components/feedback/Touchable.vue';
+import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
+import Text from '@/components/basic/Text.vue';
+import Avatar from '@/components/display/Avatar.vue';
+import Tag from '@/components/display/Tag.vue';
+import Image from '@/components/basic/Image.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+
+const props = defineProps<{
+  id: number;
+  image: string;
+  rank: number;
+  title: string;
+  score: number;
+  isAdmin: boolean;
+}>();
+
+const emit = defineEmits<{
+  (e: 'click'): void;
+}>();
+</script>

+ 10 - 57
src/pages/home/village/rank/village.vue

@@ -2,57 +2,16 @@
   <CommonTopBanner title="村社排名">
   <CommonTopBanner title="村社排名">
     <SimplePageContentLoader :loader="villageRankListLoader">
     <SimplePageContentLoader :loader="villageRankListLoader">
       <FlexCol gap="gap.lg" padding="space.md">
       <FlexCol gap="gap.lg" padding="space.md">
-        <BackgroundBox
-          v-for="(item, index) in villageRankListLoader.content.value"
+        <RankVillageItem
+          v-for="item in villageRankListLoader.content.value"
           :key="item.id"
           :key="item.id"
-          backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxDark.png"
-          :backgroundCutBorder="[6,6,6,6]"
-          :backgroundCutBorderSize="[10,10,10,10]"
-        >
-          <Touchable
-            direction="row"
-            justify="space-between"
-            align="center"
-            gap="gap.md"
-            :padding="[25,25]"
-            @click="handleGoDetails(item)"
-          >
-            <FlexRow align="center" gap="gap.lg">
-              <BackgroundBox
-                backgroundImage="https://xy.wenlvti.net/app_static/images/village/ImageBlessingCount.png"
-                width="60rpx"
-                height="60rpx"
-                center
-              >
-                <Text :text="index + 1" fontConfig="h4" color="white" />
-              </BackgroundBox>
-              <Image 
-                :src="item.image" 
-                defaultImage="https://xy.wenlvti.net/app_static/images/village/PlaceholderVillage.jpg"
-                width="170rpx"
-                height="120rpx"
-                mode="aspectFill"
-                radius="radius.md"
-              />
-              <Text :text="item.title" fontConfig="contentText" />
-            </FlexRow>
-            <FlexRow center gap="gap.md">
-              <BackgroundBox
-                backgroundImage="https://xy.wenlvti.net/app_static/images/village/TagNormal.png"
-                :backgroundCutBorder="[10,10,10,10]"
-                :backgroundCutBorderSize="[10,10,10,10]"
-                :padding="[15,10]"
-                center
-                direction="row"
-                gap="gap.md"
-                width="100"
-              >
-                <Image src="https://xy.wenlvti.net/app_static/images/village/IconLight.png" width="30rpx" height="30rpx" mode="aspectFill" />
-                <Text :text="item.points" fontConfig="contentText" />
-              </BackgroundBox>
-            </FlexRow>
-          </Touchable>
-        </BackgroundBox>
+          :id="item.id"
+          :image="item.image"
+          :rank="item.rank"
+          :title="item.title"
+          :points="item.points"
+          @click="handleGoDetails(item)"
+        />
       </FlexCol>
       </FlexCol>
     </SimplePageContentLoader>
     </SimplePageContentLoader>
   </CommonTopBanner>
   </CommonTopBanner>
@@ -65,16 +24,10 @@ import { useVillageStore } from '@/store/village';
 import { backAndCallOnPageBack, navTo } from '@/components/utils/PageAction';
 import { backAndCallOnPageBack, navTo } from '@/components/utils/PageAction';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import LightVillageApi from '@/api/light/LightVillageApi';
 import LightVillageApi from '@/api/light/LightVillageApi';
-import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
-import Text from '@/components/basic/Text.vue';
-import Image from '@/components/basic/Image.vue';
-import FlexRow from '@/components/layout/FlexRow.vue';
-import Touchable from '@/components/feedback/Touchable.vue';
 import { waitTimeOut } from '@imengyu/imengyu-utils';
 import { waitTimeOut } from '@imengyu/imengyu-utils';
-import NavBar from '@/components/nav/NavBar.vue';
-import StatusBarSpace from '@/components/layout/space/StatusBarSpace.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
+import RankVillageItem from './components/RankVillageItem.vue';
 
 
 const { querys } = useLoadQuerys({
 const { querys } = useLoadQuerys({
   regionId: 0,
   regionId: 0,

+ 9 - 57
src/pages/home/village/rank/volunteer.vue

@@ -6,59 +6,17 @@
         @goDetails="goDetails" 
         @goDetails="goDetails" 
       />
       />
       <FlexCol gap="gap.lg" padding="space.md">
       <FlexCol gap="gap.lg" padding="space.md">
-        <Touchable
+        <RankVolunteerItem
           v-for="(item, index) in villageUserRankListAfter3"
           v-for="(item, index) in villageUserRankListAfter3"
           :key="item.id"
           :key="item.id"
-          direction="column"
+          :id="item.id"
+          :image="item.image"
+          :rank="index + 4"
+          :title="item.title"
+          :score="item.score"
+          :isAdmin="item.isAdmin"
           @click="goDetails(item)"
           @click="goDetails(item)"
-        >
-          <BackgroundBox
-            backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxDark.png"
-            :backgroundCutBorder="[6,6,6,6]"
-            :backgroundCutBorderSize="[10,10,10,10]"
-            :padding="[25,25]"
-            direction="row"
-            justify="space-between"
-            align="center"
-            gap="gap.md"
-            
-          >
-            <FlexRow align="center" gap="gap.lg">
-              <BackgroundBox
-                backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxOrder.png"
-                width="120rpx"
-                height="90rpx"
-                center
-              >
-                <Text :text="index + 4" fontConfig="h5" color="white" />
-              </BackgroundBox>
-              <Avatar 
-                :url="item.image" 
-                defaultAvatar="https://xy.wenlvti.net/app_static/images/village/PlaceholderVolunteer.png"
-                :size="70" 
-                mode="aspectFill" 
-                radius="radius.md" 
-              />
-              <Text :text="item.title" fontConfig="contentText" />
-            </FlexRow>
-            <FlexRow center gap="gap.md">
-              <Tag v-if="item.isAdmin" text="管理员" size="small" />
-              <BackgroundBox
-                backgroundImage="https://xy.wenlvti.net/app_static/images/village/TagNormal.png"
-                :backgroundCutBorder="[10,10,10,10]"
-                :backgroundCutBorderSize="[10,10,10,10]"
-                :padding="[15,10]"
-                center
-                direction="row"
-                gap="gap.md"
-                width="100"
-              >
-                <Image src="https://xy.wenlvti.net/app_static/images/village/IconFruit.png" width="30rpx" height="30rpx" mode="aspectFill" />
-                <Text :text="item.score" fontConfig="contentText" />
-              </BackgroundBox>
-            </FlexRow>
-          </BackgroundBox>
-        </Touchable>
+        />
       </FlexCol>
       </FlexCol>
     </SimplePageContentLoader>
     </SimplePageContentLoader>
   </CommonTopBanner>
   </CommonTopBanner>
@@ -73,15 +31,9 @@ import { navTo } from '@/components/utils/PageAction';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import VillageUserRankList from '../../components/VillageUserRankList.vue';
 import VillageUserRankList from '../../components/VillageUserRankList.vue';
 import LightVillageApi from '@/api/light/LightVillageApi';
 import LightVillageApi from '@/api/light/LightVillageApi';
-import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
-import Text from '@/components/basic/Text.vue';
-import Avatar from '@/components/display/Avatar.vue';
-import Tag from '@/components/display/Tag.vue';
-import Image from '@/components/basic/Image.vue';
-import FlexRow from '@/components/layout/FlexRow.vue';
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
-import Touchable from '@/components/feedback/Touchable.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
+import RankVolunteerItem from './components/RankVolunteerItem.vue';
 
 
 const { querys } = useLoadQuerys({
 const { querys } = useLoadQuerys({
   regionId: 0,
   regionId: 0,