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

📦 通用内容列表页核心修改,修改问题

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

+ 5 - 3
src/common/components/SimpleDropDownPicker.vue

@@ -38,8 +38,10 @@ const emit = defineEmits([
 
 const show = ref(false);
 const dispayText = computed(() => {
-  if (props.columns) 
-    return props.columns.find(item => item.id == props.modelValue)?.name || props.defaultText;
+  if (props.columns)  {
+    return props.columns.find(item => item.id == props.modelValue)?.name 
+      || props.defaultText;
+  }
   return props.defaultText;
 });
 const selectedIndex = computed(() => {
@@ -51,7 +53,7 @@ const selectedIndex = computed(() => {
 
 function bindPickerChange(e:{ detail: { value: number }}) {
   show.value = false;
-  emit('update:modelValue', props.columns?.[e.detail.value].id || null);
+  emit('update:modelValue', props.columns?.[e.detail.value]?.id ?? null);
 }
 </script>
 

+ 3 - 0
src/common/composeabe/LoadQuerys.ts

@@ -11,9 +11,11 @@ export function useLoadQuerys<T extends Record<string, any>>(
   afterLoad?: (querys: T) => void
 ) {
   const querys = ref<T>(defaults) as Ref<T>; 
+  const rawQuerys = ref({}) as Ref<Record<string, any>>; 
 
   onLoad((_querys) => {
     if (_querys) {
+      rawQuerys.value = _querys;
       for (const key in querys.value) {
         if (typeof defaults[key] === 'number')
           (querys.value as Record<string, any>)[key] = Number(_querys[key]); 
@@ -32,6 +34,7 @@ export function useLoadQuerys<T extends Record<string, any>>(
 
   return {
     querys,
+    rawQuerys,
   }
 }
 

+ 0 - 7
src/pages.json

@@ -47,13 +47,6 @@
       }
     },
     {
-      "path": "pages/introduction/food/list",
-      "style": {
-        "navigationBarTitleText": "闽南美食",
-        "enablePullDownRefresh": true
-      }
-    },
-    {
       "path": "pages/introduction/custom/list",
       "style": {
         "navigationBarTitleText": "闽南民俗",

+ 18 - 24
src/pages/article/common/CommonCategoryHome.vue

@@ -21,7 +21,7 @@
               :title="item.title"
               :desc="item.desc"
               :tags="(item.bottomTags as string[])"
-              @click="category.detailPage(item)"
+              @click="category.detailsPage(item)"
             />
           </template>
           <template v-else-if="category.type === 'large-image2'">
@@ -38,7 +38,7 @@
                   :desc="item.desc"
                   :image="item.image"
                   :tags="(item.bottomTags as string[])"
-                  @click="category.detailPage(item)"
+                  @click="category.detailsPage(item)"
                 />
               </FlexRow>
             </scroll-view>
@@ -56,7 +56,7 @@
                   :title="item.title"
                   :desc="item.desc"
                   :image="item.thumbnail || item.image"
-                  @click="category.detailPage(item)"
+                  @click="category.detailsPage(item)"
                 />
               </view>
             </scroll-view>
@@ -72,7 +72,7 @@
                 :title="item.title"
                 :desc="item.desc"
                 :image="item.image"
-                @click="category.detailPage(item)"
+                @click="category.detailsPage(item)"
               />
             </FlexRow>
           </template>
@@ -86,7 +86,7 @@
               :desc="item.desc"
               :image="item.image"
               :tags="(item.bottomTags as string[])"
-              @click="category.detailPage(item)"
+              @click="category.detailsPage(item)"
             />
           </template>
         </FlexCol>
@@ -98,7 +98,7 @@
 <script setup lang="ts">;
 import { type PropType } from 'vue';
 import { CommonContentApi, GetContentListItem, GetContentListParams } from '@/api/CommonContent';
-import { navCommonDetail, navCommonList, resolveCommonContentFormData, resolveCommonContentGetPageDetailUrlAuto, useHomeCommonCategoryBlock, type HomeCommonCategoryBlockProps, type IHomeCommonCategoryBlock } from './CommonContent';
+import { navCommonDetail, navCommonList, resolveCommonContentFormData, resolveCommonContentGetPageDetailUrlAuto, resolveCommonContentSolveProps, useHomeCommonCategoryBlock, type HomeCommonCategoryBlockProps, type IHomeCommonCategoryBlock } from './CommonContent';
 import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
 import { navTo } from '@/components/utils/PageAction';
 import { DateUtils } from '@imengyu/imengyu-utils';
@@ -110,14 +110,15 @@ 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';
 
 export interface CategoryDefine {
   title: string;
   content: CommonContentApi|IHomeCommonCategoryBlock|HomeCommonCategoryBlockProps|null;
   type?: 'article'|'large-image2'|'horizontal-large'|'large-grid2'|'CalendarBlock'|undefined;
-  detailPage?: string;
+  detailsPage?: string;
   morePage?: string;
-  noFrom?: boolean;
+  dataSolve?: IHomeCommonCategoryListTabListDataSolve[];
   showMore?: boolean;
 }
 
@@ -135,7 +136,7 @@ const categoryDatas = props.categoryDefine.map(item => {
   if (!item.content)
     return {
       ...item,
-      detailPage: () => {},
+      detailsPage: () => {},
       morePage: () => {
         if (item.morePage) {
           navTo(item.morePage, {});
@@ -146,14 +147,14 @@ const categoryDatas = props.categoryDefine.map(item => {
   if (item.content instanceof CommonContentApi) {
     return {
       ...item,
-      detailPage: (dataItem: GetContentListItem) => {
+      detailsPage: (dataItem: GetContentListItem) => {
         const id = dataItem.id;
         const content = item.content as CommonContentApi;
-        if (item.detailPage) {
-          if (item.detailPage === 'byContent')
+        if (item.detailsPage) {
+          if (item.detailsPage === 'byContent')
             navTo(resolveCommonContentGetPageDetailUrlAuto(dataItem), { id });
           else
-            navTo(item.detailPage, { id });
+            navTo(item.detailsPage, { id });
         } else {
           navCommonDetail({
             id,
@@ -171,7 +172,7 @@ const categoryDatas = props.categoryDefine.map(item => {
             title: item.title,
             mainBodyColumnId: content.mainBodyColumnId,
             modelId: content.modelId,
-            detailsPage: item.detailPage,
+            detailsPage: item.detailsPage,
           })
         }
       },
@@ -179,14 +180,7 @@ const categoryDatas = props.categoryDefine.map(item => {
         let res = (await (item.content as CommonContentApi)
           .getContentList(new GetContentListParams(), 1, 3))
           .list;
-        if (!item.noFrom)
-          res = resolveCommonContentFormData(res);
-        else
-          res.forEach(p => {
-            if (!p.desc)
-              p.desc = DateUtils.formatDate(p.publishAt, 'YYYY-MM-dd');
-          })
-        return res;
+        return resolveCommonContentSolveProps(res, item.dataSolve || []);;
       })
     }
   } else {
@@ -194,11 +188,11 @@ const categoryDatas = props.categoryDefine.map(item => {
       item.content : 
       useHomeCommonCategoryBlock({
         ...item.content,
-        resolveData: item.noFrom ? undefined : resolveCommonContentFormData,
+        dataSolve: item.dataSolve ?? [],
       });
     return {
       ...item,
-      detailPage: block.goDetail,
+      detailsPage: block.goDetail,
       morePage: block.goList,
       data: block.loader,
     }

+ 43 - 4
src/pages/article/common/CommonContent.ts

@@ -1,6 +1,8 @@
 import CommonContent, { GetContentListItem, GetContentListParams } from "@/api/CommonContent";
 import { useSimpleDataLoader, type ISimpleDataLoader } from "@/common/composeabe/SimpleDataLoader";
 import { navTo } from "@/components/utils/PageAction";
+import type { IHomeCommonCategoryListTabListDataSolve } from "../data/CommonCategoryDefine";
+import { DateUtils } from "@imengyu/imengyu-utils";
 
 /**
  * 通用内容首页小列表控制代码组合
@@ -51,6 +53,24 @@ export function resolveCommonContentFormData(item: GetContentListItem[]) {
   })
   return item;
 }
+export function resolveCommonContentDateData(item: GetContentListItem[]) {
+  item.forEach(p => {
+    if (!p.desc)
+      p.desc = DateUtils.formatDate(p.publishAt, 'YYYY-MM-dd');
+  })
+  return item;
+}
+export function resolveCommonContentIchData(item: GetContentListItem[]) {
+  item.forEach(it => {
+    it.bottomTags = [
+      it.levelText, 
+      it.ichTypeText, 
+      it.batchText,
+      it.regionText,
+    ]
+  })
+  return item;
+}
 export function resolveCommonContentMakeDoubleSpace(item: GetContentListItem[]) {
   const result: GetContentListItem[] = [];
   item.forEach((it) => {
@@ -70,6 +90,27 @@ export function resolveCommonContentGetPageDetailUrlAuto(item: GetContentListIte
   return '/pages/article/details';
 }
 
+export function resolveCommonContentSolveProps(res: GetContentListItem[], dataSolve: IHomeCommonCategoryListTabListDataSolve[]) {
+  function resolveData(solve: IHomeCommonCategoryListTabListDataSolve) {
+    switch (solve) {
+      case 'none':
+        break;
+      case 'ich':
+        res = resolveCommonContentIchData(res);
+        break;
+      case 'date':
+        res = resolveCommonContentDateData(res);
+        break;
+      case 'common':
+        res = resolveCommonContentFormData(res);
+        break;
+    }
+  }
+  for (const solve of dataSolve)
+    resolveData(solve);
+  return res;
+}
+
 export interface HomeCommonCategoryBlockProps {
   title?: string,
   type?: '',
@@ -79,7 +120,7 @@ export interface HomeCommonCategoryBlockProps {
   detailsPage: string,
   count?: number,
   params?: Record<string, any>,
-  resolveData?: (item: GetContentListItem[]) => GetContentListItem[],
+  dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
 }
 
 /**
@@ -115,9 +156,7 @@ export function useHomeCommonCategoryBlock(p: HomeCommonCategoryBlockProps, load
       modelId: p.modelId,
       ...p.params,
     }), 1, p.count ?? 4)).list;
-    if (p.resolveData)
-      res = p.resolveData(res);
-    return res;
+    return resolveCommonContentSolveProps(res, p.dataSolve || []);;
   }, loadWhenMounted);
   return {
     type: 'CommonCategoryBlock',

+ 31 - 22
src/pages/article/common/CommonListPage.vue

@@ -39,7 +39,7 @@
           v-if="!drop.activeTab || drop.activeTab.includes(tabCurrentId)"
           :modelValue="dropDownValues[k]"
           :columns="drop.options"
-          :style="{maxWidth: `${100/dropDownNames.length}%`}"
+          :style="{maxWidth: `${100/dropDownVisibleCount}%`}"
           @update:modelValue="(v) => handleChangeDropDownValue(k, v)"
         />
       </template>
@@ -354,29 +354,38 @@ function goDetails(item: any, id: number) {
     return false;
   }
 
-  const page = props.detailsPage === 'object' ? props.detailsPage[tabCurrentIndex.value] : undefined;
-
-  if (typeof page === 'string') {
-    if (page == 'byContent' && handleByContent())
-      return;
-    navTo(page, { 
-      ...props.detailsParams, 
-      id 
-    })
-    return; 
-  }
-  if (typeof page === 'object') {
-    const item = page as {
-      page: string,
-      params: Record<string, any>,
-    };
-    if (item.page == 'byContent' && handleByContent())
+  const page = typeof props.detailsPage === 'object' ? props.detailsPage[tabCurrentId.value] : undefined;
+  if (page) {
+    if (typeof page === 'string') {
+      if (page == 'byContent' && handleByContent())
+        return;
+      navTo(page, { 
+        ...props.detailsParams, 
+        id 
+      })
+      return; 
+    }
+    if (typeof page === 'object') {
+      const item = page as {
+        page: string,
+        params: Record<string, any>,
+      };
+      if (item.page == 'byContent' && handleByContent())
+        return;
+      navTo(item.page, { 
+        ...item.params, 
+        id 
+      })
+      return; 
+    }
+  } else if (typeof props.detailsPage === 'object') {
+    if (handleByContent())
       return;
-    navTo(item.page, { 
-      ...item.params, 
-      id 
+    navTo('/pages/article/details', { 
+      ...props.detailsParams,
+      id
     })
-    return; 
+    return;
   }
   navTo(props.detailsPage as string, { 
     ...props.detailsParams,

+ 19 - 6
src/pages/article/data/CommonCategoryDefine.ts

@@ -1,6 +1,6 @@
-import { useHomeCommonCategoryBlock, type HomeCommonCategoryBlockProps } from "../common/CommonContent";
+import { type HomeCommonCategoryBlockProps } from "../common/CommonContent";
 import type { CommonListPageProps } from "../common/CommonListPage.vue";
-import { CommonCategoryDynamicDataSerializedApi, type IHomeCommonCategoryDynamicData } from "./CommonCategoryDynamicData";
+import { CommonCategoryDynamicDataSerializedApi, type IHomeCommonCategoryDropdownDynamicData, type IHomeCommonCategoryDynamicData } from "./CommonCategoryDynamicData";
 
 //基础定义
 
@@ -24,14 +24,26 @@ export interface IHomeCommonCategoryListDefine {
       text: string,
       width?: number,
       visible?: boolean,
+      detailsPage?: string,
     })[],
-    noFrom?: boolean,
+    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',
@@ -47,9 +59,9 @@ export interface IHomeCommonCategoryListTabNestCategoryDefine {
     itemType?: string,
     data: IHomeCommonCategoryDynamicData,
     morePage?: string,
-    detailPage?: string,
+    detailsPage?: string,
     count?: number,
-    noFrom?: boolean,
+    dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
     params?: Record<string, any>,
   }[],
 }
@@ -74,9 +86,10 @@ export function CommonCategoryListTabNestCategoryDataToContent(
         mainBodyColumnId: data.params.mainBodyColumnId,
         modelId: data.params.modelId,
         itemType: define.itemType,
-        detailsPage: define.detailPage || 'byContent',
+        detailsPage: define.detailsPage || 'byContent',
         count: define.count,
         params: define.params,
+        dataSolve: define.dataSolve || [],
       } as HomeCommonCategoryBlockProps;
   }
 }

+ 74 - 7
src/pages/article/data/CommonCategoryDynamicData.ts

@@ -22,8 +22,8 @@ import LanguageContent from "@/api/introduction/LanguageContent";
 import PolicyContent from "@/api/introduction/PolicyContent";
 import SeaContent from "@/api/introduction/SeaContent";
 import VictualsContent from "@/api/introduction/VictualsContent";
-import NotConfigue from "@/api/NotConfigue";
 import TeamsContent from "@/api/research/TeamsContent";
+import type { IHomeCommonCategoryListTabListDropdownDefine } from "./CommonCategoryDefine";
 
 export interface IHomeCommonCategoryDynamicDataCommonContent {
   type: 'commonContent',
@@ -31,6 +31,7 @@ export interface IHomeCommonCategoryDynamicDataCommonContent {
   params: {
     modelId: number,
     mainBodyColumnId?: string|number|number[],
+    typeId?: number, // 分类类型id
   },
   otherParams?: Record<string, any>,
 }
@@ -50,6 +51,34 @@ export type IHomeCommonCategoryDynamicData = IHomeCommonCategoryDynamicDataCommo
   | IHomeCommonCategoryDynamicDataSerializedApi 
   | IHomeCommonCategoryDynamicDataRequest;
 
+export interface IHomeCommonCategoryDropdownDynamicDataCommonContent {
+  type: 'commonContent',
+  url?: string,
+  typeId: number, // 分类类型id
+  otherParams?: Record<string, any>,
+  idKey?: string,
+  nameKey?: string,
+}
+export interface IHomeCommonCategoryDropdownStaticData {
+  type: 'static',
+  data: Record<string, any>[],
+  idKey?: string,
+  nameKey?: string,
+}
+export interface IHomeCommonCategoryDropdownDynamicDataRequest {
+  type: 'request',
+  method: "OPTIONS" | "GET" | "HEAD" | "POST" | "PUT" | "DELETE",
+  url: string,
+  querys?: Record<string, any>,
+  params?: Record<string, any>,
+  idKey?: string,
+  nameKey?: string,
+}
+export type IHomeCommonCategoryDropdownDynamicData = 
+  IHomeCommonCategoryDropdownDynamicDataCommonContent 
+  | IHomeCommonCategoryDropdownDynamicDataRequest
+  | IHomeCommonCategoryDropdownStaticData;
+
 export function CommonCategoryDynamicDataSerializedApi(item: IHomeCommonCategoryDynamicDataSerializedApi) {
   switch (item.name) {
     case 'BulidingContent': return BulidingContent;
@@ -77,12 +106,47 @@ export function CommonCategoryDynamicDataSerializedApi(item: IHomeCommonCategory
       throw new Error(`未实现的序列化接口 ${item.name}`);
   }
 }
+function CommonCategorDynamicDropDownValuesToParams(dropDownValues: (number|string|boolean)[], dropdownDefines: IHomeCommonCategoryListTabListDropdownDefine[]) {
+  const params: Record<string, any> = {};
+  dropdownDefines.forEach((define, index) => {
+    const v = dropDownValues[index]
+    if (typeof v === 'number' && v > 0)
+      params[define.key] = v;
+    else if (typeof v === 'string')
+      params[define.key] = v;
+  });
+  console.log(params,dropDownValues );
+  
+  return params;
+}
+
+export async function doLoadDynamicDropdownData(item: IHomeCommonCategoryDropdownDynamicData) {
+  switch (item.type) {
+    case 'commonContent':
+      return (await CommonContent.getCategoryList(item.typeId)) as unknown as Record<string, any>[];
+    case 'static':
+      return item.data;
+    case 'request':
+      return (await CommonContent.request(
+        item.url, 
+        { ...item.querys }, 
+        {
+          method: item.method, 
+          data: item.params,
+        },
+        '',
+        undefined,
+      )).data as unknown as Record<string, any>[];
+  }
+  throw new Error(`未实现的动态数据接口`);
+}
 export async function doLoadDynamicListData(
   item: IHomeCommonCategoryDynamicData,
   page: number,
   pageSize: number,
   keywords: string,
-  dropDownValues: number[],
+  dropdownDefines: IHomeCommonCategoryListTabListDropdownDefine[],
+  dropDownValues: (number|string|boolean)[],
 ) {
   switch (item.type) {
     default:
@@ -94,24 +158,27 @@ export async function doLoadDynamicListData(
         .setKeywords(keywords)
         .setSelfValues({
           ...item.otherParams,
-
+          ...CommonCategorDynamicDropDownValuesToParams(dropDownValues, dropdownDefines || []),
         }) 
-      , page, pageSize)
-      break;
+      , page, pageSize);
     case 'serializedApi':
       return (await CommonCategoryDynamicDataSerializedApi(item).getContentList(new GetContentListParams()
         .setKeywords(keywords)
         .setSelfValues({
           ...item.otherParams,
+          ...CommonCategorDynamicDropDownValuesToParams(dropDownValues, dropdownDefines || []),
         }) 
-      , page, pageSize))
+      , page, pageSize));
     case 'request':
       return (await CommonContent.request(
         item.url, 
         { ...item.querys, page, pageSize }, 
         {
           method: item.method, 
-          data: item.params,
+          data: {
+            ...item.params,
+            ...CommonCategorDynamicDropDownValuesToParams(dropDownValues, dropdownDefines || [])
+          },
         },
         '',
         undefined,

+ 2 - 2
src/pages/article/data/CommonCategoryGlobalLoader.ts

@@ -27,10 +27,10 @@ export function useCommonCategoryGlobalLoader() {
   async function loadCommonCategory() {
     uni.showLoading({ title: '加载中' });
     try {
-      /*if (isDev) {
+      if (isDev) {
         commonCategoryData.value = DefaultCofig as IHomeCommonCategoryDefine;
         return;
-      }*/
+      }
       const category = (await NotConfigue.get<IHomeCommonCategoryDefine>(ApiCofig.dynamicCategoryConfigServer, '加载默认分类')).data;
       if (category)
         commonCategoryData.value = category;

+ 61 - 11
src/pages/article/data/CommonCategoryList.vue

@@ -3,11 +3,14 @@
     <Result v-if="errorMessage" status="error" :description="errorMessage" />
     <CommonListPage 
       v-else-if="currentCommonCategoryDefine"
+      :startTabIndex="pageStartTab"
       v-bind="currentCommonCategoryDefine.content.props as any || undefined"
       :title="currentCommonCategoryDefine.title || undefined"
       :load="loadData"
       :tabs="tabs"
+      :dropDownNames="dropdownNames"
       :showListTabIds="showListTabIds"
+      :detailsPage="detailsPage"
     >
       <template #list="{ tabId }">
         <CommonCategoryHome 
@@ -24,15 +27,16 @@
 import { computed, onMounted, ref, watch } from 'vue';
 import { injectCommonCategory } from './CommonCategoryGlobalLoader';
 import { navTo } from '@/components/utils/PageAction';
-import { doLoadDynamicListData } from './CommonCategoryDynamicData';
+import { doLoadDynamicDropdownData, doLoadDynamicListData } from './CommonCategoryDynamicData';
 import { CommonCategoryListTabNestCategoryDataToContent, type IHomeCommonCategoryDefine, type IHomeCommonCategoryListTabDefine } from './CommonCategoryDefine';
-import type { CommonListPageProps } from '../common/CommonListPage.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 Footer from '@/components/display/Footer.vue';
 import FlexCol from '@/components/layout/FlexCol.vue';
-import { resolveCommonContentFormData } from '../common/CommonContent';
+import { resolveCommonContentSolveProps } from '../common/CommonContent';
+import type { SimpleDropDownPickerItem } from '@/common/components/SimpleDropDownPicker.vue';
 
 /**
  * 动态通用内容 - 通用列表页
@@ -46,10 +50,18 @@ const props = defineProps({
   pageConfigName: {
     type: String,
     default: '',
-  }
+  },
+  pageStartTab: {
+    type: Number,
+    default: 0,
+  },
+  pageQuerys: {
+    type: Object as () => Record<string, string|number|number[]|undefined>,
+    default: () => ({}),
+  },
 });
 
-function loadPageConfig() {
+async function loadPageConfig() {
   if (!props.pageConfigName) {
     errorMessage.value = '配置有误';
     return;
@@ -63,6 +75,35 @@ function loadPageConfig() {
   uni.setNavigationBarTitle({
     title: currentCommonCategoryDefine.value?.title || '',
   })
+
+  //加载下拉列表
+  const result = [] as DropDownNames[];
+  for (const [key, tab] of Object.entries(tabRenderDefines.value)) {
+    if (tab.type !== 'list')
+      continue;
+    if (tab.dropdownDefines) {
+      for (const dropdown of tab.dropdownDefines) {    
+        const data : SimpleDropDownPickerItem[] = (dropdown.addAll ? [{
+          id: 0, 
+          name: dropdown.addAll
+        }] : []);
+        if (dropdown.data) {
+          data.push(...(await doLoadDynamicDropdownData(dropdown.data)).map((item) => ({
+            id: item[dropdown.data.idKey || 'id'],
+            name: item[dropdown.data.nameKey || 'title'],
+          })))
+        }
+        result.push({
+          options: data,
+          activeTab: [Number(key)],
+          defaultSelectedValue: dropdown.formQueryKey ? (
+            props.pageQuerys[dropdown.formQueryKey] as number || 0
+          ) : dropdown.defaultValue || 0,
+        })
+      }
+    }
+  }
+  dropdownNames.value = result;
 }
 
 watch(() => props.pageConfigName, loadPageConfig);
@@ -90,13 +131,11 @@ const tabRenderDefines = computed(() => {
           .filter((item) => item.visible !== false)
           .map((item) => {
             return {
+              ...item,
               title: item.text,
               content: CommonCategoryListTabNestCategoryDataToContent(
                 item.data, item
               ),
-              morePage: item.morePage,
-              detailPage: item.detailPage,
-              noFrom: item.noFrom,
               type: item.type as CategoryDefine['type'],
             }
           });
@@ -143,6 +182,17 @@ const tabs = computed<CommonListPageProps['tabs']>(() => {
     }
   });
 });
+const dropdownNames = ref<DropDownNames[]>([]);
+const detailsPage = computed(() => {
+  if (tabDefines.value.find((item) => item.detailsPage)) {
+    const result = {} as Record<number, string>;
+    tabDefines.value.forEach((item, i) => {
+      result[i] = item.detailsPage || '';
+    });
+    return result;
+  }
+  return currentCommonCategoryDefine.value?.content.props.detailsPage || undefined;
+});
 
 async function loadData(
   page: number, 
@@ -161,11 +211,11 @@ async function loadData(
     page, 
     pageSize, 
     searchText, 
+    tab.dropdownDefines || [],
     dropDownValues,
   );
-  if (res && !currentCommonCategoryDefine.value?.content.props.noFrom) {
-    res.list = resolveCommonContentFormData(res.list);
-  }
+  if (res && tab.dataSolve)
+    res.list = resolveCommonContentSolveProps(res.list, tab.dataSolve);
   return res;
 }
 </script>

+ 114 - 14
src/pages/article/data/DefaultCategory.json

@@ -18,6 +18,7 @@
                     "type": "serializedApi",
                     "name": "HistoryContent"
                   },
+                  "dataSolve": [ "common" ],
                   "type": ""
                 },
                 {
@@ -31,7 +32,6 @@
                       "modelId": 18
                     }
                   },
-                  "noFrom": true,
                   "type": "article"
                 },
                 {
@@ -40,7 +40,8 @@
                     "type": "serializedApi",
                     "name": "CharacterContent"
                   },
-                  "detailPage": "/pages/introduction/character/details",
+                  "dataSolve": [ "common" ],
+                  "detailsPage": "/pages/introduction/character/details",
                   "morePage": "/pages/introduction/character/list",
                   "type": ""
                 },
@@ -50,6 +51,7 @@
                     "type": "serializedApi",
                     "name": "CustomContent"
                   },
+                  "dataSolve": [ "common" ],
                   "morePage": "/pages/introduction/custom/list",
                   "type": ""
                 },
@@ -59,14 +61,16 @@
                     "type": "serializedApi",
                     "name": "FeatureContent"
                   },
+                  "dataSolve": [ "common" ],
                   "type": ""
                 },
                 {
                   "text": "海洋文化",
                   "data": {
-                "type": "serializedApi",
-                "name": "SeaContent"
+                    "type": "serializedApi",
+                    "name": "SeaContent"
                   },
+                  "dataSolve": [ "common" ],
                   "type": ""
                 },
                 {
@@ -75,8 +79,8 @@
                     "type": "serializedApi",
                     "name": "PolicyContent"
                   },
+                  "dataSolve": [ "date" ],
                   "type": "",
-                  "noFrom": true,
                   "morePage": "/pages/home/laws"
                 }
               ]
@@ -106,6 +110,7 @@
                       "modelId": 18
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "type": ""
                 },
@@ -118,6 +123,7 @@
                       "modelId": 18
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "type": ""
                 },
@@ -130,6 +136,7 @@
                       "modelId": 18
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "type": ""
                 },
@@ -142,6 +149,7 @@
                       "modelId": 18
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "type": ""
                 },
@@ -154,6 +162,7 @@
                       "modelId": 18
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "type": ""
                 },
@@ -166,6 +175,7 @@
                       "modelId": 9
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "type": "horizontal-large"
                 },
@@ -178,6 +188,7 @@
                       "modelId": 18
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "visible": false,
                   "type": ""
@@ -190,7 +201,8 @@
               "data": {
                 "type": "serializedApi",
                 "name": "TeamsContent"
-              }
+              },
+              "dataSolve": [ "common" ]
             }
           ]
         }
@@ -217,7 +229,6 @@
                       "modelId": 16
                     }
                   },
-                  "noFrom": true,
                   "morePage": "/pages/travel/fashion/list",
                   "detailsPage": "/pages/video/details",
                   "type": "large-grid2"
@@ -231,7 +242,6 @@
                       "modelId": 18
                     }
                   },
-                  "noFrom": true,
                   "morePage": "/pages/travel/fashion/list",
                   "detailsPage": "/pages/video/details",
                   "type": "large-grid2"
@@ -244,7 +254,8 @@
                       "mainBodyColumnId": [260, 261, 262],
                       "modelId": 18
                     }
-                  }
+                  },
+                  "dataSolve": [ "common" ]
                 }
               ]
             }
@@ -274,7 +285,6 @@
                     }
                   },
                   "visible": false,
-                  "noFrom": true,
                   "morePage": "/pages/travel/fashion/list",
                   "detailsPage": "/pages/video/details",
                   "type": "large-grid2"
@@ -294,7 +304,6 @@
                       "modelId": 3
                     }
                   },
-                  "noFrom": true,
                   "detailsPage": "byContent",
                   "type": "large-grid2"
                 },
@@ -307,7 +316,6 @@
                       "modelId": 17
                     }
                   },
-                  "noFrom": true,
                   "morePage": "/pages/travel/scenic-spot/list",
                   "detailsPage": "/pages/inhert/intangible/details",
                   "type": ""
@@ -321,6 +329,7 @@
                       "modelId": 18
                     }
                   },
+                  "dataSolve": [ "common" ],
                   "detailsPage": "byContent",
                   "type": ""
                 },
@@ -333,7 +342,6 @@
                       "modelId": 17
                     }
                   },
-                  "noFrom": true,
                   "detailsPage": "byContent",
                   "type": "horizontal-large"
                 },
@@ -346,7 +354,6 @@
                       "modelId": 5
                     }
                   },
-                  "noFrom": true,
                   "detailsPage": "/pages/video/details",
                   "type": "horizontal-large"
                 }
@@ -355,6 +362,99 @@
           ]
         }
       }
+    },
+    {
+      "name": "intangible",
+      "title": "非物质文化遗产",
+      "content": {
+        "type": "CommonList",
+        "props": {
+          "itemType": "image-large-2",
+          "tabsScrollable": true,
+          "showTab": true,
+          "showTotal": true,
+          "tabs": [
+            {
+              "text": "非遗项目",
+              "type": "list",
+              "data": {
+                "type": "serializedApi",
+                "name": "ProjectsContent"
+              },
+              "dataSolve": [ "ich" ],
+              "detailsPage": "/pages/inhert/intangible/details",
+              "dropdownDefines": [
+                {
+                  "key": "ichType",
+                  "text": "分类",
+                  "addAll": "全部地区",
+                  "defaultValue": 0,
+                  "data": {
+                    "type": "commonContent",
+                    "typeId": 4
+                  }
+                },
+                {
+                  "key": "level",
+                  "text": "级别",
+                  "addAll": "全部地区",
+                  "formQueryKey": "level",
+                  "data": {
+                    "type": "commonContent",
+                    "typeId": 2
+                  }
+                },
+                {
+                  "key": "region",
+                  "text": "地区",
+                  "defaultValue": 0,
+                  "addAll": "全部地区",
+                  "data": {
+                    "type": "commonContent",
+                    "typeId": 1
+                  }
+                }
+              ]
+            },
+            {
+              "text": "非遗传承人",
+              "type": "jump",
+              "url": "/pages/inhert/inheritor/list"
+            },
+            {
+              "text": "非遗传习所",
+              "type": "list",
+              "data": {
+                "type": "serializedApi",
+                "name": "SeminarContent"
+              },
+              "dataSolve": [ "ich" ],
+              "detailsPage": "/pages/inhert/seminar/details",
+              "dropdownDefines": [
+                {
+                  "key": "region",
+                  "text": "地区",
+                  "defaultValue": 0,
+                  "addAll": "全部地区",
+                  "data": {
+                    "type": "commonContent",
+                    "typeId": 1
+                  }
+                }
+              ]
+            },
+            {
+              "text": "保护单位",
+              "type": "list",
+              "data": {
+                "type": "serializedApi",
+                "name": "UnitContent"
+              },
+              "dataSolve": [ "ich" ]
+            }
+          ]
+        }
+      }
     }
   ]
 }

+ 8 - 3
src/pages/article/data/list.vue

@@ -1,5 +1,9 @@
 <template>
-  <CommonCategoryList :pageConfigName="querys.pageConfigName" />
+  <CommonCategoryList 
+    :pageConfigName="querys.pageConfigName" 
+    :pageStartTab="querys.tab"
+    :pageQuerys="rawQuerys"
+  />
 </template>
 
 <script setup lang="ts">
@@ -8,7 +12,8 @@ import CommonCategoryList from './CommonCategoryList.vue';
 /**
  * 动态通用内容 - 通用列表页
  */
-const { querys } = useLoadQuerys({
-  pageConfigName: ''
+const { querys, rawQuerys } = useLoadQuerys({
+  pageConfigName: '',
+  tab: 0,
 });
 </script>

+ 2 - 135
src/pages/inhert/intangible/list.vue

@@ -1,140 +1,7 @@
 <template>
-  <CommonListPage 
-    ref="list"
-    title="非遗"
-    itemType="image-large-2"
-    showTotal
-    :detailsPage="[
-      '/pages/inhert/intangible/details',
-      //'/pages/inhert/product/details',
-      '',
-      '/pages/inhert/seminar/details',
-      'disabled',
-    ]"
-    :dropDownNames="dropdownNames"
-    :tabs="[
-      { id: 0, text: '非遗项目' },
-      //{ id: 1, text: '非遗作品' },
-      { id: 2, text: '非遗传承人', jump: () => navTo('/pages/inhert/inheritor/list'), onlyJump: true },
-      { id: 3, text: '非遗传习所' },
-      { id: 4, text: '保护单位' },
-    ]"
-    :tabsScrollable="true"
-    :startTabIndex="startTab"
-    :load="loadData" 
-    :loadMounted="false"
-  />
+  <CommonCategoryList pageConfigName="intangible" />
 </template>
 
 <script setup lang="ts">
-import CommonContent, { GetContentListParams } from '@/api/CommonContent';
-import ProductsContent from '@/api/inheritor/ProductsContent';
-import ProjectsContent from '@/api/inheritor/ProjectsContent';
-import SeminarContent from '@/api/inheritor/SeminarContent';
-import UnitContent from '@/api/inheritor/UnitContent';
-import { navTo } from '@/components/utils/PageAction';
-import CommonListPage, { type DropDownNames } from '@/pages/article/common/CommonListPage.vue';
-import { onLoad } from '@dcloudio/uni-app';
-import { waitTimeOut } from '@imengyu/imengyu-utils';
-import { ref } from 'vue';
-
-const list = ref();
-const dropdownNames = ref<DropDownNames[]>([]);
-const startTab = ref(0);
-async function loadData(
-  page: number, 
-  pageSize: number,
-  searchText: string,
-  dropDownValues: number[],
-  tabSelect: number,
-) {
-  let api;
-  let res;
-  switch (tabSelect) {
-    case 0: 
-      res = (await ProjectsContent.getContentList(new GetContentListParams().setSelfValues({
-        ichType: dropDownValues[0] == 0 ? undefined: dropDownValues[0],
-        level: dropDownValues[1] == 0 ? undefined: dropDownValues[1],
-        region: dropDownValues[2] == 0 ? undefined: dropDownValues[2],
-        pid: 0,
-        keywords: searchText,
-      }), page, pageSize));
-      break;
-    case 2: return {
-      list: [],
-      total: 0,
-    };
-    default:
-    case 1: 
-      res = (await ProductsContent.getContentList(new GetContentListParams().setSelfValues({
-        level: dropDownValues[1] == 0 ? undefined: dropDownValues[1],
-        region: dropDownValues[2] == 0 ? undefined: dropDownValues[2],
-        keywords: searchText,
-      }), page, pageSize));
-    break;
-    case 3:
-      res = (await SeminarContent.getContentList(new GetContentListParams().setSelfValues({
-        region: dropDownValues[2] == 0 ? undefined: dropDownValues[2],
-        keywords: searchText,
-      }), page, pageSize));
-     break;
-    case 4: 
-      res = (await UnitContent.getContentList(new GetContentListParams().setSelfValues({
-        keywords: searchText,
-      }), page, pageSize));
-     break;
-  }
-
-  res.list.forEach((item) => {
-    item.bottomTags = [
-      item.levelText, 
-      item.ichTypeText, 
-      item.batchText,
-      item.regionText,
-    ]
-  })
-  return res;
-}
-
-onLoad(async (querys) => {
-  if (querys?.tab) {
-    startTab.value = Number(querys.tab); 
-  }
-  dropdownNames.value.push({ 
-    options: [{
-      id: 0, 
-      name: '全部分类'
-    }].concat((await CommonContent.getCategoryList(4)).map((item) => ({
-      id: item.id,
-      name: item.title,
-    }))),
-    activeTab: [0],
-    defaultSelectedValue: 0,
-  });
-  const levels = await CommonContent.getCategoryList(2);
-  dropdownNames.value.push({ 
-    options: [{
-      id: 0, 
-      name: '全部级别'
-    }].concat(levels.map((item) => ({
-      id: item.id,
-      name: item.title,
-    }))),
-    activeTab: [0,2],
-    defaultSelectedValue: querys?.level ?? 0,
-  });
-  dropdownNames.value.push({ 
-    options: [{
-      id: 0, 
-      name: '全部地区'
-    }].concat((await CommonContent.getCategoryList(1)).map((item) => ({
-      id: item.id,
-      name: item.title,
-    }))),
-    activeTab: [0,3],
-    defaultSelectedValue: 0,
-  });
-  await waitTimeOut(800);
-  list.value.load();
-})
+import CommonCategoryList from '@/pages/article/data/CommonCategoryList.vue';
 </script>

+ 0 - 93
src/pages/introduction/food/list.vue

@@ -1,93 +0,0 @@
-<template>
-  <CommonListPage 
-    title="闽南美食"
-    itemType="image-large-2"
-    :detailsPage="[
-      {
-        page: '/pages/article/details',
-        params: {
-          modelId: 3,
-          mainBodyColumnId: 253,
-        }
-      },
-      {
-        page: '/pages/inhert/intangible/details',
-        params: {},
-      }
-    ]"
-    showTotal
-    :startTabIndex="1"
-    :showTab="false"
-    :dropDownNames="dropdownNames"
-    :load="loadData"
-    :tabs="[
-      { id: 0, text: '饮食文化' },
-      { id: 1, text: '非遗美食' },
-    ]"
-  />
-<!--   
-     -->
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue';
-import CommonListPage, { type DropDownNames } from '@/pages/article/common/CommonListPage.vue';
-import CommonContent, { GetContentListParams } from '@/api/CommonContent';
-import ProjectsContent from '@/api/inheritor/ProjectsContent';
-
-const dropdownNames = ref<DropDownNames[]>([]);
-
-const detailsParams = ref({
-  modelId: 3,
-  mainBodyColumnId: 253,
-})
-
-async function loadData(
-  page: number, 
-  pageSize: number,
-  searchText: string,
-  dropDownValues: number[],
-  tabSelect: number,
-) {
-  let res;
-  switch (tabSelect) {
-    default:
-    case 0:
-       res = await CommonContent.getContentList(new GetContentListParams()
-        .setKeywords(searchText)
-        .setModelId(3)
-        .setMainBodyColumnId(253)
-      , page, pageSize);
-      res.list.forEach((item) => {
-        item.bottomTags = [
-          item.levelText, 
-          item.ichTypeText, 
-          item.batchText,
-          item.regionText,
-        ]
-      })
-      break;
-    case 1:
-       res = await ProjectsContent.getContentList(new GetContentListParams()
-        .setKeywords('美食 ' + searchText)
-      , page, pageSize);
-      res.list.forEach((item) => {
-        item.bottomTags = [
-          item.levelText, 
-          item.ichTypeText, 
-          item.batchText,
-          item.regionText,
-        ]
-      })
-      break;
-    case 2:
-      res = await CommonContent.getContentList(new GetContentListParams()
-        .setKeywords(searchText)
-        .setModelId(8)
-        .setMainBodyColumnId(103)
-      , page, pageSize);
-      break;
-  }
-  return { list: res.list, total: res.total }
-}
-</script>

+ 1 - 1
src/pages/parts/Box2LineImageRightShadow.vue

@@ -6,7 +6,7 @@
       border ? 'border-all-light-light-primary shadow-s p-2 pt-3 pb-3 ' : '' ,
     ]"
     :style="{ 
-      height: 'calc(100% - 20rpx)',
+      //height: 'calc(100% - 20rpx)',
       width: 'calc(100% - 10rpx)',
     }"
     @click="$emit('click')"

+ 1 - 1
src/pages/parts/Box2LineLargeImageUserShadow.vue

@@ -9,7 +9,7 @@
     ]"
     
     :style="{ 
-      height: 'calc(100% - 20rpx)',
+      //height: 'calc(100% - 20rpx)',
       width: fixSize ? width : 'calc(100% - 10rpx)',
     }"
     @click="$emit('click')"