浏览代码

🎨 优化修改细节

快乐的梦鱼 1 月之前
父节点
当前提交
364749c900

+ 3 - 0
.gitignore

@@ -22,6 +22,9 @@ unpackage/
 src/assets/scss/mengyuu/index.css
 src/assets/scss/mengyuu/index.css.map
 3dtest/
+pack/assets/
+pack/index.html
+pack/favicon.ico
 
 # Editor directories and files
 .vscode/*

+ 0 - 11
components.d.ts

@@ -13,11 +13,8 @@ declare module 'vue' {
     AEmpty: typeof import('ant-design-vue/es')['Empty']
     APagination: typeof import('ant-design-vue/es')['Pagination']
     ASpin: typeof import('ant-design-vue/es')['Spin']
-    Box1: typeof import('./src/components/small/Box1.vue')['default']
-    Box2: typeof import('./src/components/small/Box2.vue')['default']
     Clock: typeof import('./src/components/small/Clock.vue')['default']
     CommonCatalog: typeof import('./src/components/content/CommonCatalog.vue')['default']
-    copy: typeof import('./src/components/SimplePageListContentLoader copy.vue')['default']
     GridList: typeof import('./src/components/small/GridList.vue')['default']
     Header: typeof import('./src/components/parts/Header.vue')['default']
     HoriontalLargeList: typeof import('./src/components/small/HoriontalLargeList.vue')['default']
@@ -25,11 +22,7 @@ declare module 'vue' {
     ImageLine: typeof import('./src/components/small/ImageLine.vue')['default']
     ImagePreview: typeof import('./src/components/small/ImagePreview.vue')['default']
     ImageSwiper: typeof import('./src/components/small/ImageSwiper.vue')['default']
-    NavBar: typeof import('./src/components/content/NavBar.vue')['default']
     Page: typeof import('./src/components/parts/Page.vue')['default']
-    PageLeftTitleRightContent: typeof import('./src/components/parts/PageLeftTitleRightContent.vue')['default']
-    PageRoot: typeof import('./src/components/parts/PageRoot.vue')['default']
-    PageTopTitleBottomContent: typeof import('./src/components/parts/PageTopTitleBottomContent.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     ScrollLeftRightButton: typeof import('./src/components/small/ScrollLeftRightButton.vue')['default']
@@ -40,10 +33,6 @@ declare module 'vue' {
     SimplePopup: typeof import('./src/components/SimplePopup.vue')['default']
     SimpleRemoveRichHtml: typeof import('./src/components/SimpleRemoveRichHtml.vue')['default']
     SimpleRichHtml: typeof import('./src/components/SimpleRichHtml.vue')['default']
-    SimpleScrollView: typeof import('./src/components/SimpleScrollView.vue')['default']
     Tab: typeof import('./src/components/small/Tab.vue')['default']
-    TabNav: typeof import('./src/components/small/TabNav.vue')['default']
-    VerticalImageItem: typeof import('./src/components/small/VerticalImageItem.vue')['default']
-    Viewer: typeof import('./src/components/3d/Viewer.vue')['default']
   }
 }

+ 6 - 0
env.d.ts

@@ -1 +1,7 @@
 /// <reference types="vite/client" />
+
+declare const plus: any;
+
+declare interface Window {
+  plus: any;
+}

二进制
logo.png


+ 6 - 3
pack/manifest.json

@@ -1,7 +1,7 @@
 {
     "@platforms" : [ "android", "iPhone", "iPad" ],
-    "id" : "H5A0733B1", /*应用的标识*/
-    "name" : "湖里文旅展示大屏", /*应用名称,程序桌面图标名称*/
+    "id" : "H5F7BF079", /*应用的标识*/
+    "name" : "闽南文化TV版", /*应用名称,程序桌面图标名称*/
     "version" : {
         "name" : "1.0", /*应用版本名称*/
         "code" : "100"
@@ -10,7 +10,7 @@
     "icons" : {
         "72" : "icon.png"
     },
-    "launch_path" : "https://mncdn.wenlvti.net/app_static/huli-showroom/index.html", /*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/
+    "launch_path" : "index.html", /*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/
     "developer" : {
         "name" : "", /*开发者名称*/
         "email" : "", /*开发者邮箱地址*/
@@ -202,6 +202,9 @@
                     "xhdpi" : "", /*720P高分屏启动图片,分辨率:720x1242*/
                     "xxhdpi" : "" /*1080P高分屏启动图片,分辨率:1080x1882*/
                 }
+            },
+            "ios" : {
+                "dSYMs" : false
             }
         }
     },

+ 4 - 4
package-lock.json

@@ -8,7 +8,7 @@
       "name": "wenlv-huli-showroom",
       "version": "0.0.0",
       "dependencies": {
-        "@imengyu/imengyu-utils": "^0.0.14",
+        "@imengyu/imengyu-utils": "^0.0.15",
         "@imengyu/js-request-transform": "^0.3.5",
         "@imengyu/vue-scroll-rect": "^0.1.7",
         "@vuemap/vue-amap": "^2.1.16",
@@ -2187,9 +2187,9 @@
       }
     },
     "node_modules/@imengyu/imengyu-utils": {
-      "version": "0.0.14",
-      "resolved": "https://registry.npmjs.org/@imengyu/imengyu-utils/-/imengyu-utils-0.0.14.tgz",
-      "integrity": "sha512-V/W1Te95958soeDFrK71hafr2HUi23HDED3h+hhJswvXun3AsVIibO1E9p56EaLp/epM7rBxXPSCvN29BdbgOw==",
+      "version": "0.0.15",
+      "resolved": "https://registry.npmjs.org/@imengyu/imengyu-utils/-/imengyu-utils-0.0.15.tgz",
+      "integrity": "sha512-tsM/PexQsWTMVlX4y9cdrhWy1ur9NojfmH96ywaPv8f+OdojBquqha+tHrKFKnSl8oU73OXkktPgwGqMCviunw==",
       "license": "MIT",
       "dependencies": {
         "@imengyu/js-request-transform": "^0.3.6"

+ 2 - 2
package.json

@@ -7,11 +7,11 @@
     "dev": "vite",
     "build": "run-p type-check \"build-only {@}\" --",
     "preview": "vite preview",
-    "build-only": "vite build",
+    "build-only": "vite build && node .\\src\\scripts\\copyDist.cjs",
     "type-check": "vue-tsc --build"
   },
   "dependencies": {
-    "@imengyu/imengyu-utils": "^0.0.14",
+    "@imengyu/imengyu-utils": "^0.0.15",
     "@imengyu/js-request-transform": "^0.3.5",
     "@imengyu/vue-scroll-rect": "^0.1.7",
     "@vuemap/vue-amap": "^2.1.16",

+ 3 - 1
src/App.vue

@@ -1,10 +1,12 @@
 <script setup lang="ts">
 import zhCN from 'ant-design-vue/es/locale/zh_CN';
 import { RouterView } from 'vue-router'
+import { useTvFocusImprovement } from './composeable/TvFocusImprovement';
+
+useTvFocusImprovement(true);
 </script>
 
 <template>
-  
   <a-config-provider
     :locale="zhCN"
     :theme="{

二进制
src/assets/images/AppLogo.png


+ 6 - 2
src/components/small/ImageSwiper.vue

@@ -9,8 +9,8 @@
       </slot>
     </Slide>
     <template #addons>
-      <Navigation />
-      <Pagination />
+      <Navigation v-if="showAddons" />
+      <Pagination v-if="showAddons" />
     </template>
   </Carousel>
 </template>
@@ -28,6 +28,10 @@ const props = defineProps({
     type: Object as PropType<Array<any>>,
     default: () => ([]),
   },
+  showAddons: {
+    type: Boolean,
+    default: true,
+  }
 })
 const carouselConfig =  {
   wrapAround: true,

+ 4 - 0
src/composeable/HtmlStyles.ts

@@ -0,0 +1,4 @@
+export const CommonHtmlStyles = {
+  img: 'max-width: 100%; height: auto;border-radius:4px',
+  p: 'margin-bottom: 5px',
+}

+ 90 - 0
src/composeable/TvFocusImprovement.ts

@@ -0,0 +1,90 @@
+import { Debounce } from "@imengyu/imengyu-utils";
+import { onBeforeUnmount, onMounted } from "vue";
+import { useRouter } from "vue-router";
+
+/**
+ * 安卓电视焦点控制帮助类
+ * @param fromApp 是否从应用启动
+ * @returns 
+ */
+export function useTvFocusImprovement(fromApp = false) {
+  
+  const router = useRouter()
+  if (fromApp) {
+    router.afterEach( (to, from) => {
+      setTimeout(() => {
+        focusFirstElement();
+      }, 1000);
+    });
+  }
+
+  function focusFirstElement() {
+    const focusableElements = getFocusableElement();
+    if (focusableElements.length) {
+      for (const element of focusableElements) {
+        if (element.classList.contains('active')) {//优先激活选中条目
+          element.focus();
+          return;
+        }
+      }
+      focusableElements[0].focus();
+    }
+  }
+  function getFocusableElement() {
+    return document.querySelectorAll<
+      | HTMLButtonElement
+      | HTMLAnchorElement
+      | HTMLInputElement
+      | HTMLSelectElement
+      | HTMLTextAreaElement
+    >(
+      'a[href], button, input, select, textarea, [tabindex]:not([tabindex="-1"])'
+    );
+  }
+
+  const backDebounce = new Debounce(1000, () => router.back());
+
+  function handleKeyUp(e: KeyboardEvent) {
+    if (e.key === 'Enter') {
+      if (document.activeElement)
+        (document.activeElement as HTMLElement).click();
+    } else if (e.key === 'Backspace') {
+      handleBackButton();
+    }
+  }
+  function handleBackButton() {
+    if (router.currentRoute.value.name === 'Home')
+      plus.runtime.quit();
+    else
+      backDebounce.execute();
+  }
+
+  
+  if (fromApp) {
+    if(window.plus) {
+      plusReady();  
+    } else {
+      document.addEventListener("plusready", plusReady, false);  
+    }  
+    // 扩展API准备完成后要执行的操作  
+    function plusReady(){ 
+      console.log('plusReady!');
+      plus.key.addEventListener("backbutton", handleBackButton);
+    }  
+
+    onMounted(() => {
+      window.addEventListener('keyup', handleKeyUp);
+      setTimeout(() => {
+        focusFirstElement();
+      }, 2000);
+    })
+    onBeforeUnmount(() => {
+      window.removeEventListener('keyup', handleKeyUp);
+    });
+  }
+
+  return {
+    focusFirstElement,
+    getFocusableElement,
+  }
+}

+ 52 - 0
src/scripts/copyDist.cjs

@@ -0,0 +1,52 @@
+const fs = require('fs');
+const path = require('path');
+
+// 定义源目录和目标目录路径
+const srcDir = path.resolve(__dirname, '../..', 'dist');
+const destDir = path.resolve(__dirname, '../..', 'pack');
+
+/**
+ * 递归拷贝目录内容
+ * @param {string} src - 源目录路径
+ * @param {string} dest - 目标目录路径
+ */
+function copyDir(src, dest) {
+    // 检查源目录是否存在
+    if (!fs.existsSync(src)) {
+        console.error(`错误:源目录不存在 - ${src}`);
+        process.exit(1);
+    }
+
+    // 创建目标目录(如果不存在)
+    if (!fs.existsSync(dest)) {
+        fs.mkdirSync(dest, { recursive: true });
+        console.log(`创建目标目录:${dest}`);
+    }
+
+    // 读取源目录内容
+    const entries = fs.readdirSync(src, { withFileTypes: true });
+
+    for (const entry of entries) {
+        const srcPath = path.join(src, entry.name);
+        const destPath = path.join(dest, entry.name);
+
+        if (entry.isDirectory()) {
+            // 递归处理子目录
+            copyDir(srcPath, destPath);
+        } else {
+            // 拷贝文件
+            fs.copyFileSync(srcPath, destPath);
+            console.log(`已拷贝:${srcPath} -> ${destPath}`);
+        }
+    }
+}
+
+// 执行拷贝并处理错误
+try {
+    console.log('开始拷贝文件...');
+    copyDir(srcDir, destDir);
+    console.log('文件拷贝完成!');
+} catch (err) {
+    console.error('拷贝过程中发生错误:', err);
+    process.exit(1);
+}

+ 1 - 1
src/views/Content/TabInherit.vue

@@ -314,7 +314,7 @@ function handleItemClick(item: any) {
   gap: 20px;
 
   > div {
-    width: 48%;
+    width: 45%;
     aspect-ratio: 3 / 1;
     border-radius: 15px;
     display: flex;

+ 3 - 1
src/views/Details/ArtifactDetail.vue

@@ -1,5 +1,7 @@
 <script setup lang="ts">
+import SimpleRichHtml from '@/components/SimpleRichHtml.vue';
 import CommonDetail from './CommonDetail.vue';
+import { CommonHtmlStyles } from '@/composeable/HtmlStyles';
 </script>
 
 <template>
@@ -18,7 +20,7 @@ import CommonDetail from './CommonDetail.vue';
     </template>
     <template #afterContent="{ content }">
       <h3>文物价值:</h3>
-      <SimpleRichHtml :contents="[ content?.value as string || '暂无' ]" noScroll />
+      <SimpleRichHtml :contents="[ content?.value as string || '暂无' ]" noScroll :tagStyle="CommonHtmlStyles" />
     </template>
   </CommonDetail>
 </template>

+ 2 - 1
src/views/Details/CommonDetail.vue

@@ -9,6 +9,7 @@ import SimpleRichHtml from '@/components/SimpleRichHtml.vue';
 import Header from '@/components/parts/Header.vue';
 import ImageLine from '@/components/small/ImageLine.vue';
 import ImagePreview from '@/components/small/ImagePreview.vue';
+import { CommonHtmlStyles } from '@/composeable/HtmlStyles';
 
 const emit = defineEmits(['contentLoaded','back']);
 
@@ -47,7 +48,7 @@ watch(route, () => loader.loadData(undefined, true));
             <Vue3Marquee style="width:100%;" :duration="70" :delay="10" vertical>      
               <div class="d-flex flex-col w-100">
                 <slot name="beforeContent" :content="loader.content.value" />
-                <SimpleRichHtml :contents="[ loader.content.value?.content as string || '暂无' ]" noScroll />
+                <SimpleRichHtml :contents="[ loader.content.value?.content as string || '暂无' ]" noScroll :tagStyle="CommonHtmlStyles" />
                 <slot name="afterContent" :content="loader.content.value" />
               </div>
             </Vue3Marquee>

+ 2 - 1
src/views/Details/IntangibleDetail.vue

@@ -7,6 +7,7 @@ import SimpleRichHtml from '@/components/SimpleRichHtml.vue';
 import { ScrollRect } from '@imengyu/vue-scroll-rect';
 import TabCommonList from '../Content/TabCommonList.vue';
 import { useRoute } from 'vue-router';
+import { CommonHtmlStyles } from '@/composeable/HtmlStyles';
 
 const route = useRoute();
 const currentContent = ref<GetContentDetailItem>();
@@ -92,7 +93,7 @@ async function loadSubList(page: number, pageSize: number, content: any, subList
         itemWidth="100px"
       />
       <ScrollRect v-if="activeSubTabId === 0" scroll="vertical">
-        <SimpleRichHtml :contents="[ content.intro as string, content.content ]" />
+        <SimpleRichHtml :contents="[ content.intro as string, content.content ]" :tagStyle="CommonHtmlStyles" />
       </ScrollRect>
       <video 
         v-else-if="activeSubTabId === 1"

+ 2 - 13
src/views/Details/VideoDetail.vue

@@ -1,25 +1,14 @@
 <script setup lang="ts">
-import { useRoute, useRouter } from 'vue-router';
-import Header from '@/components/parts/Header.vue';
+import { useRoute } from 'vue-router';
 import { useSimpleDataLoader } from '@/composeable/SimpleDataLoader';
 import CommonContent from '@/api/CommonContent';
+import Header from '@/components/parts/Header.vue';
 import SimplePageContentLoader from '@/components/SimplePageContentLoader.vue';
-import SimpleRichHtml from '@/components/SimpleRichHtml.vue';
-import { Vue3Marquee } from 'vue3-marquee';
-import ImageLine from '@/components/small/ImageLine.vue';
-import ImagePreview from '@/components/small/ImagePreview.vue';
-import { ref } from 'vue';
 
 const route = useRoute();
-const router = useRouter();
 const loader = useSimpleDataLoader(async () => {
   return (await CommonContent.getContentDetail(Number(route.query.id)));
 });
-
-const showPreview = ref(false);
-const activeItem = ref(0);
-
-
 </script>
 
 <template>

+ 3 - 2
src/views/HomeView.vue

@@ -12,6 +12,7 @@ import Card5 from '@/assets/images/Home/Card/5.jpg';
 import Card6 from '@/assets/images/Home/Card/6.jpg';
 import Card7 from '@/assets/images/Home/Card/7.jpg';
 import Card8 from '@/assets/images/Home/Card/8.jpg';
+import { onMounted } from 'vue';
 
 const router = useRouter();
 const mainSwiperData = useSimpleDataLoader(async () => {
@@ -77,7 +78,7 @@ function handleClick(id: number) {
 <template>
   <main class="main-content">
     <div class="main-bg absolute">
-      <ImageSwiper :items="mainSwiperData.content.value ?? []" :autoplay="4000">
+      <ImageSwiper :items="mainSwiperData.content.value ?? []" :autoplay="4000" :showAddons="false" :tabindex="-1">
         <template #item="{ item }">
           <img :src="item.image" alt="">
         </template>
@@ -125,7 +126,7 @@ function handleClick(id: number) {
   display: grid;
   grid-template-columns: repeat(4, 1fr);
   grid-gap: 20px;
-  font-size: 30px;
+  font-size: 26px;
 
   .main-card {
     font-size: 3cqh;

+ 9 - 1
src/views/Intangible/Map.vue

@@ -25,6 +25,14 @@ function handleFocus(value: any) {
   map.setZoom(15);
 }
 function handleClick(value: any) {
+  router.push({
+    name: 'ArtifactDetail',
+    query: {
+      id: value.id,
+    }
+  });
+  /*
+
   router.replace({
     query: {
       ...route.query,
@@ -34,7 +42,7 @@ function handleClick(value: any) {
   setTimeout(() => {
     showDetail.value = true;
     currentItem.value = value;
-  }, 800)
+  }, 800)*/
 }
 
 const loader = useSimpleDataLoader(async () => {