Browse Source

feat: 保存

gemercheung 1 year ago
parent
commit
06cc5361d6

+ 1 - 0
package.json

@@ -9,6 +9,7 @@
     "preview": "vite preview"
     "preview": "vite preview"
   },
   },
   "dependencies": {
   "dependencies": {
+    "@vueuse/components": "^10.6.1",
     "@vueuse/core": "^10.6.1",
     "@vueuse/core": "^10.6.1",
     "@vueuse/integrations": "^10.6.1",
     "@vueuse/integrations": "^10.6.1",
     "@vueuse/sound": "^2.0.1",
     "@vueuse/sound": "^2.0.1",

+ 14 - 0
pnpm-lock.yaml

@@ -5,6 +5,9 @@ settings:
   excludeLinksFromLockfile: false
   excludeLinksFromLockfile: false
 
 
 dependencies:
 dependencies:
+  '@vueuse/components':
+    specifier: ^10.6.1
+    version: 10.6.1(vue@3.3.8)
   '@vueuse/core':
   '@vueuse/core':
     specifier: ^10.6.1
     specifier: ^10.6.1
     version: 10.6.1(vue@3.3.8)
     version: 10.6.1(vue@3.3.8)
@@ -532,6 +535,17 @@ packages:
   /@vue/shared@3.3.8:
   /@vue/shared@3.3.8:
     resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==}
     resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==}
 
 
+  /@vueuse/components@10.6.1(vue@3.3.8):
+    resolution: {integrity: sha512-Yx7h201xJG3V4+rY1wRAYy8EI9Q1r+gpwCJzgyZ0CWPyDWyZCxPXNjPhBJsXcSzJ1h1ph9tE5cVqEXHtEs6bjg==}
+    dependencies:
+      '@vueuse/core': 10.6.1(vue@3.3.8)
+      '@vueuse/shared': 10.6.1(vue@3.3.8)
+      vue-demi: 0.14.6(vue@3.3.8)
+    transitivePeerDependencies:
+      - '@vue/composition-api'
+      - vue
+    dev: false
+
   /@vueuse/core@10.6.1(vue@3.3.8):
   /@vueuse/core@10.6.1(vue@3.3.8):
     resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==}
     resolution: {integrity: sha512-Pc26IJbqgC9VG1u6VY/xrXXfxD33hnvxBnKrLlA2LJlyHII+BSrRoTPJgGYq7qZOu61itITFUnm6QbacwZ4H8Q==}
     dependencies:
     dependencies:

+ 5 - 0
src/api/index.js

@@ -0,0 +1,5 @@
+import axios from "axios";
+
+export const request = axios.create({
+  baseURL: import.meta.env.VITE_API_URL,
+});

+ 3 - 7
src/components/heroSubTitle.vue

@@ -18,13 +18,9 @@ const props = defineProps({
     default: () => 1,
     default: () => 1,
   },
   },
 });
 });
-// const titleSrc = computed(() => `/img/subtitle_${props.type || 1}.png`);
-const titleSrc = computedAsync(
-  async () => {
-    const url = await import(`../assets/subtitle_${props.type || 1}.png`);
-    return url.default;
-  },
-  null // initial state
+
+const titleSrc = computed(
+  () => new URL(`../assets/subtitle_${props.type || 1}.png`, import.meta.url)
 );
 );
 </script>
 </script>
 
 

+ 1 - 1
src/components/infoBox.vue

@@ -11,7 +11,7 @@
         <span> {{ time }}</span>
         <span> {{ time }}</span>
         <div class="see-more" @click="$router.push(`/info-detail/${id}`)">
         <div class="see-more" @click="$router.push(`/info-detail/${id}`)">
           查看
           查看
-          <img class="see-more-img" src="img/see_more.png" alt="see more" />
+          <img class="see-more-img" src="@/assets/see_more.png" alt="see more" />
         </div>
         </div>
       </div>
       </div>
     </div>
     </div>

+ 13 - 10
src/components/showCase.vue

@@ -31,8 +31,8 @@
 
 
         <template #arrow="{ prev, next }">
         <template #arrow="{ prev, next }">
           <div class="custom-arrow">
           <div class="custom-arrow">
-            <img class="btn-img" src="img/arrow-left.png" @click="prev" />
-            <img class="btn-img" src="img/arrow-right.png" @click="next" />
+            <img class="btn-img" src="@/assets/arrow-left.png" @click="prev" />
+            <img class="btn-img" src="@/assets/arrow-right.png" @click="next" />
           </div>
           </div>
         </template>
         </template>
       </n-carousel>
       </n-carousel>
@@ -47,7 +47,7 @@
           round
           round
           @click="handleSwitchType('model')"
           @click="handleSwitchType('model')"
         >
         >
-          <img src="img/icon_model.png" /> 模型
+          <img src="@/assets/icon_model.png" /> 模型
         </n-button>
         </n-button>
         <n-button
         <n-button
           class="video btn"
           class="video btn"
@@ -56,7 +56,7 @@
           }"
           }"
           round
           round
           @click="handleSwitchType('video')"
           @click="handleSwitchType('video')"
-          ><img src="img/icon_video.png" />视频</n-button
+          ><img src="@/assets/icon_video.png" />视频</n-button
         >
         >
         <n-button
         <n-button
           class="gallery btn"
           class="gallery btn"
@@ -66,19 +66,19 @@
           round
           round
           @click="handleSwitchType('gallery')"
           @click="handleSwitchType('gallery')"
         >
         >
-          <img src="img/icon_photo.png" />图片</n-button
+          <img src="@/assets/icon_photo.png" />图片</n-button
         >
         >
       </n-space>
       </n-space>
       <div class="actions">
       <div class="actions">
         <div v-if="isModel">
         <div v-if="isModel">
-          <img src="img/zoom-in.png" />
-          <img src="img/zoom-out.png" />
-          <img src="img/reload.png" @click="reloadIframe" />
+          <img src="@/assets/zoom-in.png" />
+          <img src="@/assets/zoom-out.png" />
+          <img src="@/assets/reload.png" @click="reloadIframe" />
         </div>
         </div>
         <div v-if="isGallery">
         <div v-if="isGallery">
-          <img src="img/audio-muted.png" @click="stop" />
+          <img src="@/assets/audio-muted.png" @click="stop" />
           <img
           <img
-            src="img/audio-unmuted.png"
+            src="@/assets/audio-unmuted.png"
             @click="!isPlaying ? play() : () => {}"
             @click="!isPlaying ? play() : () => {}"
           />
           />
         </div>
         </div>
@@ -91,6 +91,9 @@
 import { ref, computed } from "vue";
 import { ref, computed } from "vue";
 import { useSound } from "@vueuse/sound";
 import { useSound } from "@vueuse/sound";
 
 
+import arrowLeft from "../assets/arrow-left.png";
+import arrowRight from "../assets/arrow-right.png";
+
 const iframeRef = ref();
 const iframeRef = ref();
 const type = ref("model");
 const type = ref("model");
 const defaultType = ref(["model", "video", "audio", "gallery"]);
 const defaultType = ref(["model", "video", "audio", "gallery"]);

+ 2 - 2
src/router/index.js

@@ -1,4 +1,4 @@
-import { createRouter, createWebHistory } from "vue-router";
+import { createRouter, createWebHashHistory } from "vue-router";
 
 
 const routes = [
 const routes = [
   {
   {
@@ -105,7 +105,7 @@ const routes = [
 const basePath = import.meta.env.VITE_PUBLIC_DIR;
 const basePath = import.meta.env.VITE_PUBLIC_DIR;
 
 
 const router = createRouter({
 const router = createRouter({
-  history: createWebHistory(basePath),
+  history: createWebHashHistory(basePath),
   routes,
   routes,
 });
 });
 
 

+ 21 - 0
src/store/home.js

@@ -0,0 +1,21 @@
+import { triggerRef } from "vue";
+import { defineStore } from "pinia";
+import { request } from "../api";
+
+export const useHomeStore = defineStore({
+  id: "home",
+  state: () => {
+    return {
+      poster: [],
+    };
+  },
+  getters: {},
+  actions: {
+    async getPoster() {
+      const { data, status } = await request.get("/show/poster/getList");
+      if (data.code === 0) {
+        this.poster = data.data;
+      }
+    },
+  },
+});

+ 46 - 22
src/store/info.js

@@ -1,40 +1,64 @@
-import { unref } from "vue";
+import { triggerRef } from "vue";
 import { defineStore } from "pinia";
 import { defineStore } from "pinia";
-import axios from "axios";
-import { useAxios } from "@vueuse/integrations/useAxios";
-
-const instance = axios.create({
-  baseURL: import.meta.env.VITE_API_URL,
-});
+import { request } from "../api";
 
 
 export const useInfoStore = defineStore({
 export const useInfoStore = defineStore({
   id: "info",
   id: "info",
   state: () => {
   state: () => {
     return {
     return {
-      poster: [],
       exhibition: [],
       exhibition: [],
       activity: [],
       activity: [],
       news: [],
       news: [],
       notices: [],
       notices: [],
+      pagination: {
+        pageNum: 1,
+        pageSize: 20,
+        searchKey: "",
+        type: "",
+        total: 0,
+      },
     };
     };
   },
   },
   getters: {},
   getters: {},
   actions: {
   actions: {
-    async getPoster() {
-      const { data, isFinished } = useAxios(
-        "/show/poster/getList",
-        { method: "get" },
-        instance
-      );
-      console.log("data", data.value);
-      this.poster = data;
+    async getExhibition(page) {
+      this.pagination.type = "exhibition";
+      this.pagination.pageNum = page || 1;
+      const { data, status } = await request.post("/show/news/pageList", {
+        ...this.pagination,
+      });
+      if (data.code === 0) {
+        this.exhibition = data.data;
+      }
+    },
+    async getActivity() {
+      this.pagination.type = "activity";
+      const { data, status } = await request.post("/show/news/pageList", {
+        ...this.pagination,
+      });
+      if (data.code === 0) {
+        this.activity = data.data;
+      }
+    },
+    async getNews(page) {
+      this.pagination.type = "news";
+      this.pagination.pageNum = page || 1;
+      const { data, status } = await request.post("/show/news/pageList", {
+        ...this.pagination,
+      });
+      if (data.code === 0) {
+        this.news = data.data;
+      }
     },
     },
-    getData() {
-      const { data, isFinished } = useAxios(
-        "/show/poster/getList",
-        { method: "get" },
-        instance
-      );
+    async getNotices() {
+      this.pagination.type = "notice";
+      this.pagination.pageNum = 1;
+      const { data, status } = await request.post("/show/news/pageList", {
+        ...this.pagination,
+      });
+      if (data.code === 0) {
+        this.notices = data.data;
+      }
     },
     },
   },
   },
 });
 });

+ 1 - 2
src/views/404.vue

@@ -25,11 +25,10 @@
 
 
 <script setup>
 <script setup>
 import { watchEffect, ref } from "vue";
 import { watchEffect, ref } from "vue";
-import { useFullscreen } from "@vueuse/core";
 import subHeader from "../components/subHeader";
 import subHeader from "../components/subHeader";
 import sideMenu from "../components/sideMenu";
 import sideMenu from "../components/sideMenu";
 import heroSubTitle from "../components/heroSubTitle";
 import heroSubTitle from "../components/heroSubTitle";
-import { useInfoStore } from "../store/info";
+
 const title = ref("detail");
 const title = ref("detail");
 
 
 watchEffect(() => {
 watchEffect(() => {

+ 2 - 3
src/views/collect.vue

@@ -6,7 +6,7 @@
         <n-tabs type="line" pane-class="tab-content">
         <n-tabs type="line" pane-class="tab-content">
           <template #prefix>
           <template #prefix>
             <span class="meta-title">
             <span class="meta-title">
-              <img src="img/subtitle_3.png" />
+              <img src="@/assets/subtitle_3.png" />
             </span>
             </span>
           </template>
           </template>
           <template #suffix>
           <template #suffix>
@@ -101,10 +101,9 @@ const XGap = ref(50);
 const YGap = ref(50);
 const YGap = ref(50);
 const inputValue = ref("");
 const inputValue = ref("");
 
 
-// const InfoStore = useInfoStore();
 
 
 onMounted(() => {
 onMounted(() => {
-  // InfoStore.getData();
+  
 });
 });
 </script>
 </script>
 
 

+ 2 - 5
src/views/exhibition.vue

@@ -6,7 +6,7 @@
         <n-tabs type="line" pane-class="tab-content">
         <n-tabs type="line" pane-class="tab-content">
           <template #prefix>
           <template #prefix>
             <span class="meta-title">
             <span class="meta-title">
-              <img src="img/subtitle_2.png" />
+              <img src="@/assets/subtitle_2.png" />
             </span>
             </span>
           </template>
           </template>
           <n-tab-pane name="all" tab="全部展览">
           <n-tab-pane name="all" tab="全部展览">
@@ -95,11 +95,8 @@ import { useInfoStore } from "../store/info";
 const XGap = ref(50);
 const XGap = ref(50);
 const YGap = ref(50);
 const YGap = ref(50);
 const { isFullscreen, enter, exit, toggle } = useFullscreen();
 const { isFullscreen, enter, exit, toggle } = useFullscreen();
-const InfoStore = useInfoStore();
 
 
-onMounted(() => {
-  InfoStore.getData();
-});
+onMounted(() => {});
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 10 - 15
src/views/home.vue

@@ -1,24 +1,18 @@
 <template>
 <template>
   <div class="main">
   <div class="main">
     <div class="left">
     <div class="left">
-      <!-- post -->
-
       <n-carousel
       <n-carousel
         dot-placement="bottom"
         dot-placement="bottom"
         style="width: 100%; height: 100%"
         style="width: 100%; height: 100%"
         autoplay
         autoplay
-        draggable
+        :draggable="posters.length > 1"
       >
       >
-        <img
-          class="carousel-img"
-          style="width: 100%; height: 100%; object-fit: cover"
-          src="img/show_banner.png"
-        />
         <template v-for="item in posters">
         <template v-for="item in posters">
           <img
           <img
             class="carousel-img"
             class="carousel-img"
             style="width: 100%; height: 100%; object-fit: cover"
             style="width: 100%; height: 100%; object-fit: cover"
             :src="domain + item.filePath"
             :src="domain + item.filePath"
+            @error="$event.target.src=errorBanner"
           />
           />
         </template>
         </template>
       </n-carousel>
       </n-carousel>
@@ -49,19 +43,20 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { computed, onBeforeMount, onMounted, ref } from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { useInfoStore } from "../store/info";
+import { computed, onMounted, ref } from "vue";
+import { useRouter } from "vue-router";
+import { useHomeStore } from "../store/home";
 import Logo from "../assets/logo.png";
 import Logo from "../assets/logo.png";
-
+import errorBanner from "@/assets/show_banner.png";
 const { push } = useRouter();
 const { push } = useRouter();
-const InfoStore = useInfoStore();
+const homeStore = useHomeStore();
+
+const posters = computed(() => homeStore.poster || []);
 
 
-const posters = computed(() => InfoStore.poster.data || []);
 const domain = ref(import.meta.env.VITE_DOMAIN_URL);
 const domain = ref(import.meta.env.VITE_DOMAIN_URL);
 
 
 onMounted(async () => {
 onMounted(async () => {
-  await InfoStore.getPoster();
+  await homeStore.getPoster();
 });
 });
 </script>
 </script>
 <style>
 <style>

+ 47 - 13
src/views/info.vue

@@ -2,14 +2,19 @@
   <div class="main">
   <div class="main">
     <div class="content">
     <div class="content">
       <sub-header />
       <sub-header />
+
       <div class="left">
       <div class="left">
-        <n-tabs type="line" pane-class="tab-content">
+        <n-tabs type="line" pane-class="tab-content" v-model:value="currentTab">
           <template #prefix>
           <template #prefix>
             <span class="meta-title">
             <span class="meta-title">
-              <img src="img/subtitle_1.png" />
+              <img src="@/assets/subtitle_1.png" />
             </span>
             </span>
           </template>
           </template>
-          <n-tab-pane name="展览" tab="展览">
+          <n-tab-pane
+            name="exhibition"
+            tab="展览"
+            v-infinite-scroll="onLoadMore"
+          >
             <n-grid :x-gap="XGap" :y-gap="YGap" :cols="3" class="tab-grid">
             <n-grid :x-gap="XGap" :y-gap="YGap" :cols="3" class="tab-grid">
               <template v-for="(_, index) in 16">
               <template v-for="(_, index) in 16">
                 <n-gi>
                 <n-gi>
@@ -23,7 +28,7 @@
               </template>
               </template>
             </n-grid>
             </n-grid>
           </n-tab-pane>
           </n-tab-pane>
-          <n-tab-pane name="活动" tab="活动">
+          <n-tab-pane name="activity" tab="活动">
             <n-grid :x-gap="XGap" :y-gap="YGap" :cols="3" class="tab-grid">
             <n-grid :x-gap="XGap" :y-gap="YGap" :cols="3" class="tab-grid">
               <template v-for="(_, index) in 16">
               <template v-for="(_, index) in 16">
                 <n-gi>
                 <n-gi>
@@ -37,7 +42,7 @@
               </template>
               </template>
             </n-grid>
             </n-grid>
           </n-tab-pane>
           </n-tab-pane>
-          <n-tab-pane name="新闻" tab="新闻">
+          <n-tab-pane name="news" tab="新闻">
             <n-grid :x-gap="XGap" :y-gap="YGap" :cols="3" class="tab-grid">
             <n-grid :x-gap="XGap" :y-gap="YGap" :cols="3" class="tab-grid">
               <template v-for="item in 16">
               <template v-for="item in 16">
                 <n-gi>
                 <n-gi>
@@ -50,7 +55,7 @@
               </template>
               </template>
             </n-grid>
             </n-grid>
           </n-tab-pane>
           </n-tab-pane>
-          <n-tab-pane name="通知" tab="通知">
+          <n-tab-pane name="notice" tab="通知">
             <n-grid :y-gap="YGap" :cols="1" class="tab-grid">
             <n-grid :y-gap="YGap" :cols="1" class="tab-grid">
               <template v-for="(_, index) in 16">
               <template v-for="(_, index) in 16">
                 <n-gi>
                 <n-gi>
@@ -72,22 +77,51 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { onMounted } from "vue";
-import { useFullscreen } from "@vueuse/core";
+import { onMounted, watch } from "vue";
+import { vInfiniteScroll } from "@vueuse/components";
 import infoBox from "../components/infoBox";
 import infoBox from "../components/infoBox";
 import subHeader from "../components/subHeader";
 import subHeader from "../components/subHeader";
 import sideMenu from "../components/sideMenu";
 import sideMenu from "../components/sideMenu";
 import noticeBox from "../components/noticeBox";
 import noticeBox from "../components/noticeBox";
 import { useInfoStore } from "../store/info";
 import { useInfoStore } from "../store/info";
+const infoStore = useInfoStore();
+
+const currentTab = ref("exhibition");
+
+const handleTabFetch = (type) => {
+  switch (type) {
+    case "exhibition":
+      infoStore.getExhibition();
+      break;
+    case "activity":
+      infoStore.getActivity();
+      break;
+    case "news":
+      infoStore.getNews();
+      break;
+    case "notice":
+      infoStore.getNews();
+      break;
+  }
+};
 
 
+watch(
+  currentTab,
+  (val) => {
+    console.log("currentTab", val);
+    handleTabFetch(val);
+  },
+  {
+    immediate: true,
+  }
+);
 const XGap = ref(50);
 const XGap = ref(50);
 const YGap = ref(50);
 const YGap = ref(50);
-const { isFullscreen, enter, exit, toggle } = useFullscreen();
-const InfoStore = useInfoStore();
 
 
-onMounted(() => {
-  InfoStore.getData();
-});
+const onLoadMore = (type) => {
+  // console.log("type", type);
+  console.log("onLoadMore");
+};
 </script>
 </script>
 
 
 <style lang="scss" scoped></style>
 <style lang="scss" scoped></style>

+ 3 - 1
vite.config.js

@@ -1,4 +1,5 @@
-import { defineConfig, loadEnv } from 'vite';
+import { defineConfig, loadEnv } from "vite";
+import { fileURLToPath, URL } from "url";
 import vue from "@vitejs/plugin-vue";
 import vue from "@vitejs/plugin-vue";
 import path from "path";
 import path from "path";
 import AutoImport from "unplugin-auto-import/vite";
 import AutoImport from "unplugin-auto-import/vite";
@@ -43,6 +44,7 @@ export default ({ mode }) =>
     resolve: {
     resolve: {
       alias: {
       alias: {
         "@": path.resolve(__dirname, "src"),
         "@": path.resolve(__dirname, "src"),
+        "##": path.resolve(__dirname, "src/assets"),
       },
       },
       extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"],
       extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"],
     },
     },