Jelajahi Sumber

新增一个单独展示某项文物的界面

任一存 2 tahun lalu
induk
melakukan
8ed208983b
4 mengubah file dengan 396 tambahan dan 18 penghapusan
  1. 375 0
      src/components/RelicDetailSinglePage.vue
  2. 2 0
      src/main.js
  3. 19 13
      src/router/index.js
  4. 0 5
      src/views/AboutView.vue

+ 375 - 0
src/components/RelicDetailSinglePage.vue

@@ -0,0 +1,375 @@
+<template>
+  <div class="relic-detail">
+    <div
+      v-show="!isShowDesc"
+      class="preview"
+    >
+      <h1>{{ title }}</h1>
+      <iframe
+        v-if="dimNumber === 3"
+        :src="iframeSrc"
+        frameborder="0"
+        class="display-3d"
+      />
+
+      <div
+        v-if="dimNumber === 2"
+        class="swiper-wrapper-mine"
+      >
+        <div
+          class="swiper-root"
+        >
+          <div
+            v-viewer="{
+              button: true,
+              navbar: false,
+              title: false,
+              toolbar: false,
+              tooltip: false,
+              movable: true,
+              zoomable: true,
+              rotatable: true,
+              scalable: true,
+              transition: false,
+              fullscreen: false,
+              keyboard: true,
+              loop: false,
+            }"
+            class="swiper-wrapper"
+          >
+            <img
+              v-for="(item, index) in imageList"
+              :key="index"
+              :src="item"
+              class="swiper-slide"
+              alt=""
+              draggable="false"
+            >
+          </div>
+          <!-- <div class="swiper-pagination" /> -->
+          <div class="swiper-pagination">
+            <span class="cur">{{ currentSlideIdx }}</span> / <span>{{ imageList.length }}</span>
+          </div>
+          <div class="swiper-button-prev" />
+          <div class="swiper-button-next" />
+        </div>
+      </div>
+
+      <div class="btn-group">
+        <button
+          @click="isShowDesc = true"
+        >
+          <img
+            src="@/assets/images/desc.png"
+            alt="详情"
+            draggable="false"
+          >
+        </button>
+      </div>
+    </div>
+
+    <article
+      v-if="isShowDesc"
+      class="desc"
+    >
+      <button
+        class="close-btn"
+        @click="isShowDesc = false"
+      >
+        <img
+          src="@/assets/images/close.png"
+          alt="关闭"
+          draggable="false"
+        >
+      </button>
+      <img
+        class="photo"
+        :src="imageList[0]"
+        alt=""
+        draggable="false"
+      >
+      <h1>{{ title }}</h1>
+      <ul>
+        <li
+          v-for="(item, index) in detailInfo"
+          :key="index"
+          class="desc-item"
+        >
+          {{ item.key }}:{{ item.value }}
+        </li>
+      </ul>
+    </article>
+  </div>
+</template>
+
+<script>
+import Swiper from 'swiper/swiper-bundle.esm.js'
+import 'swiper/swiper-bundle.css'
+import { goodsData } from "@/assets/data/data.js"
+
+export default {
+  data() {
+    return {
+      title: '',
+      dimNumber: 0,
+      iframeSrc: '',
+      imageList: [],
+      detailInfo: [],
+      currentSlideIdx: 1,
+
+      isShowDesc: false,
+    }
+  },
+  mounted() {
+    setTimeout(() => {
+      const that = this
+      new Swiper('.swiper-root', {
+      // If we need pagination
+        // pagination: {
+        //   el: '.swiper-pagination',
+        // },
+
+        // Navigation arrows
+        navigation: {
+          nextEl: '.swiper-button-next',
+          prevEl: '.swiper-button-prev',
+        },
+
+        on: {
+          slideChange: function(e) {
+            that.currentSlideIdx = e.activeIndex + 1
+          }
+        }
+      })
+    }, 400)
+
+    let relicInfo = null
+    relicInfo = goodsData['3D'].find((item) => {
+      return item.name === this.$route.params.relicName
+    })
+    if (relicInfo) {
+      this.dimNumber = 3
+    } else {
+      relicInfo = goodsData['2D'].find((item) => {
+        return item.name === this.$route.params.relicName
+      })
+      this.dimNumber = 2
+    }
+    if (!relicInfo) {
+      return
+    }
+
+    this.title = relicInfo.name
+
+    this.iframeSrc = `${process.env.VUE_APP_RELICS_MODEL_PATH}YHTLSJNG/Model2.html?m=${relicInfo.bs}`
+    if (this.dimNumber === 3) {
+      this.imageList = [`${this.$cdnPath}3D/${relicInfo.bs}.png`]
+    } else {
+      if (relicInfo.imgNum === 1) {
+        this.imageList = [`${this.$cdnPath}2D/${relicInfo.bs}.png`]
+      } else {
+        for (let index = 0; (index < relicInfo.imgNum) && (index < 3); index++) {
+          this.imageList.push(`${this.$cdnPath}2D/${relicInfo.bs} (${index + 1}).png`)
+        }
+        console.log(this.imageList)
+      }
+    }
+    this.detailInfo = [
+      {
+        key: '年代',
+        value: relicInfo.age,
+      },
+      {
+        key: '类别',
+        value: relicInfo.sort,
+      },
+      {
+        key: '尺寸',
+        value: relicInfo.size,
+      },
+      {
+        key: '质地',
+        value: relicInfo.grain,
+      },
+      {
+        key: '级别',
+        value: relicInfo.estate,
+      }
+    ]
+  },
+  methods: {
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.relic-detail {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(246,239,217,0.8);
+  backdrop-filter: blur(1.04rem);
+  > .preview {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-evenly;
+    align-items: center;
+    padding: 0 1.67rem 8rem 1.67rem;
+    > h1 {
+      font-size: 2rem;
+      font-weight: bold;
+      color: #930909;
+      line-height: 2.34rem;
+      width: 60%;
+      align-self: flex-start;
+      flex: 0 0 auto;
+    }
+    > iframe {
+      width: 100%;
+      height: 60%;
+    }
+    > .photos {
+      width: 100%;
+      max-height: 60%;
+      > img {
+        width: 100%;
+        height: 100%;
+        object-fit: contain;
+      }
+    }
+    .swiper-wrapper-mine {
+      width: calc(100% - 1.67rem * 2 - 1.83rem * 2 - 1.67rem * 2);
+      height: 60%;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      position: relative;
+      .swiper-root {
+        overflow: hidden;
+        height: 100%;
+        .swiper-wrapper {
+          // 用类选择器不会生效
+          img {
+            object-fit: contain;
+          }
+        }
+        // .swiper-pagination {
+        //   top: 100%;
+        //   bottom: initial;
+        //   height: 0.42rem;
+        //   /deep/.swiper-pagination-bullet {
+        //     width: 5.34rem;
+        //     height: 0.42rem;
+        //     background-color: #999999;
+        //     margin-right: 0.79rem;
+        //     // background-color: #930909;
+        //     border-radius: initial;
+        //   }
+        //   /deep/.swiper-pagination-bullet.swiper-pagination-bullet-active {
+        //     background-color: #930909;
+        //   }
+        // }
+        .swiper-pagination {
+          position: absolute;
+          top: 100%;
+          left: 50%;
+          transform: translateX(-50%);
+          font-size: 1.33rem;
+          font-family: Inter-Regular, Inter;
+          color: #666;
+          .cur {
+            color: #930909;
+          }
+        }
+        .swiper-button-prev {
+          left: calc(-1.67rem - 1.83rem);
+          width: 1.83rem;
+          height: 3.58rem;
+          background-image: url(@/assets/images/arrow-left.png);
+          background-size: contain;
+          &::after {
+            content: '';
+          }
+        }
+        .swiper-button-next {
+          right: calc(-1.67rem - 1.83rem);
+          width: 1.83rem;
+          height: 3.58rem;
+          background-image: url(@/assets/images/arrow-right.png);
+          background-size: contain;
+          &::after {
+            content: '';
+          }
+
+        }
+      }
+    }
+    > .btn-group {
+      flex: 0 0 auto;
+      > button {
+        width: 6.25rem;
+        height: 6.25rem;
+        > img {
+          width: 100%;
+          height: 100%;
+        }
+        &:nth-of-type(2) {
+          margin-left: 4.38rem;
+        }
+      }
+    }
+  }
+  > .desc {
+    position: absolute;
+    left: 4.7rem;
+    right: 4.7rem;
+    top: 9.75rem;
+    bottom: 14rem;
+    background: #930909;
+    border-top: solid 0.78rem #CEA763;
+    border-bottom: solid 0.78rem #CEA763;
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    padding: 2.92rem 3rem;
+    .close-btn {
+      position: absolute;
+      top: 0;
+      right: 0;
+      width: 6.25rem;
+      height: 6.25rem;
+      transform: translate(50%, -50%);
+      > img {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .photo {
+      width: 100%;
+      max-height: 40%;
+      object-fit: contain;
+      border: 0.2rem solid #DABD8E;
+    }
+    > h1 {
+      margin-top: 2.29rem;
+      font-size: 2rem;
+      font-weight: bold;
+      color: #CEA763;
+      line-height: 2.34rem;
+    }
+    > ul {
+      margin-top: 1.29rem;
+      > li {
+        font-size: 1.67rem;
+        color: #FFFFFF;
+        line-height: 2.92rem;
+        display: block;
+      }
+    }
+  }
+}
+</style>

+ 2 - 0
src/main.js

@@ -34,6 +34,8 @@ if (uaInfo.browser && uaInfo.browser.name === 'Safari') {
 if (uaInfo.device.type !== 'mobile' && window.innerWidth > window.innerHeight) {
   if (['#/lookGoods', '#/relics-appr-no-exit', '#/relic-detail'].includes(location.hash)) {
     location.replace(process.env.VUE_APP_PC_URL_ONLY_RELICS)
+  } else if (location.hash.includes('#/info/')) {
+    location.replace(location.href.replace('/YHTM/', '/YHT/'))
   } else {
     location.replace(process.env.VUE_APP_PC_URL)
   }

+ 19 - 13
src/router/index.js

@@ -1,15 +1,16 @@
-import Vue from 'vue'
-import VueRouter from 'vue-router'
 import HomeView from '../views/HomeView.vue'
-import RelicsAppr from "@/views/RelicsAppr.vue"
+import ObliqueView from "@/views/ObliqueView.vue"
+import PanoList from "@/components/PanoList.vue"
+import PanoView from "@/views/PanoView.vue"
 import RelicDetail from "@/components/RelicDetail.vue"
+import RelicDetailSinglePage from "@/components/RelicDetailSinglePage.vue"
+import RelicsAppr from "@/views/RelicsAppr.vue"
+import RelicsApprCover from "@/views/RelicsApprCover.vue"
 import SwkkFadeIn from "@/views/SwkkFadeIn.vue"
 import SwkkView from "@/views/SwkkView.vue"
-import ObliqueView from "@/views/ObliqueView.vue"
-import PanoView from "@/views/PanoView.vue"
-import PanoList from "@/components/PanoList.vue"
 import TestView from "@/components/TestView.vue"
-import RelicsApprCover from "@/views/RelicsApprCover.vue"
+import Vue from 'vue'
+import VueRouter from 'vue-router'
 
 Vue.use(VueRouter)
 
@@ -148,6 +149,8 @@ const routes = [
       next()
     },
   },
+
+  // 单独的文物鉴赏功能
   {
     path: '/lookGoods',
     name: 'lookGoods',
@@ -180,13 +183,16 @@ const routes = [
       },
     ],
   },
+
+  // 单独的文物详情查看功能
   {
-    path: '/about',
-    name: 'about',
-    // route level code-splitting
-    // this generates a separate chunk (about.[hash].js) for this route
-    // which is lazy-loaded when the route is visited.
-    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
+    path: '/info/:relicName',
+    name: 'RelicDetailSinglePage',
+    component: RelicDetailSinglePage,
+    meta: {
+      isShowBottomBar: false,
+      canFullScreen: false,
+    },
   }
 ]
 

+ 0 - 5
src/views/AboutView.vue

@@ -1,5 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>