Quellcode durchsuchen

📦 志愿者详情页

快乐的梦鱼 vor 1 Monat
Ursprung
Commit
2ea714c20e

+ 31 - 0
src/common/components/CommonTopBanner.vue

@@ -0,0 +1,31 @@
+<template>
+  <CommonRoot>
+    <FlexCol :innerStyle="{
+      backgroundImage: 'url(https://xy.wenlvti.net/app_static/images/dig/TopBanner.png)',
+      backgroundSize: '100% auto',
+      backgroundRepeat: 'no-repeat',
+      backgroundPosition: 'top center',
+      minHeight: '100vh',
+    }">
+      <StatusBarSpace  />
+      <NavBar v-if="showNav" :title="title" leftButton="back" />
+      <slot />
+    </FlexCol>
+  </CommonRoot>
+</template>
+
+<script setup lang="ts">
+import CommonRoot from '@/components/dialog/CommonRoot.vue';
+import FlexCol from '@/components/layout/FlexCol.vue';
+import StatusBarSpace from '@/components/layout/space/StatusBarSpace.vue';
+import NavBar from '@/components/nav/NavBar.vue';
+
+withDefaults(defineProps<{
+  title: string;
+  showNav?: boolean;
+}>(), {
+  title: '',
+  showNav: true,
+});
+
+</script>

+ 11 - 0
src/common/config/Theme.ts

@@ -37,11 +37,21 @@ export function configAppTheme() {
       fontSize: '40rpx',
       fontWeight: 'bold',
     };
+    theme.textConfigs.lightGoldTitle = {
+      color: '#cb8833',
+      fontFamily: 'SongtiSCBlack',
+      fontSize: '40rpx',
+      fontWeight: 'bold',
+    };
     theme.textConfigs.importantTitle = {
       color: 'text.title',
       fontSize: '36rpx',
       fontWeight: 'bold',
     };
+    theme.textConfigs.lightImportantTitle = {
+      color: 'text.title',
+      fontSize: '34rpx',
+    };
     theme.textConfigs.contentText = {
       color: 'text.content',
       fontSize: '26rpx',
@@ -54,6 +64,7 @@ export function configAppTheme() {
 
     theme.varOverrides.border.primary = '1px solid #aca696';
     theme.varOverrides.border.secondary = '1px solid #5F3F2C';
+    theme.varOverrides['DividerColor'] = '#eacb9f';
     theme.varOverrides['ImageDefaultImage'] = 'https://xy.wenlvti.net/app_static/EmptyImage.png';
     return [theme, defaultDarkTheme];
   });

+ 7 - 0
src/pages.json

@@ -105,6 +105,13 @@
       }
     },
     {
+      "path": "pages/home/village/volunteer/detail",
+      "style": {
+        "navigationBarTitleText": "志愿者详情",
+        "navigationStyle": "custom"
+      }
+    },
+    {
       "path": "pages/article/details",
       "style": {
         "navigationBarTitleText": "新闻详情"

+ 71 - 84
src/pages/chat/dependent/post/publish.vue

@@ -1,85 +1,74 @@
 <template>
-  <CommonRoot>
-    <FlexCol :innerStyle="{
-      backgroundImage: 'url(https://xy.wenlvti.net/app_static/images/dig/TopBanner.png)',
-      backgroundSize: '100% auto',
-      backgroundRepeat: 'no-repeat',
-      backgroundPosition: 'top center',
-      minHeight: '100vh',
-    }">
-      <StatusBarSpace />
-      <NavBar title="发布微信贴图" leftButton="back" rightButton="add" />
-      <FlexCol padding="space.lg">
-        <ProvideVar
-          :vars="{
-            FieldBackgroundColor: 'transparent',
-            UploaderListAddItemBackgroundImage: 'url(https://xy.wenlvti.net/app_static/images/village/ButtonUpload.png)',
-            UploaderAddIcon: '',
-          }"
-        >
-          <BackgroundBox
-            backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxLarge.png"
-            :backgroundCutBorder="[50,50,50,50]"
-            :backgroundCutBorderSize="[50,50,50,50]"
-            direction="column"
-            gap="gap.md"
-            :padding="[40, 30]"
-          >
-            <Uploader 
-              ref="uploader"
-              listType="grid"
-              :maxUploadCount="9" 
-              :upload="uploadImage"
-              @updateList="onUpdateList"
-            />
-            <Field v-model="title" type="text" placeholder="输入标题(可选)" :maxLength="30" showWordLimit />
-            <Field 
-              v-model="content" 
-              type="text" 
-              multiline 
-              placeholder="请输入内容(可选)" 
-              :maxLength="1000" 
-              rows="20" 
-              :inputStyle="{
-                height: '600rpx',
-              }"
-              showWordLimit 
-            />
-          </BackgroundBox>
-        </ProvideVar>
-        <Height :height="50" />
-        <ImageButton
-          src="https://xy.wenlvti.net/app_static/images/village/ButtonPrimary.png"
-          text="发布"
-          width="500rpx"
-          height="80rpx"
-          @click="publish"
-        />
-      </FlexCol>
-
-      <BackgroundBox 
-        position="fixed" :inset="{ b: 0, l: 0, r: 0 }"
-        backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxLarge.png"
-        :backgroundCutBorder="[50,50,0,50]"
-        :backgroundCutBorderSize="[50,50,0,50]"
-        direction="column"
-        :padding="[20, 10]"
+  <CommonTopBanner title="发布微信贴图">
+    <FlexCol padding="space.lg">
+      <ProvideVar
+        :vars="{
+          FieldBackgroundColor: 'transparent',
+          UploaderListAddItemBackgroundImage: 'url(https://xy.wenlvti.net/app_static/images/village/ButtonUpload.png)',
+          UploaderAddIcon: '',
+        }"
       >
-        <FlexRow padding="space.md" align="center" justify="space-between">
-          <FlexRow align="center" justify="center">
-            <Button icon="https://xy.wenlvti.net/app_static/images/village/IconAi.png" @click="showAgentPopup = true">AI伴写</Button>
-          </FlexRow>
-          <FlexRow align="center" justify="center">
-            <IconButton
-              icon="setting"
-              width="40rpx"
-              height="40rpx"
-            />
-          </FlexRow>
-        </FlexRow>
-        <XBarSpace />
-      </BackgroundBox>
+        <BackgroundBox
+          backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxLarge.png"
+          :backgroundCutBorder="[50,50,50,50]"
+          :backgroundCutBorderSize="[50,50,50,50]"
+          direction="column"
+          gap="gap.md"
+          :padding="[40, 30]"
+        >
+          <Uploader 
+            ref="uploader"
+            listType="grid"
+            :maxUploadCount="9" 
+            :upload="uploadImage"
+            @updateList="onUpdateList"
+          />
+          <Field v-model="title" type="text" placeholder="输入标题(可选)" :maxLength="30" showWordLimit />
+          <Field 
+            v-model="content" 
+            type="text" 
+            multiline 
+            placeholder="请输入内容(可选)" 
+            :maxLength="1000" 
+            rows="20" 
+            :inputStyle="{
+              height: '600rpx',
+            }"
+            showWordLimit 
+          />
+        </BackgroundBox>
+      </ProvideVar>
+      <Height :height="50" />
+      <ImageButton
+        src="https://xy.wenlvti.net/app_static/images/village/ButtonPrimary.png"
+        text="发布"
+        width="500rpx"
+        height="80rpx"
+        @click="publish"
+      />
     </FlexCol>
+    <BackgroundBox 
+      position="fixed" :inset="{ b: 0, l: 0, r: 0 }"
+      backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxLarge.png"
+      :backgroundCutBorder="[50,50,0,50]"
+      :backgroundCutBorderSize="[50,50,0,50]"
+      direction="column"
+      :padding="[20, 10]"
+    >
+      <FlexRow padding="space.md" align="center" justify="space-between">
+        <FlexRow align="center" justify="center">
+          <Button icon="https://xy.wenlvti.net/app_static/images/village/IconAi.png" @click="showAgentPopup = true">AI伴写</Button>
+        </FlexRow>
+        <FlexRow align="center" justify="center">
+          <IconButton
+            icon="setting"
+            width="40rpx"
+            height="40rpx"
+          />
+        </FlexRow>
+      </FlexRow>
+      <XBarSpace />
+    </BackgroundBox>
     <Popup v-model:show="showAgentPopup" position="bottom" closeable :closeIcon="false" size="60vh" round>
       <Agent 
         v-model:title="title"
@@ -89,7 +78,7 @@
         @close="showAgentPopup = false" 
       />
     </Popup>
-  </CommonRoot>
+  </CommonTopBanner>
 </template>
 
 <script setup lang="ts">
@@ -100,15 +89,11 @@ import { confirm, toast } from '@/components/dialog/CommonRoot';
 import { useAuthStore } from '@/store/auth';
 import { envVersion } from '@/common/config/AppCofig';
 import CommonContent from '@/api/CommonContent';
-import CommonRoot from '@/components/dialog/CommonRoot.vue';
 import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
 import Field from '@/components/form/Field.vue';
 import Uploader, { type UploaderInstance } from '@/components/form/Uploader.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
-import StatusBarSpace from '@/components/layout/space/StatusBarSpace.vue';
-import NavBar from '@/components/nav/NavBar.vue';
 import ProvideVar from '@/components/theme/ProvideVar.vue';
-import type { UploaderAction, UploaderItem } from '@/components/form/Uploader';
 import Height from '@/components/layout/space/Height.vue';
 import ImageButton from '@/components/basic/ImageButton.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
@@ -118,6 +103,8 @@ import IconButton from '@/components/basic/IconButton.vue';
 import Popup from '@/components/dialog/Popup.vue';
 import Agent from './agent.vue';
 import LightVillageApi, { PostMessage } from '@/api/light/LightVillageApi';
+import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
+import type { UploaderAction, UploaderItem } from '@/components/form/Uploader';
 
 const { querys } = useLoadQuerys({
   tag: '',

+ 49 - 59
src/pages/chat/index.vue

@@ -1,63 +1,54 @@
 <template>
-  <CommonRoot>
-    <FlexCol :innerStyle="{
-      backgroundImage: 'url(https://xy.wenlvti.net/app_static/images/dig/TopBanner.png)',
-      backgroundSize: '100% auto',
-      backgroundRepeat: 'no-repeat',
-      backgroundPosition: 'top center',
-      minHeight: '100vh',
-    }">
-      <StatusBarSpace />
-      <FlexCol v-if="showSessionSidebar" position="relative" width="100%" height="100%">
+  <CommonTopBanner title="">
+    <FlexCol v-if="showSessionSidebar" position="relative" width="100%" height="100%">
+      <NavBar 
+        title="历史会话" 
+        leftButton="close-bold" 
+        @leftButtonPressed="showSessionSidebar=false"
+      />
+      <ChatSessionSidebar :sessionManager="sessionManager" @close="showSessionSidebar = false" />
+    </FlexCol>
+    <ChatMessageContainer
+      v-else
+      :chatManager="chatManager"
+      :sessionManager="sessionManager"
+      :historyItemsPagerManager="historyItemsPagerManager"
+      :chatInterfaceManager="interfaceManager"
+      height="77vh"
+      @intoSelectMode="intoSelectMode"
+    >
+      <template #header>
         <NavBar 
-          title="历史会话" 
-          leftButton="close-bold" 
-          @leftButtonPressed="showSessionSidebar=false"
-        />
-        <ChatSessionSidebar :sessionManager="sessionManager" @close="showSessionSidebar = false" />
-      </FlexCol>
-      <ChatMessageContainer
-        v-else
-        :chatManager="chatManager"
-        :sessionManager="sessionManager"
-        :historyItemsPagerManager="historyItemsPagerManager"
-        :chatInterfaceManager="interfaceManager"
-        height="77vh"
-        @intoSelectMode="intoSelectMode"
-      >
-        <template #header>
-          <NavBar 
-            title="AI助手" 
-            leftButton="back"
-          >
-            <template #left-custom>
-              <FlexRow align="center">
-                <IconButton icon="menu" shape="square-full" @click="showSessionSidebar = true" />
-              </FlexRow>
-            </template>
-          </NavBar>
-        </template>
-        <template #footer>
-          <ChatFooter
-            :chatManager="chatManager" 
-            :chatInterfaceManager="interfaceManager"
-          >
-            <template #mulitSelectMode>
-              <ChatMulitSelectBar 
-                :selectedCount="selectedCount" 
-                :messages="messages" 
-                :sessionManager="sessionManager" 
-                @cancel="exitSelectMode"
-              />
-            </template>
-            <template #header>
+          title="AI助手" 
+          leftButton="back"
+        >
+          <template #left-custom>
+            <FlexRow align="center">
+              <IconButton icon="menu" shape="square-full" @click="showSessionSidebar = true" />
+            </FlexRow>
+          </template>
+        </NavBar>
+      </template>
+      <template #footer>
+        <ChatFooter
+          :chatManager="chatManager" 
+          :chatInterfaceManager="interfaceManager"
+        >
+          <template #mulitSelectMode>
+            <ChatMulitSelectBar 
+              :selectedCount="selectedCount" 
+              :messages="messages" 
+              :sessionManager="sessionManager" 
+              @cancel="exitSelectMode"
+            />
+          </template>
+          <template #header>
 
-            </template>
-          </ChatFooter>
-        </template>
-      </ChatMessageContainer>
-    </FlexCol>
-  </CommonRoot>
+          </template>
+        </ChatFooter>
+      </template>
+    </ChatMessageContainer>
+  </CommonTopBanner>
 </template>
 
 <script setup lang="ts">  
@@ -73,10 +64,9 @@ import NavBar from '@/components/nav/NavBar.vue';
 import ChatSessionSidebar from '@/pages/chat/components/Session/ChatSessionSidebar.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import ChatMulitSelectBar from '@/pages/chat/components/Footer/ChatMulitSelectBar.vue';
-import StatusBarSpace from '@/components/layout/space/StatusBarSpace.vue';
-import CommonRoot from '@/components/dialog/CommonRoot.vue';
 import IconButton from '@/components/basic/IconButton.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
+import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 
 const messages = ref<ChatMessageModel[]>([]) as Ref<ChatMessageModel[]>;
 const interfaceManager: ChatInterfaceManager = {

+ 15 - 2
src/pages/home/components/VillageUserRankList.vue

@@ -1,7 +1,7 @@
 <template>
   <Empty v-if="list.length === 0" description="暂无排名数据" />
   <FlexRow align="flex-end">
-    <FlexCol 
+    <Touchable 
       v-for="(item) in list" 
       position="relative" 
       :key="item.id" 
@@ -13,7 +13,9 @@
         backgroundPosition: 'center',
         backgroundImage: `url('https://xy.wenlvti.net/app_static/images/home/Rank${item.rank}.png')`
       }"
+      direction="column"
       overflow="hidden"
+      @click="emit('goDetails', item)"
     >
       <FlexCol 
         position="absolute"
@@ -30,7 +32,7 @@
         <Text fontConfig="h4" :text="item.title" color="white" />
         <Text fontConfig="h2" :text="item.score" :color="scoreColors[item.rank - 1]" />
       </FlexCol>
-    </FlexCol>
+    </Touchable>
   </FlexRow>
 </template>
 
@@ -38,6 +40,7 @@
 import Text from '@/components/basic/Text.vue';
 import Avatar from '@/components/display/Avatar.vue';
 import Empty from '@/components/feedback/Empty.vue';
+import Touchable from '@/components/feedback/Touchable.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import Height from '@/components/layout/space/Height.vue';
@@ -82,4 +85,14 @@ withDefaults(defineProps<{
   ],
 });
 
+const emit = defineEmits<{
+  (e: 'goDetails', item: {
+    id: number;
+    image: string;
+    title: string;
+    rank: number;
+    score: number;
+  }): void;
+}>();
+
 </script>

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

@@ -1,13 +1,5 @@
 <template>
-  <FlexCol :innerStyle="{
-    backgroundImage: 'url(https://xy.wenlvti.net/app_static/images/dig/TopBanner.png)',
-    backgroundSize: '100% auto',
-    backgroundRepeat: 'no-repeat',
-    backgroundPosition: 'top center',
-    minHeight: '100vh',
-  }">
-    <StatusBarSpace />
-    <NavBar title="村社排名" leftButton="back" />
+  <CommonTopBanner title="村社排名">
     <FlexCol gap="gap.lg" padding="space.md">
       <BackgroundBox
         v-for="(item, index) in villageRankListLoader.content.value"
@@ -61,7 +53,7 @@
         </Touchable>
       </BackgroundBox>
     </FlexCol>
-  </FlexCol>
+  </CommonTopBanner>
 </template>
 
 <script setup lang="ts">
@@ -79,6 +71,7 @@ import Touchable from '@/components/feedback/Touchable.vue';
 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';
 
 const { querys } = useLoadQuerys({
   regionId: 0,

+ 72 - 56
src/pages/home/village/rank/volunteer.vue

@@ -1,75 +1,77 @@
 <template>
-  <FlexCol :innerStyle="{
-    backgroundImage: 'url(https://xy.wenlvti.net/app_static/images/dig/TopBanner.png)',
-    backgroundSize: '100% auto',
-    backgroundRepeat: 'no-repeat',
-    backgroundPosition: 'top center',
-    minHeight: '100vh',
-  }">
-    <StatusBarSpace />
-    <NavBar title="志愿者排名" leftButton="back" />
-    <VillageUserRankList :list="villageUserRankListFirst3" />
+  <CommonTopBanner title="志愿者排名">
+    <VillageUserRankList 
+      :list="villageUserRankListFirst3" 
+      @goDetails="goDetails" 
+    />
     <FlexCol gap="gap.lg" padding="space.md">
-      <BackgroundBox
+      <Touchable
         v-for="(item, index) in villageUserRankListAfter3"
         :key="item.id"
-        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"
+        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>
+        <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>
+  </CommonTopBanner>
 </template>
 
 <script setup lang="ts">
+import { computed } from 'vue';
 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 VillageUserRankList from '../../components/VillageUserRankList.vue';
 import LightVillageApi from '@/api/light/LightVillageApi';
 import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
-import { computed } from 'vue';
 import Text from '@/components/basic/Text.vue';
 import Avatar from '@/components/display/Avatar.vue';
 import Tag from '@/components/display/Tag.vue';
@@ -77,6 +79,8 @@ 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 Touchable from '@/components/feedback/Touchable.vue';
+import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 
 const { querys } = useLoadQuerys({
   regionId: 0,
@@ -115,4 +119,16 @@ const villageUserRankListAfter3 = computed(() => {
   return villageUserRankListLoader.content.value?.slice(3) ?? [];
 });
 
+function goDetails(item: {
+  id: number;
+  image: string;
+  title: string;
+  rank: number;
+  score: number;
+}) {
+  console.log(item);
+  
+  navTo('../volunteer/detail', { id: item.id });
+}
+
 </script>

+ 164 - 0
src/pages/home/village/volunteer/detail.vue

@@ -0,0 +1,164 @@
+<template>
+  <CommonTopBanner title="志愿者详情">
+    <SimplePageContentLoader :loader="infoLoader">
+      <FlexCol v-if="infoLoader.content.value" gap="gap.md" padding="padding.md">
+        <BackgroundBox 
+          backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxLarge.png"
+          :backgroundCutBorder="32"
+          :backgroundCutBorderSize="36"
+          :padding="40"
+          direction="row"
+          align="center"
+        >
+          <Avatar
+            :src="infoLoader.content.value.image"
+            :size="200"
+          />
+          <Width :width="60" />
+          <FlexCol gap="gap.md">
+            <H3>{{ infoLoader.content.value.name }}</H3>
+            <FlexRow align="center" gap="gap.md">
+              <Text text="个人等级" fontConfig="contentText" />
+              <Tag :text="infoLoader.content.value.level + '级'" />
+            </FlexRow>
+            <FlexRow align="center" gap="gap.md">
+              <Text text="加入村庄" fontConfig="contentText" />
+              <Tag :text="(infoLoader.content.value.villageName as string)" />
+            </FlexRow>
+            <Divider />
+            <FlexRow align="center" gap="gap.md">
+              <Text text="贡献乡源光" fontConfig="contentText" />
+              <Text :text="infoLoader.content.value.points" fontConfig="lightGoldTitle" />
+            </FlexRow>
+
+          </FlexCol>
+        </BackgroundBox>
+
+        <FlexRow wrap justify="space-around" gap="gap.md">
+          <BackgroundBox 
+            v-for="(item, k) in infoGrids"
+            :key="k"
+            backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxMid.png"
+            :backgroundCutBorder="32"
+            :backgroundCutBorderSize="36"
+            :padding="24"
+            :innerStyle="{ width: 'calc(50% - 58rpx)' }"
+            direction="row"
+            align="center"
+            gap="gap.md"
+          >
+            <Image :src="item.logo" :radius="20" width="100" height="100" mode="aspectFill" />
+            <FlexCol>
+              <Text :text="item.label" fontConfig="lightImportantTitle" />
+              <FlexRow align="center" gap="gap.sm">
+                <Text :text="item.value" fontConfig="lightGoldTitle" :fontSize="60" />
+                <Text :text="item.unit" fontConfig="contentText" />
+              </FlexRow>
+            </FlexCol>
+          </BackgroundBox>
+        </FlexRow>
+
+        <HomeTitle title="最新动态" />
+        <FlexCol gap="gap.lg">
+          <FlexRow 
+            v-for="item in activityLoader.content.value" :key="item.id"
+            backgroundColor="background.tertiary"
+            radius="radius.md"
+            :padding="[20, 30]"
+            gap="gap.lg"
+            align="center"
+          > 
+            <Avatar 
+              :url="item.head"
+              :size="80"
+              :round="false"
+              :radius="10"
+            />
+            <Text :text="item.content" fontConfig="contentText" :innerStyle="{ flex: 1 }" />
+          </FlexRow>
+        </FlexCol>
+      </FlexCol>
+    </SimplePageContentLoader>
+  </CommonTopBanner>
+</template>
+
+<script setup lang="ts">
+import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
+import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
+import FlexCol from '@/components/layout/FlexCol.vue';
+import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
+import Text from '@/components/basic/Text.vue';
+import Avatar from '@/components/display/Avatar.vue';
+import Image from '@/components/basic/Image.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
+import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
+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';
+
+const { querys } = useLoadQuerys({
+  id: 0,
+}, () => {
+  infoLoader.reload();
+});
+
+const infoLoader = useSimpleDataLoader(async () => {
+  return (await VillageApi.getVolunteerInfoByIdAdmin(querys.value.id));
+});
+const infoGrids = computed(() => {
+  return [
+    {
+      label: '累计发文',
+      unit: '/篇',
+      logo: 'https://xy.wenlvti.net/app_static/images/home/volunteer/IconPosts.png',
+      value: infoLoader.content.value?.userId as number,
+    },
+    {
+      label: '点赞/评论',
+      unit: '/次',
+      value: infoLoader.content.value?.userId as number,
+      logo: 'https://xy.wenlvti.net/app_static/images/home/volunteer/IconLikes.png',
+    },
+    {
+      label: '乡源果累计',
+      unit: '/个',
+      value: infoLoader.content.value?.userId as number,
+      logo: 'https://xy.wenlvti.net/app_static/images/home/volunteer/IconFruts.png',
+    },
+    {
+      label: '已关注村社',
+      unit: '/个',
+      value: infoLoader.content.value?.userId as number,
+      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: '十级',
+    },
+
+  ];
+});
+</script>