浏览代码

📦 首页4

快乐的梦鱼 3 周之前
父节点
当前提交
91b10162a2
共有 37 个文件被更改,包括 292 次插入125 次删除
  1. 7 18
      src/App.vue
  2. 1 1
      src/common/components/parts/Box.vue
  3. 1 1
      src/common/components/parts/Box2LineImageRightShadow.vue
  4. 3 3
      src/common/components/parts/Box2LineLargeImageUserShadow.vue
  5. 12 5
      src/common/components/parts/HomeLargeTitle.vue
  6. 2 2
      src/common/components/parts/HomeTitle.vue
  7. 42 0
      src/common/config/Theme.ts
  8. 1 1
      src/components/basic/Button.vue
  9. 1 0
      src/components/basic/Image.vue
  10. 2 2
      src/components/display/Avatar.vue
  11. 2 2
      src/components/display/PreviewItem.vue
  12. 0 1
      src/components/display/block/BackgroundBox.vue
  13. 20 0
      src/components/layout/BaseView.ts
  14. 5 0
      src/components/layout/FlexView.vue
  15. 18 0
      src/components/theme/Theme.ts
  16. 2 2
      src/pages/article/details.vue
  17. 1 1
      src/pages/dig/admin/components/VolunteerItem.vue
  18. 3 3
      src/pages/dig/admin/index.vue
  19. 3 3
      src/pages/dig/admin/preview.vue
  20. 1 1
      src/pages/dig/admin/review.vue
  21. 1 1
      src/pages/dig/components/CollectModuleList.vue
  22. 1 1
      src/pages/dig/components/TaskList.vue
  23. 3 3
      src/pages/dig/details.vue
  24. 2 2
      src/pages/dig/forms/list.vue
  25. 2 2
      src/pages/dig/forms/submits.vue
  26. 3 3
      src/pages/dig/index.vue
  27. 2 2
      src/pages/home/components/VillageRankList.vue
  28. 1 1
      src/pages/home/components/VillageUserRankList.vue
  29. 2 2
      src/pages/home/discover/details.vue
  30. 2 2
      src/pages/home/discover/index.vue
  31. 3 3
      src/pages/home/index.vue
  32. 3 3
      src/pages/home/light/details.vue
  33. 3 3
      src/pages/home/village/details.vue
  34. 15 50
      src/pages/home/village/index.vue
  35. 102 0
      src/pages/home/village/introd/card.vue
  36. 19 0
      src/pages/home/village/introd/tree.vue
  37. 1 1
      src/pages/index.vue

+ 7 - 18
src/App.vue

@@ -1,16 +1,16 @@
 <script setup lang="ts">
 import AppConfig, { isTestEnv } from '@/common/config/AppCofig'
-import { onError, onLaunch } from '@dcloudio/uni-app'
 import { useAuthStore } from './store/auth'
-import { configTheme } from './components/theme/ThemeDefine';
+import { useAppInit } from './common/composeabe/AppInit';
+import { BugReporterAbstractionUniapp } from './common/BugReporter/impl/BugReporterAbstractionUniapp';
+import { IconUtils } from './components/basic/IconUtils';
+import { configAppTheme } from './common/config/Theme';
 import { getCurrentPageUrl, navTo } from './components/utils/PageAction';
+import { onError, onLaunch } from '@dcloudio/uni-app'
 import { RequestApiConfig, RequestApiError } from '@imengyu/imengyu-utils';
 import ApiCofig from './common/config/ApiCofig';
-import { useAppInit } from './common/composeabe/AppInit';
 import MemoryTimeOut from './common/composeabe/MemoryTimeOut';
-import BugReporter, { type BugDetailDeviceInfo } from './common/BugReporter';
-import { BugReporterAbstractionUniapp } from './common/BugReporter/impl/BugReporterAbstractionUniapp';
-import { IconUtils } from './components/basic/IconUtils';
+import BugReporter from './common/BugReporter';
 
 const authStore = useAuthStore();
 const { init } = useAppInit();
@@ -77,18 +77,7 @@ function loadFontFace() {
   });
 }
 
-//修改默认主题颜色
-configTheme(false, (theme, defaultDarkTheme) => {
-  theme.colorConfigs.default.primary = '#e19579';
-  theme.colorConfigs.pressed.primary = '#fbce7a';
-  theme.colorConfigs.default.button = '#f6e9d9';
-  theme.colorConfigs.background.primary = '#fef2e8';
-  theme.colorConfigs.background.secondary = '#f7f8f9';
-  theme.colorConfigs.background.tertiary = '#fff7f1';
-
-  theme.varOverrides['ImageDefaultImage'] = 'https://xy.wenlvti.net/app_static/EmptyImage.png';
-  return [theme, defaultDarkTheme];
-});
+configAppTheme();
 
 IconUtils.loadDefaultIcons('https://mncdn.wenlvti.net/app_static/xiangyuan/data/DefaultIcon.json');
 </script>

+ 1 - 1
src/common/components/parts/Box.vue

@@ -5,7 +5,7 @@
       backDropFilter: 'blur(10px)',
     }"
     :padding="padding ? [35,25] : 0" 
-    :radius="30" 
+    radius="radius.large" 
     shadow="light"
   >
     <SubTitle v-if="title" :title="title" :showMore="showMore" @moreClicked="emit('moreClicked')">

+ 1 - 1
src/common/components/parts/Box2LineImageRightShadow.vue

@@ -15,7 +15,7 @@
       <Image 
         :width="wideImage ? 250 : 150"
         :height="150"
-        :radius="10"
+        radius="radius.small"
         :flexShrink="0"
         :src="image"
         mode="aspectFill"

+ 3 - 3
src/common/components/parts/Box2LineLargeImageUserShadow.vue

@@ -4,7 +4,7 @@
     :flexShrink="fixSize ? 0 : undefined"
     :flexGrow="fixSize ? undefined : 1"
     :gap="10"
-    :radius="20"
+    radius="radius.medium"
     overflow="hidden"
     position="relative"
     backgroundColor="white"
@@ -23,7 +23,7 @@
       v-if="image" 
       :height="300" 
       width="100%"
-      :radius="20"
+      radius="radius.medium"
       :src="image" 
       mode="aspectFill" 
     />
@@ -51,7 +51,7 @@
       :top="0"
       :right="0"
       :margin="15"
-      :radius="20" 
+      radius="radius.large" 
       :padding="15"
       backgroundColor="background.primary" 
     >

+ 12 - 5
src/common/components/parts/HomeLargeTitle.vue

@@ -1,17 +1,19 @@
 <template>
-  <FlexRow center :padding="[25, 0, 20, 0]">
-    <Image :src="icon" :width="75" :height="46" mode="widthFix" />
+  <Touchable direction="row" center :padding="[25, 0, 20, 0]" @click="emit('click')">
+    <slot name="icon">
+      <Image :src="icon" :width="75" :height="46" mode="widthFix" />
+    </slot>
     <Width :width="15" />
-    <Text :text="title" fontConfig="h4" fontFamily="SongtiSCBlack" color="#5f3f2c" />
-  </FlexRow>
+    <Text :text="title" fontConfig="h4" :color="active ? '#55989a' : '#5f3f2c'" fontFamily="SongtiSCBlack" />
+  </Touchable>
 </template>
 
 <script setup lang="ts">
 import Image from '@/components/basic/Image.vue';
 import Text from '@/components/basic/Text.vue';
+import Touchable from '@/components/feedback/Touchable.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import Width from '@/components/layout/space/Width.vue';
-import { computed } from 'vue';
 
 const props = defineProps({
   title: {
@@ -26,5 +28,10 @@ const props = defineProps({
     type: Number,
     default: 2,
   },
+  active: {
+    type: Boolean,
+    default: false,
+  },
 });
+const emit = defineEmits(['click']);
 </script>

+ 2 - 2
src/common/components/parts/HomeTitle.vue

@@ -13,8 +13,8 @@
     </template>
     <template #title> 
       <FlexRow align="center">
-        <Text :text="titleBegin2" fontConfig="h4" fontFamily="SongtiSCBlack" color="#55989a" />
-        <Text v-if="titleEnd" :text="titleEnd" fontConfig="h4" fontFamily="SongtiSCBlack" color="#5f3f2c" />
+        <Text :text="titleBegin2" fontConfig="primaryTitle" color="#55989a" />
+        <Text v-if="titleEnd" :text="titleEnd" fontConfig="primaryTitle" color="#5f3f2c" />
       </FlexRow>
     </template>
   </SubTitle>

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

@@ -0,0 +1,42 @@
+import { configTheme } from "@/components/theme/ThemeDefine";
+
+export function configAppTheme() {
+  //修改默认主题颜色
+  configTheme(false, (theme, defaultDarkTheme) => {
+    theme.colorConfigs.default.primary = '#e19579';
+    theme.colorConfigs.pressed.primary = '#fbce7a';
+    theme.colorConfigs.default.button = '#f6e9d9';
+    theme.colorConfigs.background.primary = '#fef2e8';
+    theme.colorConfigs.background.secondary = '#f7f8f9';
+    theme.colorConfigs.background.tertiary = '#fff7f1';
+
+    theme.colorConfigs.text.title = '#62422f';
+    theme.colorConfigs.text.content = '#7b5e49';
+    theme.colorConfigs.text.second = '#95755a';
+
+    theme.varOverrides.radius.smaller = '5rpx';
+    theme.varOverrides.radius.small = '10rpx';
+    theme.varOverrides.radius.medium = '20rpx';
+    theme.varOverrides.radius.large = '30rpx';
+    theme.varOverrides.radius.larger = '50rpx';
+
+    theme.textConfigs.primaryTitle = {
+      color: 'text.title',
+      fontFamily: 'SongtiSCBlack',
+      fontSize: '22px',
+      fontWeight: 'bold',
+    };
+    theme.textConfigs.contentText = {
+      color: 'text.content',
+      fontSize: '13px',
+    };
+    theme.textConfigs.secondText = {
+      color: 'text.second',
+      fontSize: '12px',
+    };
+
+
+    theme.varOverrides['ImageDefaultImage'] = 'https://xy.wenlvti.net/app_static/EmptyImage.png';
+    return [theme, defaultDarkTheme];
+  });
+}

+ 1 - 1
src/components/basic/Button.vue

@@ -138,7 +138,7 @@ export interface ButtonProp {
    * 当按扭为round圆形按扭时的圆角大小。
    * @default 5
    */
-  radius?: number,
+  radius?: number|string,
   /**
    * 按钮尺寸. 支持 large、medium、small、mini 四种尺寸。
    * @default 'medium'

+ 1 - 0
src/components/basic/Image.vue

@@ -37,6 +37,7 @@
         :size="themeContext.resolveThemeSize(loadingSize)"
       />
     </view>
+    <slot v-if="!src && !defaultImage" name="empty"></slot>
     <slot />
   </view>
 </template>

+ 2 - 2
src/components/display/Avatar.vue

@@ -73,12 +73,12 @@ export interface AvatarProps {
    * 头像的大小。
    * @default 40
    */
-  size?: number,
+  size?: number|string,
   /**
    * 头像圆角大小
    * @default 0
    */
-  radius?: number,
+  radius?: number|string,
   /**
    * 头像是否是圆型,设置后 radius 无效
    * @default false

+ 2 - 2
src/components/display/PreviewItem.vue

@@ -23,7 +23,7 @@
           :key="k" 
           :width="100" 
           :height="100"
-          :radius="12"
+          radius="radius.small"
           round
           v-bind="(valueProps as ImageProps)" 
           :src="item"
@@ -34,7 +34,7 @@
         v-else
         :width="100"
         :height="100"
-        :radius="12"
+        radius="radius.small"
         round
         v-bind="(valueProps as ImageProps)"
         :src="value"

+ 0 - 1
src/components/display/block/BackgroundBox.vue

@@ -2,7 +2,6 @@
   <!-- 组件:背景图显示盒子 -->
   <FlexView
     v-bind="$props"
-    center
     :flexShrink="0"
     :innerStyle="style" 
   >

+ 20 - 0
src/components/layout/BaseView.ts

@@ -68,6 +68,21 @@ export function useBaseViewStyleBuilder(props: FlexProps) {
       obj.marginHorizontal = undefined;
     }
 
+    if (props.inset) {
+      if (Array.isArray(props.inset)) {
+        obj.left = themeContext.resolveThemeSize(props.inset[0]);
+        obj.right = themeContext.resolveThemeSize(props.inset[1]);
+        obj.top = themeContext.resolveThemeSize(props.inset[2]);
+        obj.bottom = themeContext.resolveThemeSize(props.inset[3]);
+      } else {
+        const v = themeContext.resolveThemeSize(props.inset);
+        obj.left = v;
+        obj.right = v;
+        obj.top = v;
+        obj.bottom = v;
+      }
+    }
+
     //绝对距样式
     if (typeof props.left !== 'undefined')
       obj.left = themeContext.resolveThemeSize(props.left);
@@ -80,6 +95,11 @@ export function useBaseViewStyleBuilder(props: FlexProps) {
     if (typeof props.flex !== 'undefined')
       obj.flex = props.flex;
 
+    for (const key in obj) {
+      if (obj[key] === undefined)
+        delete obj[key];
+    }
+
     return obj
   });
 

+ 5 - 0
src/components/layout/FlexView.vue

@@ -99,6 +99,11 @@ export interface FlexProps {
   bottom?: number|string,
   left?: number|string,
   /**
+   * 设置元素与其父元素之间的距离(支持数字或数组,等同于 top, right, bottom, left,
+   * 但优先级比它们低),
+   */
+  inset?: (number|string)[]|string|number,
+  /**
    * 圆角
    */
   radius?: number|string,

+ 18 - 0
src/components/theme/Theme.ts

@@ -16,6 +16,17 @@ export const DefaultTheme : ThemeConfig = {
       large: 38,
       larger: 46,
     },
+    gap: {
+      xs: '2rpx',
+      sm: '5rpx',
+      md: '10rpx',
+      lg: '20rpx',
+      xl: '30rpx',
+      '2xl': '40rpx',
+      '3xl': '50rpx',
+      '4xl': '60rpx',
+      '5xl': '70rpx',
+    },
     shadow: {
       default: '0 0 10px rgba(0, 0, 0, 0.1)',
       light: '0 0 10px rgba(0, 0, 0, 0.05)',
@@ -26,6 +37,13 @@ export const DefaultTheme : ThemeConfig = {
       default: '1px solid #dddddd',
       none: 'none',
     },
+    radius: {
+      smaller: '5rpx',
+      small: '10rpx',
+      medium: '20rpx',
+      large: '30rpx',
+      larger: '50rpx',
+    },
   },
   colorConfigs: {
     default: {

+ 2 - 2
src/pages/article/details.vue

@@ -17,7 +17,7 @@
                 :src="item" 
                 width="100%"
                 :height="500"
-                :radius="20"
+                radius="radius.medium"
                 mode="aspectFill"
                 touchable
                 @click="onPreviewImage(key)"
@@ -26,7 +26,7 @@
           </swiper>
           <Image 
             v-else-if="loader.content.value.image"
-            :radius="20"
+            radius="radius.medium"
             :src="loader.content.value.image"
             mode="widthFix"
             width="100%"

+ 1 - 1
src/pages/dig/admin/components/VolunteerItem.vue

@@ -2,7 +2,7 @@
   <FlexRow
     :key="item.id" 
     backgroundColor="white" 
-    radius="20"
+    radius="radius.medium"
     justify="space-between"
     align="center"
     :padding="20"

+ 3 - 3
src/pages/dig/admin/index.vue

@@ -9,8 +9,8 @@
           @search="search"
         />
         <ButtonGroup>
-          <NButton :radius="40" size="small" @click="navTo('review', { villageId: querys.villageId })">待审核志愿者</NButton>
-          <NButton :radius="40" size="small" type="primary" @click="newData">+ 新增</NButton>
+          <NButton radius="radius.larger" size="small" @click="navTo('review', { villageId: querys.villageId })">待审核志愿者</NButton>
+          <NButton radius="radius.larger" size="small" type="primary" @click="newData">+ 新增</NButton>
         </ButtonGroup>
       </FlexRow>
       <FlexCol :gap="20" :margin="[20,0,0,0]">
@@ -61,7 +61,7 @@
                 },
               ]"
             >
-              <NButton type="primary" icon="edit-filling" :radius="40" />
+              <NButton type="primary" icon="edit-filling" radius="radius.larger" />
             </BubbleBox>
           </template>
         </VolunteerItem>

+ 3 - 3
src/pages/dig/admin/preview.vue

@@ -2,7 +2,7 @@
   <FlexCol :padding="30" :gap="20">
     <ImageSwiper
       :images="imageList"
-      :radius="20"
+      radius="radius.medium"
       round
       mode="widthFix"
       :width="690" 
@@ -24,7 +24,7 @@
         ]"
       />
       <FlexCol :margin="[20, 0, 0, 0]">
-        <Parse :content="overviewLoader.content.value.overview" />
+        <Parse :content="(overviewLoader.content.value.overview as string)" />
         <Text v-if="!overviewLoader.content.value.overview" fontConfig="subText">暂无采编简内容</Text>
       </FlexCol>
     </FlexCol>
@@ -42,7 +42,7 @@
 
     <FlexCol :margin="[20, 0, 30, 0]">
       <SubTitle title="地理位置" />
-      <FlexCol :radius="20" backgroundColor="white" :margin="[20, 0, 0, 0]">
+      <FlexCol radius="radius.medium" backgroundColor="white" :margin="[20, 0, 0, 0]">
         <map 
           id="map"
           :latitude="center[1]"

+ 1 - 1
src/pages/dig/admin/review.vue

@@ -34,7 +34,7 @@
               </FlexCol>
             </FlexRow>
             <template #action>
-              <Button type="primary" icon="task-filling" :radius="40" @click="handleShowDetail(item)" />
+              <Button type="primary" icon="task-filling" radius="radius.larger" @click="handleShowDetail(item)" />
             </template>
           </VolunteerItem>
         </FlexCol>

+ 1 - 1
src/pages/dig/components/CollectModuleList.vue

@@ -3,7 +3,7 @@
     <Image
       v-if="currentTaskBanner"
       :src="currentTaskBanner"
-      :radius="20"
+      radius="radius.medium"
       :width="690"
       mode="widthFix"
     />

+ 1 - 1
src/pages/dig/components/TaskList.vue

@@ -44,7 +44,7 @@ defineProps({
 <template>
   <Touchable 
     :padding="25" 
-    :radius="20" 
+    radius="radius.medium" 
     :touchable="button && enable"
     direction="row"
     backgroundColor="white" 

+ 3 - 3
src/pages/dig/details.vue

@@ -3,10 +3,10 @@
     <Image
       src="https://mn.wenlvti.net/app_static/xiangan/banner_dig_1.jpg" 
       mode="widthFix"
-      :radius="20"
+      radius="radius.medium"
       :width="690" 
     />
-    <FlexRow align="center" :gap="10" backgroundColor="white" :padding="20" :radius="20">
+    <FlexRow align="center" :gap="10" backgroundColor="white" :padding="20" radius="radius.medium">
       <FlexRow flexBasis="50%">
         <Text :fontSize="30" text="已认领:" />
         <Width :width="20" />
@@ -23,7 +23,7 @@
     <Touchable 
       direction="column" 
       touchable 
-      :radius="20"
+      radius="radius.medium"
       :padding="30"
       align="center"
       backgroundColor="background.primary"

+ 2 - 2
src/pages/dig/forms/list.vue

@@ -16,7 +16,7 @@
         :key="item.id" 
         :gap="20"
         :padding="[15,20]"
-        :radius="15"
+        radius="radius.medium"
         align="center"
         backgroundColor="white"
         direction="row"
@@ -28,7 +28,7 @@
           :showFailed="false"
           :width="100"
           :height="100"
-          :radius="10"
+          radius="radius.small"
           mode="aspectFill"
           round
         />

+ 2 - 2
src/pages/dig/forms/submits.vue

@@ -39,7 +39,7 @@
           v-for="item in listLoader.list.value"
           :key="item.id" 
           :padding="[15,20]"
-          :radius="15"
+          radius="radius.medium"
           justify="space-between"
           align="center"
           backgroundColor="white"
@@ -53,7 +53,7 @@
               :showFailed="false"
               :width="150"
               :height="150"
-              :radius="10"
+              radius="radius.small"
               mode="aspectFill"
               round
             />

+ 3 - 3
src/pages/dig/index.vue

@@ -7,7 +7,7 @@
         src="https://xy.wenlvti.net/app_static/images/dig/IntrodBanner.png"
         width="100%"
         :height="300"
-        radius="20"
+        radius="radius.medium"
         :innerStyle="{
           border: '1px solid #fff',
         }"
@@ -38,7 +38,7 @@
             <FlexRow 
               v-for="item in villageListLoader.content.value"
               :key="item.id"
-              :radius="20"
+              radius="radius.medium"
               :padding="20"
               align="center"
               justify="space-between"
@@ -99,7 +99,7 @@
 
       <Height :height="20" />
       <HomeTitle v-if="authStore.isLogged" title="我的贡献" />
-      <FlexRow v-if="authStore.isLogged" backgroundColor="white" :radius="20" :padding="[40,20]">
+      <FlexRow v-if="authStore.isLogged" backgroundColor="white" radius="radius.medium" :padding="[40,20]">
         <FlexCol :flex="1" :gap="10" center>
           <Text :fontSize="60" fontFamily="Rockwell" color="primary">{{ volunteerInfoLoader.content.value?.points || 0 }}</Text>
           <Text>文化积分</Text>

+ 2 - 2
src/pages/home/components/VillageRankList.vue

@@ -6,10 +6,10 @@
       :width="item.rank == 1 ? '40%' : '28.5%'" 
       position="relative" 
       justify="space-between"
-      :radius="20"
+      radius="radius.medium"
       overflow="hidden"
     >
-      <Image :src="item.image" width="100%" :height="280" mode="aspectFill" :radius="20" />
+      <Image :src="item.image" width="100%" :height="280" mode="aspectFill" radius="radius.medium" />
       <FlexRow
         position="absolute"
         :left="0"

+ 1 - 1
src/pages/home/components/VillageUserRankList.vue

@@ -21,7 +21,7 @@
         :bottom="item.rank == 1 ? 66 : 40"
         center
       >
-        <Avatar :url="item.image" :size="item.rank == 1 ? 100 : 90" mode="aspectFill" :radius="20" />
+        <Avatar :url="item.image" :size="item.rank == 1 ? 100 : 90" mode="aspectFill" radius="radius.medium" />
         <Height :height="item.rank == 1 ? 15 : 10" />
         <Text fontConfig="h4" :text="item.title" color="white" />
         <Text fontConfig="h2" :text="item.score" :color="scoreColors[item.rank - 1]" />

+ 2 - 2
src/pages/home/discover/details.vue

@@ -18,7 +18,7 @@
                   :src="item" 
                   width="100%"
                   :height="500"
-                  :radius="20"
+                  radius="radius.medium"
                   mode="aspectFill" 
                   @click="onPreviewImage(key)"
                 />
@@ -44,7 +44,7 @@
               :src="loader.content.value.image"
               :imageWidth="100"
               :imageHeight="100"
-              :radius="20"
+              radius="radius.medium"
               :title="loader.content.value.villageName"
               :desc="`${loader.content.value.villageProvince}${loader.content.value.villageCity}`"
             />

+ 2 - 2
src/pages/home/discover/index.vue

@@ -6,7 +6,7 @@
       src="https://xy.wenlvti.net/app_static/images/dig/IntrodBanner.png"
       width="100%"
       :height="300"
-      radius="20"
+      radius="radius.medium"
       :innerStyle="{
         border: '1px solid #fff',
       }"
@@ -30,7 +30,7 @@
     
     <HomeTitle title="最新推荐" />
     <SimplePageContentLoader :loader="discoverLoader">
-      <FlexCol :gap="25" backgroundColor="background.tertiary" :radius="20" :padding="30">
+      <FlexCol :gap="25" backgroundColor="background.tertiary" radius="radius.medium" :padding="30">
         <ImageBlock3 
           v-for="(item, i) in discoverLoader.content.value"
           :key="i"

+ 3 - 3
src/pages/home/index.vue

@@ -30,9 +30,9 @@
 
     <VillageMiniMap />
     <FlexRow justify="space-between" :padding="[10, 16]">
-      <Button icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">切换城市</Button>
-      <Button icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">我的关注</Button>
-      <Button icon="https://xy.wenlvti.net/app_static/images/home/IconLight.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">点亮村社</Button>
+      <Button icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png" radius="radius.larger" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">切换城市</Button>
+      <Button icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png" radius="radius.larger" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">我的关注</Button>
+      <Button icon="https://xy.wenlvti.net/app_static/images/home/IconLight.png" radius="radius.larger" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">点亮村社</Button>
     </FlexRow>
 
     <HomeTitle title="乡村排名" showMore />

+ 3 - 3
src/pages/home/light/details.vue

@@ -15,7 +15,7 @@
         <swiper-item v-for="(item, k) in data.images" :key="k">
           <Image 
             :src="item" 
-            :radius="20"
+            radius="radius.medium"
             :height="500"
             :width="750"
             mode="aspectFill"
@@ -25,7 +25,7 @@
         </swiper-item>
       </swiper>
 
-      <FlexCol :padding="20" :radius="20" :gap="20">
+      <FlexCol :padding="20" radius="radius.medium" :gap="20">
 
         <Height :height="20" />
         <FlexCol>
@@ -55,7 +55,7 @@
 
         <FlexCol :margin="[20, 0, 30, 0]">
           <SubTitle title="地理位置" />
-          <FlexCol :radius="20" backgroundColor="white" :margin="[20, 0, 0, 0]">
+          <FlexCol radius="radius.medium" backgroundColor="white" :margin="[20, 0, 0, 0]">
             <map 
               id="map"
               :latitude="center[1]"

+ 3 - 3
src/pages/home/village/details.vue

@@ -15,7 +15,7 @@
         <swiper-item v-for="(item, k) in data.images" :key="k">
           <Image 
             :src="item" 
-            :radius="20"
+            radius="radius.medium"
             :height="500"
             :width="750"
             mode="aspectFill"
@@ -25,7 +25,7 @@
         </swiper-item>
       </swiper>
 
-      <FlexCol :padding="20" :radius="20" :gap="20">
+      <FlexCol :padding="20" radius="radius.medium" :gap="20">
 
         <Height :height="20" />
         <FlexCol>
@@ -70,7 +70,7 @@
 
         <FlexCol :margin="[20, 0, 30, 0]">
           <SubTitle title="地理位置" />
-          <FlexCol :radius="20" backgroundColor="white" :margin="[20, 0, 0, 0]">
+          <FlexCol radius="radius.medium" backgroundColor="white" :margin="[20, 0, 0, 0]">
             <map 
               id="map"
               :latitude="center[1]"

+ 15 - 50
src/pages/home/village/index.vue

@@ -1,66 +1,31 @@
 <template>
   <FlexCol :gap="20" :padding="30">
-    <HomeLargeTitle title="发现" />
-    <Image
-      mode="aspectFill" 
-      src="https://xy.wenlvti.net/app_static/images/dig/IntrodBanner.png"
-      width="100%"
-      :height="300"
-      radius="20"
-      :innerStyle="{
-        border: '1px solid #fff',
-      }"
-    />
-    
 
-
-    <HomeTitle title="最新推荐" />
-    <SimplePageContentLoader :loader="discoverLoader">
-      <FlexCol :gap="25" backgroundColor="background.tertiary" :radius="20" :padding="30">
-        <ImageBlock3 
-          v-for="(item, i) in discoverLoader.content.value"
-          :key="i"
-          backgroundColor="transparent"
-          :src="item.image"
-          :title="item.title"
-          :desc="item.desc"
-          :imageRadius="15"
-          :imageWidth="200"
-          :imageHeight="140"
-        />
-      </FlexCol>
-    </SimplePageContentLoader>
-    
+    <FlexRow center :gap="30">
+      <HomeLargeTitle title="村社名片" :active="tab === 'card'" @click="tab = 'card'" />
+      <HomeLargeTitle title="乡源树" :active="tab === 'tree'" @click="tab = 'tree'">
+        <template #icon>
+          <Image src="https://xy.wenlvti.net/app_static/images/village/IconLargeTree.png" :width="45" :height="46" mode="heightFix" />
+        </template>
+      </HomeLargeTitle>
+    </FlexRow>
+    <Card v-if="tab === 'card'" />
+    <Tree v-if="tab === 'tree'" />
     <Loadmore status="nomore" />
     <Height :height="150" />
   </FlexCol>
 </template>
 
 <script setup lang="ts">
-import { navTo } from '@/components/utils/PageAction';
-import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
-import SimplePageContentLoader from '@/common/components/SimplePageContentLoader.vue';
 import Loadmore from '@/components/display/loading/Loadmore.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import Height from '@/components/layout/space/Height.vue';
-import ProvideVar from '@/components/theme/ProvideVar.vue';
-import Grid from '@/components/layout/grid/Grid.vue';
-import GridItem from '@/components/layout/grid/GridItem.vue';
-import VillageInfoApi from '@/api/inhert/VillageInfoApi';
-import Tag from '@/components/display/Tag.vue';
 import Image from '@/components/basic/Image.vue';
 import HomeLargeTitle from '@/common/components/parts/HomeLargeTitle.vue';
-import HomeTitle from '@/common/components/parts/HomeTitle.vue';
-import ImageBlock3 from '@/components/display/block/ImageBlock3.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+import { ref } from 'vue';
+import Card from './introd/card.vue';
+import Tree from './introd/tree.vue';
 
-const discoverLoader = useSimpleDataLoader(async () => {
-  return (await VillageInfoApi.getListForDiscover(1, 30)).list.map((item) => {
-    return {
-      ...item,
-      image: (item.thumbnail || item.image) as string,
-      desc: item.desc || '',
-      title: item.title,
-    }
-  })
-});
+const tab = ref('card');
 </script>

+ 102 - 0
src/pages/home/village/introd/card.vue

@@ -0,0 +1,102 @@
+<template>
+  <FlexCol>
+
+    <BackgroundBox 
+      color1="#eecaa0"
+      color2="white"
+      radius="radius.large"
+      direction="column"
+      :padding="[35,30]"
+      gap="gap.lg"
+    >
+
+      <!-- 标题 -->
+      <FlexRow justify="space-between" width="100%">
+        <FlexCol gap="gap.md">
+          <Text :text="villageInfoLoader.content.value?.title" fontConfig="primaryTitle" />
+          <Text :text="villageInfoLoader.content.value?.address" fontConfig="secondText" />
+        </FlexCol>
+        <FlexCol gap="gap.md">
+          <Button icon="https://xy.wenlvti.net/app_static/images/village/IconUser.png" radius="radius.larger" :padding="[10, 30]" backgroundColor="white">申请管理者</Button>
+          <Text :text="`${villageInfoLoader.content.value?.applyCount} 个乡源果可申请`" fontConfig="secondText" />
+        </FlexCol>
+      </FlexRow>
+      
+      <!-- 图片 -->
+      <FlexRow v-if="villageInfoLoader.content.value" justify="space-between">
+        <Image 
+          v-for="index of 3" 
+          :key="index" 
+          :src="villageInfoLoader.content.value.images[index - 1]" 
+          radius="radius.medium"
+          :width="200"
+          :height="140"
+          mode="aspectFill"
+          touchable
+        >
+          <template #empty>
+            <Touchable 
+              direction="column" 
+              position="absolute" 
+              inset="0" 
+              center
+              backgroundColor="background.primary"
+            >
+              <Icon name="add" size="fontSize.medium" />
+              <Text text="上传封面" fontConfig="secondText" />
+            </Touchable>
+          </template>
+          <FlexCol 
+            v-if="index === 3 && villageInfoLoader.content.value.images.length > 3" 
+            position="absolute" inset="0" 
+            center 
+            backgroundColor="mask.default"
+          >
+            <Text :text="`+${villageInfoLoader.content.value.images.length - 3}`" fontSize="fontSize.large" color="white" />
+          </FlexCol>
+        </Image>
+      </FlexRow>
+
+      <!-- 地址 -->
+
+
+    </BackgroundBox>
+
+    <HomeTitle title="排行榜" />
+
+    <HomeTitle title="魅力乡源" />
+
+
+  </FlexCol>
+
+</template>
+
+<script setup lang="ts">
+import HomeTitle from '@/common/components/parts/HomeTitle.vue';
+import ImageSwiper from '@/common/components/parts/ImageSwiper.vue';
+import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
+import Button from '@/components/basic/Button.vue';
+import Icon from '@/components/basic/Icon.vue';
+import Image from '@/components/basic/Image.vue';
+import Text from '@/components/basic/Text.vue';
+import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
+import Touchable from '@/components/feedback/Touchable.vue';
+import FlexCol from '@/components/layout/FlexCol.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+
+const villageInfoLoader = useSimpleDataLoader(async () => {
+  return {
+    title: '高点社区',
+    desc: '',
+    address: '福建省厦门市同安区高浦社区',
+    applyCount: 100,
+    images: [
+      'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest1.jpg',
+      'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest2.jpg',
+      'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest3.jpg',
+      'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest4.jpg',
+      'https://mn.wenlvti.net/app_static/minnan/images/test/ImageTest5.jpg',
+    ],
+  };
+});
+</script>

+ 19 - 0
src/pages/home/village/introd/tree.vue

@@ -0,0 +1,19 @@
+<template>
+  <FlexCol>
+
+
+    <HomeTitle title="排行榜" />
+
+    <HomeTitle title="魅力乡源" />
+
+
+  </FlexCol>
+
+</template>
+
+<script setup lang="ts">
+import HomeTitle from '@/common/components/parts/HomeTitle.vue';
+import FlexCol from '@/components/layout/FlexCol.vue';
+
+
+</script>

+ 1 - 1
src/pages/index.vue

@@ -52,7 +52,7 @@ import DiscoverIndex from './home/discover/index.vue';
 import VillageIndex from './home/village/index.vue';
 import CommonRoot from '@/components/dialog/CommonRoot.vue';
 
-const tabIndex = ref(0);
+const tabIndex = ref(1);
 const themeContext = useTheme();
 
 onShareAppMessage(() => {