浏览代码

📦 修改首页背景图,闽南美食,村落筛选,增加传习所列表

imengyu 4 周之前
父节点
当前提交
93280913fb

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

@@ -159,7 +159,7 @@ export class VillageApi extends AppServerRequestModule<DataModel> {
   }
   async getVallageList(level?: number) {
     return (this.get('/village/village/getList', '村落列表', {
-      level,
+      history_level: level,
     })) 
       .then(res => transformArrayDataModel<VillageListItem>(VillageListItem, transformSomeToArray(res.data2), `村落`, true))
       .catch(e => { throw e });

+ 27 - 7
src/pages.json

@@ -21,7 +21,15 @@
     {
       "path": "pages/introduction/character/list",
       "style": {
-        "navigationBarTitleText": "历史人物列表"
+        "navigationBarTitleText": "历史人物列表",
+        "enablePullDownRefresh": true
+      }
+    },
+    {
+      "path": "pages/introduction/food/list",
+      "style": {
+        "navigationBarTitleText": "闽南美食",
+        "enablePullDownRefresh": true
       }
     },
     {
@@ -67,7 +75,8 @@
     {
       "path": "pages/inhert/artifact/list",
       "style": {
-        "navigationBarTitleText": "文物古迹"
+        "navigationBarTitleText": "文物古迹",
+        "enablePullDownRefresh": true
       }
     },
     {
@@ -97,7 +106,8 @@
     {
       "path": "pages/inhert/inheritor/list",
       "style": {
-        "navigationBarTitleText": "传承人列表"
+        "navigationBarTitleText": "传承人列表",
+        "enablePullDownRefresh": true
       }
     },
     {
@@ -107,9 +117,16 @@
       }
     },
     {
+      "path": "pages/inhert/seminar/details",
+      "style": {
+        "navigationBarTitleText": "传习所详情"
+      }
+    },
+    {
       "path": "pages/inhert/old/list",
       "style": {
-        "navigationBarTitleText": "老字号"
+        "navigationBarTitleText": "老字号",
+        "enablePullDownRefresh": true
       }
     },
     {
@@ -121,7 +138,8 @@
     {
       "path": "pages/inhert/village/list",
       "style": {
-        "navigationBarTitleText": "村落列表"
+        "navigationBarTitleText": "村落列表",
+        "enablePullDownRefresh": true
       }
     },
     {
@@ -133,7 +151,8 @@
     {
       "path": "pages/article/common/list",
       "style": {
-        "navigationBarTitleText": "通用列表页"
+        "navigationBarTitleText": "通用列表页",
+        "enablePullDownRefresh": true
       }
     },
     {
@@ -145,7 +164,8 @@
     {
       "path": "pages/article/list",
       "style": {
-        "navigationBarTitleText": "文章列表页"
+        "navigationBarTitleText": "文章列表页",
+        "enablePullDownRefresh": true
       }
     },
     {

+ 47 - 25
src/pages/article/common/CommonListPage.vue

@@ -6,11 +6,10 @@
       hasBg ? 'bg-base p-3' : ''
     ]"
   >
-    <view class="top-tab bg-base">
-      <u-tabs 
-        v-if="tabs"
+    <view v-if="tabs" class="top-tab bg-base">
+      <u-tabs
         :list="tabs" 
-        :current="tab"
+        :current="tabCurrentIndex"
         lineWidth="30"
         lineColor="#d9492e"
         :activeStyle="{
@@ -22,7 +21,7 @@
           color: '#606266',
           transform: 'scale(1)'
         }"
-        :scrollable="tabs && tabs.length > 5" 
+        :scrollable="tabsScrollable || (tabs && tabs.length > 5)" 
         @click="handleTabClick"
       />
     </view>
@@ -44,27 +43,27 @@
       v-if="dropDownNames.length > 0" 
       class="d-flex flex-row justify-between align-center mt-2"
       :class="[
-        dropDownNames.length >= 3 ? 'justify-around' : ('justify-between')
+        dropDownVisibleCount >= 3 ? 'justify-around' : ('justify-between')
       ]"
     >
       <template v-for="(drop, k) in dropDownNames" :key="k" >
         <SimpleDropDownPicker 
-          v-if="drop.activeTab == undefined || drop.activeTab == tab"
+          v-if="!drop.activeTab || drop.activeTab.includes(tabCurrentIndex)"
           :modelValue="dropDownValues[k]"
-          :columns="drop.options" 
+          :columns="drop.options"
           :style="{maxWidth: `${100/dropDownNames.length}%`}"
           @update:modelValue="(v) => handleChangeDropDownValue(k, v)"
         />
       </template>
       <view 
-        v-if="showTotal && dropDownNames.length < 3" 
+        v-if="(showTotal && dropDownVisibleCount < 3)" 
         class="d-flex flex-row align-center mt-3 size-s color-primary text-bold"
       >
         <text>总共有 {{ listLoader.total }} 个</text>
       </view>
     </view>
     <view 
-      v-if="showTotal && (dropDownNames.length >= 3 || dropDownNames.length == 0)" 
+      v-if="(dropDownVisibleCount >= 3 || dropDownVisibleCount == 0)" 
       class="d-flex flex-row justify-center align-center mt-3 size-s color-primary text-bold"
     >
       <text>总共有 {{ listLoader.total }} 个</text>
@@ -126,7 +125,7 @@
 </template>
 
 <script setup lang="ts">
-import { onMounted, ref, watch, type PropType } from 'vue';
+import { computed, onMounted, ref, watch, type PropType } from 'vue';
 import { useSimplePageListLoader } from '@/common/composeabe/SimplePageListLoader';
 import { navTo } from '@/common/utils/PageAction';
 import SimplePageListLoader from '@/common/components/SimplePageListLoader.vue';
@@ -145,7 +144,7 @@ function getItemClass(index: number) {
 export interface DropDownNames {
   options: SimpleDropDownPickerItem[],
   defaultSelectedValue: number|string,
-  activeTab?: number,
+  activeTab?: number[],
 }
 export interface CommonListItem extends Record<string, any>  {
   id: number,
@@ -172,6 +171,10 @@ const props = defineProps({
     }[]>,
     default: null,
   },
+  tabsScrollable: {
+    type: Boolean,
+    default: false, 
+  },
   /**
    * 是否显示搜索框
    */
@@ -242,14 +245,26 @@ const props = defineProps({
     type: Boolean,
     default: true,
   },
-  startTab: {
+  startTabIndex: {
     type: Number,
     default: undefined, 
-  }
+  },
+  loadMounted: {
+    type: Boolean,
+    default: true,
+  },
 })
 
 const emit = defineEmits([ 'goCustomDetails' ])
 
+const dropDownVisibleCount = computed(() => {
+  let c = 0;
+  for (const element of props.dropDownNames) {
+    if (!element.activeTab || element.activeTab.includes(tabCurrentIndex.value))
+      c++;
+  }
+  return c;
+})
 const dropDownValues = ref<any>([]);
 const searchValue = ref('');
 const listLoader = useSimplePageListLoader(props.pageSize, async (page, pageSize) => {
@@ -257,10 +272,10 @@ const listLoader = useSimplePageListLoader(props.pageSize, async (page, pageSize
     page, pageSize, 
     searchValue.value,
     dropDownValues.value,
-    tab.value,
+    props.tabs?.[tabCurrentIndex.value]?.id ?? tabCurrentIndex.value,
   )
 });
-const tab = ref(0)
+const tabCurrentIndex = ref(0)
 
 function handleChangeDropDownValue(index: number, value: number) {
   dropDownValues.value[index] = value;
@@ -275,7 +290,7 @@ function goDetails(item: any, id: number) {
     return;
   }
   if (typeof props.detailsPage == 'object') {
-    navTo(props.detailsPage[tab.value], { 
+    navTo(props.detailsPage[tabCurrentIndex.value], { 
       ...props.detailsPage.params, 
       id 
     })
@@ -292,28 +307,35 @@ function handleTabClick(e: any) {
     e.jump();
     return;
   }
-  tab.value = e.id;
+  tabCurrentIndex.value = e.index;
   listLoader.loadData(undefined, true);
 }
 
-watch(tab, () => {
+watch(tabCurrentIndex, () => {
   listLoader.loadData(undefined, true);
 });
-watch(() => props.startTab, () => {
-  if (props.startTab) {
-    tab.value = props.startTab;
+watch(() => props.startTabIndex, () => {
+  if (props.startTabIndex) {
+    tabCurrentIndex.value = props.startTabIndex;
   }
 });
 
+defineExpose({
+  load: () => {
+    listLoader.loadData(undefined, true);
+  },
+})
+
 onMounted(() => {
   setTimeout(() => {  
-    if (props.startTab)
-      tab.value = props.startTab;
+    if (props.startTabIndex)
+      tabCurrentIndex.value = props.startTabIndex;
     if (props.title)
       uni.setNavigationBarTitle({ title: props.title, })
     for (const element of props.dropDownNames)
       dropDownValues.value.push(element.defaultSelectedValue);
-    listLoader.loadData(undefined, true);
+    if (props.loadMounted)
+      listLoader.loadData(undefined, true);
   }, 300);
 });
 </script>

+ 5 - 7
src/pages/home.vue

@@ -238,13 +238,7 @@ const subTabs = [
   { 
     name: '闽南美食', 
     icon: MainBoxIcon2, 
-    onClick: () => navTo('/pages/article/common/list', {
-      title: '闽南美食',
-      mainBodyColumnId: 103,
-      modelId: 8,
-      itemType: 'article-common',
-      detailsPage: '/pages/article/details',
-    }) 
+    onClick: () => navTo('/pages/introduction/food/list') 
   },
   { name: '历史人物', icon: MainBoxIcon3, onClick: () => navTo('/pages/introduction/character/list') },
   { 
@@ -477,6 +471,10 @@ function handleGoDetails(item: any) {
 
 <style lang="scss">
 .page-home {
+  .content {
+    margin-top: 470rpx;
+  }
+
   .map-tags {
     left: 0;
     top: 0;

+ 1 - 1
src/pages/inhert/inheritor/list.vue

@@ -60,7 +60,7 @@ onLoad(async (querys) => {
       id: item.id,
       name: item.title,
     }))),
-    activeTab: 0,
+    activeTab: [0],
     defaultSelectedValue: querys?.level ? (levels.find(p => p.title == querys.level)?.id ?? 0) : 0,
   });
   dropdownNames.value.push({ 

+ 11 - 5
src/pages/inhert/intangible/list.vue

@@ -6,14 +6,18 @@
     :detailsPage="[
       '/pages/inhert/intangible/details',
       '/pages/inhert/product/details',
+      '',
+      '/pages/inhert/seminar/details',
     ]"
     :dropDownNames="dropdownNames"
     :tabs="[
       { id: 0, name: '非遗项目' },
       { id: 1, name: '非遗作品' },
       { id: 2, name: '非遗传承人', jump: () => navTo('/pages/inhert/inheritor/list') },
+      { id: 3, name: '非遗传习所' },
     ]"
-    :startTab="startTab"
+    :tabsScrollable="true"
+    :startTabIndex="startTab"
     :load="loadData" 
   />
 </template>
@@ -22,6 +26,7 @@
 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 { navTo } from '@/common/utils/PageAction';
 import CommonListPage, { type DropDownNames } from '@/pages/article/common/CommonListPage.vue';
 import { onLoad } from '@dcloudio/uni-app';
@@ -41,10 +46,11 @@ async function loadData(
     case 0: api = ProjectsContent; break;
     default:
     case 1: api = ProductsContent; break;
+    case 3: api = SeminarContent; break;
   }
   const res = (await api.getContentList(new GetContentListParams().setSelfValues({
     ichType: tabSelect !== 0 || dropDownValues[0] == 0 ? undefined: dropDownValues[0],
-    level: tabSelect !== 0 || dropDownValues[1] == 0 ? undefined: dropDownValues[1],
+    level: (tabSelect !== 0 && tabSelect !== 2) || dropDownValues[1] == 0 ? undefined: dropDownValues[1],
     region: tabSelect !== 0 || dropDownValues[2] == 0 ? undefined: dropDownValues[2],
     keywords: searchText,
   }), page, pageSize));
@@ -72,7 +78,7 @@ onLoad(async (querys) => {
       id: item.id,
       name: item.title,
     }))),
-    activeTab: 0,
+    activeTab: [0],
     defaultSelectedValue: 0,
   });
   const levels = await CommonContent.getCategoryList(2);
@@ -84,7 +90,7 @@ onLoad(async (querys) => {
       id: item.id,
       name: item.title,
     }))),
-    activeTab: 0,
+    activeTab: [0,3],
     defaultSelectedValue: querys?.level ? (levels.find(p => p.title == querys.level)?.id ?? 0) : 0,
   });
   dropdownNames.value.push({ 
@@ -95,7 +101,7 @@ onLoad(async (querys) => {
       id: item.id,
       name: item.title,
     }))),
-    activeTab: 0,
+    activeTab: [0],
     defaultSelectedValue: 0,
   });
 })

+ 7 - 0
src/pages/inhert/seminar/details.vue

@@ -0,0 +1,7 @@
+<template>
+  <DetailsCommon commonRefName="项目" commonRefTarget="intangible" />
+</template>
+
+<script setup lang="ts">
+import DetailsCommon from '../intangible/DetailsCommon.vue';
+</script>

+ 18 - 22
src/pages/inhert/village/list.vue

@@ -1,11 +1,14 @@
 <template>
   <CommonListPage 
+    ref="list"
     title="传统村落"
     itemType="image-large-2"
     detailsPage="custom"
     showTotal
     :dropDownNames="dropdownNames"
     :load="loadData" 
+    :tabs="tabs"
+    :startTabIndex="1"
     @goCustomDetails="goDetails"
   />
 </template>
@@ -13,21 +16,22 @@
 <script setup lang="ts">
 import CommonListPage, { type DropDownNames } from '@/pages/article/common/CommonListPage.vue';
 import { onMounted, ref } from 'vue';
-import VillageApi, { VillageListItem } from '@/api/inhert/VillageApi';
+import VillageApi from '@/api/inhert/VillageApi';
 import { navTo } from '@/common/utils/PageAction';
+import CommonContent from '@/api/CommonContent';
 
 const dropdownNames = ref<DropDownNames[]>([]);
+const list = ref();
 
 async function loadData(
   page: number, 
   pageSize: number,
   searchText: string,
-  dropDownValues: number[]
+  dropDownValues: number[],
+  tabSelect: number,
 ) {
 
-  const list = page == 1 ? await VillageApi.getVallageList(
-    dropDownValues[0] == 0 ? undefined : dropDownValues[0]
-  ) : [];
+  const list = page == 1 ? await VillageApi.getVallageList(tabSelect) : [];
   list.filter((p) => !searchText || p.title.includes(searchText)).forEach((p) => {
     p.desc = p.ichName as string;
     p.badge = p.district;
@@ -45,23 +49,15 @@ function goDetails(item: any) {
   navTo('details', { id: item.id })
 }
 
+const tabs = ref<{id: number, name: string}[]>();
+
 onMounted(async () => {
-  dropdownNames.value.push({ 
-    options: [
-      {
-        id: 0, 
-        name: '全部'
-      },
-      {
-        id: 1, 
-        name: '传统村落'
-      },
-      {
-        id: 2, 
-        name: '特色村舍'
-      },
-    ],
-    defaultSelectedValue: 1,
-  });
+  const res = await CommonContent.getCategoryList(151);
+  const it1 = res.find(p => p.title == '国家级');
+  const it2 = res.find(p => p.title == '省级');
+  if (it1) it1.title = '特色村舍';
+  if (it2) it2.title = '传统村落';
+  tabs.value = res.map((p) => ({ id: p.id, name: p.title }));
+  list.value.load();
 })
 </script>

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

@@ -0,0 +1,52 @@
+<template>
+  <CommonListPage 
+    title="闽南美食"
+    itemType="image-large-2"
+    :detailsPage="[
+      '/pages/inhert/intangible/details',
+      '/pages/article/common/details',
+    ]"
+    showTotal
+    :dropDownNames="dropdownNames"
+    :load="loadData" 
+    :tabs="[
+      { id: 0, name: '非遗美食' },
+      { id: 1, name: '美食资讯' },
+    ]"
+  />
+</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[]>([]);
+
+async function loadData(
+  page: number, 
+  pageSize: number,
+  searchText: string,
+  dropDownValues: number[],
+  tabSelect: number,
+) {
+  let res;
+  switch (tabSelect) {
+    case 0:
+      res = await ProjectsContent.getContentList(new GetContentListParams()
+        .setKeywords('美食 ' + searchText)
+      , page, pageSize);
+      break;
+    case 1:
+    default:
+      res = await CommonContent.getContentList(new GetContentListParams()
+        .setKeywords(searchText)
+        .setModelId(8)
+        .setMainBodyColumnId(103)
+      , page, pageSize);
+      break;
+  }
+  return { list: res.list, total: res.total }
+}
+</script>