瀏覽代碼

改版一波

shaogen1995 9 月之前
父節點
當前提交
dcfa28a2c4

File diff suppressed because it is too large
+ 6352 - 0
web/public/4dage.js


+ 0 - 2
web/public/index.html

@@ -8,8 +8,6 @@
     <meta name="description" content="Web site created using create-react-app" />
     <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
 
-    <script src="./myData/myData.js"></script>
-
     <!--
       manifest.json provides metadata used when your web app is installed on a
       user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/

+ 30 - 0
web/public/model.html

@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang="zh">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <script src="./4dage.js"></script>
+    <title>Document</title>
+    <style>
+      html {
+        overflow: hidden;
+      }
+    </style>
+  </head>
+
+  <body>
+    <div id="ui"></div>
+    <script>
+      let url = getQueryVariable('m')
+      fdage.embed(url, {
+        transparentBackground: true,
+        width: 800,
+        height: 600,
+        autoStart: true,
+        fullFrame: true,
+        pagePreset: false
+      })
+    </script>
+  </body>
+</html>

File diff suppressed because it is too large
+ 0 - 2793
web/public/myData/myData.js


+ 15 - 13
web/src/App.tsx

@@ -18,19 +18,21 @@ export default function App() {
       <AsyncSpinLoding />
 
       {/* 所有图片点击预览查看大图 */}
-      <Image
-        preview={{
-          visible: lookBigImg.show,
-          src: lookBigImg.url,
-          onVisibleChange: value => {
-            // 清除仓库信息
-            store.dispatch({
-              type: 'layout/lookBigImg',
-              payload: { url: '', show: false }
-            })
-          }
-        }}
-      />
+      {lookBigImg.show ? (
+        <Image
+          preview={{
+            visible: lookBigImg.show,
+            src: lookBigImg.url,
+            onVisibleChange: value => {
+              // 清除仓库信息
+              store.dispatch({
+                type: 'layout/lookBigImg',
+                payload: { url: '', show: false }
+              })
+            }
+          }}
+        />
+      ) : null}
 
       {/* antd 轻提示 ---兼容360浏览器 */}
       <MessageCom />

二進制
web/src/assets/img/expert/bg.jpg


二進制
web/src/assets/img/expert/li1.png


二進制
web/src/assets/img/expert/li2.png


二進制
web/src/assets/img/expert/li3.png


二進制
web/src/assets/img/expert/mjfc.png


二進制
web/src/assets/img/expert/moveBg.png


二進制
web/src/assets/img/expert/moveInco.png


二進制
web/src/assets/img/expert/topBg.png


二進制
web/src/assets/img/goods/bg.jpg


二進制
web/src/assets/img/goods/close.png


二進制
web/src/assets/img/goods/iconS.png


二進制
web/src/assets/img/goods/null.png


web/src/assets/img/rowBg.png → web/src/assets/img/goods/rowBg.png


+ 6 - 4
web/src/assets/styles/base.css

@@ -9,7 +9,8 @@ html {
   user-select: none;
 }
 body {
-  font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
+  font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB',
+    'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
   height: 100%;
   color: black;
 }
@@ -125,6 +126,7 @@ textarea {
   background: rgba(0, 0, 0, 0.2);
 }
 #root {
+  /* 待完善 */
   /*横屏*/
 }
 #root #ScreenChange {
@@ -213,10 +215,10 @@ textarea {
     right: 0px;
   }
 }
-#LookGood {
-  animation: LookGood 0.5s linear forwards;
+#A3look {
+  animation: A3look 0.5s linear forwards;
 }
-@keyframes LookGood {
+@keyframes A3look {
   0% {
     opacity: 0.1;
   }

+ 3 - 3
web/src/assets/styles/base.less

@@ -263,11 +263,11 @@ textarea {
   }
 }
 
-#LookGood {
-  animation: LookGood 0.5s linear forwards;
+#A3look {
+  animation: A3look 0.5s linear forwards;
 }
 
-@keyframes LookGood {
+@keyframes A3look {
   0% {
     opacity: 0.1;
   }

+ 29 - 0
web/src/pages/A1home/data.ts

@@ -0,0 +1,29 @@
+export const text = `
+<p>
+   &emsp;&emsp;时光荏苒,岁月流芳。1964年,在首任院长谢志光、首任所长梁伯强、首任副院长廖月琴等院所先驱的带领下,中山大学肿瘤防治中心的前身——华南肿瘤医院、中山医学院肿瘤研究所相继成立,成为新中国最早成立的肿瘤医院之一,肩负起肿瘤防治的时代重任。
+ </p>
+ <p>
+   &emsp;&emsp;六十载春华秋实、风雨兼程,一代代中肿人始终不忘初心,以“征服癌症,造福人类”为己任,栉风沐雨、砥砺前行,为我国医学事业的发展、为人民的健康做出了杰出贡献。今日的中肿,“诚实、友爱、敬业、创新”的院训精神薪火相传,“幸福、同心、奋斗”的中心文化历久弥新。中肿人正以时不我待的紧迫感与使命感,加快构建三院区发展新格局。
+ </p>
+ <p>
+   &emsp;&emsp;甲子华诞,怀揣着这份内心的感动与自豪,我们在有限的空间里重新打造了这一开放式院史馆,希望通过馆中的一图一文、一物一品,能够让大家一起重温令人心潮澎湃的历史脉动,共同见证中心艰辛而又光辉的发展历程,激励后来者在通向世界顶尖梦想的征途上砥砺前行。
+ </p>
+`
+
+export const rightArr = [
+  {
+    id: 1,
+    name: '展馆漫游',
+    path: '/scene'
+  },
+  {
+    id: 2,
+    name: '精品典藏',
+    path: '/goods'
+  },
+  {
+    id: 3,
+    name: '专家风采',
+    path: '/expert'
+  }
+]

+ 2 - 29
web/src/pages/A1home/index.tsx

@@ -8,24 +8,7 @@ import classNames from 'classnames'
 // 图片导入
 import logoImg from '@/assets/img/home/logo.png'
 import yanImg from '@/assets/img/home/yan.png'
-
-const rightArr = [
-  {
-    id: 1,
-    name: '展馆漫游',
-    path: '/scene'
-  },
-  {
-    id: 2,
-    name: '精品典藏',
-    path: '/goods'
-  },
-  {
-    id: 3,
-    name: '专家风采',
-    path: '/expert'
-  }
-]
+import { rightArr, text } from './data'
 
 function A1home() {
   const { visitSum } = useSelector((state: RootState) => state.A0Layout)
@@ -73,17 +56,7 @@ function A1home() {
         {/* 左侧文字 */}
         <div className='A1Left'>
           <img src={logoImg} alt='' />
-          <div className='A1LeftTxt mySorrlNo'>
-            <p>
-              &emsp;&emsp;时光荏苒,岁月流芳。1964年,在首任院长谢志光、首任所长梁伯强、首任副院长廖月琴等院所先驱的带领下,中山大学肿瘤防治中心的前身——华南肿瘤医院、中山医学院肿瘤研究所相继成立,成为新中国最早成立的肿瘤医院之一,肩负起肿瘤防治的时代重任。
-            </p>
-            <p>
-              &emsp;&emsp;六十载春华秋实、风雨兼程,一代代中肿人始终不忘初心,以“征服癌症,造福人类”为己任,栉风沐雨、砥砺前行,为我国医学事业的发展、为人民的健康做出了杰出贡献。今日的中肿,“诚实、友爱、敬业、创新”的院训精神薪火相传,“幸福、同心、奋斗”的中心文化历久弥新。中肿人正以时不我待的紧迫感与使命感,加快构建三院区发展新格局。
-            </p>
-            <p>
-              &emsp;&emsp;甲子华诞,怀揣着这份内心的感动与自豪,我们在有限的空间里重新打造了这一开放式院史馆,希望通过馆中的一图一文、一物一品,能够让大家一起重温令人心潮澎湃的历史脉动,共同见证中心艰辛而又光辉的发展历程,激励后来者在通向世界顶尖梦想的征途上砥砺前行。
-            </p>
-          </div>
+          <div className='A1LeftTxt mySorrlNo' dangerouslySetInnerHTML={{ __html: text }}></div>
         </div>
 
         {/* 右侧信息 */}

+ 109 - 0
web/src/pages/A3goods/A3look/index.module.scss

@@ -0,0 +1,109 @@
+.A3look {
+  position: absolute;
+  z-index: 10;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  opacity: 0.1;
+  transition: opacity 0.5s;
+  :global {
+    .Lcolse {
+      z-index: 10;
+      cursor: pointer;
+      position: absolute;
+      top: 20px;
+      right: 20px;
+      width: 50px;
+    }
+    .Lmain {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      width: 860px;
+      height: 560px;
+      .LmainCen {
+        width: 100%;
+        height: 490px;
+        .ant-carousel {
+          width: 100%;
+          height: 100%;
+          .adm-image {
+            width: 100% !important;
+            height: 490px !important;
+          }
+          .slick-dots {
+            bottom: -20px;
+            li button {
+              opacity: 1;
+              background-color: #fff;
+            }
+            .slick-active button {
+              background-color: var(--themeColor);
+            }
+          }
+        }
+        .Limg {
+          width: 100%;
+          height: 100%;
+          cursor: zoom-in;
+
+          img {
+            pointer-events: none;
+            width: 100%;
+            height: 100%;
+            object-fit: contain !important;
+          }
+        }
+        video {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      .LmTxt {
+        margin-top: 50px;
+        font-size: 22px;
+        font-weight: 700;
+        padding: 0 40px;
+        text-align: center;
+        .LmTxt2 {
+          text-align: left;
+          white-space: pre-wrap;
+          max-height: 120px;
+          overflow-y: auto;
+          letter-spacing: 3px;
+          margin-top: 5px;
+          line-height: 24px;
+          font-size: 16px;
+        }
+      }
+    }
+    .LmainFull {
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      transform: translate(0, 0);
+      .LmainCen {
+        height: 100%;
+        overflow: hidden;
+        iframe {
+          width: 100%;
+          height: 100%;
+        }
+      }
+      .LmTxt {
+        width: 1200px;
+        position: absolute;
+        z-index: 5;
+        bottom: 40px;
+        left: 50%;
+        transform: translateX(-50%);
+        .LmTxt2 {
+          max-height: 100px;
+        }
+      }
+    }
+  }
+}

+ 87 - 0
web/src/pages/A3goods/A3look/index.tsx

@@ -0,0 +1,87 @@
+import React, { useCallback, useEffect, useState } from 'react'
+import styles from './index.module.scss'
+import classNames from 'classnames'
+import { FileType, GoodsRow } from '@/types'
+import LazyImg from '@/components/LazyImg'
+
+// 图片导入
+import closeImg from '@/assets/img/goods/close.png'
+import { getGoodsInfo } from '@/store/action/all'
+import { baseURL } from '@/utils/http'
+import { Carousel } from 'antd'
+import store from '@/store'
+
+type Props = {
+  closeFu: () => void
+  id: number
+}
+
+function A3look({ closeFu, id }: Props) {
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await getGoodsInfo(id)
+    if (res.code === 0) {
+      setInfo(res.data.entity)
+      setFile(res.data.file)
+    }
+  }, [])
+
+  useEffect(() => {
+    getInfoFu(id)
+  }, [getInfoFu, id])
+
+  const [info, setInfo] = useState({} as GoodsRow)
+
+  const [file, setFile] = useState([] as FileType[])
+
+  return (
+    <div className={classNames(styles.A3look)} id='A3look'>
+      {info.id ? (
+        <>
+          {/* 关闭按钮 */}
+          <img onClick={closeFu} className='Lcolse' src={closeImg} alt='' />
+          <div className={classNames('Lmain', info.fileType === 'model' ? 'LmainFull' : '')}>
+            <div className='LmainCen'>
+              {info.fileType === 'img' ? (
+                <Carousel>
+                  {file.map(v => (
+                    <div
+                      key={v.id}
+                      className='Limg'
+                      onClick={() =>
+                        store.dispatch({
+                          type: 'layout/lookBigImg',
+                          payload: { url: baseURL + v.filePath, show: true }
+                        })
+                      }
+                    >
+                      <LazyImg src={baseURL + v.thumb} />
+                    </div>
+                  ))}
+                </Carousel>
+              ) : null}
+              {info.fileType === 'model' ? (
+                <iframe
+                  src={`model.html?m=${baseURL + file[0].filePath}`}
+                  frameBorder='0'
+                  title='model'
+                ></iframe>
+              ) : null}
+              {info.fileType === 'video' ? (
+                <video src={baseURL + file[0].filePath} controls />
+              ) : null}
+            </div>
+
+            <div className='LmTxt'>
+              <div>{info.name}</div>
+              <div className='LmTxt2 mySorrl'>{info.remark}</div>
+            </div>
+          </div>
+        </>
+      ) : null}
+    </div>
+  )
+}
+
+const MemoA3look = React.memo(A3look)
+
+export default MemoA3look

+ 14 - 0
web/src/pages/A3goods/data.ts

@@ -0,0 +1,14 @@
+export const nameObj = {
+  1: {
+    name: '二维图片',
+    name2: 'Picture'
+  },
+  2: {
+    name: '三维模型',
+    name2: 'Model'
+  },
+  3: {
+    name: '影音资料',
+    name2: 'Audiovisual'
+  }
+}

+ 3 - 1
web/src/pages/A3goods/index.module.scss

@@ -1,5 +1,6 @@
 .A3goods {
   background-size: 100% 100%;
+  background-image: url('../../assets/img/goods/bg.jpg');
   :global {
     .A2main {
       position: absolute;
@@ -12,7 +13,7 @@
       justify-content: space-around;
       & > div {
         width: 26%;
-        background-image: url('../../assets/img/rowBg.png');
+        background-image: url('../../assets/img/goods/rowBg.png');
         background-size: 100% 100%;
         .A2top {
           padding: 4% 6% 0;
@@ -94,6 +95,7 @@
 
             // 没有搜到东西
             .A2IrowNull {
+              pointer-events: none;
               width: 100%;
               height: 100%;
               display: flex;

+ 289 - 6
web/src/pages/A3goods/index.tsx

@@ -1,13 +1,296 @@
-import React from 'react'
+import React, { useCallback, useEffect, useState } from 'react'
 import styles from './index.module.scss'
-function AAAAA() {
+import LeftTopLogo from '@/components/LeftTopLogo'
+
+import { SearchOutline } from 'antd-mobile-icons'
+
+import { Swiper, SwiperSlide } from 'swiper/react'
+
+import { FreeMode, Mousewheel } from 'swiper'
+// Import Swiper styles
+import 'swiper/css'
+import 'swiper/css/free-mode'
+import 'swiper/css/mousewheel'
+
+import classNames from 'classnames'
+import LazyImg from '@/components/LazyImg'
+import { Input } from 'antd-mobile'
+import { baseURL } from '@/utils/http'
+import { GoodsRow } from '@/types'
+import { getGoodsList } from '@/store/action/all'
+import { nameObj } from './data'
+
+// 图片导入
+import iconSImg from '@/assets/img/goods/iconS.png'
+import nullImg from '@/assets/img/goods/null.png'
+import A3look from './A3look'
+
+function A3goods() {
+  const [dataAll1, setDataAll1] = useState<GoodsRow[]>([])
+  const [dataAll2, setDataAll2] = useState<GoodsRow[]>([])
+  const [dataAll3, setDataAll3] = useState<GoodsRow[]>([])
+  const [loding, setLoding] = useState(false)
+
+  const getDataAll = useCallback(async () => {
+    const res = await getGoodsList({ dictId: '', pageNum: 1, pageSize: 99999, searchKey: '' })
+
+    if (res.code === 0) {
+      setLoding(true)
+      const dataZong: GoodsRow[] = res.data.records || []
+      const type1 = dataZong.filter(v => v.fileType === 'img')
+      const type2 = dataZong.filter(v => v.fileType === 'model')
+      const type3 = dataZong.filter(v => v.fileType === 'video')
+
+      setDataAll1(type1)
+      setDataAll2(type2)
+      setDataAll3(type3)
+
+      setData1(type1)
+      setData2(type2)
+      setData3(type3)
+
+      const types1 = type1.map(v => v.dictName)
+      setrowArr1(['全部', ...Array.from(new Set(types1))])
+
+      const types2 = type2.map(v => v.dictName)
+      setrowArr2(['全部', ...Array.from(new Set(types2))])
+
+      const types3 = type3.map(v => v.dictName)
+      setrowArr3(['全部', ...Array.from(new Set(types3))])
+    }
+  }, [])
+
+  useEffect(() => {
+    getDataAll()
+  }, [getDataAll])
+
+  const [data1, setData1] = useState<GoodsRow[]>([])
+  const [ac1, setAc1] = useState('全部')
+  const [rowArr1, setrowArr1] = useState<string[]>([])
+  const [txt1, setTxt1] = useState('')
+  const [txtFlag1, setTxtFlag1] = useState(false)
+
+  const [data2, setData2] = useState<GoodsRow[]>([])
+  const [ac2, setAc2] = useState('全部')
+  const [rowArr2, setrowArr2] = useState<string[]>([])
+  const [txt2, setTxt2] = useState('')
+  const [txtFlag2, setTxtFlag2] = useState(false)
+
+  const [data3, setData3] = useState<GoodsRow[]>([])
+  const [ac3, setAc3] = useState('全部')
+  const [rowArr3, setrowArr3] = useState<string[]>([])
+  const [txt3, setTxt3] = useState('')
+  const [txtFlag3, setTxtFlag3] = useState(false)
+
+  // 滚动到顶部
+  const sollrTop = useCallback((classKey: string) => {
+    const dom: HTMLDivElement = document.querySelector('.' + classKey)!
+    if (dom) dom.scrollTop = 0
+  }, [])
+
+  useEffect(() => {
+    if (loding) {
+    }
+  }, [loding])
+
+  // 切换顶部
+  const topCut = useCallback(
+    (name: string, acTxt: string, index: 1 | 2 | 3, classKey: string) => {
+      if (name === acTxt) return
+      index === 1 ? setAc1(name) : index === 2 ? setAc2(name) : setAc3(name)
+
+      index === 1 ? setTxt1('') : index === 2 ? setTxt2('') : setTxt3('')
+
+      const dataAll = index === 1 ? dataAll1 : index === 2 ? dataAll2 : dataAll3
+
+      let resData: GoodsRow[] = []
+
+      if (name === '全部') resData = dataAll
+      else resData = dataAll.filter(v => v.dictName === name)
+
+      index === 1 ? setData1(resData) : index === 2 ? setData2(resData) : setData3(resData)
+
+      sollrTop(classKey)
+    },
+    [dataAll1, dataAll2, dataAll3, sollrTop]
+  )
+
+  // 点击搜索
+  const searchFu = useCallback(
+    (val: string, acTxt: string, index: 1 | 2 | 3, classKey: string) => {
+      const dataAllTemp = index === 1 ? dataAll1 : index === 2 ? dataAll2 : dataAll3
+
+      const dataAll = acTxt === '全部' ? dataAllTemp : dataAllTemp.filter(v => v.dictName === acTxt)
+
+      let resData: GoodsRow[] = []
+
+      if (val === '') resData = dataAll
+      else resData = dataAll.filter(v => v.name.includes(val))
+
+      index === 1 ? setData1(resData) : index === 2 ? setData2(resData) : setData3(resData)
+
+      sollrTop(classKey)
+    },
+    [dataAll1, dataAll2, dataAll3, sollrTop]
+  )
+
+  // // 打开详情
+  // const [opInfo, setOpInfo] = useState({} as GoodsRow)
+  // const [opType, setOpType] = useState<any>('')
+
+  const rowBox = useCallback(
+    (index: 1 | 2 | 3) => {
+      const rowArr = index === 1 ? rowArr1 : index === 2 ? rowArr2 : rowArr3
+      const acTxt = index === 1 ? ac1 : index === 2 ? ac2 : ac3
+      const data = index === 1 ? data1 : index === 2 ? data2 : data3
+      const txtFlag = index === 1 ? txtFlag1 : index === 2 ? txtFlag2 : txtFlag3
+
+      return (
+        <div>
+          <div className='A2top'>
+            <div className='A2top1'>
+              <h1>{Reflect.get(nameObj, index).name}</h1> {Reflect.get(nameObj, index).name2}
+            </div>
+            <div className='A2top2'>
+              <Swiper
+                modules={[FreeMode, Mousewheel]}
+                className='appSw'
+                spaceBetween={0}
+                slidesPerView='auto'
+                freeMode={true}
+                mousewheel={true}
+                // onSlideChange={(e) => console.log("slide change", e)}
+                // onSwiper={(swiper) => (mySwiperRef.current = swiper)}
+              >
+                {rowArr.map(v => (
+                  <SwiperSlide key={v}>
+                    <div
+                      onClick={() => topCut(v, acTxt, index, 'A2Sorrl' + index)}
+                      className={classNames('topRow', acTxt === v ? 'active' : '')}
+                    >
+                      <span>{v}</span>
+                    </div>
+                  </SwiperSlide>
+                ))}
+              </Swiper>
+            </div>
+          </div>
+
+          <div className='A2info'>
+            <div className={classNames('mySorrl', 'A2Sorrl' + index)}>
+              {data.length ? (
+                <>
+                  {data.map(v => (
+                    <div
+                      className='A2Irow'
+                      onClick={() => setLookId(v.id)}
+                      key={v.id}
+                      title={v.name}
+                    >
+                      <div className='A2Irow1'>
+                        <LazyImg src={baseURL + v.thumb} />
+                      </div>
+                      <div className='A2Irow2'>
+                        {v.name}
+                        <img src={iconSImg} alt='' />
+                      </div>
+                    </div>
+                  ))}
+                </>
+              ) : (
+                <div className='A2IrowNull' hidden={!loding}>
+                  <img src={nullImg} alt='' />
+                  <p>暂时没有数据</p>
+                  <p>请试一下其他关键字</p>
+                </div>
+              )}
+            </div>
+          </div>
+
+          {/* 底部搜索 */}
+          <div className='A2Search'>
+            {txtFlag ? (
+              <Input
+                onEnterPress={() =>
+                  searchFu(
+                    index === 1 ? txt1 : index === 2 ? txt2 : txt3,
+                    acTxt,
+                    index,
+                    'A2Sorrl' + index
+                  )
+                }
+                placeholder='请输入搜索内容'
+                value={index === 1 ? txt1 : index === 2 ? txt2 : txt3}
+                onChange={value => {
+                  const txtRes = value.replace(/\s+/g, '')
+                  index === 1 ? setTxt1(txtRes) : index === 2 ? setTxt2(txtRes) : setTxt3(txtRes)
+                }}
+              />
+            ) : null}
+
+            <div
+              className='A2SearchIcon'
+              onClick={() => {
+                if (!txtFlag) {
+                  index === 1
+                    ? setTxtFlag1(true)
+                    : index === 2
+                    ? setTxtFlag2(true)
+                    : setTxtFlag3(true)
+                } else
+                  searchFu(
+                    index === 1 ? txt1 : index === 2 ? txt2 : txt3,
+                    acTxt,
+                    index,
+                    'A2Sorrl' + index
+                  )
+              }}
+            >
+              <SearchOutline />
+            </div>
+          </div>
+        </div>
+      )
+    },
+    [
+      rowArr1,
+      rowArr2,
+      rowArr3,
+      ac1,
+      ac2,
+      ac3,
+      data1,
+      data2,
+      data3,
+      txtFlag1,
+      txtFlag2,
+      txtFlag3,
+      loding,
+      txt1,
+      txt2,
+      txt3,
+      topCut,
+      searchFu
+    ]
+  )
+
+  const [lookId, setLookId] = useState(0)
+
   return (
-    <div className={styles.AAAAA}>
-      <h1>AAAAA</h1>
+    <div className={styles.A3goods}>
+      <LeftTopLogo />
+
+      <div className='A2main' hidden={!!lookId}>
+        {rowBox(1)}
+        {rowBox(2)}
+        {rowBox(3)}
+      </div>
+
+      {lookId ? <A3look id={lookId} closeFu={() => setLookId(0)} /> : null}
     </div>
   )
 }
 
-const MemoAAAAA = React.memo(AAAAA)
+const MemoA3goods = React.memo(A3goods)
 
-export default MemoAAAAA
+export default MemoA3goods

+ 14 - 0
web/src/store/action/all.ts

@@ -6,3 +6,17 @@ import http from '@/utils/http'
 export const getvisit = () => {
   return http.get('show/visit/add')
 }
+
+/**
+ * 获取馆藏列表
+ */
+export const getGoodsList = (data: any) => {
+  return http.post('show/goods/pageList', data)
+}
+
+/**
+ * 获取馆藏详情
+ */
+export const getGoodsInfo = (id: number) => {
+  return http.get(`show/goods/detail/${id}`)
+}

+ 31 - 0
web/src/types/api/layot.d.ts

@@ -0,0 +1,31 @@
+export type GoodsRow = {
+  createTime: string
+  creatorId: number
+  creatorName: string
+  dictId: string
+  dictName: string
+  dirCode: string
+  fileIds: string
+  fileType: string
+  id: number
+  modelUrl: string
+  name: string
+  remark: string
+  sort: number
+  thumb: string
+  thumbPc: string
+  updateTime: string
+}
+
+export type FileType = {
+  createTime: string
+  creatorName: string
+  description: string
+  fileName: string
+  filePath: string
+  id: number
+  moduleName: string
+  thumb: string
+  type: string
+  updateTime: string
+}