shaogen1995 3 тижнів тому
коміт
07bbc6000e
100 змінених файлів з 43072 додано та 0 видалено
  1. 12 0
      code/.editorconfig
  2. 3 0
      code/.env
  3. 23 0
      code/.gitignore
  4. 2 0
      code/.npmrc
  5. 11 0
      code/.prettierrc.js
  6. 4 0
      code/.vscode/settings.json
  7. 1 0
      code/README.md
  8. 13 0
      code/config-overrides.js
  9. 30435 0
      code/package-lock.json
  10. 63 0
      code/package.json
  11. 8 0
      code/path.tsconfig.json
  12. 50 0
      code/public/index.html
  13. 192 0
      code/public/myData/base.js
  14. BIN
      code/public/myData/kai.ttf
  15. 119 0
      code/src/App.tsx
  16. 141 0
      code/src/assets/styles/base.css
  17. 190 0
      code/src/assets/styles/base.less
  18. 21 0
      code/src/components/AsyncSpinLoding/index.module.scss
  19. 15 0
      code/src/components/AsyncSpinLoding/index.tsx
  20. 29 0
      code/src/components/Message/index.tsx
  21. 24 0
      code/src/components/NotFound/index.tsx
  22. 10 0
      code/src/components/SpinLoding/index.module.scss
  23. 13 0
      code/src/components/SpinLoding/index.tsx
  24. 21 0
      code/src/components/Ztop/index.module.scss
  25. 19 0
      code/src/components/Ztop/index.tsx
  26. 35 0
      code/src/index.tsx
  27. 118 0
      code/src/pages/A1home/index.module.scss
  28. 37 0
      code/src/pages/A1home/index.tsx
  29. 272 0
      code/src/pages/A2main/index.module.scss
  30. 154 0
      code/src/pages/A2main/index.tsx
  31. 48 0
      code/src/pages/A3liuChao1/index.module.scss
  32. 32 0
      code/src/pages/A3liuChao1/index.tsx
  33. 133 0
      code/src/pages/A3liuChao2/index.module.scss
  34. 82 0
      code/src/pages/A3liuChao2/index.tsx
  35. 108 0
      code/src/pages/A4diao/index.module.scss
  36. 75 0
      code/src/pages/A4diao/index.tsx
  37. 4 0
      code/src/pages/初始化组件/index.module.scss
  38. 14 0
      code/src/pages/初始化组件/index.tsx
  39. 20 0
      code/src/store/index.ts
  40. 13 0
      code/src/store/reducer/index.ts
  41. 42 0
      code/src/store/reducer/layout.ts
  42. 38 0
      code/src/types/api/layot.d.ts
  43. 11 0
      code/src/types/declaration.d.ts
  44. 1 0
      code/src/types/index.d.ts
  45. 13 0
      code/src/utils/domShow.ts
  46. 30 0
      code/src/utils/history.ts
  47. 7 0
      code/src/utils/http.ts
  48. 50 0
      code/src/utils/message.ts
  49. 18 0
      code/src/utils/storage.ts
  50. 27 0
      code/tsconfig.json
  51. 10271 0
      code/yarn.lock
  52. BIN
      静态资源/staticData/home/bg.jpg
  53. BIN
      静态资源/staticData/home/bs.png
  54. BIN
      静态资源/staticData/home/diBac.png
  55. BIN
      静态资源/staticData/home/hover.png
  56. BIN
      静态资源/staticData/home/kuang.png
  57. BIN
      静态资源/staticData/home/logo.png
  58. BIN
      静态资源/staticData/home/title.png
  59. BIN
      静态资源/staticData/main/back.png
  60. BIN
      静态资源/staticData/main/bg.jpg
  61. BIN
      静态资源/staticData/main/d1.png
  62. BIN
      静态资源/staticData/main/d2.png
  63. BIN
      静态资源/staticData/main/da1.png
  64. BIN
      静态资源/staticData/main/da1x.png
  65. BIN
      静态资源/staticData/main/da2.png
  66. BIN
      静态资源/staticData/main/da2x.png
  67. BIN
      静态资源/staticData/main/da3.png
  68. BIN
      静态资源/staticData/main/da3x.png
  69. BIN
      静态资源/staticData/main/diao/1.png
  70. BIN
      静态资源/staticData/main/diao/1_0.jpg
  71. BIN
      静态资源/staticData/main/diao/1_1.jpg
  72. BIN
      静态资源/staticData/main/diao/2.png
  73. BIN
      静态资源/staticData/main/diao/2_1.jpg
  74. BIN
      静态资源/staticData/main/diao/3.png
  75. BIN
      静态资源/staticData/main/diao/3_0.jpg
  76. BIN
      静态资源/staticData/main/diao/bg.jpg
  77. BIN
      静态资源/staticData/main/diao/left.png
  78. BIN
      静态资源/staticData/main/diao/right.png
  79. BIN
      静态资源/staticData/main/l1.png
  80. BIN
      静态资源/staticData/main/l2.png
  81. BIN
      静态资源/staticData/main/l3.png
  82. BIN
      静态资源/staticData/main/l4.png
  83. BIN
      静态资源/staticData/main/l4Ac.png
  84. BIN
      静态资源/staticData/main/l5.png
  85. BIN
      静态资源/staticData/main/liuchao/1.png
  86. BIN
      静态资源/staticData/main/liuchao/10.png
  87. BIN
      静态资源/staticData/main/liuchao/10_0.png
  88. BIN
      静态资源/staticData/main/liuchao/11.png
  89. BIN
      静态资源/staticData/main/liuchao/11_0.png
  90. BIN
      静态资源/staticData/main/liuchao/2.png
  91. BIN
      静态资源/staticData/main/liuchao/3.png
  92. BIN
      静态资源/staticData/main/liuchao/4.png
  93. BIN
      静态资源/staticData/main/liuchao/5.png
  94. BIN
      静态资源/staticData/main/liuchao/6.png
  95. BIN
      静态资源/staticData/main/liuchao/7.png
  96. BIN
      静态资源/staticData/main/liuchao/7_0.png
  97. BIN
      静态资源/staticData/main/liuchao/7_1.png
  98. BIN
      静态资源/staticData/main/liuchao/8.png
  99. BIN
      静态资源/staticData/main/liuchao/8_0.png
  100. 0 0
      静态资源/staticData/main/liuchao/9.png

+ 12 - 0
code/.editorconfig

@@ -0,0 +1,12 @@
+root = true # 控制配置文件 .editorconfig 是否生效的字段
+ 
+[**] # 匹配全部文件
+indent_style = space # 缩进风格,可选space|tab
+indent_size = 2 # 缩进的空格数
+charset = utf-8 # 设置字符集
+trim_trailing_whitespace = true # 删除一行中的前后空格
+insert_final_newline = true # 设为true表示使文件以一个空白行结尾
+end_of_line = lf
+ 
+[**.md] # 匹配md文件
+trim_trailing_whitespace = false

+ 3 - 0
code/.env

@@ -0,0 +1,3 @@
+# .env.production
+GENERATE_SOURCEMAP = false
+# 关闭映射

+ 23 - 0
code/.gitignore

@@ -0,0 +1,23 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# production
+/build
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*

+ 2 - 0
code/.npmrc

@@ -0,0 +1,2 @@
+registry=https://registry.npmmirror.com/
+@dage:registry=http://192.168.20.245:4873/

+ 11 - 0
code/.prettierrc.js

@@ -0,0 +1,11 @@
+module.exports = {
+  printWidth: 100, // 一行的字符数,如果超过会进行换行
+  tabWidth: 2, // 一个tab代表几个空格数,默认就是2
+  useTabs: false, // 是否启用tab取代空格符缩进,.editorconfig设置空格缩进,所以设置为false
+  semi: false, // 行尾是否使用分号,默认为true
+  singleQuote: true, // 字符串是否使用单引号
+  trailingComma: "none", // 对象或数组末尾是否添加逗号 none| es5| all
+  jsxSingleQuote: true, // 在jsx里是否使用单引号,你看着办
+  bracketSpacing: true, // 对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
+  arrowParens: "avoid", // 箭头函数如果只有一个参数则省略括号
+};

+ 4 - 0
code/.vscode/settings.json

@@ -0,0 +1,4 @@
+{
+  "editor.defaultFormatter": "esbenp.prettier-vscode",
+  "editor.formatOnSave": true
+}

+ 1 - 0
code/README.md

@@ -0,0 +1 @@
+1.使用 yarn。 npm 有问题

+ 13 - 0
code/config-overrides.js

@@ -0,0 +1,13 @@
+const path = require('path')
+const { override, addWebpackAlias, setWebpackTarget } = require('customize-cra')
+
+// 添加 @ 别名(移除错误的 ssr 配置)
+const webpackAlias = addWebpackAlias({
+  '@': path.resolve(__dirname, 'src')
+})
+
+// 导出要进行覆盖的 webpack 配置
+module.exports = override(
+  webpackAlias,
+  setWebpackTarget('web') // 显式指定为浏览器环境(禁用Node.js/SSR相关处理)
+)

Різницю між файлами не показано, бо вона завелика
+ 30435 - 0
code/package-lock.json


+ 63 - 0
code/package.json

@@ -0,0 +1,63 @@
+{
+  "name": "demo2",
+  "version": "0.1.0",
+  "private": true,
+  "dependencies": {
+    "@ant-design/cssinjs": "^1.5.6",
+    "@testing-library/jest-dom": "^5.16.5",
+    "@testing-library/react": "^13.4.0",
+    "@testing-library/user-event": "^13.5.0",
+    "@types/jest": "^27.5.2",
+    "@types/node": "^16.18.3",
+    "@types/react": "^18.0.24",
+    "@types/react-dom": "^18.0.8",
+    "antd": "^5.8.3",
+    "antd-mobile": "^5.30.0",
+    "axios": "^1.13.2",
+    "classnames": "^2.5.1",
+    "react": "^18.2.0",
+    "react-dom": "^18.2.0",
+    "react-redux": "^8.0.4",
+    "react-router-dom": "5.3",
+    "react-scripts": "5.0.1",
+    "react-sortablejs": "^6.1.4",
+    "redux": "^4.2.0",
+    "redux-devtools-extension": "^2.13.9",
+    "redux-thunk": "^2.4.1",
+    "sass": "^1.55.0",
+    "typescript": "^4.8.4",
+    "web-vitals": "^2.1.4"
+  },
+  "scripts": {
+    "dev": "react-app-rewired start --host 0.0.0.0",
+    "build": "react-app-rewired build",
+    "test": "react-app-rewired test",
+    "eject": "react-scripts eject"
+  },
+  "eslintConfig": {
+    "extends": [
+      "react-app",
+      "react-app/jest"
+    ]
+  },
+  "browserslist": {
+    "production": [
+      ">0.2%",
+      "not dead",
+      "not op_mini all"
+    ],
+    "development": [
+      "last 1 chrome version",
+      "last 1 firefox version",
+      "last 1 safari version"
+    ]
+  },
+  "devDependencies": {
+    "@types/crypto-js": "^4.2.2",
+    "@types/history": "^5.0.0",
+    "@types/react-router-dom": "^5.3.3",
+    "customize-cra": "^1.0.0",
+    "react-app-rewired": "^2.2.1"
+  },
+  "homepage": "."
+}

+ 8 - 0
code/path.tsconfig.json

@@ -0,0 +1,8 @@
+{
+    "compilerOptions": {
+      "baseUrl": "./",
+      "paths": {
+        "@/*": ["src/*"]
+      }
+    }
+  }

+ 50 - 0
code/public/index.html

@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html lang="zh">
+
+<head>
+  <meta charset="utf-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+  <meta name="theme-color" content="#000000" />
+  <meta name="description" content="Web site created using create-react-app" />
+  <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
+  <!-- <link rel="shortcut icon" href="./favicon.ico" type="image/x-icon" /> -->
+  <script src="./myData/base.js"></script>
+
+
+  <style>
+    @font-face {
+      font-family: 'kai';
+      src: url('./myData/kai.ttf');
+    }
+
+    .fontLoding {
+      position: absolute;
+      top: 0;
+      left: 0;
+      opacity: 0;
+      pointer-events: none;
+      font-family: 'kai';
+    }
+  </style>
+  <title>扬州大运河-六朝石刻</title>
+</head>
+
+<body>
+  <noscript>You need to enable JavaScript to run this app.</noscript>
+  <div id="root"></div>
+  <!-- 一进页面就加载字体 -->
+  <i class="fontLoding">123</i>
+</body>
+
+<!-- <script>
+    window.onload = function () {
+      var script = document.createElement('script')
+      script.src = 'https://cdn.bootcss.com/eruda/1.5.4/eruda.min.js'
+      document.body.appendChild(script)
+      script.onload = function () {
+        eruda.init()
+      }
+    }
+  </script> -->
+
+</html>

Різницю між файлами не показано, бо вона завелика
+ 192 - 0
code/public/myData/base.js


BIN
code/public/myData/kai.ttf


+ 119 - 0
code/src/App.tsx

@@ -0,0 +1,119 @@
+import '@/assets/styles/base.css'
+// 关于路由
+import React, { useCallback, useEffect, useRef } from 'react'
+import { Router, Route, Switch } from 'react-router-dom'
+import history from './utils/history'
+import SpinLoding from './components/SpinLoding'
+import store from './store'
+import NotFound from '@/components/NotFound'
+import AsyncSpinLoding from './components/AsyncSpinLoding'
+import MessageCom from '@/components/Message'
+
+const A1home = React.lazy(() => import('./pages/A1home'))
+const A2main = React.lazy(() => import('./pages/A2main'))
+
+let tempW = document.documentElement.clientWidth
+let tempH = document.documentElement.clientHeight
+
+let tempMax = tempW >= tempH ? tempW : tempH
+let tempMin = tempW >= tempH ? tempH : tempW
+
+const pageBi = Math.round(Number((tempMax / tempMin).toFixed(2)))
+
+// 设计图按照 1920 X 1080 来开发
+const planSize = {
+  width: 1920,
+  height: Math.round(Number((1920 / pageBi).toFixed(0)))
+}
+
+export default function App() {
+  // 根元素
+  const rootRef = useRef<any>(null)
+
+  // // 把初始地址变量存到样式中(scss用不了 暂时放弃)
+  // useEffect(() => {
+  //   document.documentElement.style.setProperty('--baseUrl', baseUrl)
+  // }, [])
+
+  const pageFullChangeFu = useCallback(() => {
+    let width = document.documentElement.clientWidth
+    let height = document.documentElement.clientHeight
+
+    // let isHHTemp = false
+
+    if (width >= height) {
+      if (tempMax - width > 100) return
+
+      //横屏
+      // isHHTemp = true
+      const sizeW = width / planSize.width
+      let sizeH = height / planSize.height
+
+      let moveX = (planSize.width - width) / 2
+      let moveY = (planSize.height - height) / 2
+
+      if (width >= planSize.width) moveX = 0
+      rootRef.current.style.left = '0'
+      rootRef.current.style.transform = `translate3d(${-moveX}px,${-moveY}px,0px) scale(${sizeW},${sizeH}) rotate(0deg)`
+      rootRef.current.style.transformOrigin = 'center'
+
+      store.dispatch({
+        type: 'layout/style',
+        payload: {
+          width: planSize.width,
+          moveX: -moveX,
+          moveY: -moveY,
+          sizeW,
+          sizeH
+        }
+      })
+    } else {
+      if (tempMax - height > 100) return
+      // 竖屏
+      // isHHTemp = false
+      const temp = width
+      width = height
+      height = temp
+      const sizeW = width / planSize.width
+      let sizeH = height / planSize.height
+      rootRef.current.style.left = '100%'
+      rootRef.current.style.transform = `rotate(90deg) scale(${sizeW},${sizeH})`
+      rootRef.current.style.transformOrigin = 'left top'
+    }
+
+    // 横竖屏变化的时候 刷新页面
+
+    // if (window.isHH !== isHHTemp) {
+    //   window.location.reload()
+  }, [])
+
+  useEffect(() => {
+    rootRef.current = document.querySelector('#root')
+    rootRef.current.style.width = planSize.width + 'px'
+    rootRef.current.style.height = planSize.height + 'px'
+
+    pageFullChangeFu()
+    window.addEventListener('resize', pageFullChangeFu, false)
+  }, [pageFullChangeFu])
+
+  return (
+    <>
+      {/* 关于路由 */}
+      <Router history={history}>
+        <React.Suspense fallback={<SpinLoding />}>
+          <Switch>
+            A3shiKe1
+            <Route path='/' component={A1home} exact />
+            <Route path='/main/:num' component={A2main} exact />
+            <Route path='*' component={NotFound} />
+          </Switch>
+        </React.Suspense>
+      </Router>
+
+      {/* 发送请求的加载组件 */}
+      <AsyncSpinLoding />
+
+      <MessageCom />
+    </>
+  )
+}

+ 141 - 0
code/src/assets/styles/base.css

@@ -0,0 +1,141 @@
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+  word-wrap: break-word;
+  -webkit-tap-highlight-color: transparent;
+  font-family: 'SimHei', 'SimSun', 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
+}
+/* 全局css变量 */
+:root {
+  --themeColor: #261003;
+  --themeColor2: #f6e8a5;
+  --baseUrl: '';
+}
+html {
+  height: 100%;
+  user-select: none;
+}
+body {
+  position: relative;
+  font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB', 'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
+  font-size: var(--fontNum);
+  height: 100%;
+  color: #fff;
+  overflow: hidden;
+  background-color: var(--themeColor);
+}
+#root {
+  overflow: hidden;
+  margin: auto;
+  position: relative;
+}
+#root > div {
+  width: 100%;
+  height: 100%;
+}
+i {
+  font-style: normal;
+}
+img {
+  vertical-align: middle;
+}
+ul {
+  list-style: none;
+}
+/* 找不到页面 */
+.noFindPage {
+  opacity: 0;
+  transition: opacity 0.5s;
+  text-align: center;
+}
+.noFindPage .ant-result-title,
+.noFindPage .ant-result-subtitle {
+  color: #fff !important;
+}
+.noFindPage .ant-result {
+  padding: 20px !important;
+}
+.noFindPage .ant-result .ant-result-subtitle {
+  font-size: 20px;
+}
+[hidden] {
+  display: none !important;
+}
+.mySorrl::-webkit-scrollbar {
+  /*滚动条整体样式*/
+  width: 5px;
+  /*高宽分别对应横竖滚动条的尺寸*/
+  height: 1px;
+}
+.mySorrl::-webkit-scrollbar-thumb {
+  /*滚动条里面小方块*/
+  border-radius: 10px;
+  -webkit-box-shadow: inset 0 0 5px transparent;
+  background: var(--themeColor);
+}
+.mySorrl::-webkit-scrollbar-track {
+  /*滚动条里面轨道*/
+  -webkit-box-shadow: inset 0 0 5px transparent;
+  border-radius: 10px;
+  background: transparent;
+}
+.hideSorrl::-webkit-scrollbar {
+  width: 0px;
+  height: 0px;
+  display: none;
+}
+.HotIconBase {
+  animation: yunShan 2s infinite linear;
+}
+@keyframes yunShan {
+  0% {
+    opacity: 1;
+  }
+  50% {
+    opacity: 0.4;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+#opacityCss {
+  animation: opacityCss 0.8s linear forwards;
+}
+@keyframes opacityCss {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+#root .kaiFont {
+  font-family: 'kai';
+}
+@keyframes ringing {
+  10% {
+    transform: rotateZ(2deg);
+  }
+  20% {
+    transform: rotateZ(-2deg);
+  }
+  30% {
+    transform: rotateZ(3deg);
+  }
+  40% {
+    transform: rotateZ(-3deg);
+  }
+  50% {
+    transform: rotateZ(2deg);
+  }
+  60% {
+    transform: rotateZ(-2deg);
+  }
+  70% {
+    transform: rotateZ(0);
+  }
+  100% {
+    transform: rotateZ(0);
+  }
+}

+ 190 - 0
code/src/assets/styles/base.less

@@ -0,0 +1,190 @@
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+  word-wrap: break-word;
+  -webkit-tap-highlight-color: transparent;
+  font-family: 'SimHei', 'SimSun', 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB',
+    'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
+}
+
+
+
+/* 全局css变量 */
+:root {
+  --themeColor: #261003;
+  --themeColor2: #f6e8a5;
+  --baseUrl: ''
+}
+
+html {
+  height: 100%;
+  user-select: none;
+}
+
+body {
+  position: relative;
+  font: 1em/1.4 'Microsoft Yahei', 'PingFang SC', 'Avenir', 'Segoe UI', 'Hiragino Sans GB',
+    'STHeiti', 'Microsoft Sans Serif', 'WenQuanYi Micro Hei', sans-serif;
+  font-size: var(--fontNum);
+  height: 100%;
+  color: #fff;
+  overflow: hidden;
+  background-color: var(--themeColor);
+  // background-color: rgba(0, 0, 0, 0.8);
+}
+
+
+#root {
+  overflow: hidden;
+  margin: auto;
+  position: relative;
+
+  &>div {
+    width: 100%;
+    height: 100%;
+  }
+}
+
+i {
+  font-style: normal;
+}
+
+img {
+  vertical-align: middle;
+}
+
+ul {
+  list-style: none;
+}
+
+/* 找不到页面 */
+.noFindPage {
+
+  opacity: 0;
+  transition: opacity 0.5s;
+  text-align: center;
+
+  .ant-result-title,
+  .ant-result-subtitle {
+    color: #fff !important;
+  }
+
+  .ant-result {
+    padding: 20px !important;
+
+    .ant-result-subtitle {
+      font-size: 20px;
+    }
+  }
+}
+
+[hidden] {
+  display: none !important;
+}
+
+// 滚动条
+.mySorrl::-webkit-scrollbar {
+  /*滚动条整体样式*/
+  width: 5px;
+  /*高宽分别对应横竖滚动条的尺寸*/
+  height: 1px;
+}
+
+.mySorrl::-webkit-scrollbar-thumb {
+  /*滚动条里面小方块*/
+  border-radius: 10px;
+  -webkit-box-shadow: inset 0 0 5px transparent;
+  background: var(--themeColor);
+}
+
+.mySorrl::-webkit-scrollbar-track {
+  /*滚动条里面轨道*/
+  -webkit-box-shadow: inset 0 0 5px transparent;
+  border-radius: 10px;
+  background: transparent;
+}
+
+.hideSorrl {
+  &::-webkit-scrollbar {
+    width: 0px;
+    height: 0px;
+    display: none;
+  }
+}
+
+
+// 热点图标闪动
+.HotIconBase {
+  animation: yunShan 2s infinite linear;
+}
+
+@keyframes yunShan {
+  0% {
+    opacity: 1;
+  }
+
+  50% {
+    opacity: 0.4;
+  }
+
+  100% {
+    opacity: 1;
+  }
+}
+
+
+// 页面透明度渐变
+#opacityCss {
+  animation: opacityCss 0.8s linear forwards;
+}
+
+@keyframes opacityCss {
+  0% {
+    opacity: 0;
+  }
+
+  100% {
+    opacity: 1;
+  }
+}
+
+#root .kaiFont {
+  font-family: 'kai';
+}
+
+
+// 晃动动画
+@keyframes ringing {
+  10% {
+    transform: rotateZ(2deg);
+  }
+
+  20% {
+    transform: rotateZ(-2deg);
+  }
+
+  30% {
+    transform: rotateZ(3deg);
+  }
+
+  40% {
+    transform: rotateZ(-3deg);
+  }
+
+  50% {
+    transform: rotateZ(2deg);
+  }
+
+  60% {
+    transform: rotateZ(-2deg);
+  }
+
+  70% {
+    transform: rotateZ(0);
+  }
+
+  100% {
+    transform: rotateZ(0);
+  }
+}

+ 21 - 0
code/src/components/AsyncSpinLoding/index.module.scss

@@ -0,0 +1,21 @@
+.AsyncSpinLoding {
+  opacity: 0;
+  pointer-events: none;
+  transition: all .5s;
+  position: fixed;
+  z-index: 9998;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  // background-color: rgba(0, 0, 0, .6);
+  background-color: transparent;
+  :global{
+    .ant-spin-spinning{
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%,-50%);
+    }
+  }
+}

+ 15 - 0
code/src/components/AsyncSpinLoding/index.tsx

@@ -0,0 +1,15 @@
+import styles from "./index.module.scss";
+import { Spin } from "antd";
+import React from "react";
+
+function AsyncSpinLoding() {
+  return (
+    <div id="AsyncSpinLoding" className={styles.AsyncSpinLoding}>
+      <Spin size="large" />
+    </div>
+  );
+}
+
+const MemoAsyncSpinLoding = React.memo(AsyncSpinLoding);
+
+export default MemoAsyncSpinLoding;

+ 29 - 0
code/src/components/Message/index.tsx

@@ -0,0 +1,29 @@
+import React, { useEffect } from "react";
+import { message } from "antd";
+import { useSelector } from "react-redux";
+import { RootState } from "@/store";
+
+function MessageCom() {
+  // 从仓库中获取 antd 轻提示信息
+  const messageReducerInfo = useSelector(
+    (state: RootState) => state.A0Layout.message
+  );
+
+  const [messageApi, contextHolder] = message.useMessage();
+
+  useEffect(() => {
+    if (messageReducerInfo.txt) {
+      messageApi.open({
+        type: messageReducerInfo.type,
+        content: messageReducerInfo.txt,
+        duration: messageReducerInfo.duration,
+      });
+    }
+  }, [messageApi, messageReducerInfo]);
+
+  return <>{contextHolder}</>;
+}
+
+const MemoMessage = React.memo(MessageCom);
+
+export default MemoMessage;

+ 24 - 0
code/src/components/NotFound/index.tsx

@@ -0,0 +1,24 @@
+import history from "@/utils/history";
+import { Button, Result } from "antd";
+import { useEffect, useRef } from "react";
+
+export default function NotFound() {
+  const timeRef = useRef(-1);
+
+  useEffect(() => {
+    timeRef.current = window.setTimeout(() => {
+      const dom: HTMLDivElement = document.querySelector(".noFindPage")!;
+      dom.style.opacity = "1";
+    }, 500);
+    return () => {
+      clearTimeout(timeRef.current);
+    };
+  }, []);
+
+  return (
+    <div className="noFindPage">
+      <Result status="404" title="404" subTitle="找不到页面!" />
+      <Button onClick={()=>history.replace('/')}>去首页</Button>
+    </div>
+  );
+}

+ 10 - 0
code/src/components/SpinLoding/index.module.scss

@@ -0,0 +1,10 @@
+.SpinLoding {
+  position: relative;
+  z-index: 9999;
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}

+ 13 - 0
code/src/components/SpinLoding/index.tsx

@@ -0,0 +1,13 @@
+import styles from "./index.module.scss";
+import { Spin } from "antd";
+import React from "react";
+function SpinLoding() {
+  return (
+    <div className={styles.SpinLoding}>
+      <Spin size='large'/>
+    </div>
+  );
+}
+const MemoSpinLoding = React.memo(SpinLoding);
+
+export default MemoSpinLoding;

+ 21 - 0
code/src/components/Ztop/index.module.scss

@@ -0,0 +1,21 @@
+.Ztop {
+  position: fixed;
+  z-index: 99;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 70px;
+
+  :global {
+    .Zbimg {
+      pointer-events: auto;
+      animation: yunShan 2s infinite linear;
+      position: absolute;
+      right: 30px;
+      height: calc(100% - 20px);
+      top: 10px;
+      cursor: pointer;
+      z-index: 10;
+    }
+  }
+}

+ 19 - 0
code/src/components/Ztop/index.tsx

@@ -0,0 +1,19 @@
+import React from 'react'
+import styles from './index.module.scss'
+import { baseUrl } from '@/utils/http'
+
+type Props = {
+  backFu: () => void
+}
+
+function Ztop({ backFu }: Props) {
+  return (
+    <div className={styles.Ztop} style={{ backgroundImage: `url(${baseUrl}main/nav.png)` }}>
+      <img className='Zbimg' src={`${baseUrl}main/back.png`} alt='' onClick={backFu} />
+    </div>
+  )
+}
+
+const MemoZtop = React.memo(Ztop)
+
+export default MemoZtop

+ 35 - 0
code/src/index.tsx

@@ -0,0 +1,35 @@
+// import 'default-passive-events';
+
+import App from './App'
+import store from './store/index'
+
+import { Provider } from 'react-redux'
+import { createRoot } from 'react-dom/client'
+
+import { ConfigProvider } from 'antd'
+
+// 兼容360浏览器
+import { StyleProvider, legacyLogicalPropertiesTransformer } from '@ant-design/cssinjs'
+
+import 'dayjs/locale/zh-cn'
+import locale from 'antd/locale/zh_CN'
+
+const container = document.getElementById('root') as HTMLElement
+const root = createRoot(container)
+
+root.render(
+  <ConfigProvider
+    locale={locale}
+    theme={{
+      token: {
+        colorPrimary: '#261003'
+      }
+    }}
+  >
+    <Provider store={store}>
+      <StyleProvider hashPriority='high' transformers={[legacyLogicalPropertiesTransformer]}>
+        <App />
+      </StyleProvider>
+    </Provider>
+  </ConfigProvider>
+)

+ 118 - 0
code/src/pages/A1home/index.module.scss

@@ -0,0 +1,118 @@
+.A1home {
+  background-size: 100% 100%;
+  position: relative;
+
+  img {
+    pointer-events: none;
+  }
+
+  :global {
+    .A1logo {
+      width: 226px;
+      height: auto;
+      position: absolute;
+      top: 40px;
+      left: 40px;
+    }
+
+    .A1tit {
+      position: absolute;
+      top: 80px;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 600px;
+      height: auto;
+    }
+
+    .A1shi {
+      position: absolute;
+      bottom: 20px;
+      left: 50%;
+      transform: translateX(-50%);
+      width: 740px;
+      height: auto;
+    }
+
+    .A1right {
+      position: absolute;
+      right: 40px;
+      top: 40px;
+      font-size: 16px;
+      text-align: right;
+    }
+
+    .A1di {
+      position: absolute;
+      z-index: 2;
+      bottom: 0;
+      left: 0;
+      width: 100%;
+      height: 62px;
+      background-size: 100% 100%;
+      display: flex;
+      justify-content: space-around;
+      padding: 0 300px;
+
+      .A1row {
+        width: 370px;
+        height: 85px;
+        display: flex;
+        justify-content: center;
+
+        .A1rowSon {
+          animation: yunShan 2s infinite linear;
+          cursor: pointer;
+          position: relative;
+          top: -28px;
+          background-color: var(--baseUrl);
+          width: 240px;
+          height: 56px;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          font-size: 22px;
+
+          &>img {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            z-index: -1;
+          }
+
+          .A1rImg2 {
+            opacity: 0;
+            width: 110%;
+            height: 110%;
+          }
+        }
+
+        &:hover {
+          .A1rowSon {
+            animation: none;
+            top: -62px;
+            padding-top: 40px;
+            width: 100%;
+            height: 100%;
+            color: #3E2210;
+            font-weight: 700;
+            font-size: 24px;
+            padding-left: 30px;
+            left: -5%;
+
+            .A1rImg1 {
+              opacity: 0;
+            }
+
+            .A1rImg2 {
+              opacity: 1;
+            }
+          }
+        }
+      }
+    }
+
+
+  }
+}

+ 37 - 0
code/src/pages/A1home/index.tsx

@@ -0,0 +1,37 @@
+import React from 'react'
+import styles from './index.module.scss'
+import { baseUrl, myData } from '@/utils/http'
+import history from '@/utils/history'
+function A1home() {
+  return (
+    <div className={styles.A1home} style={{ backgroundImage: `url(${baseUrl}home/bg.jpg)` }}>
+      <img className='A1logo' src={`${baseUrl}home/logo.png`} alt='' />
+      <img className='A1tit' src={`${baseUrl}home/title.png`} alt='' />
+      <img className='A1shi' src={`${baseUrl}home/bs.png`} alt='' />
+      <div className='A1right'>
+        主办单位
+        <br />
+        扬州中国大运河博物馆
+      </div>
+      <div className='A1di' style={{ backgroundImage: `url(${baseUrl}home/diBac.png)` }}>
+        {myData.home.map((item, index) => (
+          <div
+            key={item.name}
+            className={`A1row`}
+            onClick={() => history.replace(`/main/${item.sorrlNum}`)}
+          >
+            <div className='A1rowSon'>
+              <img className='A1rImg1' src={`${baseUrl}home/kuang.png`} alt='' />
+              <img className='A1rImg2' src={`${baseUrl}home/hover.png`} alt='' />
+              {item.name}
+            </div>
+          </div>
+        ))}
+      </div>
+    </div>
+  )
+}
+
+const MemoA1home = React.memo(A1home)
+
+export default MemoA1home

+ 272 - 0
code/src/pages/A2main/index.module.scss

@@ -0,0 +1,272 @@
+.A2main {
+  overflow: auto;
+  scroll-behavior: smooth;
+
+  img {
+    pointer-events: none;
+  }
+
+  :global {
+    .A2box {
+      width: 100%;
+      height: 14357px;
+      background-size: 100% 100%;
+      position: relative;
+
+      // -----------守望千年---------------------
+
+      .A2s1 {
+        padding: 118px 90px 0 60px;
+        display: flex;
+        justify-content: space-between;
+
+        &>img {
+          width: 400px;
+          height: auto;
+        }
+
+        &>div {
+          font-size: 24px;
+          padding-top: 10px;
+
+          &>p {
+            &:nth-of-type(2) {
+              font-size: 20px;
+            }
+          }
+        }
+      }
+
+      .A2s12 {
+        position: relative;
+        top: -80px;
+        margin: 0 auto;
+        background-size: 100% 100%;
+        width: 1500px;
+        height: 1900px;
+        text-align: center;
+        padding-top: 190px;
+
+        .A2s12_1 {
+          display: inline-block;
+          width: 350px;
+          height: auto;
+        }
+
+        .A2s12_2 {
+          text-align: left;
+          width: 915px;
+          margin: 80px auto 90px;
+
+          &>p {
+            font-size: 24px;
+            font-family: 'kai';
+            margin-bottom: 40px;
+          }
+        }
+
+        .A2s12_3 {
+          width: 894px;
+          height: auto;
+          display: inline-block;
+        }
+      }
+
+
+      // -----------六朝兴替 石刻为证---------------------
+
+      .A2l1 {
+        padding-top: 200px;
+        text-align: center;
+
+        .A2l1_1 {
+          position: relative;
+          left: 40px;
+          display: inline-block;
+          width: 343px;
+          height: auto;
+          margin-bottom: 295px;
+        }
+      }
+
+      .A2l2 {
+        width: 1533px;
+        height: 204px;
+        background-size: 100% 100%;
+        margin: 0px auto -30px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        padding: 0 140px;
+
+        &>p {
+          font-size: 24px;
+          line-height: 36px;
+        }
+      }
+
+      .A2l3 {
+        width: 100%;
+        height: 853px;
+        background-size: 100% 100%;
+        display: flex;
+        justify-content: space-between;
+        padding: 145px 240px 108px 240px;
+
+        .A2l3_1 {
+          width: 367px;
+          display: flex;
+          flex-direction: column;
+          justify-content: space-around;
+
+          &>div {
+            width: 100%;
+            height: 89px;
+            position: relative;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            font-size: 36px;
+            cursor: pointer;
+            animation: yunShan 2s infinite linear;
+
+            &>p {
+              position: relative;
+              z-index: 2;
+              color: black;
+            }
+
+            &>img {
+              position: absolute;
+              top: 0;
+              left: 0;
+              width: 100%;
+              height: 100%;
+            }
+
+            .A2l3_1_2 {
+              opacity: 0;
+            }
+          }
+
+          .A2l3_1Ac {
+            animation: none;
+            pointer-events: none;
+
+            .A2l3_1_1 {
+              opacity: 0;
+            }
+
+            .A2l3_1_2 {
+              opacity: 1;
+            }
+
+            &>p {
+              color: #fff;
+            }
+
+          }
+        }
+
+        .A2l3_2 {
+          width: 1035px;
+          height: 600px;
+          border: 2px solid var(--themeColor2);
+          display: flex;
+          justify-content: space-around;
+
+          .A2l3_2_1 {
+            animation: yunShan 2s infinite linear;
+            transform-origin: 50% 0%;
+            cursor: pointer;
+            width: 125px;
+            height: 631px;
+            position: relative;
+            top: -70px;
+            background-size: 100% 100%;
+            writing-mode: vertical-lr;
+            font-size: 34px;
+            color: black;
+            letter-spacing: 2px;
+            display: flex;
+            align-items: center;
+            padding-top: 260px;
+
+            &:hover {
+              animation: ringing 5s linear forwards;
+
+            }
+          }
+        }
+      }
+
+      // ---------------雕凿天工 翼兽传奇
+      .A2d1 {
+        margin-top: 40px;
+        width: 100%;
+        height: 364px;
+        background-size: 100% 100%;
+        position: relative;
+
+        .A2d1row {
+          cursor: pointer;
+          position: absolute;
+          top: 273px;
+          left: 278px;
+          width: 411px;
+          height: 339px;
+          background-size: 100% 100%;
+
+
+          &>img {
+            transform-origin: 50% 0%;
+            animation: yunShan 2s infinite linear;
+            pointer-events: auto;
+            position: absolute;
+            top: -200px;
+            right: 50px;
+            width: 50px;
+            height: 356px;
+          }
+
+          &:hover {
+            &>img {
+              animation: ringing 5s linear forwards;
+
+            }
+          }
+        }
+
+        .A2d1row2 {
+          top: 358px;
+          left: 757px;
+
+          &>img {
+            top: -315px;
+            height: 470px;
+            right: 67px;
+          }
+        }
+
+        .A2d1row3 {
+          top: 248px;
+          left: auto;
+          right: 304px;
+
+          &>img {
+            top: -117px;
+          }
+        }
+      }
+
+      .A2d2 {
+        margin: 390px auto 106px;
+        width: 1200px;
+        font-size: 24px;
+        line-height: 36px;
+      }
+
+
+    }
+  }
+}

+ 154 - 0
code/src/pages/A2main/index.tsx

@@ -0,0 +1,154 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import classNames from 'classnames'
+import { baseUrl, myData } from '@/utils/http'
+import { useParams } from 'react-router-dom'
+import A3liuChao1 from '../A3liuChao1'
+import A3liuChao2 from '../A3liuChao2'
+import A4diao from '../A4diao'
+
+function A2main() {
+  // 从首页进来才需要平滑滚动
+
+  const { num } = useParams<{ num: string }>()
+
+  const sorrlRef = useRef<HTMLDivElement>(null)
+
+  // useEffect(() => {
+  //   if (sorrlRef.current) {
+  //     sorrlRef.current.addEventListener('scroll', e => {
+  //       console.log(sorrlRef.current?.scrollTop)
+  //     })
+  //   }
+  // }, [])
+
+  // 进页面滚动到指定位置
+  useEffect(() => {
+    if (num && sorrlRef.current) {
+      sorrlRef.current.scrollTop = Number(num)
+    }
+  }, [num])
+
+  //  ---------------------六朝兴替 石刻为证
+  const [liuAc, setLiuAc] = useState('六朝兴替')
+
+  const liuArr = useMemo(() => {
+    return myData.main.liuChao.arr.find(v => v.name === liuAc)!.son
+  }, [liuAc])
+
+  const [liuPage, setLiuPage] = useState({ key: '', id: 0 })
+
+  const liuClickFu = useCallback(
+    (id: number) => {
+      if (sorrlRef.current) {
+        setLiuPage({ key: liuAc === '六朝兴替' ? '1' : '2', id })
+      }
+    },
+    [liuAc]
+  )
+
+  // ------雕凿天工--------
+  const [diaoId, setDiaoId] = useState(0)
+
+  return (
+    <div className={classNames(styles.A2main, 'hideSorrl')} ref={sorrlRef}>
+      <div className='A2box' style={{ backgroundImage: `url(${baseUrl}main/bg.jpg)` }}>
+        {/* ------------守望千年--------------- */}
+        <div className='A2s1'>
+          <img src={`${baseUrl}main/s_1.png`} alt='' />
+          <div>
+            <p className='kaiFont'>主办单位</p>
+            <p className='kaiFont'>扬州中国大运河博物馆</p>
+          </div>
+        </div>
+
+        <div className='A2s12' style={{ backgroundImage: `url(${baseUrl}main/s_3.png)` }}>
+          <img className='A2s12_1' src={`${baseUrl}main/s_2.png`} alt='' />
+
+          <div className='A2s12_2' dangerouslySetInnerHTML={{ __html: myData.main.shouWang }}></div>
+
+          <img className='A2s12_3' src={`${baseUrl}main/s_4.png`} alt='' />
+        </div>
+
+        {/* ---------------------六朝兴替 石刻为证 */}
+        <div className='A2l1'>
+          <img className='A2l1_1' src={`${baseUrl}main/l1.png`} alt='' />
+        </div>
+
+        <div className='A2l2' style={{ backgroundImage: `url(${baseUrl}main/l2.png)` }}>
+          <p className='kaiFont' dangerouslySetInnerHTML={{ __html: myData.main.liuChao.tit }}></p>
+        </div>
+
+        <div className='A2l3' style={{ backgroundImage: `url(${baseUrl}main/l3.png)` }}>
+          <div className='A2l3_1'>
+            {myData.main.liuChao.arr.map(v => (
+              <div
+                key={v.name}
+                className={classNames(liuAc === v.name ? 'A2l3_1Ac' : '')}
+                onClick={() => setLiuAc(v.name)}
+              >
+                <img className='A2l3_1_1' src={`${baseUrl}main/l4.png`} alt='' />
+                <img className='A2l3_1_2' src={`${baseUrl}main/l4Ac.png`} alt='' />
+                <p className='kaiFont'>{v.name}</p>
+              </div>
+            ))}
+          </div>
+          <div className='A2l3_2'>
+            {liuArr.map(item => (
+              <div
+                onClick={() => liuClickFu(item.id)}
+                className='A2l3_2_1 kaiFont'
+                style={{ backgroundImage: `url(${baseUrl}main/l5.png)` }}
+                key={item.id}
+                dangerouslySetInnerHTML={{ __html: item.name }}
+              ></div>
+            ))}
+          </div>
+        </div>
+
+        {/* ---------------------雕凿天工 翼兽传奇 */}
+        <div className='A2l1'>
+          <img className='A2l1_1' src={`${baseUrl}main/d1.png`} alt='' />
+        </div>
+
+        <div className='A2l2' style={{ backgroundImage: `url(${baseUrl}main/l2.png)` }}>
+          <p className='kaiFont' dangerouslySetInnerHTML={{ __html: myData.main.chuangQi.tit }}></p>
+        </div>
+
+        <div className='A2d1' style={{ backgroundImage: `url(${baseUrl}main/d2.png)` }}>
+          {myData.main.chuangQi.diaoArr.map((item, index) => (
+            <div
+              onClick={() => setDiaoId(item.id)}
+              key={item.id}
+              className={classNames('A2d1row', index > 0 ? `A2d1row${index + 1}` : '')}
+              style={{ backgroundImage: `url(${baseUrl}main/da${index + 1}.png)` }}
+            >
+              <img src={`${baseUrl}main/da${index + 1}x.png`} alt='' />
+            </div>
+          ))}
+        </div>
+
+        <div
+          className='A2d2 kaiFont'
+          dangerouslySetInnerHTML={{ __html: myData.main.chuangQi.tit2 }}
+        ></div>
+
+        {/* end */}
+      </div>
+
+      {/* ---------------------六朝兴替 石刻为证详情页 */}
+      {liuPage.key === '1' ? (
+        <A3liuChao1 id={liuPage.id} closeFu={() => setLiuPage({ key: '', id: 0 })} />
+      ) : liuPage.key === '2' ? (
+        <A3liuChao2 id={liuPage.id} closeFu={() => setLiuPage({ key: '', id: 0 })} />
+      ) : null}
+
+      {/* ---------------------雕凿天工 详情页 */}
+      {diaoId ? <A4diao id={diaoId} closeFu={() => setDiaoId(0)} /> : null}
+    </div>
+  )
+}
+
+const MemoA2main = React.memo(A2main)
+
+export default MemoA2main

+ 48 - 0
code/src/pages/A3liuChao1/index.module.scss

@@ -0,0 +1,48 @@
+.A3liuChao1 {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+  overflow: auto;
+
+  :global {
+    .A3box {
+      width: 100%;
+      height: 2120px;
+      background-size: 100% 100%;
+      padding-top: 112px;
+
+      .A3tit {
+        display: block;
+        width: 242px;
+        height: 526px;
+        margin: 0 auto 190px;
+      }
+
+      .A3txt {
+        width: 1533px;
+        height: 204px;
+        background-size: 100% 100%;
+        margin: 0px auto;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        padding: 0 140px;
+
+        &>p {
+          font-size: 24px;
+          line-height: 36px;
+        }
+      }
+
+      .A3Zhou {
+        width: 1851px;
+        height: 931px;
+        display: block;
+        margin: 90px auto 0;
+      }
+    }
+  }
+}

+ 32 - 0
code/src/pages/A3liuChao1/index.tsx

@@ -0,0 +1,32 @@
+import React from 'react'
+import styles from './index.module.scss'
+import { baseUrl, myData } from '@/utils/http'
+import Ztop from '@/components/Ztop'
+import classNames from 'classnames'
+
+type Props = {
+  closeFu: () => void
+  id: number
+}
+
+function A3liuChao1({ closeFu, id }: Props) {
+  return (
+    <div id='opacityCss' className={classNames(styles.A3liuChao1, 'hideSorrl')}>
+      <Ztop backFu={closeFu} />
+
+      <div className='A3box' style={{ backgroundImage: `url(${baseUrl}main/liuchao/bg.jpg)` }}>
+        <img className='A3tit' src={`${baseUrl}main/liuchao/tit.png`} alt='' />
+
+        <div className='A3txt' style={{ backgroundImage: `url(${baseUrl}main/l2.png)` }}>
+          <p className='kaiFont' dangerouslySetInnerHTML={{ __html: myData.main.liuChao.tit }}></p>
+        </div>
+
+        <img className='A3Zhou' src={`${baseUrl}main/liuchao/${id}.png`} alt='' />
+      </div>
+    </div>
+  )
+}
+
+const MemoA3liuChao1 = React.memo(A3liuChao1)
+
+export default MemoA3liuChao1

+ 133 - 0
code/src/pages/A3liuChao2/index.module.scss

@@ -0,0 +1,133 @@
+.A3liuChao2 {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+  overflow: auto;
+
+  :global {
+    .A3box2 {
+      width: 100%;
+      height: 2120px;
+      background-size: 100% 100%;
+      padding-top: 112px;
+      padding-top: 270px;
+
+      .A3tit2 {
+        display: flex;
+        justify-content: center;
+
+        &>img {
+          width: 170px;
+          height: 465px;
+        }
+
+        &>div {
+          display: flex;
+          align-items: center;
+          margin-left: 42px;
+          width: 677px;
+          font-size: 24px;
+          line-height: 36px;
+          letter-spacing: 4px;
+        }
+      }
+
+      .A3zhou2 {
+        position: relative;
+        background-size: 100% 100%;
+        margin: 434px 0 122px 185px;
+        width: 1229px;
+        height: 671px;
+        padding-top: 167px;
+
+        .A3Ztop {
+          width: 215px;
+          height: auto;
+          position: absolute;
+          top: -114px;
+          left: 106px;
+        }
+
+        .A3Ztxt {
+          width: 650px;
+          height: 460px;
+          margin-left: 215px;
+          overflow-y: auto;
+
+          &>P {
+            color: #170C07;
+            font-size: 24px;
+            line-height: 36px;
+            margin-bottom: 30px;
+            letter-spacing: 2px;
+            font-family: 'kai';
+          }
+
+        }
+
+        .A3Zimg {
+          position: absolute;
+          top: -46px;
+          right: -330px;
+          width: 616px;
+          height: 800px;
+
+          &>img {
+            width: 100%;
+            height: 710px;
+            display: block;
+            margin-bottom: 26px;
+          }
+
+          .A3ZimgBtn {
+            padding: 0 60px;
+            height: 64px;
+            display: flex;
+            align-items: center;
+
+            &>img {
+              pointer-events: auto;
+              cursor: pointer;
+              width: 64px;
+              height: 64px;
+              animation: yunShan 2s infinite linear;
+            }
+
+            .A3ZimgBtnNo {
+              pointer-events: none;
+              animation: none;
+              opacity: 0.5;
+            }
+
+            &>p {
+              font-size: 24px;
+              width: calc(100% - 128px);
+              padding: 0 5px;
+              text-align: center;
+            }
+          }
+
+          .A3ZimgBtn2 {
+            &>img {
+              opacity: 0 !important;
+            }
+          }
+        }
+
+      }
+
+      .A3ZdiTxt {
+        margin-top: 140px;
+        font-size: 24px;
+        line-height: 36px;
+        width: 1423px;
+        margin: 0 auto;
+        letter-spacing: 1px;
+      }
+
+    }
+  }
+}

+ 82 - 0
code/src/pages/A3liuChao2/index.tsx

@@ -0,0 +1,82 @@
+import React, { useMemo, useState } from 'react'
+import styles from './index.module.scss'
+import { baseUrl, myData } from '@/utils/http'
+import Ztop from '@/components/Ztop'
+import classNames from 'classnames'
+
+type Props = {
+  closeFu: () => void
+  id: number
+}
+
+function A3liuChao2({ closeFu, id }: Props) {
+  const txtRes = useMemo(() => {
+    const obj = myData.main.liuChao.arr[1]
+    return {
+      txt1: obj.txt1,
+      txt2: obj.txt2
+    }
+  }, [])
+
+  const info = useMemo(() => {
+    const sonArr = myData.main.liuChao.arr[1].son
+    return sonArr.find(v => v.id === id)!
+  }, [id])
+
+  const [ind, setInd] = useState(0)
+
+  const imgArr = useMemo(() => {
+    return info.imgArr
+  }, [info.imgArr])
+
+  return (
+    <div id='opacityCss' className={classNames(styles.A3liuChao2, 'hideSorrl')}>
+      <Ztop backFu={closeFu} />
+
+      <div className='A3box2' style={{ backgroundImage: `url(${baseUrl}main/liuchao/bg2.jpg)` }}>
+        <div className='A3tit2'>
+          <img src={`${baseUrl}main/liuchao/tit2.png`} alt='' />
+          <div className='kaiFont' dangerouslySetInnerHTML={{ __html: txtRes.txt1! }}></div>
+        </div>
+
+        <div
+          className='A3zhou2'
+          style={{ backgroundImage: `url(${baseUrl}main/liuchao/zhou2.png)` }}
+        >
+          <img className='A3Ztop' src={`${baseUrl}main/liuchao/${id}.png`} alt='' />
+
+          <div className='A3Ztxt hideSorrl' dangerouslySetInnerHTML={{ __html: info.text }}></div>
+
+          <div className='A3Zimg'>
+            {imgArr[ind].url ? (
+              <>
+                <img src={baseUrl + imgArr[ind].url} alt='' />
+                <div className={classNames('A3ZimgBtn', imgArr.length <= 1 ? 'A3ZimgBtn2' : '')}>
+                  <img
+                    onClick={() => setInd(ind - 1)}
+                    className={classNames(ind <= 0 ? 'A3ZimgBtnNo' : '')}
+                    src={`${baseUrl}main/liuchao/left.png`}
+                    alt=''
+                  />
+                  <p className='kaiFont'>{imgArr[ind].name}</p>
+                  <img
+                    onClick={() => setInd(ind + 1)}
+                    className={classNames(ind >= imgArr.length - 1 ? 'A3ZimgBtnNo' : '')}
+                    src={`${baseUrl}main/liuchao/right.png`}
+                    alt=''
+                  />
+                </div>
+              </>
+            ) : null}
+          </div>
+        </div>
+
+        <div className='A3ZdiTxt kaiFont' dangerouslySetInnerHTML={{ __html: txtRes.txt2! }}></div>
+      </div>
+    </div>
+  )
+}
+
+const MemoA3liuChao2 = React.memo(A3liuChao2)
+
+export default MemoA3liuChao2

+ 108 - 0
code/src/pages/A4diao/index.module.scss

@@ -0,0 +1,108 @@
+.A4diao {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+  background-size: 100% 100%;
+
+  :global {
+    .A4left {
+      position: absolute;
+      top: 327px;
+      left: 131px;
+      width: 612px;
+
+      &>img {
+        display: block;
+        margin: 0 auto 46px;
+        height: 80px;
+        width: auto;
+      }
+
+      &>div {
+        font-family: 'kai';
+        font-size: 24px;
+        line-height: 36px;
+      }
+    }
+
+    .A4right {
+      position: absolute;
+      top: 200px;
+      right: 234px;
+      width: 800px;
+      height: 545px;
+
+      .A4row {
+        width: 100%;
+        height: 100%;
+        position: absolute;
+        top: 0;
+        left: 0;
+        opacity: 0;
+        z-index: 1;
+        transition: all 0.5s;
+        transform: rotate(-8deg);
+        pointer-events: none;
+
+        &>img {
+          width: 100%;
+          height: 100%;
+        }
+
+        &>p {
+          margin-top: 40px;
+          color: #F1DDCA;
+          font-size: 24px;
+          text-align: center;
+          display: none;
+          // padding-left: 150px;
+        }
+      }
+
+      .A4rowNext {
+        z-index: 2;
+        opacity: 0.8;
+      }
+
+      .A4rowAc {
+        opacity: 1;
+        z-index: 3;
+        transform: rotate(0deg);
+
+        &>p {
+          display: block;
+        }
+      }
+
+      .A4btn {
+        position: absolute;
+        top: 50%;
+        left: -90px;
+        pointer-events: auto;
+        transform: translateY(-50%);
+        width: 38px;
+        height: 67px;
+        cursor: pointer;
+        animation: yunShan 2s infinite linear;
+      }
+
+      .A4btnNo {
+        pointer-events: none;
+        animation: none;
+        opacity: 0.2;
+      }
+
+      .A4btnHide {
+        opacity: 0 !important;
+      }
+
+      .A4btn2 {
+        left: auto;
+        right: -90px;
+      }
+    }
+  }
+}

+ 75 - 0
code/src/pages/A4diao/index.tsx

@@ -0,0 +1,75 @@
+import React, { useMemo, useState } from 'react'
+import styles from './index.module.scss'
+import Ztop from '@/components/Ztop'
+import { baseUrl, myData } from '@/utils/http'
+import classNames from 'classnames'
+
+type Props = {
+  closeFu: () => void
+  id: number
+}
+
+function A4diao({ closeFu, id }: Props) {
+  const info = useMemo(() => {
+    return myData.main.chuangQi.diaoArr.find(v => v.id === id)!
+  }, [id])
+
+  const [ind, setInd] = useState(0)
+
+  return (
+    <div
+      id='opacityCss'
+      className={styles.A4diao}
+      style={{ backgroundImage: `url(${baseUrl}main/diao/bg.jpg)` }}
+    >
+      <Ztop backFu={closeFu} />
+
+      <div className='A4left'>
+        <img src={`${baseUrl}main/diao/${id}.png`} alt='' />
+        <div dangerouslySetInnerHTML={{ __html: info.txt }}></div>
+      </div>
+
+      <div className='A4right'>
+        {info.imgArr.map((item, index) => (
+          <div
+            className={classNames(
+              'A4row',
+              ind === index - 1 ? 'A4rowNext' : '',
+              ind === index ? 'A4rowAc' : ''
+            )}
+            key={item.url}
+          >
+            <img src={baseUrl + item.url} alt='' />
+            <p className='kaiFont'>{item.name}</p>
+          </div>
+        ))}
+
+        {/* 左右按钮 */}
+        <img
+          onClick={() => setInd(ind - 1)}
+          className={classNames(
+            'A4btn',
+            ind <= 0 ? 'A4btnNo' : '',
+            info.imgArr.length <= 1 ? 'A4btnHide' : ''
+          )}
+          src={`${baseUrl}main/diao/left.png`}
+          alt=''
+        />
+        <img
+          className={classNames(
+            'A4btn A4btn2',
+            ind >= info.imgArr.length - 1 ? 'A4btnNo' : '',
+            info.imgArr.length <= 1 ? 'A4btnHide' : ''
+          )}
+          onClick={() => setInd(ind + 1)}
+          src={`${baseUrl}main/diao/right.png`}
+          alt=''
+        />
+      </div>
+    </div>
+  )
+}
+
+const MemoA4diao = React.memo(A4diao)
+
+export default MemoA4diao

+ 4 - 0
code/src/pages/初始化组件/index.module.scss

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

+ 14 - 0
code/src/pages/初始化组件/index.tsx

@@ -0,0 +1,14 @@
+import React from "react";
+import styles from "./index.module.scss";
+ function AAAAA() {
+  
+  return (
+    <div className={styles.AAAAA}>
+      <h1>AAAAA</h1>
+    </div>
+  )
+}
+
+const MemoAAAAA = React.memo(AAAAA);
+
+export default MemoAAAAA;

+ 20 - 0
code/src/store/index.ts

@@ -0,0 +1,20 @@
+// 导入 redux
+import { applyMiddleware, legacy_createStore as createStore } from 'redux'
+// 导入自己封装的  rootReducer 
+import rootReducer from './reducer'
+// 导入调试工具和 异步的 redux(用来发送异步请求)
+// 调试工具需要下载谷歌 扩展程序 我用的是 Redux DevTools 3.0.17
+import { composeWithDevTools } from 'redux-devtools-extension'
+import thunk from 'redux-thunk'
+
+// 创建仓库实例
+const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))
+
+// 声明 RootState,在使用仓库的时候用来使用
+export type RootState = ReturnType<typeof store.getState>
+
+// 声明 AppDispatch,在异步请求的时候来使用
+export type AppDispatch = typeof store.dispatch
+
+// 导出仓库实例
+export default store

+ 13 - 0
code/src/store/reducer/index.ts

@@ -0,0 +1,13 @@
+// 导入合并reducer的依赖
+import { combineReducers } from 'redux'
+
+// 导入 登录 模块的 reducer
+import A0Layout from './layout'
+
+// 合并 reducer
+const rootReducer = combineReducers({
+  A0Layout,
+})
+
+// 默认导出
+export default rootReducer

+ 42 - 0
code/src/store/reducer/layout.ts

@@ -0,0 +1,42 @@
+import { MessageType } from '@/utils/message'
+
+// 初始化状态
+const initState = {
+  style: {},
+  // antd轻提示(兼容360浏览器)
+  message: {
+    txt: '',
+    type: 'info',
+    duration: 3
+  } as MessageType
+}
+
+// 定义 action 类型
+type LayoutActionType =
+  | { type: 'layout/style'; payload: any }
+  | { type: 'layout/message'; payload: MessageType }
+  | {
+      type: 'layout/closeUpFile'
+      payload: {
+        fu: () => void
+        state: boolean
+      }
+    }
+
+// 频道 reducer
+export default function layoutReducer(state = initState, action: LayoutActionType) {
+  switch (action.type) {
+    case 'layout/style':
+      return { ...state, style: action.payload }
+
+    // antd轻提示(兼容360浏览器)
+    case 'layout/message':
+      return { ...state, message: action.payload }
+    // 上传文件点击取消
+    case 'layout/closeUpFile':
+      return { ...state, closeUpFile: action.payload }
+
+    default:
+      return state
+  }
+}

+ 38 - 0
code/src/types/api/layot.d.ts

@@ -0,0 +1,38 @@
+type ImgArrType = {
+  name: string
+  url: string
+}[]
+
+export type MyDataType = {
+  home: {
+    name: string
+    sorrlNum: number
+  }[]
+  main: {
+    shouWang: string
+    liuChao: {
+      tit: string
+      arr: {
+        name: string
+        txt1?: string
+        txt2?: string
+        son: {
+          id: number
+          name: string
+          text: string
+          imgArr: ImgArrType
+        }[]
+      }[]
+    }
+    chuangQi: {
+      tit: string
+      tit2: string
+      diaoArr: {
+        id: number
+        name: string
+        txt: string
+        imgArr: ImgArrType
+      }[]
+    }
+  }
+}

+ 11 - 0
code/src/types/declaration.d.ts

@@ -0,0 +1,11 @@
+declare module 'history'
+declare module '*.scss'
+declare module '*.png'
+declare module '*.jpg'
+declare module '*.gif'
+declare module '*.svg'
+
+// public/myData.js 里面的一些数据的类型
+declare const baseUrl1: string
+declare const baseUrl2: string
+declare const myDataTemp

+ 1 - 0
code/src/types/index.d.ts

@@ -0,0 +1 @@
+export * from './api/layot'

+ 13 - 0
code/src/utils/domShow.ts

@@ -0,0 +1,13 @@
+// 加载和上传的盒子的显示隐藏
+export const domShowFu = (ele: string, val: boolean) => {
+  const dom: HTMLDivElement = document.querySelector(ele)!
+  if (dom) {
+    if (val) {
+      dom.style.opacity = '1'
+      dom.style.pointerEvents = 'auto'
+    } else {
+      dom.style.opacity = '0'
+      dom.style.pointerEvents = 'none'
+    }
+  }
+}

+ 30 - 0
code/src/utils/history.ts

@@ -0,0 +1,30 @@
+import { createHashHistory } from 'history'
+const history = createHashHistory()
+export default history
+
+// 判断是手机端还是pc端
+export const isMobiileFu = () => {
+  if (
+    window.navigator.userAgent.match(
+      /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
+    )
+  ) {
+    return true
+  } else return false
+}
+
+// 监听路由
+let routerLength = 0
+history.listen((_: any, listener: any) => {
+  if (listener === 'PUSH') {
+    routerLength += 1
+  } else if (listener === 'POP') {
+    if (routerLength >= 1) routerLength -= 1
+  }
+})
+
+// 点击返回
+export const backPageFu = (path: string) => {
+  if (routerLength) history.go(-1)
+  else window.location.replace(path)
+}

+ 7 - 0
code/src/utils/http.ts

@@ -0,0 +1,7 @@
+import { MyDataType } from '@/types'
+
+export const envFlag = process.env.NODE_ENV === 'development'
+
+export const baseUrl = envFlag ? baseUrl1 : baseUrl2
+
+export const myData: MyDataType = myDataTemp

+ 50 - 0
code/src/utils/message.ts

@@ -0,0 +1,50 @@
+import store from "@/store";
+
+export type MessageType = {
+  txt: string;
+  type: "info" | "success" | "error" | "warning";
+  duration: number;
+};
+
+export const MessageFu = {
+  info: (txt: string, duration?: number) => {
+    store.dispatch({
+      type: "layout/message",
+      payload: {
+        txt,
+        type: "info",
+        duration: duration === undefined ? 3 : duration,
+      },
+    });
+  },
+  success: (txt: string, duration?: number) => {
+    store.dispatch({
+      type: "layout/message",
+      payload: {
+        txt,
+        type: "success",
+        duration: duration === undefined ? 3 : duration,
+      },
+    });
+  },
+  error: (txt: string, duration?: number) => {
+    store.dispatch({
+      type: "layout/message",
+      payload: {
+        txt,
+        type: "error",
+        duration: duration === undefined ? 3 : duration,
+      },
+    });
+  },
+  warning: (txt: string, duration?: number) => {
+    store.dispatch({
+      type: "layout/message",
+      payload: {
+        txt,
+        type: "warning",
+        duration: duration === undefined ? 3 : duration,
+      },
+    });
+  },
+};

+ 18 - 0
code/src/utils/storage.ts

@@ -0,0 +1,18 @@
+import store from '@/store'
+
+// ----------------------中英文本地存储
+const LANGUE_KEY = 'CZB_WEB_LANGUE'
+
+/**
+ * 从本地缓存中获取语言
+ */
+export const locGetLangue = (): 'ZH' | 'EN' => {
+  return (localStorage.getItem(LANGUE_KEY) || 'ZH') as 'ZH' | 'EN'
+}
+
+/**
+ * 存语言
+ */
+export const locSetLangue = (val: 'ZH' | 'EN') => {
+  localStorage.setItem(LANGUE_KEY, val)
+}

+ 27 - 0
code/tsconfig.json

@@ -0,0 +1,27 @@
+{
+  "extends": "./path.tsconfig.json",
+  "compilerOptions": {
+    "target": "es2015",  
+    "lib": [
+      "dom",
+      "dom.iterable",
+      "esnext"
+    ],
+    "allowJs": true,
+    "skipLibCheck": true,
+    "esModuleInterop": true,
+    "allowSyntheticDefaultImports": true,
+    "strict": true,
+    "forceConsistentCasingInFileNames": true,
+    "noFallthroughCasesInSwitch": true,
+    "module": "esnext",
+    "moduleResolution": "node",
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "noEmit": true,
+    "jsx": "react-jsx"
+  },
+  "include": [
+    "src"
+  ]
+}

Різницю між файлами не показано, бо вона завелика
+ 10271 - 0
code/yarn.lock


BIN
静态资源/staticData/home/bg.jpg


BIN
静态资源/staticData/home/bs.png


BIN
静态资源/staticData/home/diBac.png


BIN
静态资源/staticData/home/hover.png


BIN
静态资源/staticData/home/kuang.png


BIN
静态资源/staticData/home/logo.png


BIN
静态资源/staticData/home/title.png


BIN
静态资源/staticData/main/back.png


BIN
静态资源/staticData/main/bg.jpg


BIN
静态资源/staticData/main/d1.png


BIN
静态资源/staticData/main/d2.png


BIN
静态资源/staticData/main/da1.png


BIN
静态资源/staticData/main/da1x.png


BIN
静态资源/staticData/main/da2.png


BIN
静态资源/staticData/main/da2x.png


BIN
静态资源/staticData/main/da3.png


BIN
静态资源/staticData/main/da3x.png


BIN
静态资源/staticData/main/diao/1.png


BIN
静态资源/staticData/main/diao/1_0.jpg


BIN
静态资源/staticData/main/diao/1_1.jpg


BIN
静态资源/staticData/main/diao/2.png


BIN
静态资源/staticData/main/diao/2_1.jpg


BIN
静态资源/staticData/main/diao/3.png


BIN
静态资源/staticData/main/diao/3_0.jpg


BIN
静态资源/staticData/main/diao/bg.jpg


BIN
静态资源/staticData/main/diao/left.png


BIN
静态资源/staticData/main/diao/right.png


BIN
静态资源/staticData/main/l1.png


BIN
静态资源/staticData/main/l2.png


BIN
静态资源/staticData/main/l3.png


BIN
静态资源/staticData/main/l4.png


BIN
静态资源/staticData/main/l4Ac.png


BIN
静态资源/staticData/main/l5.png


BIN
静态资源/staticData/main/liuchao/1.png


BIN
静态资源/staticData/main/liuchao/10.png


BIN
静态资源/staticData/main/liuchao/10_0.png


BIN
静态资源/staticData/main/liuchao/11.png


BIN
静态资源/staticData/main/liuchao/11_0.png


BIN
静态资源/staticData/main/liuchao/2.png


BIN
静态资源/staticData/main/liuchao/3.png


BIN
静态资源/staticData/main/liuchao/4.png


BIN
静态资源/staticData/main/liuchao/5.png


BIN
静态资源/staticData/main/liuchao/6.png


BIN
静态资源/staticData/main/liuchao/7.png


BIN
静态资源/staticData/main/liuchao/7_0.png


BIN
静态资源/staticData/main/liuchao/7_1.png


BIN
静态资源/staticData/main/liuchao/8.png


BIN
静态资源/staticData/main/liuchao/8_0.png


+ 0 - 0
静态资源/staticData/main/liuchao/9.png


Деякі файли не було показано, через те що забагато файлів було змінено