Explorar o código

📦 按要求修改细节问题,增加传承谱系,增加来源

快乐的梦鱼 hai 2 meses
pai
achega
d46c1096de

+ 2 - 2
src/api/CommonContent.ts

@@ -40,7 +40,7 @@ export class GetColumListParams extends DataModel<GetColumListParams> {
   /**
    * 内容数量,默认4
    */
-  size = 4;
+  size?: number;
 }
 export class GetContentListParams extends DataModel<GetContentListParams> {
   
@@ -110,7 +110,7 @@ export class GetContentListParams extends DataModel<GetContentListParams> {
   /**
    * 内容数量,默认4
    */
-  size = 4;
+  size ?: number;
   /**
    * 关键字查询
    */

+ 2 - 2
src/common/components/SimplePageContentLoader.vue

@@ -11,7 +11,7 @@
   >
     <Empty
       mode="page"
-      :text="loader.loadError.value"
+      :description="loader.loadError.value"
     >
       <Height :height="20" />
       <Button text="重试" @click="handleRetry" />
@@ -26,7 +26,7 @@
   >
     <Empty
       mode="data"
-      :text="emptyView?.text ?? '暂无数据'"
+      :description="emptyView?.text ?? '暂无数据'"
     >
       <view v-if="emptyView?.button" style="margin-top: 20rpx">
         <Button

+ 7 - 0
src/components/nav/Tabs.vue

@@ -48,6 +48,7 @@
               class="tab-item-text"
               :style="{
                 color: tab.disabled ? themedDisableTextColor : (currentIndex == index ? themedActiveTextColor : themedTextColor),
+                whiteSpace: props.noWrap ? 'nowrap' : 'normal',
                 ...(currentIndex == index ? activeTextStyle : textStyle),
               }"
             >
@@ -155,6 +156,11 @@ export interface TabsProps {
    */
   autoScroll?: boolean,
   /**
+   * 是否禁止标签文字换行
+   * @default true
+   */
+  noWrap?: boolean,
+  /**
    * 标签宽度,在 autoItemWidth 为 false 时有效。
    * 如果设置为-1,则根据文字宽度自动调整。
    * @default 100 (rpx)
@@ -218,6 +224,7 @@ const props = withDefaults(defineProps<TabsProps>(), {
   indicatorAnim: true,
   showIndicator: true,
   autoScroll: true,
+  noWrap: true,
   defaultItemWidth: () => propGetThemeVar('TabsDefaultItemWidth', 120),
   defaultIndicatorWidth: () => propGetThemeVar('TabsDefaultIndicatorWidth', 100),
   textColor: () => propGetThemeVar('TabsTextColor', 'text.title'),

+ 7 - 0
src/pages.json

@@ -62,6 +62,13 @@
       }
     },
     {
+      "path": "pages/travel/fashion/list",
+      "style": {
+        "navigationBarTitleText": "闽南歌曲",
+        "enablePullDownRefresh": true
+      }
+    },
+    {
       "path": "pages/travel/nav/navto",
       "style": {
         "navigationBarTitleText": "导航"

+ 4 - 2
src/pages/article/common/CommonListPage.vue

@@ -111,7 +111,7 @@
 </template>
 
 <script setup lang="ts">
-import { computed, onMounted, ref, watch, type PropType } from 'vue';
+import { computed, nextTick, onMounted, ref, watch, type PropType } from 'vue';
 import { useSimplePageListLoader } from '@/common/composeabe/SimplePageListLoader';
 import { navTo } from '@/components/utils/PageAction';
 import SimplePageListLoader from '@/common/components/SimplePageListLoader.vue';
@@ -270,7 +270,9 @@ function handleChangeDropDownValue(index: number, value: number) {
   listLoader.loadData(undefined, true);
 }
 function handleTabClick(e: any) {
-  listLoader.loadData(undefined, true);
+  nextTick(() => {
+    listLoader.loadData(undefined, true);
+  })
 }
 function doSearch() {
   listLoader.loadData(undefined, true);

+ 1 - 0
src/pages/article/common/DetailTabPage.vue

@@ -52,6 +52,7 @@
                 :content="loader.content.value.content"
                 :tagStyle="commonParserStyle"
               />
+              <text v-if="!loader.content.value.intro && !loader.content.value.content">暂无简介</text>
             </template>
             <!-- 图片 -->
             <template v-else-if="tabCurrentId == 1">

+ 5 - 0
src/pages/article/common/list.vue

@@ -40,6 +40,11 @@ async function loadData(
     region: querys.value.region || undefined,
   }), page, pageSize);
 
+  for (const element of res.list || []) {
+    if (!element.desc && element.from)
+      element.desc = `来源:${element.from}`;
+  }
+
   return res;
 }
 </script>

+ 49 - 1
src/pages/article/details.vue

@@ -42,6 +42,24 @@
               :content="loader.content.value.content"
               :tagStyle="commonParserStyle"
             />
+            <text v-if="emptyContent">暂无简介</text>
+          </view>
+          
+          <!-- 推荐 -->
+          <view v-if="recommendListLoader.content.value?.length" class="d-flex flex-col p-3">
+            <text class="size-base text-bold mb-3">推荐文章</text>
+            <Box2LineImageRightShadow
+              class="w-100"
+              titleColor="title-text"
+              v-for="item in recommendListLoader.content.value"
+              :key="item.id"
+              :image="item.thumbnail || item.image || AppCofig.defaultImage"
+              :title="item.title"
+              :desc="item.desc"
+              :badge="item.badge"
+              :wideImage="true"
+              @click="goDetails(item.id)"
+            />
           </view>
 
           <ContentNote />
@@ -74,6 +92,12 @@ import commonParserStyle from "@/common/style/commonParserStyle";
 import SimplePageContentLoader from "@/common/components/SimplePageContentLoader.vue";
 import ContentNote from "../parts/ContentNote.vue";
 import Parse from "@/components/display/parse/Parse.vue";
+import { computed } from "vue";
+import { useSimpleDataLoader } from "@/common/composeabe/SimpleDataLoader";
+import { navTo } from "@/components/utils/PageAction";
+import CommonContent, { GetContentListParams } from "@/api/CommonContent";
+import Box2LineImageRightShadow from "../parts/Box2LineImageRightShadow.vue";
+import AppCofig from "@/common/config/AppCofig";
 
 const loader = useSimplePageContentLoader<
   GetContentDetailItem, 
@@ -89,7 +113,31 @@ const loader = useSimplePageContentLoader<
 
 const { onPreviewImage } = useSwiperImagePreview(() => loader.content.value?.images || [])
 
-useLoadQuerys({ id : 0, }, (p) => loader.loadData(p));
+const emptyContent = computed(() => (loader.content.value?.content || '').trim() === '')
+
+const recommendListLoader = useSimpleDataLoader(async () => {
+  if (!querys.value.modelId || !querys.value.mainBodyColumnId)
+    return []
+  return (await CommonContent.getContentList(new GetContentListParams()
+    .setModelId(querys.value.modelId)
+    .setMainBodyColumnId(querys.value.mainBodyColumnId)
+  , 1, 10)).list.filter((p) => p.id !== querys.value.id);
+});
+
+
+function goDetails(id: number) {
+  navTo('/pages/article/details', { 
+    id, 
+    mainBodyColumnId: querys.value.mainBodyColumnId, 
+    modelId: querys.value.modelId 
+  });
+}
+
+const { querys } = useLoadQuerys({ 
+  id: 0,
+  mainBodyColumnId: 0,
+  modelId: 0,
+}, (t) => loader.loadData(t));
 
 function getPageShareData() {
   if (!loader.content.value)

+ 1 - 1
src/pages/discover.vue

@@ -311,7 +311,7 @@ const topicsData = useSimpleDataLoader(async () => {
 });
 
 function goAnswer() {
-  const url = `https://mn.wenlvti.net/app_static/minnan-answer?token=${authStore.token}#/pages/home/dashboard`
+  const url = `https://mn.wenlvti.net/app_static/minnan-answer/index.html?token=${authStore.token}&t=${new Date().getTime()}#/pages/home/dashboard`
   console.log(url)
   navTo('/pages/article/web/ewebview', { url: url })
 }

+ 32 - 1
src/pages/inhert.vue

@@ -110,6 +110,19 @@
             />
           </view>
         </scroll-view>
+        <view class="d-flex flex-col wing-l">
+          <Box1AudioPlay
+            class="w-100 mt-3" 
+            :title="indexAudioPlayer.currentTitle.value"
+            :image="indexAudioPlayer.currentItem?.value?.image"
+            :playState="indexAudioPlayer.isPlaying.value"
+            :playTime="indexAudioPlayer.timeString.value"
+            @playPauseClick="indexAudioPlayer.playpause"
+            @nextClick="indexAudioPlayer.next"
+            @prevClick="indexAudioPlayer.prev"
+            @click="handleGoAudioList"
+          />
+        </view>
       </SimplePageContentLoader>
 
       <view class="d-flex flex-col wing-l">
@@ -203,7 +216,7 @@
 <script setup lang="ts">
 import { navTo } from '@/components/utils/PageAction';
 import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
-import { GetContentListParams } from '@/api/CommonContent';
+import CommonContent, { GetContentListParams } from '@/api/CommonContent';
 import Tabbar from '@/common/components/tabs/tabbar.vue';
 import HomeTitle from './parts/HomeTitle.vue';
 import Box2LineLargeImageUserShadow from './parts/Box2LineLargeImageUserShadow.vue';
@@ -217,6 +230,7 @@ import { useHomePageMiniCommonListGoMoreAndGoDetail } from './article/common/Com
 import ProductsContent from '@/api/inheritor/ProductsContent';
 import InheritorContent from '@/api/inheritor/InheritorContent';
 import { onShareTimeline, onShareAppMessage } from '@dcloudio/uni-app';
+import { useSimpleListAudioPlayer } from '@/common/composeabe/SimpleAudioPlayer';
 
 const artifactData = useSimpleDataLoader(async () => 
   (await UnmoveableContent.getContentList(new GetContentListParams(), 1, 4)).list.map(p => ({
@@ -268,6 +282,23 @@ const productsData = useSimpleDataLoader(async () =>
   }))
 );
 
+const indexAudioPlayer = useSimpleListAudioPlayer(async () => {
+  return (await CommonContent.getContentList(new GetContentListParams()
+    .setModelId(5)
+    .setMainBodyColumnId(313)
+  , 1, 6)).list.sort(() => Math.random()>0.5?-1:1).map((p) => {
+    return {
+      id: p.id,
+      title: p.title,
+      image: p.thumbnail || p.image,
+      src: p.audio as string, 
+    }
+  });
+})
+function handleGoAudioList() {
+  navTo('/pages/inhert/language/list') 
+}
+
 const {
   loader: corseData,
   goList: goCourseList,

+ 4 - 5
src/pages/inhert/artifact/list.vue

@@ -1,14 +1,14 @@
 <template>
   <view class="d-flex flex-column bg-base">
 
-    <view class="top-tab bg-base">
+   <!--  <view class="top-tab bg-base">
       <Tabs
         :tabs="tabs" 
         :currentIndex="tab"
         class="top-tab"
         @click="(e: any) => tab = e.index"
       />
-    </view>
+    </view> -->
 
     <view class="d-flex flex-col p-2">
       <SearchBar
@@ -43,18 +43,17 @@
 
 <script setup lang="ts">
 import { ref, watch } from 'vue';
-import CommonContent, { GetContentListParams } from '@/api/CommonContent';
 import { useSimplePageListLoader } from '@/common/composeabe/SimplePageListLoader';
+import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
 import { navTo } from '@/components/utils/PageAction';
+import CommonContent, { GetContentListParams } from '@/api/CommonContent';
 import MoveableContent from '@/api/inheritor/MoveableContent';
 import UnmoveableContent from '@/api/inheritor/UnmoveableContent';
 import SimplePageListLoader from '@/common/components/SimplePageListLoader.vue';
 import Box2LineLargeImageUserShadow from '@/pages/parts/Box2LineLargeImageUserShadow.vue';
 import SimpleDropDownPicker from '@/common/components/SimpleDropDownPicker.vue';
-import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
 import AppCofig from '@/common/config/AppCofig';
 import Tabs from '@/components/nav/Tabs.vue';
-import S from '@/components/typography/S.vue';
 import SearchBar from '@/components/form/SearchBar.vue';
 
 const categoryData = useSimpleDataLoader(async () => 

+ 22 - 8
src/pages/inhert/intangible/DetailsCommon.vue

@@ -15,18 +15,24 @@
       },
       {
         id: 7,
-        text: '非遗作品',
+        text: '传承谱系',
         width: 180,
         visible: true,
       },
       {
         id: 8,
-        text: '相关资讯',
+        text: '非遗作品',
         width: 180,
         visible: true,
       },
       {
         id: 9,
+        text: '相关资讯',
+        width: 180,
+        visible: true,
+      },
+      {
+        id: 10,
         text: '地理位置',
         width: 180,
         visible: true,
@@ -61,6 +67,11 @@
         />
       </template>
       <template v-else-if="tabCurrentId==7">
+        <view class="d-flex flex-col mt-3 mb-2">
+          <Parse :content="content.pedigree" :tagStyle="commonParserStyle" />
+        </view>
+      </template>
+      <template v-else-if="tabCurrentId==8">
         <!-- 非遗作品 -->
         <CommonListPage 
           :showSearch="false"
@@ -73,7 +84,7 @@
           }"
         />
       </template>
-      <template v-else-if="tabCurrentId==8">
+      <template v-else-if="tabCurrentId==9">
         <!-- 相关资讯 -->
         <CommonListPage 
           :showSearch="false"
@@ -86,7 +97,7 @@
           }"
         />
       </template>
-      <template v-else-if="tabCurrentId==9">
+      <template v-else-if="tabCurrentId==10">
         <!-- 地理位置 -->
         <view class="d-flex flex-col mt-3 mb-2">
          <HomeTitle title="地理位置" />
@@ -111,7 +122,7 @@
               <text class="iconfont icon-navigation"></text>
               <text class="address">{{ content.address }}</text>
             </view>
-            <view class="d-flex flex-row align-center" @click="navTo('/pages/travel/nav/navto', {
+            <view class="d-flex flex-row align-center flex-shrink-0" @click="navTo('/pages/travel/nav/navto', {
               latitude: content.latitude,
               longitude: content.longitude,
             })">
@@ -211,6 +222,8 @@ import ProductsContent from "@/api/inheritor/ProductsContent";
 import SeminarContent from "@/api/inheritor/SeminarContent";
 import ImagesUrls from "@/common/config/ImagesUrls";
 import Tag from "@/components/display/Tag.vue";
+import Parse from "@/components/display/parse/Parse.vue";
+import commonParserStyle from "@/common/style/commonParserStyle";
 
 defineProps({	
   commonRefName : {
@@ -231,9 +244,10 @@ async function load(id: number, tabsArray: Ref<TabControlItem[]>) {
   );
   tabsArray.value[4].visible = Boolean(d.ichSitesList && (d.ichSitesList as any[]).length > 0);
   tabsArray.value[5].visible = Boolean(d.inheritorsList && (d.inheritorsList as any[]).length > 0);
-  tabsArray.value[6].visible = Boolean(d.worksList && (d.worksList as any[]).length > 0);
-  tabsArray.value[7].visible = Boolean(d.associationMeList && (d.associationMeList as any[]).length > 0);
-  tabsArray.value[8].visible = Boolean(d.longitude && d.latitude);
+  tabsArray.value[6].visible = Boolean(d.pedigree);
+  tabsArray.value[7].visible = Boolean(d.worksList && (d.worksList as any[]).length > 0);
+  tabsArray.value[8].visible = Boolean(d.associationMeList && (d.associationMeList as any[]).length > 0);
+  tabsArray.value[9].visible = Boolean(d.longitude && d.latitude);
   return d;
 }
 async function loadSubList(page: number, pageSize: number, content: any, subList: string) {

+ 2 - 2
src/pages/introduction/custom/list.vue

@@ -10,8 +10,8 @@
     :dropDownNames="dropdownNames"
     :load="loadData" 
     :tabs="[
-      { id: 0, name: '民俗资讯' },
-      { id: 1, name: '非遗民俗' },
+      { id: 0, text: '民俗资讯' },
+      { id: 1, text: '非遗民俗' },
     ]"
     :detailsParams="{
       modelId: 4,

+ 20 - 4
src/pages/introduction/food/list.vue

@@ -10,8 +10,9 @@
     :dropDownNames="dropdownNames"
     :load="loadData"
     :tabs="[
-      { id: 0, name: '美食资讯' },
-      { id: 1, name: '非遗美食' },
+      { id: 0, text: '饮食文化' },
+      { id: 1, text: '非遗美食' },
+      { id: 2, text: '美食资讯' },
     ]"
   />
 <!--   
@@ -35,6 +36,22 @@ async function loadData(
 ) {
   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)
@@ -48,8 +65,7 @@ async function loadData(
         ]
       })
       break;
-    case 0:
-    default:
+    case 2:
       res = await CommonContent.getContentList(new GetContentListParams()
         .setKeywords(searchText)
         .setModelId(8)

+ 1 - 20
src/pages/travel.vue

@@ -190,13 +190,7 @@ const subTabs = [
   { 
     name: '闽南歌曲', 
     icon: CategoryIcon6 , 
-    onClick: () => navTo('/pages/article/common/list', {
-      title: '闽南歌曲',
-      mainBodyColumnId: 315,
-      modelId: 16,
-      itemType: 'article-common',
-      detailsPage: '/pages/video/details',
-    }) 
+    onClick: () => navTo('/pages/travel/fashion/list')
   },
 ]
 
@@ -236,19 +230,6 @@ const {
   detailsPage: '/pages/article/details',
 });
 
-const activityData = useSimpleDataLoader(async () => [
-  {
-    title: '闽南文化节',
-    desc: '泉州市区',
-    right: '报名中',
-  },
-  {
-    title: '泉州市区',
-    desc: '泉州市区',
-    right: '已截至',
-  },
-]);
-
 onShareTimeline(() => {
   return {}; 
 })

+ 1 - 1
src/pages/travel/calendar.vue

@@ -116,7 +116,7 @@ const tabs = [
   },
   {
     id: 3,
-    name: '信祭祀'
+    name: '信祭祀'
   },
   {
     id: 4,

+ 65 - 0
src/pages/travel/fashion/list.vue

@@ -0,0 +1,65 @@
+<template>
+  <CommonListPage 
+    title="闽南歌曲"
+    itemType="article-common"
+    showTotal
+    detailsPage="/pages/video/details"
+    :dropDownNames="dropdownNames"
+    :detailsParams="detailsParams"
+    :tabs="[
+      {
+        id: 191,
+        text: '闽南语经典歌曲',
+      },
+      {
+        id: 315,
+        text: '闽南语原创歌曲',
+      },
+    ]"
+    :load="loadData" 
+  />
+</template>
+
+<script setup lang="ts">
+import CommonContent, { GetContentListParams } from '@/api/CommonContent';
+import CommonListPage, { type DropDownNames } from '@/pages/article/common/CommonListPage.vue';
+import { onMounted, ref } from 'vue';
+
+const dropdownNames = ref<DropDownNames[]>([]);
+
+async function loadData(
+  page: number, 
+  pageSize: number,
+  searchText: string,
+  dropDownValues: number[],
+  tabId: number,
+) {
+  detailsParams.value.mainBodyColumnId = tabId;
+  const res = (await CommonContent.getContentList(new GetContentListParams()
+    .setModelId(16)
+    .setMainBodyColumnId(tabId)
+    .setKeywords(searchText)
+    .setSelfValues({
+
+    })
+  , page, pageSize));
+  res.list.forEach((p) => {
+    p.desc = p.ichName as string;
+    p.bottomTags = [
+      p.levelText, 
+      p.batchText,
+      p.ichTypeText,
+    ];
+  })
+  return res;
+}
+
+const detailsParams = ref({
+  mainBodyColumnId: 0,
+  modelId: 16,
+});
+
+onMounted(async () => {
+  
+})
+</script>

+ 49 - 1
src/pages/video/details.vue

@@ -35,9 +35,28 @@
           </view>
           <view class="content radius-l bg-light p-3">
             <Parse :content="loader.content.value.content" :tagStyle="commonParserStyle" />
+            <text v-if="emptyContent" class="size-s color-text-content-second">暂无简介</text>
+          </view>
+
+          <!-- 推荐视频 -->
+          <view v-if="recommendListLoader.content.value?.length" class="d-flex flex-col p-3">
+            <text class="size-base text-bold mb-3">推荐视频</text>
+            <Box2LineImageRightShadow
+              class="w-100"
+              titleColor="title-text"
+              v-for="item in recommendListLoader.content.value"
+              :key="item.id"
+              :image="item.thumbnail || item.image || AppCofig.defaultImage"
+              :title="item.title"
+              :desc="item.desc"
+              :badge="item.badge"
+              :wideImage="true"
+              @click="goDetails(item.id)"
+            />
           </view>
         </view>
         <ContentNote />
+
         <view class="bottom-actions">
           <view class="action">
             <text class="iconfont icon-like"></text>
@@ -63,6 +82,12 @@ import { useLoadQuerys } from "@/common/composeabe/LoadQuerys";
 import { DataDateUtils } from "@imengyu/js-request-transform";
 import ContentNote from "../parts/ContentNote.vue";
 import Parse from "@/components/display/parse/Parse.vue";
+import { useSimpleDataLoader } from "@/common/composeabe/SimpleDataLoader";
+import CommonContent, { GetContentListParams } from "@/api/CommonContent";
+import Box2LineImageRightShadow from "../parts/Box2LineImageRightShadow.vue";
+import AppCofig from "@/common/config/AppCofig";
+import { navTo } from "@/components/utils/PageAction";
+import { computed } from "vue";
 
 const loader = useSimplePageContentLoader<
   GetContentDetailItem, 
@@ -75,7 +100,30 @@ const loader = useSimplePageContentLoader<
   return res;
 });
 
-useLoadQuerys({ id: 0 }, (t) => loader.loadData(t));
+const recommendListLoader = useSimpleDataLoader(async () => {
+  if (!querys.value.modelId || !querys.value.mainBodyColumnId)
+    return []
+  return (await CommonContent.getContentList(new GetContentListParams()
+    .setModelId(querys.value.modelId)
+    .setMainBodyColumnId(querys.value.mainBodyColumnId)
+  , 1, 10)).list.filter((p) => p.id !== querys.value.id);
+});
+
+const emptyContent = computed(() => (loader.content.value?.content || '').trim() === '')
+
+function goDetails(id: number) {
+  navTo('/pages/video/details', { 
+    id, 
+    mainBodyColumnId: querys.value.mainBodyColumnId, 
+    modelId: querys.value.modelId 
+  });
+}
+
+const { querys } = useLoadQuerys({ 
+  id: 0,
+  mainBodyColumnId: 0,
+  modelId: 0,
+}, (t) => loader.loadData(t));
 </script>
 
 <style lang="scss">