瀏覽代碼

web-pc首页

shaogen1995 10 月之前
父節點
當前提交
f96d71e6eb

+ 32 - 1
web/public/myData/myData.js

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

+ 7 - 0
web/src/AppM.tsx

@@ -3,6 +3,7 @@ import '@/assets/styles/base.css'
 import { useCallback, useEffect, useRef } from 'react'
 import MessageCom from './components/Message'
 import RouterOrder from './components/RouterOrder'
+import screenImg from '@/assets/img/landtip.png'
 
 export default function AppM() {
   const setFullFu = useCallback(() => {
@@ -39,6 +40,12 @@ export default function AppM() {
 
       {/* antd 轻提示 ---兼容360浏览器 */}
       <MessageCom />
+
+      {/* 横屏提示 */}
+      <div id='ScreenChange'>
+        <img src={screenImg} alt='' />
+        <p>请在竖屏模式浏览</p>
+      </div>
     </div>
   )
 }

+ 59 - 7
web/src/assets/styles/base.css

@@ -64,11 +64,19 @@ textarea {
   height: 100%;
   position: relative;
 }
+#root #App > div {
+  width: 100%;
+  height: 100%;
+}
 #root #AppM {
   overflow: hidden;
   max-width: 500px;
   margin: 0 auto;
 }
+#root #AppM > div {
+  width: 100%;
+  height: 100%;
+}
 #root #AppM .noFindPage {
   padding-top: 0;
 }
@@ -80,7 +88,7 @@ textarea {
 }
 .mySorrl::-webkit-scrollbar {
   /*滚动条整体样式*/
-  width: 3px;
+  width: 1px;
   /*高宽分别对应横竖滚动条的尺寸*/
   height: 1px;
 }
@@ -88,7 +96,7 @@ textarea {
   /*滚动条里面小方块*/
   border-radius: 10px;
   -webkit-box-shadow: inset 0 0 5px transparent;
-  background: var(--themeColor2);
+  background: transparent;
 }
 .mySorrl::-webkit-scrollbar-track {
   /*滚动条里面轨道*/
@@ -130,14 +138,58 @@ textarea {
     pointer-events: auto;
   }
 }
-.A1locBoxLoc {
-  animation: moveDian 1s linear infinite alternate;
+.A1baseLogo {
+  animation: A1baseLogo 1s linear forwards;
+}
+@keyframes A1baseLogo {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+.A1Left {
+  animation: A1Left 2s linear forwards;
+}
+@keyframes A1Left {
+  0% {
+    left: -500px;
+  }
+  100% {
+    left: 0px;
+  }
+}
+.A1rRow0 .A1rRowOne {
+  animation: A1rRow0 0.8s linear forwards;
+}
+@keyframes A1rRow0 {
+  0% {
+    right: -800px;
+  }
+  100% {
+    right: 0px;
+  }
+}
+.A1rRow1 .A1rRowOne {
+  animation: A1rRow1 1.6s linear forwards;
+}
+@keyframes A1rRow1 {
+  0% {
+    right: -1600px;
+  }
+  100% {
+    right: 0px;
+  }
+}
+.A1rRow2 .A1rRowOne {
+  animation: A1rRow2 2.2s linear forwards;
 }
-@keyframes moveDian {
+@keyframes A1rRow2 {
   0% {
-    transform: translateY(-6px);
+    right: -2200px;
   }
   100% {
-    transform: translateY(6px);
+    right: 0px;
   }
 }

+ 73 - 8
web/src/assets/styles/base.less

@@ -76,6 +76,10 @@ textarea {
     width: 100%;
     height: 100%;
     position: relative;
+    & > div {
+      width: 100%;
+      height: 100%;
+    }
   }
 
   // 移动端AppM组件的样式
@@ -83,6 +87,10 @@ textarea {
     overflow: hidden;
     max-width: 500px;
     margin: 0 auto;
+    & > div {
+      width: 100%;
+      height: 100%;
+    }
     .noFindPage {
       padding-top: 0;
     }
@@ -101,7 +109,7 @@ textarea {
 // 滚动条
 .mySorrl::-webkit-scrollbar {
   /*滚动条整体样式*/
-  width: 3px;
+  width: 1px;
   /*高宽分别对应横竖滚动条的尺寸*/
   height: 1px;
 }
@@ -110,7 +118,7 @@ textarea {
   /*滚动条里面小方块*/
   border-radius: 10px;
   -webkit-box-shadow: inset 0 0 5px transparent;
-  background: var(--themeColor2);
+  background: transparent;
 }
 
 .mySorrl::-webkit-scrollbar-track {
@@ -159,17 +167,74 @@ textarea {
   }
 }
 
-// pc首页箭头动画帧
-.A1locBoxLoc {
-  animation: moveDian 1s linear infinite alternate;
+// 首页的动画
+
+.A1baseLogo {
+  animation: A1baseLogo 1s linear forwards;
+}
+
+@keyframes A1baseLogo {
+  0% {
+    opacity: 1;
+  }
+
+  100% {
+    opacity: 0;
+  }
+}
+
+.A1Left {
+  animation: A1Left 2s linear forwards;
+}
+
+@keyframes A1Left {
+  0% {
+    left: -500px;
+  }
+
+  100% {
+    left: 0px;
+  }
+}
+
+.A1rRow0 .A1rRowOne {
+  animation: A1rRow0 0.8s linear forwards;
+}
+
+@keyframes A1rRow0 {
+  0% {
+    right: -800px;
+  }
+
+  100% {
+    right: 0px;
+  }
+}
+
+.A1rRow1 .A1rRowOne {
+  animation: A1rRow1 1.6s linear forwards;
+}
+
+@keyframes A1rRow1 {
+  0% {
+    right: -1600px;
+  }
+
+  100% {
+    right: 0px;
+  }
+}
+
+.A1rRow2 .A1rRowOne {
+  animation: A1rRow2 2.2s linear forwards;
 }
 
-@keyframes moveDian {
+@keyframes A1rRow2 {
   0% {
-    transform: translateY(-6px);
+    right: -2200px;
   }
 
   100% {
-    transform: translateY(6px);
+    right: 0px;
   }
 }

+ 8 - 0
web/src/index.tsx

@@ -14,10 +14,18 @@ import 'dayjs/locale/zh-cn'
 import locale from 'antd/locale/zh_CN'
 
 import { isMobileFu } from './utils/history'
+import { httpGet } from './utils/http'
 
 const container = document.getElementById('root') as HTMLElement
 const root = createRoot(container)
 
+// 浏览量
+httpGet('https://count.4dage.com/api/count/saveVisit/SG-mSXPpz8xPea', res => {
+  if (res.code === 0) {
+    store.dispatch({ type: 'layout/visitSum', payload: res.data.visitSum })
+  }
+})
+
 root.render(
   <ConfigProvider
     locale={locale}

+ 162 - 4
web/src/pages/A1home/index.module.scss

@@ -1,5 +1,163 @@
-.A1home{
-  :global{
-    
+.A1home {
+  background-size: 100% 100%;
+  position: relative;
+  overflow: hidden;
+  :global {
+    .A1baseLogo {
+      pointer-events: none;
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      z-index: 10;
+    }
+    .leftTopLogo {
+      pointer-events: none;
+      position: fixed;
+      // z-index: 9998;
+      top: 20px;
+      left: 20px;
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+
+      & > p {
+        img {
+          width: 20px;
+        }
+        & > span {
+          font-weight: 700;
+          position: relative;
+          top: 1px;
+          display: inline-block;
+          margin: 0 10px;
+        }
+      }
+    }
+    .A1main {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      width: 80%;
+      height: 70%;
+      display: flex;
+      .A1Left {
+        position: relative;
+        width: calc(25% - 25px);
+        margin-right: 25px;
+        & > img {
+          width: 100%;
+        }
+        .A1LeftTxt {
+          height: calc(100% - 180px);
+          overflow-y: auto;
+          margin-top: 15px;
+          // &::-webkit-scrollbar {
+          //   width: 5px;
+          // }
+          p {
+            font-size: 16px;
+            line-height: 26px;
+            letter-spacing: 4px;
+            text-align: justify;
+          }
+        }
+      }
+      .A1Right {
+        width: 75%;
+        display: flex;
+        justify-content: space-around;
+
+        .A1rRow {
+          cursor: pointer;
+          background-size: 100% 100%;
+          position: relative;
+          width: 30%;
+          height: 100%;
+
+          right: 0;
+          & > div {
+            position: absolute;
+            top: 0;
+            right: 0;
+            width: 100%;
+            height: 100%;
+            opacity: 0;
+            pointer-events: none;
+            transition: opacity 0.5s;
+            background-size: 100% 100%;
+          }
+
+          .A1rRowOne {
+            opacity: 1;
+            pointer-events: auto;
+            position: relative;
+            width: 100%;
+            height: 100%;
+            perspective: 1000px;
+            transform-style: preserve-3d;
+            & > div {
+              position: absolute;
+              top: 0;
+              right: -0;
+              width: 100%;
+              height: 100%;
+              background-size: 100% 100%;
+              transition: transform 2s;
+              backface-visibility: hidden;
+            }
+
+            .A1rRow1 {
+              opacity: 1;
+              pointer-events: auto;
+              transform: rotateY(0deg);
+            }
+
+            .A1rRow2 {
+              right: 0;
+              transform: rotateY(180deg);
+            }
+          }
+
+          .A1rRow3 {
+            right: 0;
+            top: -20px;
+            height: calc(100% + 40px);
+          }
+          &:hover {
+            .A1rRowOne {
+              opacity: 0;
+              pointer-events: none;
+            }
+            .A1rRow3 {
+              opacity: 1;
+              pointer-events: auto;
+            }
+          }
+        }
+
+        .A1rRowAc {
+          .A1rRowOne {
+            .A1rRow1 {
+              transform: rotateY(-180deg);
+            }
+            .A1rRow2 {
+              transform: rotateY(0deg);
+            }
+          }
+        }
+      }
+    }
+    .A1mainMask {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      z-index: 10;
+      // background-color: red;
+      opacity: 0.5;
+    }
   }
-}
+}

+ 98 - 8
web/src/pages/A1home/index.tsx

@@ -1,14 +1,104 @@
-import React from "react";
-import styles from "./index.module.scss";
- function A1home() {
-  
+import React, { useEffect, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import history, { baseURL, isMobileFu, myData } from '@/utils/history'
+import { useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import classNames from 'classnames'
+function A1home() {
+  const { visitSum } = useSelector((state: RootState) => state.A0Layout)
+
+  const [bacFlag, setBacFlag] = useState([false, false, false])
+
+  const timeRef = useRef(-1)
+
+  const [clickFlag, setClickFlag] = useState(false)
+
+  useEffect(() => {
+    timeRef.current = window.setTimeout(() => {
+      setBacFlag([true, false, false])
+      timeRef.current = window.setTimeout(() => {
+        setBacFlag([true, true, false])
+        timeRef.current = window.setTimeout(() => {
+          setBacFlag([true, true, true])
+          timeRef.current = window.setTimeout(() => {
+            setClickFlag(true)
+          }, 2000)
+        }, 600)
+      }, 800)
+    }, 800)
+    return () => {
+      clearTimeout(timeRef.current)
+    }
+  }, [])
+
   return (
-    <div className={styles.A1home}>
-      <h1>A1home</h1>
+    <div
+      className={styles.A1home}
+      style={{
+        backgroundImage: `url(${baseURL + myData.home.bg})`
+      }}
+    >
+      {/* 初始化logo */}
+      <img className='A1baseLogo' src={baseURL + myData.home.logo} alt='' />
+
+      {/* 顶部浏览量 */}
+      <div className='leftTopLogo' v-show='!isMobile'>
+        <p>欢迎您的到来,您是第{visitSum}位参观者!</p>
+        <p>
+          <img src={baseURL + myData.home.yan} alt='' />
+          <span>{visitSum}</span>浏览量
+        </p>
+      </div>
+
+      {/* 主体 */}
+      <div className='A1main'>
+        {/* 左侧文字 */}
+        <div className='A1Left'>
+          <img src={baseURL + myData.home.logo} alt='' />
+          <div
+            className='A1LeftTxt mySorrl'
+            dangerouslySetInnerHTML={{ __html: myData.home.txt }}
+          ></div>
+        </div>
+
+        {/* 右侧信息 */}
+        <div className='A1Right'>
+          {myData.home.arr.map((v, i) => (
+            <div
+              className={classNames('A1rRow', 'A1rRow' + i, bacFlag[i] ? 'A1rRowAc' : '')}
+              key={v.id}
+              onClick={() => history.push(`${v.path}${isMobileFu() ? 'M' : ''}`)}
+            >
+              <div className='A1rRowOne'>
+                {/* 反的 */}
+                <div
+                  className='A1rRow1'
+                  style={{ backgroundImage: `url(${baseURL}home/${v.id}F.png)` }}
+                ></div>
+
+                {/* 正常的 */}
+                <div
+                  className='A1rRow2'
+                  style={{ backgroundImage: `url(${baseURL}home/${v.id}.png)` }}
+                ></div>
+              </div>
+
+              {/* 鼠标移入的 */}
+              <div
+                className='A1rRow3'
+                style={{ backgroundImage: `url(${baseURL}home/${v.id}Ac.png)` }}
+              ></div>
+            </div>
+          ))}
+        </div>
+      </div>
+
+      {/* 主体遮罩 */}
+      {clickFlag ? null : <div className='A1mainMask'></div>}
     </div>
   )
 }
 
-const MemoA1home = React.memo(A1home);
+const MemoA1home = React.memo(A1home)
 
-export default MemoA1home;
+export default MemoA1home

+ 7 - 7
web/src/pages/A1homeM/index.tsx

@@ -1,14 +1,14 @@
-import React from "react";
-import styles from "./index.module.scss";
- function A1homeM() {
-  
+import React from 'react'
+import styles from './index.module.scss'
+function A1homeM() {
   return (
     <div className={styles.A1homeM}>
-      <h1>A1homeM</h1>
+      <h1>中山大学附属肿瘤医院线上院史馆</h1>
+      <h2>移动端开发中,敬请期待.</h2>
     </div>
   )
 }
 
-const MemoA1homeM = React.memo(A1homeM);
+const MemoA1homeM = React.memo(A1homeM)
 
-export default MemoA1homeM;
+export default MemoA1homeM

+ 4 - 0
web/src/pages/A2scene/index.module.scss

@@ -0,0 +1,4 @@
+.A2scene {
+  :global {
+  }
+}

+ 14 - 0
web/src/pages/A2scene/index.tsx

@@ -0,0 +1,14 @@
+import React from 'react'
+import styles from './index.module.scss'
+function A2scene() {
+  return (
+    <div className={styles.A2scene}>
+      <h1>中山大学附属肿瘤医院线上院史馆</h1>
+      <h2>移动端开发中,敬请期待.</h2>
+    </div>
+  )
+}
+
+const MemoA2scene = React.memo(A2scene)
+
+export default MemoA2scene

+ 4 - 0
web/src/pages/A2sceneM/index.module.scss

@@ -0,0 +1,4 @@
+.A2sceneM {
+  :global {
+  }
+}

+ 14 - 0
web/src/pages/A2sceneM/index.tsx

@@ -0,0 +1,14 @@
+import React from 'react'
+import styles from './index.module.scss'
+function A2sceneM() {
+  return (
+    <div className={styles.A2sceneM}>
+      <h1>中山大学附属肿瘤医院线上院史馆</h1>
+      <h2>移动端开发中,敬请期待.</h2>
+    </div>
+  )
+}
+
+const MemoA2sceneM = React.memo(A2sceneM)
+
+export default MemoA2sceneM

+ 10 - 2
web/src/store/reducer/layout.ts

@@ -7,11 +7,16 @@ const initState = {
     txt: '',
     type: 'info',
     duration: 3
-  } as MessageType
+  } as MessageType,
+
+  // 浏览量
+  visitSum: 0
 }
 
 // 定义 action 类型
-type LayoutActionType = { type: 'layout/message'; payload: MessageType }
+type LayoutActionType =
+  | { type: 'layout/message'; payload: MessageType }
+  | { type: 'layout/visitSum'; payload: number }
 
 // 频道 reducer
 export default function layoutReducer(state = initState, action: LayoutActionType) {
@@ -19,6 +24,9 @@ export default function layoutReducer(state = initState, action: LayoutActionTyp
     // antd轻提示(兼容360浏览器)
     case 'layout/message':
       return { ...state, message: action.payload }
+    // 浏览量
+    case 'layout/visitSum':
+      return { ...state, visitSum: action.payload }
     default:
       return state
   }

+ 1 - 1
web/src/types/api/layot.d.ts

@@ -1 +1 @@
-export type MyDataType = { id: number }
+

+ 13 - 0
web/src/types/declaration.d.ts

@@ -11,3 +11,16 @@ declare module 'braft-utils'
 declare const baseUrlLoc: string
 declare const baseUrlAtl: string
 declare const myDataTemp: MyDataType
+type MyDataType = {
+  home: {
+    bg: string
+    logo: string
+    yan: string
+    txt: string
+    arr: {
+      id: number
+      name: string
+      path: string
+    }[]
+  }
+}

+ 11 - 0
web/src/utils/http.ts

@@ -0,0 +1,11 @@
+export const httpGet = (url: string, fu: (res: any) => void) => {
+  fetch(url)
+    .then(response => {
+      if (!response.ok) {
+        throw new Error('Network response was not ok')
+      }
+      return response.json()
+    })
+    .then(data => fu(data))
+    .catch(error => console.error('Fetch error:', error))
+}

二進制
web静态资源/staticData/home/1.png


二進制
web静态资源/staticData/home/1Ac.png


二進制
web静态资源/staticData/home/1F.png


二進制
web静态资源/staticData/home/2.png


二進制
web静态资源/staticData/home/2Ac.png


二進制
web静态资源/staticData/home/2F.png


二進制
web静态资源/staticData/home/3.png


二進制
web静态资源/staticData/home/3Ac.png


二進制
web静态资源/staticData/home/3F.png


二進制
web静态资源/staticData/home/bg.jpg


二進制
web静态资源/staticData/home/logo.png


二進制
web静态资源/staticData/home/yan.png