shaogen1995 2 years ago
parent
commit
9ef4d16cf2

+ 13 - 5
houtai/src/views/tab2/index.vue

@@ -177,7 +177,9 @@
             <el-table-column prop="day" label="日期"> </el-table-column>
             <el-table-column label="操作">
               <template #default="{ row }">
-                <el-button type="text" @click="lookQrCode(row.qrPath)"
+                <el-button
+                  type="text"
+                  @click="lookQrCode(row.qrPath, row.fileName)"
                   >二维码</el-button
                 >
 
@@ -219,8 +221,12 @@
       ></div>
       <img v-if="qrCodeSrc" :src="baseURL + qrCodeSrc" alt="" />
       <!-- 下载二维码 -->
-      <a target="blank" :href="baseURL + qrCodeSrc" download class="qrCodeDown"
-        >下载二维码</a
+      <a
+        target="blank"
+        :href="baseURL + qrCodeSrc"
+        :download="qrName"
+        class="qrCodeDown"
+        >保存二维码</a
       >
     </div>
   </div>
@@ -288,7 +294,8 @@ export default {
       dictTextureArr: [],
       dictAgeArr: [],
       // 二维码查看
-      qrCodeSrc: ''
+      qrCodeSrc: '',
+      qrName: ''
     }
   },
   // 监听属性 类似于data概念
@@ -302,8 +309,9 @@ export default {
   // 方法集合
   methods: {
     // 点击二维码
-    lookQrCode (url) {
+    lookQrCode (url, name) {
       this.qrCodeSrc = url
+      this.qrName = name.split('.')[0]
     },
 
     // 处理说明的文本

+ 1 - 1
webNew/public/4dage.js

@@ -5304,7 +5304,7 @@ fdage = {},
                     this.container.appendChild(this.thumbnail),
                     this.playButton = document.createElement("input"),
                     this.playButton.type = "image",
-                    this.playButton.src = I.dataLocale + "play.png",
+                    // this.playButton.src = I.dataLocale + "play.png",
                     this.playButton.style.position = "absolute",
                     this.playButton.style.left = "50%",
                     this.playButton.style.top = "50%",

+ 2 - 0
webNew/src/App.tsx

@@ -9,6 +9,7 @@ import React from "react"
 import { Router, Route, Switch, Redirect } from "react-router-dom"
 import history from "./utils/history"
 const Home = React.lazy(() => import('./pages/Home'))
+const Model = React.lazy(() => import('./pages/Model'))
 
 export default function App() {
   // const dispatch = useDispatch()
@@ -19,6 +20,7 @@ export default function App() {
         <React.Suspense fallback={<div className='lodingApp'>加载中...</div>}>
           <Switch>
             <Redirect exact path="/" to="Home" />
+            <Route path="/Model" component={Model} />
             <Route path="/Home" component={Home} />
           </Switch>
         </React.Suspense>

+ 48 - 60
webNew/src/components/Model/index.module.scss

@@ -22,20 +22,20 @@
     .rightTxt {
       position: absolute;
       z-index: 2;
-      top: 30px;
-      right: 30px;
-      width: 400px;
-      height: 565px;
+      top: 60px;
+      right: 50px;
+      width: 300px;
+      height: 465px;
       background-image: url('../../assets//img//txtBac.png');
       background-size: 100% 100%;
 
       &::before {
         content: "";
         position: absolute;
-        left: 22px;
-        top: 121px;
+        left: 16px;
+        top: 99px;
         width: 1px;
-        height: 413px;
+        height: 344px;
         background-color: #BE262B;
       }
 
@@ -48,17 +48,17 @@
         letter-spacing: 4px;
         writing-mode: tb-rl;
         position: absolute;
-        top: 34px;
-        right: 40px;
-        width: 72px;
-        height: 351px;
+        top: 28px;
+        right: 30px;
+        width: 55px;
+        height: 289px;
         color: #020101;
         font-weight: 700;
         font-size: 24px;
       }
 
       .model_txt::-webkit-scrollbar {
-        width: 3px;
+        width: 2px;
       }
 
       .model_txt::-webkit-scrollbar-thumb {
@@ -73,75 +73,63 @@
       .model_txt {
         padding-left: 10px;
         position: absolute;
-        left: 24px;
-        top: 117px;
-        width: 247px;
-        height: 350px;
+        left: 17px;
+        top: 98px;
+        width: 185px;
+        height: 265px;
         overflow-y: auto;
-        font-size: 16px;
+        font-size: 14px;
       }
 
-      .model_age {
+      .model_floo {
         position: absolute;
-        bottom: 20px;
-        padding-bottom: 6px;
-        right: 125px;
-        font-size: 16px;
-        cursor: pointer;
-        width: 240px;
-        height: 36px;
-        display: flex;
-        justify-content: center;
+        top: 360px;
+        right: 6px;
+        font-size: 14px;
+        width: 70px;
 
         .model_ageRow {
-          max-width: 100%;
-          height: 100%;
-          border-bottom: 2px solid #a7191e;
-          padding: 0 12px;
-          overflow: hidden;
-          text-overflow: ellipsis;
-          white-space: nowrap;
+          &>p {
+            font-size: 12px;
+            margin: 0;
+            padding: 0;
+            line-height: 14px;
+          }
         }
-      }
-      .model_sort{
-        position: absolute;
-        bottom: 50px;
-        padding-bottom: 6px;
-        right: 125px;
-        font-size: 16px;
-        cursor: pointer;
-        width: 240px;
-        height: 36px;
-        display: flex;
-        justify-content: center;
 
         .model_sortRow {
-          max-width: 100%;
-          height: 100%;
-          padding: 0 12px;
-          overflow: hidden;
-          text-overflow: ellipsis;
-          white-space: nowrap;
+          margin-bottom: 5px;
+
+          &>p {
+            font-size: 12px;
+            margin: 0;
+            padding: 0;
+          }
         }
       }
 
 
+
       .model_size {
-        transform: scale(0.9);
         position: absolute;
-        right: 9px;
+        right: 83px;
         bottom: 5px;
-        width: 96px;
-        height: 125px;
+        width: 190px;
+        height: 103px;
         font-size: 14px;
 
-        &>div {
+        &>p {
+          font-size: 12px;
+          margin: 0;
+          padding: 0;
           cursor: pointer;
-          width: 100%;
+          display: -webkit-box;
           overflow: hidden;
+          white-space: normal !important;
           text-overflow: ellipsis;
-          white-space: nowrap;
-          margin-bottom: 8px;
+          word-wrap: break-word;
+          -webkit-line-clamp: 4;
+          -webkit-box-orient: vertical;
         }
       }
     }

+ 12 - 16
webNew/src/components/Model/index.tsx

@@ -30,7 +30,7 @@ export default function Model({ modelId, closeModel }: props) {
       setMusic(true)
       setTimeout(() => {
         musicPlayFu(true)
-        
+
       }, 500);
     }
     // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -57,7 +57,6 @@ export default function Model({ modelId, closeModel }: props) {
     const dom = musicRef.current
     if (dom) {
       if (flag) {
-        console.log('--------------');
 
         // 打开音乐
         setMusic(true)
@@ -89,24 +88,21 @@ export default function Model({ modelId, closeModel }: props) {
         {
           info.description ? (<div className='model_txt' dangerouslySetInnerHTML={{ __html: info.description }}></div>) : <div className='model_txt'>暂无信息</div>
         }
-        <div className='model_age'>
-          {
-            info.dictAgeFront ? (<div className='model_ageRow' title={info.dictAgeFront}>年代:{info.dictAgeFront}</div>) : <div className='model_ageRow'>年代:(空)</div>
-          }
-        </div>
 
-        <div className='model_sort'>
-          {
-            info.dictTextureName ? (<div className='model_sortRow' title={info.dictTextureName}>类别:{info.dictTextureName}</div>) : <div className='model_sortRow'>类别:(空)</div>
-          }
+        <div className='model_floo'>
+          <div className='model_sortRow'>类别:
+            <p>{info.dictTextureName ? info.dictTextureName : '(空)'}</p>
+          </div>
+          <div className='model_ageRow'>年代:
+            <p>{info.dictAgeName ? info.dictAgeName : '(空)'}</p>
+          </div>
+
         </div>
 
+
         {
-          <div className='model_size'>
-            {info.sizeLength || info.sizeWidth || info.sizeHeight ? (<div>尺寸</div>) : null}
-            {info.sizeLength ? (<div title={info.sizeLength.replace(',', '')}>长 {info.sizeLength.replace(',', '')}</div>) : null}
-            {info.sizeWidth ? (<div title={info.sizeWidth.replace(',', '')}>宽 {info.sizeWidth.replace(',', '')}</div>) : null}
-            {info.sizeHeight ? (<div title={info.sizeHeight.replace(',', '')}>高 {info.sizeHeight.replace(',', '')}</div>) : null}
+          <div className='model_size'>尺寸:
+            <p title={info.sizeLength}>{info.sizeLength ? info.sizeLength : '(空)'}</p>
           </div>
         }
 

+ 2 - 10
webNew/src/pages/Home/index.tsx

@@ -74,7 +74,7 @@ export default function Home() {
 
   const fromData = useRef({
     pageNum: 1,
-    pageSize: 30,
+    pageSize: 12,
     searchKey: '',
     dictTextureId: -1,
     dictAgeId: -1
@@ -102,14 +102,6 @@ export default function Home() {
   }, [sort])
 
 
-  // useEffect(() => {
-  //   fromData.current.dictAgeId = ageSerach
-  //   fromData.current.pageNum = 1
-  //   setPageNum(1)
-  //   getModelList()
-  //   // eslint-disable-next-line react-hooks/exhaustive-deps
-  // }, [ageSerach])
-
   // 点击每个模型出来的页面
   const [modelId, setModelId] = useState(0)
 
@@ -184,7 +176,7 @@ export default function Home() {
 
         {/* 分页器 */}
         <div className='page'>
-          <Pagination size="small" current={pageNum} total={total} pageSize={30} hideOnSinglePage={true} onChange={pageChangeFu} />
+          <Pagination size="small" current={pageNum} total={total} pageSize={12} hideOnSinglePage={true} onChange={pageChangeFu} />
 
         </div>
 

+ 176 - 0
webNew/src/pages/Model/index.module.scss

@@ -0,0 +1,176 @@
+.Model {
+  width: 100%;
+  height: 100%;
+  background-image: url('../../assets/img/modelBac.png');
+  background-size: 100% 100%;
+  background-color: #fff;
+
+  :global {
+    .ifrBox {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+
+      iframe {
+        width: 100%;
+        height: 100%;
+      }
+    }
+
+    .rightTxt {
+      position: absolute;
+      z-index: 2;
+      top: 60px;
+      right: 50px;
+      width: 300px;
+      height: 465px;
+      background-image: url('../../assets//img//txtBac.png');
+      background-size: 100% 100%;
+
+      &::before {
+        content: "";
+        position: absolute;
+        left: 16px;
+        top: 99px;
+        width: 1px;
+        height: 344px;
+        background-color: #BE262B;
+      }
+
+      .model_title {
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        text-align: center;
+        letter-spacing: 4px;
+        writing-mode: tb-rl;
+        position: absolute;
+        top: 28px;
+        right: 30px;
+        width: 55px;
+        height: 289px;
+        color: #020101;
+        font-weight: 700;
+        font-size: 24px;
+      }
+
+      .model_txt::-webkit-scrollbar {
+        width: 2px;
+      }
+
+      .model_txt::-webkit-scrollbar-thumb {
+        border-radius: 10px;
+        background-color: #a7191e;
+      }
+
+      .model_txt::-webkit-scrollbar-track {
+        border-radius: 10px;
+      }
+
+      .model_txt {
+        padding-left: 10px;
+        position: absolute;
+        left: 17px;
+        top: 98px;
+        width: 185px;
+        height: 265px;
+        overflow-y: auto;
+        font-size: 14px;
+      }
+
+      .model_floo {
+        position: absolute;
+        top: 360px;
+        right: 6px;
+        font-size: 14px;
+        width: 70px;
+
+        .model_ageRow {
+          &>p {
+            font-size: 12px;
+            margin: 0;
+            padding: 0;
+            line-height: 14px;
+          }
+        }
+
+        .model_sortRow {
+          margin-bottom: 5px;
+
+          &>p {
+            font-size: 12px;
+            margin: 0;
+            padding: 0;
+          }
+        }
+      }
+
+
+
+      .model_size {
+        position: absolute;
+        right: 83px;
+        bottom: 5px;
+        width: 190px;
+        height: 103px;
+        font-size: 14px;
+
+        &>p {
+          font-size: 12px;
+          margin: 0;
+          padding: 0;
+          cursor: pointer;
+          display: -webkit-box;
+          overflow: hidden;
+          white-space: normal !important;
+          text-overflow: ellipsis;
+          word-wrap: break-word;
+          -webkit-line-clamp: 4;
+          -webkit-box-orient: vertical;
+        }
+      }
+    }
+
+    .flootBtnBox {
+      position: absolute;
+      z-index: 10;
+      bottom: 30px;
+      right: 30px;
+      display: flex;
+
+      .flootRow {
+        width: 38px;
+        height: 38px;
+        cursor: pointer;
+        margin-right: 6px;
+        background-size: 100% 100%;
+      }
+
+      .flootRow1 {
+        background-image: url('../../assets/img/inco1.png');
+      }
+
+      .flootRow2 {
+        background-image: url('../../assets/img/inco2.png');
+      }
+
+      .flootRow3 {
+        background-image: url('../../assets/img/inco3.png');
+      }
+
+      .flootRow4 {
+        background-image: url('../../assets/img/inco4.png');
+      }
+
+      .flootRowM {
+        &>img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+    }
+  }
+}

+ 114 - 0
webNew/src/pages/Model/index.tsx

@@ -0,0 +1,114 @@
+/* eslint-disable jsx-a11y/iframe-has-title */
+import { useEffect, useRef, useState } from 'react';
+import musicImg from '@/assets/img/music.png'
+import musicImgAc from '@/assets/img/musicAc.png'
+import styles from './index.module.scss'
+import { baseURL } from '@/utils/http';
+import { useLocation } from 'react-router-dom';
+import { useDispatch, useSelector } from 'react-redux';
+import { getModelInfo } from '@/store/action/home';
+import { RootState } from '@/store';
+
+export default function Model() {
+
+  const location = useLocation()
+
+  const dispatch = useDispatch()
+
+  // 发送请求获取信息,存到仓库
+  useEffect(() => {
+    const arr = location.search.split('=')
+    const id = arr[1]
+    dispatch(getModelInfo(id))
+  }, [dispatch, location.search])
+
+  // 从仓库获取信息
+  const info = useSelector((state: RootState) => state.homeStore.qrModel)
+
+
+  // 控制模型放大缩小和复位
+  const ifrBoxRef = useRef<any>(null)
+  const modelChangeFu = (val: number) => {
+    const dom = ifrBoxRef.current
+
+    if (dom && dom.contentWindow && dom.contentWindow.webview) {
+      if (val === 1) dom.contentWindow.webview.zoomIn()  // 放大
+      else if (val === 2) dom.contentWindow.webview.zoomOut() // 缩小
+      else dom.contentWindow.webview.resetView() // 复位
+    }
+  }
+
+  // 控制音乐播放暂停
+  const musicRef = useRef<HTMLAudioElement>(null)
+
+  const [music, setMusic] = useState(false)
+  const musicPlayFu = (flag: boolean) => {
+    const dom = musicRef.current
+    if (dom) {
+      if (flag) {
+
+        // 打开音乐
+        setMusic(true)
+        dom.play()
+        dom.addEventListener('ended', function () {
+          setMusic(false)
+        }, false);
+      } else {
+        // 关闭音乐
+        setMusic(false)
+        dom.pause()
+      }
+    }
+  }
+
+
+  return (
+    <div className={styles.Model}>
+      {/* 音频 */}
+      {info.audioPath ? (<audio src={baseURL + info.audioPath} ref={musicRef}></audio>) : null}
+      {/* 模型盒子 */}
+      <div className='ifrBox'>
+        {info.fileName ? (<iframe ref={ifrBoxRef} src={`model.html?m=${info.fileName}`} frameBorder='no'></iframe>) : null}
+
+      </div>
+      {/* 右边介绍 */}
+      <div className='rightTxt'>
+        <div className='model_title'>{info.name}</div>
+        {
+          info.description ? (<div className='model_txt' dangerouslySetInnerHTML={{ __html: info.description }}></div>) : <div className='model_txt'>暂无信息</div>
+        }
+
+        <div className='model_floo'>
+          <div className='model_sortRow'>类别:
+            <p>{info.dictTextureName ? info.dictTextureName : '(空)'}</p>
+          </div>
+          <div className='model_ageRow'>年代:
+            <p>{info.dictAgeName ? info.dictAgeName : '(空)'}</p>
+          </div>
+
+        </div>
+
+
+        {
+          <div className='model_size'>尺寸:
+            <p title={info.sizeLength}>{info.sizeLength ? info.sizeLength : '(空)'}</p>
+          </div>
+        }
+
+      </div>
+
+      {/* 底部按钮 */}
+      <div className='flootBtnBox'>
+        <div className='flootRow flootRow1' title='放大' onClick={() => modelChangeFu(1)}></div>
+        <div className='flootRow flootRow2' title='缩小' onClick={() => modelChangeFu(2)}></div>
+        {info.audioPath ? (<div className='flootRow flootRowM' title={music ? '暂停音频' : '播放音频'}>
+          {music ? (<img src={musicImgAc} alt="" onClick={() => musicPlayFu(false)} />) :
+            (<img src={musicImg} alt="" onClick={() => musicPlayFu(true)} />)}
+        </div>) : null}
+
+        <div className='flootRow flootRow4' title='重置' onClick={() => modelChangeFu(3)}></div>
+      </div>
+
+    </div>
+  )
+}

+ 9 - 0
webNew/src/store/action/home.ts

@@ -47,3 +47,12 @@ export const getListAction = (data: any) => {
 }
 
 
+// 扫码进页面获取的单个文物详情
+export const getModelInfo = (id: string) => {
+  return async (dispatch: AppDispatch) => {
+    const res =await http.get(`/api/show/goods/detail/${id}`)
+    dispatch({ type: 'home/Model', payload: res.data })
+  }
+}
+
+

+ 12 - 8
webNew/src/store/reducer/home.ts

@@ -1,4 +1,4 @@
-import { HomeSortType, HomeModelType } from "@/types"
+import { HomeSortType, HomeModelType, modelItem } from "@/types"
 
 
 
@@ -6,23 +6,27 @@ import { HomeSortType, HomeModelType } from "@/types"
 const initState = {
   sortList: [] as HomeSortType[],
   ageList: [] as HomeSortType[],
-  modelInfo: {} as HomeModelType
+  modelInfo: {} as HomeModelType,
+  qrModel: {} as modelItem,
 }
 
 type HomeActionType =
-| { type: 'home/setSort', payload: HomeSortType[] }
-| { type: 'home/setAge', payload: HomeSortType[] }
-| { type: 'home/setList', payload: HomeModelType }
+  | { type: 'home/setSort', payload: HomeSortType[] }
+  | { type: 'home/setAge', payload: HomeSortType[] }
+  | { type: 'home/setList', payload: HomeModelType }
+  | { type: 'home/Model', payload: modelItem }
 
 // 频道 reducer
 export default function loginReducer(state = initState, action: HomeActionType) {
   switch (action.type) {
     case 'home/setSort':
       return { ...state, sortList: action.payload }
-      case 'home/setAge':
-        return { ...state, ageList: action.payload }
-      case 'home/setList':
+    case 'home/setAge':
+      return { ...state, ageList: action.payload }
+    case 'home/setList':
       return { ...state, modelInfo: action.payload }
+    case 'home/Model':
+      return { ...state, qrModel: action.payload }
     default:
       return state
   }