Pārlūkot izejas kodu

📦 村社志愿者列表与详情页对接

快乐的梦鱼 1 mēnesi atpakaļ
vecāks
revīzija
ae75b4b959

+ 16 - 1
src/api/inhert/VillageApi.ts

@@ -102,17 +102,32 @@ export class VolunteerInfo extends DataModel<VolunteerInfo> {
   static STATUS_APPROVED = 1;
   static STATUS_PENDING = 0;
   static STATUS_REJECTED = -1;
-
   id !: number;
   mainBodyId !: number;
+  avatar = '';
   type = '';
   name = '';
+  /**
+   * 累计发文
+   */
+  collectCount = 0;
+  /**
+   * 已关注村社数
+   */
+  followVillageCount = 0;
   sex = 0;
   mobile = '';
   regionId = null as number|null;
   address = '';
   image = '';
   birthday = new Date();
+  /**
+   * 乡源果累计
+   */
+  fruittotal = 0;
+  /**
+   * 文化积分
+   */
   points = 0;
   level = 0;
   status = '';

+ 5 - 0
src/common/components/box/BoxMid.vue

@@ -4,6 +4,11 @@ import type { FlexProps } from '@/components/layout/FlexView.vue';
 
 const props = defineProps<FlexProps>();
 
+defineOptions({
+  options: {
+    virtualHost: true,
+  }
+});
 </script>
 
 <template>

+ 4 - 2
src/pages/home/village/introd/card.vue

@@ -102,8 +102,10 @@
         </FlexCol>
         <Divider type="vertical" />
         <FlexCol center gap="gap.sm" flexBasis="25%">
-          <Text text="乡源人数" fontConfig="contentText" />
-          <Text :text="villageInfoLoader.content.value?.memberCount" fontConfig="importantTitle" />
+          <Touchable direction="column" center @click="navTo('/pages/home/village/volunteer/list')">
+            <Text text="乡源人数" fontConfig="contentText" />
+            <Text :text="villageInfoLoader.content.value?.memberCount" fontConfig="importantTitle" />
+          </Touchable>
           <WxButton openType="share">
             <Button type="text" size="mini" text="邀请加入" @click="navTo('/pages/home/village/task/index')" />
           </WxButton>

+ 55 - 52
src/pages/home/village/rank/village.vue

@@ -1,58 +1,60 @@
 <template>
   <CommonTopBanner title="村社排名">
-    <FlexCol gap="gap.lg" padding="space.md">
-      <BackgroundBox
-        v-for="(item, index) in villageRankListLoader.content.value"
-        :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)"
+    <SimplePageContentLoader :loader="villageRankListLoader">
+      <FlexCol gap="gap.lg" padding="space.md">
+        <BackgroundBox
+          v-for="(item, index) in villageRankListLoader.content.value"
+          :key="item.id"
+          backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxDark.png"
+          :backgroundCutBorder="[6,6,6,6]"
+          :backgroundCutBorderSize="[10,10,10,10]"
         >
-          <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>
-    </FlexCol>
+          <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>
+      </FlexCol>
+    </SimplePageContentLoader>
   </CommonTopBanner>
 </template>
 
@@ -72,6 +74,7 @@ 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 SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 
 const { querys } = useLoadQuerys({
   regionId: 0,

+ 61 - 60
src/pages/home/village/rank/volunteer.vue

@@ -1,64 +1,66 @@
 <template>
   <CommonTopBanner title="志愿者排名">
-    <VillageUserRankList 
-      :list="villageUserRankListFirst3" 
-      @goDetails="goDetails" 
-    />
-    <FlexCol gap="gap.lg" padding="space.md">
-      <Touchable
-        v-for="(item, index) in villageUserRankListAfter3"
-        :key="item.id"
-        direction="column"
-        @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"
-          
+    <SimplePageContentLoader :loader="villageUserRankListLoader">
+      <VillageUserRankList 
+        :list="villageUserRankListFirst3" 
+        @goDetails="goDetails" 
+      />
+      <FlexCol gap="gap.lg" padding="space.md">
+        <Touchable
+          v-for="(item, index) in villageUserRankListAfter3"
+          :key="item.id"
+          direction="column"
+          @click="goDetails(item)"
         >
-          <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>
+          <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>
+    </SimplePageContentLoader>
   </CommonTopBanner>
 </template>
 
@@ -77,8 +79,7 @@ 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 StatusBarSpace from '@/components/layout/space/StatusBarSpace.vue';
-import NavBar from '@/components/nav/NavBar.vue';
+import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 import Touchable from '@/components/feedback/Touchable.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 

+ 16 - 31
src/pages/home/village/volunteer/detail.vue

@@ -1,7 +1,6 @@
 <template>
   <CommonTopBanner title="志愿者详情">
     <SimplePageContentLoader :loader="infoLoader">
-      <Construction text="现在是接口缺少部分数据" />
       <FlexCol v-if="infoLoader.content.value" gap="gap.md" padding="padding.md">
         <BackgroundBox 
           backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxLarge.png"
@@ -40,7 +39,7 @@
             v-for="(item, k) in infoGrids"
             :key="k"
             :padding="24"
-            :innerStyle="{ width: 'calc(50% - 58rpx)' }"
+            :innerStyle="{ width: 'calc(50% - 76rpx)' }"
             direction="row"
             align="center"
             gap="gap.md"
@@ -58,6 +57,7 @@
 
         <HomeTitle title="最新动态" />
         <FlexCol gap="gap.lg">
+          <Loadmore v-if="activityLoader.content.value?.length == 0" status="nomore" />
           <FlexRow 
             v-for="item in activityLoader.content.value" :key="item.id"
             backgroundColor="background.tertiary"
@@ -67,12 +67,12 @@
             align="center"
           > 
             <Avatar 
-              :url="item.head"
+              :url="infoLoader.content.value?.avatar || ''"
               :size="80"
               :round="false"
               :radius="10"
             />
-            <Text :text="item.content" fontConfig="contentText" :innerStyle="{ flex: 1 }" />
+            <Text :text="item.remark || '没有说明文字!'" fontConfig="contentText" :innerStyle="{ flex: 1 }" />
           </FlexRow>
         </FlexCol>
       </FlexCol>
@@ -81,6 +81,7 @@
 </template>
 
 <script setup lang="ts">
+import { computed } from 'vue';
 import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
 import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
 import FlexCol from '@/components/layout/FlexCol.vue';
@@ -95,11 +96,11 @@ import VillageApi from '@/api/inhert/VillageApi';
 import H3 from '@/components/typography/H3.vue';
 import Tag from '@/components/display/Tag.vue';
 import Divider from '@/components/display/Divider.vue';
-import { computed } from 'vue';
 import HomeTitle from '@/common/components/parts/HomeTitle.vue';
 import Width from '@/components/layout/space/Width.vue';
-import Construction from '@/common/components/Construction.vue';
 import BoxMid from '@/common/components/box/BoxMid.vue';
+import TreeApi from '@/api/light/TreeApi';
+import Loadmore from '@/components/display/loading/Loadmore.vue';
 
 const { querys } = useLoadQuerys({
   id: 0,
@@ -116,49 +117,33 @@ const infoGrids = computed(() => {
       label: '累计发文',
       unit: '/篇',
       logo: 'https://xy.wenlvti.net/app_static/images/home/volunteer/IconPosts.png',
-      value: infoLoader.content.value?.userId as number,
+      value: infoLoader.content.value?.collectCount as number || 0,
     },
     {
       label: '文化积分',
       unit: '/次',
-      value: infoLoader.content.value?.userId as number,
+      value: infoLoader.content.value?.points as number || 0,
       logo: 'https://xy.wenlvti.net/app_static/images/home/volunteer/IconLikes.png',
     },
     {
       label: '乡源果累计',
       unit: '/个',
-      value: infoLoader.content.value?.userId as number,
+      value: infoLoader.content.value?.fruittotal as number || 0,
       logo: 'https://xy.wenlvti.net/app_static/images/home/volunteer/IconFruts.png',
     },
     {
       label: '已关注村社',
       unit: '/个',
-      value: infoLoader.content.value?.userId as number,
+      value: infoLoader.content.value?.followVillageCount || 0,
       logo: 'https://xy.wenlvti.net/app_static/images/home/volunteer/IconFollows.png',
     },
   ];
 });
 const activityLoader = useSimpleDataLoader(async () => {
-  return [
-    {
-      id: 1,
-      head: 'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest1.png',
-      content: '测试数据,没有接口!:福泽乡里 为全村加成+10%乡源果,可持续24小时',
-      levelText: '一级',
-    },
-    {
-      id: 2,
-      head: 'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest2.png',
-      content: '福泽乡里 为全村加成+10%乡源果,可持续24小时',
-      levelText: '五级',
-    },
-    {
-      id: 3,
-      head: 'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest3.png',
-      content: '福泽乡里 为全村加成+10%乡源果,可持续24小时',
-      levelText: '十级',
-    },
-
-  ];
+  return (await TreeApi.getFruitLogList({
+    userId: querys.value.id,
+    page: 1,
+    pageSize: 6,
+  })).list || [];
 });
 </script>

+ 51 - 68
src/pages/home/village/volunteer/list.vue

@@ -1,70 +1,62 @@
 <template>
   <CommonTopBanner title="乡源人数">
-    <FlexCol gap="gap.lg" padding="space.md">
-      <Touchable
-        v-for="(item, index) in villageUserRankListLoader.content.value"
-        :key="item.id"
-        direction="column"
-        @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"
-          
+    <SimplePageContentLoader :loader="villageUserRankListLoader">
+      <FlexCol gap="gap.lg" padding="space.md">
+        <Touchable
+          v-for="(item, index) in villageUserRankListLoader.content.value"
+          :key="item.id"
+          direction="column"
+          @click="goDetails(item)"
         >
-          <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>
+          <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">
+              <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>
+    </SimplePageContentLoader>
   </CommonTopBanner>
 </template>
 
 <script setup lang="ts">
 import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
 import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
-import { ArrayUtils } from '@imengyu/imengyu-utils';
 import { navTo } from '@/components/utils/PageAction';
 import FlexCol from '@/components/layout/FlexCol.vue';
-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';
@@ -73,26 +65,21 @@ import Image from '@/components/basic/Image.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import Touchable from '@/components/feedback/Touchable.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
+import VillageApi from '@/api/inhert/VillageApi';
+import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 
 const { querys } = useLoadQuerys({
-  regionId: 0,
   villageId: 0,
 }, () => {
   villageUserRankListLoader.reload();
 }); 
 
 const villageUserRankListLoader = useSimpleDataLoader(async () => {
-  //TODO: 获取指定村落乡源人列表
-  const res = (await LightVillageApi.getVolunteerRankList({ 
-    region_id: querys.value.regionId || undefined, 
-    village_id: querys.value.villageId || undefined,
-    num: 30,
-  }))
+  const res = (await VillageApi.getVillageVolunteerList(querys.value.villageId))
     .map((item, i) => ({
       id: item.id,
       image: item.image ?? '',
       title: item.name,
-      rank: i + 1,
       score: item.points,
       isAdmin: item.type === 'admin',
     }));
@@ -101,10 +88,6 @@ const villageUserRankListLoader = useSimpleDataLoader(async () => {
 
 function goDetails(item: {
   id: number;
-  image: string;
-  title: string;
-  rank: number;
-  score: number;
 }) {
   console.log(item);