Explorar o código

📦 首页和通用核心修改

快乐的梦鱼 hai 1 semana
pai
achega
95a3a46cb7

+ 3 - 1
src/common/composeabe/TabControl.ts

@@ -21,7 +21,9 @@ export function useTabControl(options: {
 
   const tabCurrentIndex = ref(0)
   const tabCurrentId = computed(() => {
-    return tabsArray.value.filter(t => t.visible !== false)[tabCurrentIndex.value].id
+    return tabsArray.value
+      .filter(t => t.visible !== false)[tabCurrentIndex.value]
+      ?.id || tabCurrentIndex.value
   });
   const tabsArray = ref<TabControlItem[]>(options.tabs ?? []);
 

+ 47 - 12
src/pages/article/common/CommonCategoryHome.vue

@@ -4,14 +4,23 @@
     <!-- 分类 -->
     <template v-for="category in categoryDatas" :key="category.title">
       <HomeTitle 
+        v-if="category.showTitle"
         :title="category.title"
         :showMore="category.showMore !== false"
-        moreText="更多"
+        :moreText="category.moreText || '更多'"
         @clickMore="category.morePage" 
       />
+      <!--预制块-->
       <template v-if="category.type === 'CalendarBlock'">
-        <CalendarBlock />
+        <CalendarBlock v-bind="category.blockProps" />
       </template>
+      <template v-else-if="category.type === 'StatsBlock'">
+        <StatsBlock v-bind="category.blockProps" />
+      </template>
+      <template v-else-if="category.type === 'MapBlock'">
+        <MapCategoryBlock v-bind="category.blockProps" />
+      </template>
+      <!--通用列表-->
       <SimplePageContentLoader v-else-if="category.data" :loader="category.data" >
         <FlexCol>
           <template v-if="category.type === 'article'">
@@ -76,6 +85,30 @@
               />
             </FlexRow>
           </template>
+          <template v-else-if="category.type === 'small-grid2'">
+            <view class="d-flex flex-row justify-between flex-wrap">
+              <view 
+                v-for="(tab, k) in category.data.content.value"
+                :key="k"
+                class="grid4-item position-relative mb-3"
+                @click="category.detailsPage(tab)"
+              >
+                <text 
+                  class="tag bg-mask-white color-primary radius-l p-1 position-absolute size-s text-lines-1"
+                >
+                  {{ tab.title }}
+                </text> 
+                <Image
+                  width="100%"
+                  :height="250"
+                  :radius="15"
+                  :defaultImage="AppCofig.defaultImage"
+                  :src="tab.thumbnail || tab.image"
+                  mode="aspectFit"
+                />
+              </view>  
+            </view>
+          </template>
           <template v-else>
             <Box2LineImageRightShadow
               v-for="(item, i) in category.data.content.value"
@@ -98,10 +131,10 @@
 <script setup lang="ts">;
 import { type PropType } from 'vue';
 import { CommonContentApi, GetContentListItem, GetContentListParams } from '@/api/CommonContent';
-import { navCommonDetail, navCommonList, resolveCommonContentFormData, resolveCommonContentGetPageDetailUrlAuto, resolveCommonContentSolveProps, useHomeCommonCategoryBlock, type HomeCommonCategoryBlockProps, type IHomeCommonCategoryBlock } from './CommonContent';
+import { navCommonDetail, navCommonList, resolveCommonContentGetPageDetailUrlAuto, resolveCommonContentSolveProps, useHomeCommonCategoryBlock, type HomeCommonCategoryBlockProps, type IHomeCommonCategoryBlock } from '../common/CommonContent';
 import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
 import { navTo } from '@/components/utils/PageAction';
-import { DateUtils } from '@imengyu/imengyu-utils';
+import type { IHomeCommonCategoryListTabNestCategoryItemDefine } from './CommonCategoryDefine';
 import HomeTitle from '@/pages/parts/HomeTitle.vue';
 import SimplePageContentLoader from '@/common/components/SimplePageContentLoader.vue';
 import Box2LineImageRightShadow from '@/pages/parts/Box2LineImageRightShadow.vue';
@@ -110,16 +143,18 @@ import FlexCol from '@/components/layout/FlexCol.vue';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import CalendarBlock from '@/pages/travel/calendar/block.vue';
 import Box2LineLargeImageUserShadow from '@/pages/parts/Box2LineLargeImageUserShadow.vue';
-import type { IHomeCommonCategoryListTabListDataSolve } from '../data/CommonCategoryDefine';
+import StatsBlock from '@/pages/blocks/StatsBlock.vue';
+import MapCategoryBlock from '@/pages/blocks/MapBlock.vue';
+import Image from '@/components/basic/Image.vue';
+import AppCofig from '@/common/config/AppCofig';
 
-export interface CategoryDefine {
+export interface CategoryDefine extends Omit<IHomeCommonCategoryListTabNestCategoryItemDefine, 'type'> {
   title: string;
+  showTitle: boolean;
   content: CommonContentApi|IHomeCommonCategoryBlock|HomeCommonCategoryBlockProps|null;
-  type?: 'article'|'large-image2'|'horizontal-large'|'large-grid2'|'CalendarBlock'|undefined;
-  detailsPage?: string;
-  morePage?: string;
-  dataSolve?: IHomeCommonCategoryListTabListDataSolve[];
-  showMore?: boolean;
+  type?: 'article'|'large-image2'|'horizontal-large'|'large-grid2'
+    |'CalendarBlock'|'StatsBlock'|'MapBlock'|'CalendarBlock'
+    |undefined;
 }
 
 const props = defineProps({
@@ -178,7 +213,7 @@ const categoryDatas = props.categoryDefine.map(item => {
       },
       data: useSimpleDataLoader(async () => {
         let res = (await (item.content as CommonContentApi)
-          .getContentList(new GetContentListParams(), 1, 3))
+          .getContentList(new GetContentListParams(), 1, item.count || 4))
           .list;
         return resolveCommonContentSolveProps(res, item.dataSolve || []);;
       })

+ 7 - 82
src/pages/article/data/CommonCategoryDefine.ts

@@ -1,6 +1,9 @@
-import { type HomeCommonCategoryBlockProps } from "../common/CommonContent";
-import type { CommonListPageProps } from "../common/CommonListPage.vue";
-import { CommonCategoryDynamicDataSerializedApi, type IHomeCommonCategoryDropdownDynamicData, type IHomeCommonCategoryDynamicData } from "./CommonCategoryDynamicData";
+import type { IHomeCommonCategoryHomeDefine } from "./defines/Home";
+import type { IHomeCommonCategoryListDefine } from "./defines/List";
+
+export * from "./defines/Blocks";
+export * from "./defines/List";
+export * from "./defines/Home";
 
 //基础定义
 
@@ -11,85 +14,7 @@ export interface IHomeCommonCategoryDefine {
   page: {
     name: string,
     title: string,
-    content: IHomeCommonCategoryListDefine,
-  }[],
-}
-
-// 列表定义
-
-export interface IHomeCommonCategoryListDefine {
-  type: 'CommonList',
-  props: Omit<CommonListPageProps, 'load'|'tabs'> & {
-    tabs?: (IHomeCommonCategoryListTabDefine & {
-      text: string,
-      width?: number,
-      visible?: boolean,
-      detailsPage?: string,
-    })[],
-    dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
-    data?: IHomeCommonCategoryDynamicData,
-  },
-}
-export interface IHomeCommonCategoryListTabListDropdownDefine {
-  key: string,
-  text: string,
-  defaultValue?: string|number,
-  formQueryKey?: string,
-  addAll?: string,
-  data: IHomeCommonCategoryDropdownDynamicData,
-}
-export type IHomeCommonCategoryListTabListDataSolve = 'none'|'ich'|'common'|'date';
-export interface IHomeCommonCategoryListTabListDefine {
-  type: 'list',
-  data: IHomeCommonCategoryDynamicData,
-  dropdownDefines?: IHomeCommonCategoryListTabListDropdownDefine[],
-  dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
-}
-export interface IHomeCommonCategoryListTabJumpDefine {
-  type: 'jump',
-  url: string,
-  params?: Record<string, any>,
-}
-export interface IHomeCommonCategoryListTabNestCategoryDefine {
-  type: 'nestCategory',
-  categorys: {
-    visible?: boolean,
-    text: string,
-    type: string, 
-    itemType?: string,
-    data: IHomeCommonCategoryDynamicData,
-    morePage?: string,
-    detailsPage?: string,
-    count?: number,
-    dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
-    params?: Record<string, any>,
+    content: IHomeCommonCategoryListDefine|IHomeCommonCategoryHomeDefine,
   }[],
 }
-export type IHomeCommonCategoryListTabDefine = IHomeCommonCategoryListTabListDefine 
-  | IHomeCommonCategoryListTabJumpDefine 
-  | IHomeCommonCategoryListTabNestCategoryDefine;
 
-export function CommonCategoryListTabNestCategoryDataToContent(
-  data: IHomeCommonCategoryDynamicData,
-  define: IHomeCommonCategoryListTabNestCategoryDefine['categorys'][0],
-) {
-  if (!data)
-    return null;
-  switch (data.type) {
-    case 'serializedApi':
-      return CommonCategoryDynamicDataSerializedApi(data);
-    case 'request':
-      throw new Error(`未实现的动态数据接口 ${data.type}`);
-    case 'commonContent':
-      return {
-        title: define.text,
-        mainBodyColumnId: data.params.mainBodyColumnId,
-        modelId: data.params.modelId,
-        itemType: define.itemType,
-        detailsPage: define.detailsPage || 'byContent',
-        count: define.count,
-        params: define.params,
-        dataSolve: define.dataSolve || [],
-      } as HomeCommonCategoryBlockProps;
-  }
-}

+ 9 - 0
src/pages/article/data/CommonCategoryDynamicData.ts

@@ -25,6 +25,8 @@ import VictualsContent from "@/api/introduction/VictualsContent";
 import TeamsContent from "@/api/research/TeamsContent";
 import type { IHomeCommonCategoryListTabListDropdownDefine } from "./CommonCategoryDefine";
 
+//默认动态数据接口定义
+
 export interface IHomeCommonCategoryDynamicDataCommonContent {
   type: 'commonContent',
   url?: string,
@@ -51,6 +53,8 @@ export type IHomeCommonCategoryDynamicData = IHomeCommonCategoryDynamicDataCommo
   | IHomeCommonCategoryDynamicDataSerializedApi 
   | IHomeCommonCategoryDynamicDataRequest;
 
+// 下拉列表动态数据接口定义
+
 export interface IHomeCommonCategoryDropdownDynamicDataCommonContent {
   type: 'commonContent',
   url?: string,
@@ -79,6 +83,9 @@ export type IHomeCommonCategoryDropdownDynamicData =
   | IHomeCommonCategoryDropdownDynamicDataRequest
   | IHomeCommonCategoryDropdownStaticData;
 
+/**
+ * 动态数据序列化接口
+ */
 export function CommonCategoryDynamicDataSerializedApi(item: IHomeCommonCategoryDynamicDataSerializedApi) {
   switch (item.name) {
     case 'BulidingContent': return BulidingContent;
@@ -118,6 +125,8 @@ function CommonCategorDynamicDropDownValuesToParams(dropDownValues: (number|stri
   return params;
 }
 
+//加载接口
+
 export async function doLoadDynamicDropdownData(item: IHomeCommonCategoryDropdownDynamicData) {
   switch (item.type) {
     case 'commonContent':

+ 0 - 1
src/pages/article/data/CommonCategoryGlobalLoader.ts

@@ -1,5 +1,4 @@
 import { inject, provide, ref, type Ref } from "vue";
-import { requireNotNull } from "@imengyu/imengyu-utils";
 import NotConfigue from "@/api/NotConfigue";
 import { showError } from "@/common/composeabe/ErrorDisplay";
 import type { IHomeCommonCategoryDefine } from "./CommonCategoryDefine";

+ 16 - 8
src/pages/article/data/CommonCategoryList.vue

@@ -13,7 +13,7 @@
       :detailsPage="detailsPage"
     >
       <template #list="{ tabId }">
-        <CommonCategoryHome 
+        <CommonCategoryBlocks
           v-if="tabRenderDefines[tabId]?.type === 'nestCategory'" 
           :categoryDefine="tabRenderDefines[tabId].categoryDefine"
         />
@@ -28,16 +28,16 @@ import { computed, onMounted, ref, watch } from 'vue';
 import { injectCommonCategory } from './CommonCategoryGlobalLoader';
 import { navTo } from '@/components/utils/PageAction';
 import { doLoadDynamicDropdownData, doLoadDynamicListData } from './CommonCategoryDynamicData';
-import { CommonCategoryListTabNestCategoryDataToContent, type IHomeCommonCategoryDefine, type IHomeCommonCategoryListTabDefine } from './CommonCategoryDefine';
+import { CommonCategoryListTabNestCategoryDataToContent, type IHomeCommonCategoryDefine, type IHomeCommonCategoryListDefine, type IHomeCommonCategoryListTabDefine } from './CommonCategoryDefine';
+import { resolveCommonContentSolveProps } from '../common/CommonContent';
+import { waitTimeOut } from '@imengyu/imengyu-utils';
+import type { SimpleDropDownPickerItem } from '@/common/components/SimpleDropDownPicker.vue';
 import type { CommonListPageProps, DropDownNames } from '../common/CommonListPage.vue';
 import CommonListPage from '../common/CommonListPage.vue';
 import Result from '@/components/feedback/Result.vue';
-import CommonCategoryHome, { type CategoryDefine } from '../common/CommonCategoryHome.vue';
+import CommonCategoryBlocks, { type CategoryDefine } from './CommonCategoryBlocks.vue';
 import Footer from '@/components/display/Footer.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
-import { resolveCommonContentSolveProps } from '../common/CommonContent';
-import type { SimpleDropDownPickerItem } from '@/common/components/SimpleDropDownPicker.vue';
-import { waitTimeOut } from '@imengyu/imengyu-utils';
 
 /**
  * 动态通用内容 - 通用列表页
@@ -46,6 +46,7 @@ import { waitTimeOut } from '@imengyu/imengyu-utils';
 const loadState = ref(false);
 const errorMessage = ref('');
 const currentCommonCategoryDefine = ref<IHomeCommonCategoryDefine['page'][0]>();
+const currentCommonCategoryContentDefine = ref<IHomeCommonCategoryListDefine>();
 const commonCategory = injectCommonCategory();
 
 const props = defineProps({
@@ -74,6 +75,12 @@ async function loadPageConfig() {
     errorMessage.value = '未找到指定的分类配置:' + props.pageConfigName;
     return;
   }
+  if (currentCommonCategoryDefine.value.content.type !== 'CommonList') {
+    errorMessage.value = '分类配置:' + props.pageConfigName + ' 不是列表类型';
+    return;
+  }
+  currentCommonCategoryContentDefine.value = 
+    currentCommonCategoryDefine.value.content as IHomeCommonCategoryListDefine;
   uni.setNavigationBarTitle({
     title: currentCommonCategoryDefine.value?.title || '',
   })
@@ -118,7 +125,7 @@ type RenderTabDefine = IHomeCommonCategoryListTabDefine & {
   categoryDefine?: CategoryDefine[];  
 };
 
-const tabDefines = computed(() => currentCommonCategoryDefine.value?.content.props.tabs || []);
+const tabDefines = computed(() => currentCommonCategoryContentDefine.value?.props.tabs || []);
 const tabRenderDefines = computed(() => {
   const result = {} as Record<number, RenderTabDefine>;
   tabDefines.value.forEach((item, i) => {
@@ -137,6 +144,7 @@ const tabRenderDefines = computed(() => {
           .map((item) => {
             return {
               ...item,
+              showTitle: item.showTitle !== false,
               title: item.text,
               content: CommonCategoryListTabNestCategoryDataToContent(
                 item.data, item
@@ -196,7 +204,7 @@ const detailsPage = computed(() => {
     });
     return result;
   }
-  return currentCommonCategoryDefine.value?.content.props.detailsPage || undefined;
+  return currentCommonCategoryContentDefine.value?.props.detailsPage || undefined;
 });
 
 async function loadData(

+ 153 - 1
src/pages/article/data/DefaultCategory.json

@@ -1,6 +1,158 @@
 {
   "page": [
     {
+      "name": "home",
+      "title": "",
+      "content": {
+        "type": "Home",
+        "props": {
+          "title": "世界闽南文化交流中心",
+          "subTitle": "闽南文化生态保护区(厦门市)",
+          "homeBanner": "https://mncdn.wenlvti.net/app_static/minnan/images/home/BackgroundBanner5.jpg",
+          "homeButtons": [
+            {
+              "title": "常识一点通",
+              "icon": "https://mncdn.wenlvti.net/app_static/minnan/images/home/IconMap.png",
+              "size": 50,
+              "link": ["/pages/article/data/list", { "pageConfigName": "explore" }]
+            },
+            {
+              "title": "闽南新鲜事",
+              "icon": "https://mncdn.wenlvti.net/app_static/minnan/images/home/IconDoc.png",
+              "size": 50,
+              "link": ["/pages/introduction/news", {}]
+            },
+            {
+              "title": "遗产报你知",
+              "icon": "https://mncdn.wenlvti.net/app_static/minnan/images/home/IconIch.png",
+              "size": 50,
+              "link": ["/pages/introduction/inhert", {}]
+            },
+            {
+              "title": "文化新视角",
+              "icon": "https://mncdn.wenlvti.net/app_static/minnan/images/home/IconReserch.png",
+              "size": 50,
+              "link": ["/pages/article/data/list", { "pageConfigName": "research" }]
+            },
+            {
+              "title": "世界走透透",
+              "icon": "https://mncdn.wenlvti.net/app_static/minnan/images/home/IconArtifact.png",
+              "size": 50,
+              "link": ["/pages/article/data/list", { "pageConfigName": "communicate" }]
+            },
+            {
+              "title": "来厦门䢐迌",
+              "icon": "https://mncdn.wenlvti.net/app_static/minnan/images/home/IconDiscover.png",
+              "size": 50,
+              "link": ["/pages/article/data/list", { "pageConfigName": "travel" }]
+            }
+          ],
+          "categorys": [
+            {
+              "text": "数据统计",
+              "showTitle": false,
+              "blockProps" : {
+                "statsNameConfig": [
+                  {
+                    "name": "projects",
+                    "title": "非物质文化遗产代表性项目"
+                  },
+                  {
+                    "name": "inheritors",
+                    "title": "非物质文化遗产代表性传承人"
+                  },
+                  {
+                    "name": "ichCenter",
+                    "title": "ichCenter"
+                  },
+                  {
+                    "name": "historyData",
+                    "title": "重要相关历史风貌区"
+                  },
+                  {
+                    "name": "minnanCr",
+                    "title": "闽南文化重要相关文物古迹"
+                  }
+                ]
+              },
+              "type": "StatsBlock"
+            },
+            {
+              "text": "文化地图",
+              "blockProps" : {
+                "mapConfigItems": [
+                  {
+                    "title": "非遗项目",
+                    "icon": "icon-read",
+                    "data": {
+                      "type": "serializedApi",
+                      "name": "ProjectsContent"
+                    }
+                  },
+                  {
+                    "title": "非遗传习所",
+                    "icon": "icon-task-trip",
+                    "data": {
+                      "type": "serializedApi",
+                      "name": "SeminarContent"
+                    }
+                  },
+                  {
+                    "title": "文物古迹",
+                    "icon": "icon-task-buliding",
+                    "data": {
+                      "type": "serializedApi",
+                      "name": "UnmoveableContent"
+                    }
+                  },
+                  {
+                    "title": "传统村落",
+                    "icon": "icon-place",
+                    "data": {
+                      "type": "serializedApi",
+                      "name": "ProjectsContent"
+                    }
+                  },
+                  {
+                    "title": "闽南文化景区",
+                    "icon": "icon-task-environment-3",
+                    "data": {
+                      "type": "serializedApi",
+                      "name": "ProjectsContent"
+                    }
+                  }
+                ]
+              },
+              "morePage": "/pages/inhert/map/index",
+              "type": "MapBlock"
+            },
+            {
+              "text": "精彩推荐",
+              "data": {
+                "type": "serializedApi",
+                "name": "ProjectsContent"
+              },
+              "showMore": false,
+              "detailsPage": "/pages/inhert/intangible/details",
+              "dataSolve": [ "common" ],
+              "type": "small-grid2"
+            },
+            {
+              "text": "推荐文物",
+              "data": {
+                "type": "serializedApi",
+                "name": "UnmoveableContent"
+              },
+              "showTitle": false,
+              "detailsPage": "/pages/inhert/artifact/details",
+              "dataSolve": [ "common" ],
+              "type": "small-grid2"
+            }
+          ]
+        }
+      }
+    },
+    {
       "name": "explore",
       "title": "闽南百科",
       "content": {
@@ -422,7 +574,7 @@
               "url": "/pages/inhert/inheritor/list"
             },
             {
-              "text": "非遗传习所",
+              "text": "传习中心(",
               "type": "list",
               "data": {
                 "type": "serializedApi",

+ 24 - 0
src/pages/article/data/defines/Blocks.ts

@@ -0,0 +1,24 @@
+// 单元定义
+
+import type { IHomeCommonCategoryDynamicData } from "../CommonCategoryDynamicData"
+
+/**
+ * 首页统计栏目名称配置
+ */
+export interface IHomeCommonCategoryBlockStatsProps {
+  statsNameConfig: {
+    name: string,
+    title: string,
+    visible?: boolean,
+  }[]
+}
+
+export interface IHomeCommonCategoryBlockMapProps {
+  mapPage?: string,
+  mapConfigItems: {
+    title: string,
+    icon: string,
+    visible?: boolean,
+    data: IHomeCommonCategoryDynamicData
+  }[],
+}

+ 19 - 0
src/pages/article/data/defines/Home.ts

@@ -0,0 +1,19 @@
+// 首页列表定义
+
+import type { IHomeCommonCategoryListTabNestCategoryItemDefine } from "./List";
+
+export interface IHomeCommonCategoryHomeDefine {
+  type: 'Home',
+  props: {
+    title: string,
+    subTitle: string,
+    homeBanner: string,
+    homeButtons: {
+      title: string,
+      icon: string,
+      link: [string, object],
+      size: number
+    }[],
+    categorys: IHomeCommonCategoryListTabNestCategoryItemDefine[],
+  },
+}

+ 88 - 0
src/pages/article/data/defines/List.ts

@@ -0,0 +1,88 @@
+
+// 列表定义
+
+import type { HomeCommonCategoryBlockProps } from "../../common/CommonContent";
+import type { CommonListPageProps } from "../../common/CommonListPage.vue";
+import { CommonCategoryDynamicDataSerializedApi, type IHomeCommonCategoryDropdownDynamicData, type IHomeCommonCategoryDynamicData } from "../CommonCategoryDynamicData";
+
+export interface IHomeCommonCategoryListDefine {
+  type: 'CommonList',
+  props: Omit<CommonListPageProps, 'load'|'tabs'> & {
+    tabs?: (IHomeCommonCategoryListTabDefine & {
+      text: string,
+      width?: number,
+      visible?: boolean,
+      detailsPage?: string,
+    })[],
+    dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
+    data?: IHomeCommonCategoryDynamicData,
+  },
+}
+export interface IHomeCommonCategoryListTabListDropdownDefine {
+  key: string,
+  text: string,
+  defaultValue?: string|number,
+  formQueryKey?: string,
+  addAll?: string,
+  data: IHomeCommonCategoryDropdownDynamicData,
+}
+export type IHomeCommonCategoryListTabListDataSolve = 'none'|'ich'|'common'|'date';
+export interface IHomeCommonCategoryListTabListDefine {
+  type: 'list',
+  data: IHomeCommonCategoryDynamicData,
+  dropdownDefines?: IHomeCommonCategoryListTabListDropdownDefine[],
+  dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
+}
+export interface IHomeCommonCategoryListTabJumpDefine {
+  type: 'jump',
+  url: string,
+  params?: Record<string, any>,
+}
+export interface IHomeCommonCategoryListTabNestCategoryDefine {
+  type: 'nestCategory',
+  categorys: IHomeCommonCategoryListTabNestCategoryItemDefine[],
+}
+export interface IHomeCommonCategoryListTabNestCategoryItemDefine {
+  visible?: boolean,
+  text: string,
+  showTitle?: boolean,
+  showMore?: boolean,
+  moreText?: string,
+  type: string,
+  itemType?: string,
+  data: IHomeCommonCategoryDynamicData,
+  morePage?: string,
+  detailsPage?: string,
+  count?: number,
+  dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
+  params?: Record<string, any>,
+  blockProps?: any;
+}
+export type IHomeCommonCategoryListTabDefine = IHomeCommonCategoryListTabListDefine 
+  | IHomeCommonCategoryListTabJumpDefine 
+  | IHomeCommonCategoryListTabNestCategoryDefine;
+
+export function CommonCategoryListTabNestCategoryDataToContent(
+  data: IHomeCommonCategoryDynamicData,
+  define: IHomeCommonCategoryListTabNestCategoryDefine['categorys'][0],
+) {
+  if (!data)
+    return null;
+  switch (data.type) {
+    case 'serializedApi':
+      return CommonCategoryDynamicDataSerializedApi(data);
+    case 'request':
+      throw new Error(`未实现的动态数据接口 ${data.type}`);
+    case 'commonContent':
+      return {
+        title: define.text,
+        mainBodyColumnId: data.params.mainBodyColumnId,
+        modelId: data.params.modelId,
+        itemType: define.itemType,
+        detailsPage: define.detailsPage || 'byContent',
+        count: define.count,
+        params: define.params,
+        dataSolve: define.dataSolve || [],
+      } as HomeCommonCategoryBlockProps;
+  }
+}

+ 91 - 0
src/pages/blocks/MapBlock.vue

@@ -0,0 +1,91 @@
+<template>
+  <view class="position-relative radius-l overflow-hidden">
+    <map 
+      id="map"
+      mapId="map"
+      class="w-100 height-400"
+      :markers="mapLoader.content.value || []"
+      :enable-zoom="false"
+      :enable-scroll="false"
+      :longitude="AppCofig.defaultLonLat[0]"
+      :latitude="AppCofig.defaultLonLat[1]"
+      :scale="15"
+      @click="navTo(
+        props.mapPage || '/pages/inhert/map/index', 
+        { tab: mapTab }
+      )"
+    />
+    <scroll-view class="map-tags position-absolute" :scroll-x="true">
+      <view class="tag-bar d-flex flex-row flex-nowrap">
+        <view 
+          v-for="item in mapButtons" :key="item.id"
+          :class="mapTab == item.id ? 'active' : ''"
+          @click="mapTab=item.id"
+        >
+          <text :class="`iconfont ${item.icon}`" />
+          {{ item.title }}
+        </view>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
+import { navTo } from '@/components/utils/PageAction';
+import { computed, getCurrentInstance, ref, watch } from 'vue';
+import { doLoadDynamicListData } from '../article/data/CommonCategoryDynamicData';
+import type { IHomeCommonCategoryBlockMapProps } from '../article/data/CommonCategoryDefine';
+import AppCofig from '@/common/config/AppCofig';
+import { waitTimeOut } from '@imengyu/imengyu-utils';
+
+const props = defineProps<IHomeCommonCategoryBlockMapProps>();
+const instance = getCurrentInstance();
+const mapCtx = uni.createMapContext('map', instance);
+const mapTab = ref(0);
+
+const mapButtons = computed(() => {
+  return props.mapConfigItems
+    .filter(item => item.visible !== false)
+    .map((item, i) => ({
+      ...item,
+      id: i,
+    }));
+})
+const mapLoader = useSimpleDataLoader(async () => {
+  let list = (await doLoadDynamicListData(
+    props.mapConfigItems[mapTab.value].data,
+    1, 6, '', [], []
+  ))?.list || [];
+  const res = list.map((p) => {
+    return {
+      title: p.title || p.name,
+      id: p.id,
+      longitude: Number(p.longitude),
+      latitude: Number(p.latitude),
+      iconPath: p.thumbnail,
+      width: 40,
+      height: 40,
+    };
+  });
+  await waitTimeOut(200);
+  mapCtx.includePoints({
+    points: res.map(p => {
+      if (!p.longitude || !p.latitude) {
+        p.longitude = AppCofig.defaultLonLat[0];
+        p.latitude = AppCofig.defaultLonLat[1];
+      }
+      return {
+        latitude: p.latitude,
+        longitude: p.longitude,
+      }
+    }),
+    padding: [20, 20, 20, 20],
+  });
+  console.log(res);
+  return res;
+}, true, undefined, true);
+
+watch(mapTab, () => mapLoader.loadData(undefined, true));
+
+</script>

+ 163 - 0
src/pages/blocks/StatsBlock.vue

@@ -0,0 +1,163 @@
+<template>
+  <!-- 数据统计 -->
+  <SimplePageContentLoader :loader="statsLoader">
+    <view v-if="statsLoader.content.value" class="d-flex flex-col justify-center mt-3 pt-3 pb-3 bg-light-page radius-base">
+      <view class="d-flex flex-col">
+        <StatsText
+          :title="statsLoader.content.value[0].title" 
+          :data="statsLoader.content.value[0].datas" 
+          :type="statsLoader.content.value[0].type" 
+        />
+        <view class="p-2">
+          <HorizontalScrollText :text="statsText1" :fontSize="26" color="text.second" :outerStyle="{ height: '40rpx' }" />
+        </view>
+      </view>
+      <view class="border-top-light-primary pt-2 mt-3"></view>
+      <view class="d-flex flex-col">
+        <StatsText
+          :title="statsLoader.content.value[1].title" 
+          :data="statsLoader.content.value[1].datas" 
+          :type="statsLoader.content.value[1].type" 
+        />
+        <view class="p-2">
+          <HorizontalScrollText :text="statsText2" :fontSize="26" color="text.second" :outerStyle="{ height: '40rpx' }" />
+        </view>
+      </view>
+      <view class="border-top-light-primary pt-2 mt-3"></view>
+      <StatsText
+        :title="statsLoader.content.value[2].title" 
+        :data="statsLoader.content.value[2].datas" 
+        :type="statsLoader.content.value[2].type" 
+      />
+      <view class="border-top-light-primary pt-2 mt-3"></view>
+      <StatsText
+        :title="statsLoader.content.value[3].title" 
+        :data="statsLoader.content.value[3].datas" 
+        :type="statsLoader.content.value[3].type" 
+      />
+      <view class="border-top-light-primary pt-2 mt-3"></view>
+      <StatsText
+        :title="statsLoader.content.value[4].title" 
+        :data="statsLoader.content.value[4].datas" 
+        :type="statsLoader.content.value[4].type" 
+      />
+    </view>
+  </SimplePageContentLoader>
+</template>
+
+<script setup lang="ts">
+import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
+import { navTo } from '@/components/utils/PageAction';
+import { ref } from 'vue';
+import { navCommonList } from '../article/common/CommonContent';
+import type { StatsTextItem } from '../parts/StatsText.vue';
+import type { IHomeCommonCategoryBlockStatsProps } from '../article/data/CommonCategoryDefine';
+import SimplePageContentLoader from '@/common/components/SimplePageContentLoader.vue';
+import StatsText from '../parts/StatsText.vue';
+import HorizontalScrollText from '@/components/typography/HorizontalScrollText.vue';
+import IndexContent from '@/api/introduction/IndexContent';
+
+const props = defineProps<IHomeCommonCategoryBlockStatsProps>()
+
+const statsText1 = ref('');
+const statsText2 = ref('');
+const statsLoader = useSimpleDataLoader(async () => {
+  const data = (await IndexContent.getStats());
+
+  let sumInheritor = 0;
+  let sumProject = 0;
+  const topLevelProject = data.ichData.find((p: any) => p.level_text == '人类非遗')?.total || 0;
+  const secondLevelProject = data.ichData.find((p: any) => p.level_text == '国家级')?.total || 0;
+  const thirdLevelProject = data.ichData.find((p: any) => p.level_text == '省级')?.total || 0;
+  const forthLevelProject = data.ichData.find((p: any) => p.level_text == '市级')?.total || 0;
+
+  const topLevelInheritor = data.inheritorData.find((p: any) => p.level_text == '国家级')?.total || 0;
+  const secondLevelInheritor = data.inheritorData.find((p: any) => p.level_text == '省级')?.total || 0;
+  const thirdLevelInheritor = data.inheritorData.find((p: any) => p.level_text == '市级')?.total || 0;
+
+  const projects = (data.ichData as any[]).filter((p: any) => [ '人类非遗', '国家级', '省级', '市级' ].includes(p.level_text)).map((item: any) => {
+    if (item.level_text != '人类非遗')
+      sumProject += item.total;
+    return {
+      title: item.level_text,
+      value: item.total,
+      titleSuffix: '项',
+      type: 'forth',
+      onClick: () => navTo('/pages/article/data/list', { pageConfigName: 'intangible', tab: 0, level: item.level }),
+    } as StatsTextItem
+  });
+  const inheritors = data.inheritorData.filter((p: any) => [ '国家级', '省级', '市级' ].includes(p.title)).map((item: any) => {
+    sumInheritor += item.total;
+    return {
+      title: item.title,
+      value: item.total,
+      titleSuffix: '人',
+      type: 'normal',
+      onClick: () => navTo('/pages/inhert/inheritor/list', { level: item.level }),
+    }
+  });
+
+  statsText1.value = `目前厦门市非遗项目市级以上共有 ${sumProject} 项,其中:国家级 ${secondLevelProject} 项(含 ${topLevelProject} 项为人类非遗)、省级 ${thirdLevelProject} 项、市级 ${forthLevelProject} 项。`;
+  statsText2.value = `目前厦门市非遗传承人市级以上共有 ${sumInheritor} 人,其中:国家级 ${topLevelInheritor} 人、省级 ${secondLevelInheritor} 人、市级 ${thirdLevelInheritor} 人。`;
+
+  const dataMap  = {
+    projects,
+    inheritors,
+    ichCenter: data.ichCenter.map((item: any) => {
+      return {
+        title: item.title,
+        value: item.total,
+        titleSuffix: '处',
+        type: 'normal',
+        onClick: () => navTo('/pages/inhert/seminar/list', { region: item.id }),
+      }
+    }),
+    historyData: data.historyData.map((item: any) => {
+      return {
+        title: item.title,
+        value: item.total,
+        titleSuffix: '处',
+        onClick: () => {
+          switch (item.title) {
+            case '世界文化遗产':
+              navCommonList({
+                title: '世界文化遗产',
+                modelId: 17,
+                mainBodyColumnId: 310
+              });
+              break;
+            case '传统村落':
+              navTo('/pages/inhert/village/list');
+              break;
+            case '重点区域':
+              navCommonList({
+                title: '重点区域',
+                modelId: 17,
+                mainBodyColumnId: 283
+              });
+              break;
+          }
+        },
+      }
+    }),
+    minnanCr: data.minnanCr.map((item: any) => {
+      return {
+        title: item.title,
+        value: item.total,
+        titleSuffix: '处',
+        onClick: () => navTo('/pages/inhert/artifact/list', {
+          level: item.level
+        }),
+      }
+    }),
+  } as Record<string, StatsTextItem[]>;
+
+  return props.statsNameConfig.map((item: any) => {
+    return {
+      ...item,
+      datas: dataMap[item.name],
+    }
+  });
+});
+
+</script>

+ 53 - 350
src/pages/home/index.vue

@@ -3,7 +3,7 @@
     <Image 
       innerClass="main-banner position-absolute"
       width="100%"
-      src="https://mncdn.wenlvti.net/app_static/minnan/images/home/BackgroundBanner5.jpg"
+      :src="pageContentDefine?.props.homeBanner"
       mode="widthFix"
     />
     <view class="content d-flex flex-col wing-l">
@@ -17,8 +17,16 @@
         <view 
           class="main-banner-box mb-25"
         >
-          <text class="title">世界闽南文化交流中心</text>
-          <text>闽南文化生态保护区(厦门市)</text>
+          <Image 
+            innerClass="logo"
+            src="https://mncdn.wenlvti.net/app_static/minnan/images/home/MainLogo.png"
+            :width="150"
+            mode="widthFix"
+          />
+          <view>
+            <text class="title">{{pageContentDefine?.props.title || ''}}</text>
+            <text>{{pageContentDefine?.props.subTitle || ''}}</text>
+          </view>
           <Image 
             innerClass="footer"
             src="https://mncdn.wenlvti.net/app_static/minnan/images/home/MainBanner2.png"
@@ -29,43 +37,14 @@
         
         <view class="position-relative d-flex flex-row flex-wrap justify-between mt-25 row-gap-sss">
           <HomeButton
-            title="常识一点通"
-            icon="https://mncdn.wenlvti.net/app_static/minnan/images/home/IconMap.png"
-            :size="50"
-            @click="navTo('/pages/article/data/list', { pageConfigName: 'explore' })"
-          />
-          <HomeButton
-            title="闽南新鲜事"
-            icon="https://mncdn.wenlvti.net/app_static/minnan/images/home/IconDoc.png"
-            :size="50"
-            @click="navTo('/pages/introduction/news')"
-          />
-          <HomeButton
-            title="遗产报你知"
-            icon="https://mncdn.wenlvti.net/app_static/minnan/images/home/IconIch.png"
-            :size="50"
-            @click="navTo('/pages/introduction/inhert')"
-          />
-          <HomeButton
-            title="文化新视角"
-            icon="https://mncdn.wenlvti.net/app_static/minnan/images/home/IconReserch.png"
-            :size="50"
-            @click="navTo('/pages/article/data/list', { pageConfigName: 'research' })"
-          />
-          <HomeButton
-            title="世界走透透"
-            icon="https://mncdn.wenlvti.net/app_static/minnan/images/home/IconArtifact.png"
-            :size="50"
-            @click="navTo('/pages/article/data/list', { pageConfigName: 'communicate' })"
-          />
-          <HomeButton
-            title="来厦门䢐迌"
-            icon="https://mncdn.wenlvti.net/app_static/minnan/images/home/IconDiscover.png"
-            :size="50"
-            @click="navTo('/pages/article/data/list', { pageConfigName: 'travel' })"
+            v-for="item in pageContentDefine?.props.homeButtons || []"
+            :key="item.title"
+            :title="item.title"
+            :icon="item.icon"
+            :size="item.size"
+            @click="navTo(item.link[0], item.link[1] as Record<string, unknown>)"
           />
         </view>
-
         <view class="position-relative d-flex flex-row flex-wrap justify-between mt-3">
           <Box1AudioPlay
             class="w-100" 
@@ -82,193 +61,44 @@
         </view>
       </view>
 
-      <!-- 数据统计 -->
-      <SimplePageContentLoader :loader="statsLoader">
-        <view v-if="statsLoader.content.value" class="d-flex flex-col justify-center mt-3 pt-3 pb-3 bg-light-page radius-base">
-          <view class="d-flex flex-col">
-            <StatsText
-              :title="statsLoader.content.value[0].title" 
-              :data="statsLoader.content.value[0].datas" 
-              :type="statsLoader.content.value[0].type" 
-            />
-            <view class="p-2">
-              <HorizontalScrollText :text="statsText1" :fontSize="26" color="text.second" :outerStyle="{ height: '40rpx' }" />
-            </view>
-          </view>
-          <view class="border-top-light-primary pt-2 mt-3"></view>
-          <view class="d-flex flex-col">
-            <StatsText
-              :title="statsLoader.content.value[1].title" 
-              :data="statsLoader.content.value[1].datas" 
-              :type="statsLoader.content.value[1].type" 
-            />
-            <view class="p-2">
-              <HorizontalScrollText :text="statsText2" :fontSize="26" color="text.second" :outerStyle="{ height: '40rpx' }" />
-            </view>
-          </view>
-          <view class="border-top-light-primary pt-2 mt-3"></view>
-          <StatsText
-            :title="statsLoader.content.value[2].title" 
-            :data="statsLoader.content.value[2].datas" 
-            :type="statsLoader.content.value[2].type" 
-          />
-          <view class="border-top-light-primary pt-2 mt-3"></view>
-          <StatsText
-            :title="statsLoader.content.value[3].title" 
-            :data="statsLoader.content.value[3].datas" 
-            :type="statsLoader.content.value[3].type" 
-          />
-          <view class="border-top-light-primary pt-2 mt-3"></view>
-          <StatsText
-            :title="statsLoader.content.value[4].title" 
-            :data="statsLoader.content.value[4].datas" 
-            :type="statsLoader.content.value[4].type" 
-          />
-        </view>
-      </SimplePageContentLoader>
-
-      <!-- 文化地图 -->
-      <HomeTitle title="文化地图" />
-      <view class="position-relative radius-l overflow-hidden">
-        <map 
-          id="map"
-          class="w-100 height-400"
-          :markers="mapLoader.content.value || []"
-          :enable-zoom="false"
-          :enable-scroll="false"
-          :scale="15"
-          @click="navTo('/pages/inhert/map/index', { tab: mapTab })"
-        />
-        <scroll-view class="map-tags position-absolute" :scroll-x="true">
-          <view class="tag-bar d-flex flex-row flex-nowrap">
-            <view :class="mapTab == 1 ? 'active' : ''" @click="mapTab=1">
-              <text class="iconfont icon-read" />
-              非遗项目
-            </view>
-            <view :class="mapTab == 2 ? 'active' : ''" @click="mapTab=2">
-              <text class="iconfont icon-task-trip" />
-              非遗传习所
-            </view>
-            <view :class="mapTab == 3 ? 'active' : ''" @click="mapTab=3">
-              <text class="iconfont icon-task-buliding" />
-              文物古迹
-            </view>
-            <view :class="mapTab == 4 ? 'active' : ''" @click="mapTab=4">
-              <text class="iconfont icon-place" />
-              传统村落
-            </view>
-            <view :class="mapTab == 5 ? 'active' : ''" @click="mapTab=5">
-              <text class="iconfont icon-task-environment-3" />
-              闽南文化景区
-            </view>
-          </view>
-        </scroll-view>
-      </view>
-      
-      <!-- 精彩推荐 -->
-      <HomeTitle title="精彩推荐" />
-      <SimplePageContentLoader :loader="recommendLoader">
-        <view class="d-flex flex-row justify-between flex-wrap">
-          <view 
-            v-for="(tab, k) in recommendLoader.content.value"
-            :key="k"
-            class="grid4-item position-relative mb-3"
-            @click="handleGoDetails(tab)"
-          >
-            <text 
-              class="tag bg-mask-white color-primary radius-l p-1 position-absolute size-s text-lines-1"
-            >
-              {{ tab.title }}
-            </text> 
-            <Image
-              width="100%"
-              :height="250"
-              :radius="15"
-              :src="tab.thumbnail || tab.image || AppCofig.defaultImage"
-              mode="aspectFit"
-            />
-          </view>
-        </view>
-      </SimplePageContentLoader>
+      <CommonCategoryBlocks :categoryDefine="categoryDefine" />
     </view>
   </view>
   <Tabbar :current="0" />
 </template>
 
 <script setup lang="ts">
-import { ref, watch } from 'vue';
+import { computed } from 'vue';
 import { onShareTimeline, onShareAppMessage } from '@dcloudio/uni-app';
 import { navTo } from '@/components/utils/PageAction';
-import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
 import { useSimpleListAudioPlayer } from '@/common/composeabe/SimpleAudioPlayer';
-import { navCommonList } from '@/pages/article/common/CommonContent';
+import { injectCommonCategory } from '../article/data/CommonCategoryGlobalLoader';
+import { CommonCategoryListTabNestCategoryDataToContent, type IHomeCommonCategoryHomeDefine } from '../article/data/CommonCategoryDefine';
 import CommonContent, { GetContentListParams } from '@/api/CommonContent';
-import UnmoveableContent from '@/api/inheritor/UnmoveableContent';
-import SeminarContent from '@/api/inheritor/SeminarContent';
-import ProjectsContent from '@/api/inheritor/ProjectsContent';
-import AppCofig from '@/common/config/AppCofig';
-import VillageApi from '@/api/inhert/VillageApi';
-import ScenicSpotContent from '@/api/fusion/ScenicSpotContent';
-import IndexContent from '@/api/introduction/IndexContent';
-import StatsText, { type StatsTextItem } from '../parts/StatsText.vue';
-import HomeTitle from '@/pages/parts/HomeTitle.vue'; 
 import Tabbar from '@/common/components/tabs/Tabbar.vue';
 import Box1AudioPlay from '@/pages/parts/Box1AudioPlay.vue';
-import SimplePageContentLoader from "@/common/components/SimplePageContentLoader.vue";
-import HorizontalScrollText from '@/components/typography/HorizontalScrollText.vue';
 import Image from '@/components/basic/Image.vue';
 import HomeButton from '../parts/HomeButton.vue';
+import CommonCategoryBlocks, { type CategoryDefine } from '../article/data/CommonCategoryBlocks.vue';
 
-const mapCtx = uni.createMapContext('map');
-const mapTab = ref(1);
-const mapLoader = useSimpleDataLoader(async () => {
-  let list ;
-  switch (mapTab.value) {
-    default:
-    case 1:
-      list = (await ProjectsContent.getContentList(new GetContentListParams(), 1, 6)).list
-      break;
-    case 2:
-      list = (await SeminarContent.getContentList(new GetContentListParams(), 1, 6)).list
-      break;
-    case 3:
-      list = (await UnmoveableContent.getContentList(new GetContentListParams(), 1, 6)).list
-      break;
-    case 4:
-      list = (await VillageApi.getVallageList()).slice(1, 10)
-      break;
-    case 5:
-      list = (await ScenicSpotContent.getContentList(new GetContentListParams(), 1, 6)).list
-      break;
-  }  
-  const res = list.map((p) => {
-    return {
-      ...p,
-      id: p.id,
-      longitude: Number(p.longitude),
-      latitude: Number(p.latitude),
-      iconPath: p.thumbnail,
-      width: 40,
-      height: 40,
-    };
-  });
-  mapCtx.includePoints({
-    points: res.map(p => {
-      if (!p.longitude || !p.latitude) {
-        p.longitude = AppCofig.defaultLonLat[0];
-        p.latitude = AppCofig.defaultLonLat[1];
-      }
-      return {
-        latitude: p.latitude,
-        longitude: p.longitude,
-      }
-    }),
-    padding: [20, 20, 20, 20],
-  });
-  return res;
-}, true, undefined, true);
+const commonCategory = injectCommonCategory();
+const pageDefine = computed(() => commonCategory.value.page.find((p) => p.name === 'home'));
+const pageContentDefine = computed(() => pageDefine.value?.content as IHomeCommonCategoryHomeDefine);
 
-watch(mapTab, () => mapLoader.loadData(undefined, true));
+const categoryDefine = computed(() => pageContentDefine.value?.props.categorys
+  .filter((item) => item.visible !== false)
+  .map((item) => {
+    return {
+      ...item,
+      showTitle: item.showTitle !== false,
+      title: item.text,
+      content: CommonCategoryListTabNestCategoryDataToContent(
+        item.data, item
+      ),
+      type: item.type as CategoryDefine['type'],
+    }
+  })
+);
 
 const indexAudioPlayer = useSimpleListAudioPlayer(async () => {
   return (await CommonContent.getContentList(new GetContentListParams()
@@ -287,147 +117,7 @@ function handleGoAudioList() {
   navTo('/pages/inhert/language/list') 
 }
 
-const recommendLoader = useSimpleDataLoader(async () => {
-  const list = [];
-  list.push(...(await ProjectsContent.getContentList(new GetContentListParams(), 1, 6)).list.map((p) => {
-    p.itemType = 'intangible';
-    return p;
-  }));
-  list.push(...(await CommonContent.getContentList(new GetContentListParams()
-    .setModelId(1)
-  , 1, 6)).list.map((p) => {
-    p.itemType = p.type == GetContentListParams.TYPE_VIDEO ? 'video' : 'artifact';
-    return p;
-  }));
-  return list;
-});
-const statsText1 = ref('');
-const statsText2 = ref('');
-const statsLoader = useSimpleDataLoader(async () => {
-  const data = (await IndexContent.getStats());
-
-  let sumInheritor = 0;
-  let sumProject = 0;
-  const topLevelProject = data.ichData.find((p: any) => p.level_text == '人类非遗')?.total || 0;
-  const secondLevelProject = data.ichData.find((p: any) => p.level_text == '国家级')?.total || 0;
-  const thirdLevelProject = data.ichData.find((p: any) => p.level_text == '省级')?.total || 0;
-  const forthLevelProject = data.ichData.find((p: any) => p.level_text == '市级')?.total || 0;
-
-  const topLevelInheritor = data.inheritorData.find((p: any) => p.level_text == '国家级')?.total || 0;
-  const secondLevelInheritor = data.inheritorData.find((p: any) => p.level_text == '省级')?.total || 0;
-  const thirdLevelInheritor = data.inheritorData.find((p: any) => p.level_text == '市级')?.total || 0;
-
-  const projects = (data.ichData as any[]).filter((p: any) => [ '人类非遗', '国家级', '省级', '市级' ].includes(p.level_text)).map((item: any) => {
-    if (item.level_text != '人类非遗')
-      sumProject += item.total;
-    return {
-      title: item.level_text,
-      value: item.total,
-      titleSuffix: '项',
-      type: 'forth',
-      onClick: () => navTo('/pages/article/data/list', { pageConfigName: 'intangible', tab: 0, level: item.level }),
-    } as StatsTextItem
-  });
-  const inheritors = data.inheritorData.filter((p: any) => [ '国家级', '省级', '市级' ].includes(p.title)).map((item: any) => {
-    sumInheritor += item.total;
-    return {
-      title: item.title,
-      value: item.total,
-      titleSuffix: '人',
-      type: 'normal',
-      onClick: () => navTo('/pages/inhert/inheritor/list', { level: item.level }),
-    }
-  });
-
-  statsText1.value = `目前厦门市非遗项目市级以上共有 ${sumProject} 项,其中:国家级 ${secondLevelProject} 项(含 ${topLevelProject} 项为人类非遗)、省级 ${thirdLevelProject} 项、市级 ${forthLevelProject} 项。`;
-  statsText2.value = `目前厦门市非遗传承人市级以上共有 ${sumInheritor} 人,其中:国家级 ${topLevelInheritor} 人、省级 ${secondLevelInheritor} 人、市级 ${thirdLevelInheritor} 人。`;
-
-  return [
-    {
-      title: '非物质文化遗产代表性项目',
-      datas: projects
-    },
-    {
-      title: '非物质文化遗产代表性传承人',
-      datas: inheritors
-    },
-    {
-      title: '非物质文化遗产传习中心',
-      datas: data.ichCenter.map((item: any) => {
-        return {
-          title: item.title,
-          value: item.total,
-          titleSuffix: '处',
-          type: 'normal',
-          onClick: () => navTo('/pages/inhert/seminar/list', { region: item.id }),
-        }
-      }),
-    },
-    {
-      title: '重要相关历史风貌区',
-      datas: data.historyData.map((item: any) => {
-        return {
-          title: item.title,
-          value: item.total,
-          titleSuffix: '处',
-          onClick: () => {
-            switch (item.title) {
-              case '世界文化遗产':
-                navCommonList({
-                  title: '世界文化遗产',
-                  modelId: 17,
-                  mainBodyColumnId: 310
-                });
-                break;
-              case '传统村落':
-                navTo('/pages/inhert/village/list');
-                break;
-              case '重点区域':
-                navCommonList({
-                  title: '重点区域',
-                  modelId: 17,
-                  mainBodyColumnId: 283
-                });
-                break;
-            }
-          },
-        }
-      }),
-    },
-    {
-      title: '闽南文化重要相关文物古迹',
-      type: 'none',
-      datas: data.minnanCr.map((item: any) => {
-        return {
-          title: item.title,
-          value: item.total,
-          titleSuffix: '处',
-          onClick: () => navTo('/pages/inhert/artifact/list', {
-            level: item.level
-          }),
-        }
-      }),
-    },
-  ]
 
-});
-
-function handleGoDetails(item: any) {
-  switch (item.itemType) {
-    case 'artifact': 
-      navTo('/pages/inhert/artifact/details', { id: item.id });
-      break;
-    case 'intangible': 
-      navTo('/pages/inhert/intangible/details', { id: item.id });
-      break;
-    case 'video': 
-      navTo('/pages/video/details', { id: item.id, modelId: item.modelId, mainBodyColumnId: item.mainBodyColumnId });
-      break;
-    default:
-      navTo('/pages/article/details', { id: item.id, modelId: item.modelId, mainBodyColumnId: item.mainBodyColumnId });
-      break;
-  }
-}
 
 onShareTimeline(() => {
   return {}; 
@@ -489,7 +179,9 @@ onShareAppMessage(() => {
   .main-banner-box {
     position: relative;
     display: flex;
-    flex-direction: column;
+    flex-direction: row;
+    align-items: center;
+    justify-content: space-between;
     overflow: hidden;
     border-radius: 15rpx;
     background: linear-gradient(180deg, #E5CDAB 0%, #F0E3D6 100%), #F7F3E8;
@@ -497,6 +189,16 @@ onShareAppMessage(() => {
     font-family: "SongtiSCBlack";
     color: #432A04;
 
+    > view {
+      display: flex;
+      flex-direction: column;
+    }
+
+    .logo {
+      margin-left: -20rpx;
+      margin-right: 0rpx;
+    }
+    
     .title {
       font-size: 40rpx;
     }
@@ -527,6 +229,7 @@ onShareAppMessage(() => {
       width: 180rpx;
       z-index: 2;
       height: auto;
+      opacity: 0.4;
     }
   }
 }