shaogen1995 1 năm trước cách đây
commit
11ff52094c
40 tập tin đã thay đổi với 37744 bổ sung0 xóa
  1. 23 0
      code/.gitignore
  2. 3 0
      code/README.md
  3. 10 0
      code/config-overrides.js
  4. 30270 0
      code/package-lock.json
  5. 62 0
      code/package.json
  6. 8 0
      code/path.tsconfig.json
  7. 6344 0
      code/public/4dage.js
  8. 48 0
      code/public/index.html
  9. 64 0
      code/public/model.html
  10. 31 0
      code/src/App.tsx
  11. BIN
      code/src/assets/img/IMGerror.png
  12. BIN
      code/src/assets/img/active.png
  13. BIN
      code/src/assets/img/chosen.png
  14. BIN
      code/src/assets/img/landtip.png
  15. BIN
      code/src/assets/img/loading.gif
  16. 125 0
      code/src/assets/styles/base.css
  17. 165 0
      code/src/assets/styles/base.less
  18. 51 0
      code/src/components/ImageLazy/index.module.scss
  19. 40 0
      code/src/components/ImageLazy/index.tsx
  20. 29 0
      code/src/components/Message/index.tsx
  21. 30 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. 73 0
      code/src/index.tsx
  25. 45 0
      code/src/pages/A1Home/index.module.scss
  26. 49 0
      code/src/pages/A1Home/index.tsx
  27. 5 0
      code/src/pages/初始化组件/index.module.scss
  28. 14 0
      code/src/pages/初始化组件/index.tsx
  29. 20 0
      code/src/store/index.ts
  30. 14 0
      code/src/store/reducer/index.ts
  31. 39 0
      code/src/store/reducer/layout.ts
  32. 27 0
      code/src/types/api/layot.d.ts
  33. 8 0
      code/src/types/declaration.d.ts
  34. 2 0
      code/src/types/index.d.ts
  35. 26 0
      code/src/utils/history.ts
  36. 50 0
      code/src/utils/message.ts
  37. 27 0
      code/tsconfig.json
  38. BIN
      静态资源/staticData/A1Home/pc/bg.jpg
  39. BIN
      静态资源/staticData/A1Home/pc/tab.png
  40. 19 0
      静态资源/staticData/dataTemp.js

+ 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*

+ 3 - 0
code/README.md

@@ -0,0 +1,3 @@
+本地运行:静态资源里面先运行一个服务 
+使用 http-server
+确保服务地址是:http://127.0.0.1:8080

+ 10 - 0
code/config-overrides.js

@@ -0,0 +1,10 @@
+const path = require('path')
+const { override, addWebpackAlias } = require('customize-cra')
+
+// 添加 @ 别名
+const webpackAlias = addWebpackAlias({
+  '@': path.resolve(__dirname, 'src'),
+})
+
+// 导出要进行覆盖的 webpack 配置
+module.exports = override(webpackAlias)

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 30270 - 0
code/package-lock.json


+ 62 - 0
code/package.json

@@ -0,0 +1,62 @@
+{
+  "name": "demo",
+  "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.1.3",
+    "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",
+    "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/history": "^5.0.0",
+    "@types/lodash": "^4.14.198",
+    "@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/*"]
+      }
+    }
+  }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 6344 - 0
code/public/4dage.js


+ 48 - 0
code/public/index.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="zh">
+
+<head>
+  <meta charset="utf-8" />
+  <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
+  <meta name="viewport" content="width=device-width, initial-scale=1" />
+  <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" />
+
+
+  <script src="http://127.0.0.1:8080/staticData/dataTemp.js"></script>
+  <script src="./staticData/dataTemp.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/
+    -->
+
+  <!--
+      Notice the use of %PUBLIC_URL% in the tags above.
+      It will be replaced with the URL of the `public` folder during the build.
+      Only files inside the `public` folder can be referenced from the HTML.
+
+      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
+      work correctly both with client-side routing and a non-root public URL.
+      Learn how to configure a non-root public URL by running `npm run build`.
+    -->
+  <title>开平碉楼建筑群</title>
+</head>
+
+<body>
+  <noscript>You need to enable JavaScript to run this app.</noscript>
+  <div id="root"></div>
+  <!--
+      This HTML file is a template.
+      If you open it directly in the browser, you will see an empty page.
+
+      You can add webfonts, meta tags, or analytics to this file.
+      The build step will place the bundled scripts into the <body> tag.
+
+      To begin the development, run `npm start` or `yarn start`.
+      To create a production bundle, use `npm run build` or `yarn build`.
+    -->
+</body>
+
+</html>

+ 64 - 0
code/public/model.html

@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<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;
+    }
+
+    .bacBox {
+      opacity: 1;
+      pointer-events: auto;
+      position: absolute;
+      z-index: 998;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      background-color: #cfcfd0;
+      transition: all 1s;
+    }
+  </style>
+</head>
+
+<body>
+  <div id="ui"></div>
+  <div class="bacBox"></div>
+  <script>
+    let number = getQueryVariable("m");
+    let num = getQueryVariable("n");
+    // console.log('ppppppppp',number);
+
+    window.autoRotate = true; // 是否自动旋转
+
+    // 打包配置
+
+    let src = ''
+
+    if (window.location.href.includes('http://')) {
+      // 本地环境
+      src = 'http://127.0.0.1:8080/staticData/'
+    } else {
+      // 正式环境
+      src = './staticData/'
+    }
+
+    // fdage.embed( number, {
+    fdage.embed(`${src}3Goods/${number}/main${num}.4dage`, {
+      transparentBackground: true,
+      width: 800,
+      height: 600,
+      autoStart: true,
+      fullFrame: true,
+      pagePreset: false
+    });
+  </script>
+</body>
+
+</html>

+ 31 - 0
code/src/App.tsx

@@ -0,0 +1,31 @@
+import "@/assets/styles/base.css";
+// 关于路由
+import React from "react";
+import { Router, Route, Switch } from "react-router-dom";
+import history from "./utils/history";
+import SpinLoding from "./components/SpinLoding";
+import MessageCom from "./components/Message";
+import NotFound from "./components/NotFound";
+const A1Home = React.lazy(() => import("./pages/A1Home"));
+
+export default function App() {
+  return (
+    <>
+      {/* 关于路由 */}
+      <Router history={history}>
+        <React.Suspense fallback={<SpinLoding />}>
+          <Switch>
+            {/* 首页 */}
+            <Route path="/" exact component={A1Home} />
+
+            {/* 找不到页面 */}
+            <Route path="*" component={NotFound} />
+          </Switch>
+        </React.Suspense>
+      </Router>
+
+      {/* antd 轻提示 ---兼容360浏览器 */}
+      <MessageCom />
+    </>
+  );
+}

BIN
code/src/assets/img/IMGerror.png


BIN
code/src/assets/img/active.png


BIN
code/src/assets/img/chosen.png


BIN
code/src/assets/img/landtip.png


BIN
code/src/assets/img/loading.gif


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

@@ -0,0 +1,125 @@
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+html {
+  height: 100%;
+  font-size: 14px;
+  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;
+  height: 100%;
+  color: black;
+}
+a {
+  text-decoration: none;
+  color: black;
+  outline: none;
+}
+i {
+  font-style: normal;
+}
+img {
+  max-width: 100%;
+  max-height: 100%;
+  vertical-align: middle;
+  object-fit: cover;
+}
+ul {
+  list-style: none;
+}
+body {
+  overflow: auto;
+  overflow-y: overlay;
+}
+/* 文本域取消下拉 */
+textarea {
+  resize: none !important;
+  min-height: 100px !important;
+}
+/* 主题色 */
+:root {
+  --themeColor: #FCE9AC;
+}
+/* 找不到页面 */
+.noFindPage {
+  opacity: 0;
+  transition: opacity 0.5s;
+}
+#root {
+  width: 100vw;
+  height: 100vh;
+  min-width: 1600px;
+  min-height: 900px;
+  overflow: auto;
+  overflow-y: overlay;
+  /* antd图片预览组件 */
+}
+#root > div {
+  width: 100%;
+  height: 100%;
+}
+#root .ant-image {
+  display: none;
+}
+[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;
+}
+.AppM {
+  width: 100vw;
+  max-width: 500px;
+  margin: 0 auto;
+  overflow: hidden;
+}
+#ScreenChange {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 10000;
+  background-color: rgba(0, 0, 0, 0.8);
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  opacity: 0;
+  pointer-events: none;
+  transition: all 0.5s;
+}
+#ScreenChange > img {
+  width: 200px;
+}
+#ScreenChange > p {
+  margin-top: 20px;
+  color: #fff;
+  font-size: 18px;
+  height: 40px;
+}
+/*横屏*/
+@media screen and (orientation: landscape) {
+  #ScreenChange {
+    opacity: 1;
+    pointer-events: auto;
+  }
+}

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

@@ -0,0 +1,165 @@
+* {
+  margin: 0;
+  padding: 0;
+  box-sizing: border-box;
+}
+
+html {
+  height: 100%;
+  font-size: 14px;
+  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;
+  height: 100%;
+  color: black;
+}
+
+a {
+  text-decoration: none;
+  color: black;
+  outline: none;
+}
+
+i {
+  font-style: normal;
+}
+
+img {
+  max-width: 100%;
+  max-height: 100%;
+  vertical-align: middle;
+  object-fit: cover;
+}
+
+ul {
+  list-style: none;
+}
+
+body {
+  overflow: auto;
+  overflow-y: overlay;
+}
+
+/* 文本域取消下拉 */
+textarea {
+  resize: none !important;
+  min-height: 100px !important;
+}
+
+/* 主题色 */
+:root {
+  --themeColor: #FCE9AC;
+}
+
+
+
+
+
+/* 找不到页面 */
+.noFindPage {
+  opacity: 0;
+  transition: opacity .5s;
+}
+
+
+// 重置antd样式
+#root {
+  width: 100vw;
+  height: 100vh;
+  min-width: 1600px;
+  min-height: 900px;
+  overflow: auto;
+  overflow-y: overlay;
+
+  &>div {
+    width: 100%;
+    height: 100%;
+  }
+
+  // a {
+  //   color: var(--themeColor);
+  // }
+
+
+  /* antd图片预览组件 */
+  .ant-image {
+    display: none;
+  }
+
+}
+
+
+[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;
+}
+
+
+.AppM {
+  width: 100vw;
+  max-width: 500px;
+  margin: 0 auto;
+  overflow: hidden;
+}
+
+// 横屏 竖屏的切换
+#ScreenChange {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 10000;
+  background-color: rgba(0, 0, 0, .8);
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  opacity: 0;
+  pointer-events: none;
+  transition: all .5s;
+
+  &>img {
+    width: 200px;
+  }
+
+  &>p {
+    margin-top: 20px;
+    color: #fff;
+    font-size: 18px;
+    height: 40px;
+  }
+}
+
+/*横屏*/
+@media screen and (orientation: landscape) {
+  #ScreenChange {
+    opacity: 1;
+    pointer-events: auto;
+  }
+}

+ 51 - 0
code/src/components/ImageLazy/index.module.scss

@@ -0,0 +1,51 @@
+.ImageLazy {
+  position: relative;
+
+  :global {
+    .lazyBox {
+      width: 100%;
+      height: 100%;
+      position: relative;
+
+      .adm-image {
+        width: 100%;
+        height: 100%;
+
+        img {
+          width: 100%;
+          height: 100%;
+        }
+      }
+
+      .lookImg {
+        cursor: pointer;
+        transition: opacity .3s;
+        opacity: 0;
+        pointer-events: none;
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        font-size: 18px;
+        color: #fff;
+        background-color: rgba(0, 0, 0, .6);
+
+        &>div {
+          font-size: 14px;
+        }
+      }
+
+      &:hover {
+        .lookImg {
+          opacity: 1;
+          pointer-events: auto;
+        }
+      }
+    }
+  }
+
+}

+ 40 - 0
code/src/components/ImageLazy/index.tsx

@@ -0,0 +1,40 @@
+import React from "react";
+import styles from "./index.module.scss";
+import imgLoding from "@/assets/img/loading.gif";
+import imgErr from "@/assets/img/IMGerror.png";
+import { Image } from "antd-mobile";
+import { baseUrl } from "@/index";
+
+type Props = {
+  width?: number | string;
+  height?: number | string;
+  src: string;
+  noLook?: boolean;
+  offline?: boolean;
+};
+
+function ImageLazy({
+  width = 100,
+  height = 100,
+  src,
+  noLook,
+  offline = false,
+}: Props) {
+  return (
+    <div className={styles.ImageLazy} style={{ width: width, height: height }}>
+      <div className="lazyBox">
+        <Image
+          lazy
+          src={src ? (offline ? src : baseUrl + src) : ""}
+          placeholder={<img src={imgLoding} alt="" />}
+          fallback={<img src={imgErr} alt="" />}
+          fit="cover"
+        />
+      </div>
+    </div>
+  );
+}
+
+const MemoImageLazy = React.memo(ImageLazy);
+
+export default MemoImageLazy;

+ 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;

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

@@ -0,0 +1,30 @@
+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";
+    }, 300);
+    return () => {
+      clearTimeout(timeRef.current);
+    };
+  }, []);
+
+  return (
+    <div className="noFindPage">
+      <Result status="404" title="404" subTitle="找不到页面" />
+      <div style={{ display: "flex", justifyContent: "center" }}>
+        <Button type="primary" onClick={() => history.push("/")}>
+          首页
+        </Button>
+        &emsp;
+        <Button onClick={() => history.go(-1)}>返回</Button>
+      </div>
+    </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;

+ 73 - 0
code/src/index.tsx

@@ -0,0 +1,73 @@
+// 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";
+import { isMobileFu } from "./utils/history";
+// import AppM from "./AppM";
+
+const container = document.getElementById("root") as HTMLElement;
+const root = createRoot(container);
+
+// 静态资源地址
+// @ts-ignore
+export const baseUrl = baseUrlTemp;
+
+// 数据存到仓库
+// @ts-ignore
+store.dispatch({ type: "layout/setDataAll", payload: staticDataTemp });
+
+if (isMobileFu()) {
+  root.render(
+    <ConfigProvider
+      locale={locale}
+      theme={{
+        token: {
+          colorPrimary: "#FCE9AC",
+        },
+      }}
+    >
+      <Provider store={store}>
+        <StyleProvider
+          hashPriority="high"
+          transformers={[legacyLogicalPropertiesTransformer]}
+        >
+          {/* <AppM /> */}
+          <App />
+        </StyleProvider>
+      </Provider>
+    </ConfigProvider>
+  );
+} else {
+  root.render(
+    <ConfigProvider
+      locale={locale}
+      theme={{
+        token: {
+          colorPrimary: "#FCE9AC",
+        },
+      }}
+    >
+      <Provider store={store}>
+        <StyleProvider
+          hashPriority="high"
+          transformers={[legacyLogicalPropertiesTransformer]}
+        >
+          <App />
+        </StyleProvider>
+      </Provider>
+    </ConfigProvider>
+  );
+}

+ 45 - 0
code/src/pages/A1Home/index.module.scss

@@ -0,0 +1,45 @@
+.A1Home{
+  background-size: 100% 100%;
+  padding-top: 36px;
+  :global{
+    .A1tab{
+      width: 1600px;
+      height: 91px;
+      margin: 0 auto;
+      background-size: 100% 100%;
+      padding: 18px 0 0 180px;
+      display: flex;
+
+      .A1tabRow{
+        width: 180px;
+        height: 51px;
+        font-size: 22px;
+        color: #fff;
+        line-height: 51px;
+        text-align: center;
+        cursor: pointer;
+        &:nth-of-type(3){
+          margin-left: 522px;
+        }
+      }
+      .A1tabRowAc{
+        background-image: url('../../assets/img/active.png');
+        background-size: 100% 100%;
+        color: var(--themeColor);
+        position: relative;
+        &::after{
+          content: '';
+          position: absolute;
+          top: 50%;
+          left: 50%;
+          transform: translate(-50%,-50%);
+          width: 116px;
+          height: 16px;
+          background-image: url('../../assets/img/chosen.png');
+          background-size: 100% 100%;
+        }
+      }
+
+    }
+  }
+}

+ 49 - 0
code/src/pages/A1Home/index.tsx

@@ -0,0 +1,49 @@
+import React, { useCallback, useState } from "react";
+import styles from "./index.module.scss";
+import classNames from "classnames";
+import { baseUrl } from "@/index";
+
+const tabList = [
+  { id: 1, name: "总览" },
+  { id: 2, name: "村落" },
+  { id: 3, name: "建筑" },
+  { id: 4, name: "构件" },
+];
+
+function A1Home() {
+  const [acId, setAcId] = useState(1);
+
+  const cutTabFu = useCallback((id: number) => {
+    setAcId(id);
+  }, []);
+
+  return (
+    <div
+      className={styles.A1Home}
+      style={{ backgroundImage: `url(${baseUrl}/A1Home/pc/bg.jpg)` }}
+    >
+      {/* 顶部tab */}
+      <div
+        className="A1tab"
+        style={{ backgroundImage: `url(${baseUrl}/A1Home/pc/tab.png)` }}
+      >
+        {tabList.map((v) => (
+          <div
+            onClick={() => cutTabFu(v.id)}
+            className={classNames(
+              "A1tabRow",
+              acId === v.id ? "A1tabRowAc" : ""
+            )}
+            key={v.id}
+          >
+            {v.name}
+          </div>
+        ))}
+      </div>
+    </div>
+  );
+}
+
+const MemoA1Home = React.memo(A1Home);
+
+export default MemoA1Home;

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

@@ -0,0 +1,5 @@
+.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

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

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

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

@@ -0,0 +1,39 @@
+import { DataAllType } from "@/types";
+import { MessageType } from "@/utils/message";
+
+// 初始化状态
+const initState = {
+  // antd轻提示(兼容360浏览器)
+  message: {
+    txt: "",
+    type: "info",
+    duration: 3,
+  } as MessageType,
+
+  // 所有数据
+  dataAll: { Home: {} } as DataAllType,
+};
+
+// 定义 action 类型
+type LayoutActionType =
+  | { type: "layout/message"; payload: MessageType }
+  | { type: "layout/setDataAll"; payload: DataAllType };
+
+// 频道 reducer
+export default function layoutReducer(
+  state = initState,
+  action: LayoutActionType
+) {
+  switch (action.type) {
+    // antd轻提示(兼容360浏览器)
+    case "layout/message":
+      return { ...state, message: action.payload };
+
+    // 设置所有数据
+    case "layout/setDataAll":
+      return { ...state, dataAll: action.payload };
+
+    default:
+      return state;
+  }
+}

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

@@ -0,0 +1,27 @@
+export type Goods = {
+  id: number;
+  type1: string;
+  type2: string;
+  name: string;
+  name2: string;
+  num: string;
+  age: string;
+  grain: string;
+  size: string;
+  level: string;
+  state: string;
+  showType: 'model'|'img';
+  showNum: number;
+};
+
+export type DataAllType = {
+  Home: {
+    scene: {
+      id: number;
+      name: string;
+      path: string;
+    }[];
+    vr:string
+  };
+  goods: Goods[];
+};

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

@@ -0,0 +1,8 @@
+declare module "history";
+declare module "*.scss";
+declare module "*.png";
+declare module "*.jpg";
+declare module "*.gif";
+declare module "*.svg";
+declare module "js-export-excel";
+declare module 'braft-utils';

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

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

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

@@ -0,0 +1,26 @@
+import { createHashHistory  } from 'history'
+const history = createHashHistory()
+export default history
+
+export const urlParameter = (data: string) => {
+  if (data) {
+    const query = data.substring(data.indexOf("?") + 1);
+    const arr = query.split("&");
+    const params = {} as any;
+    arr.forEach((v) => {
+      const key = v.substring(0, v.indexOf("="));
+      const val = v.substring(v.indexOf("=") + 1);
+      params[key] = val;
+    });
+    return params;
+  } else return {};
+};
+
+// 判断是手机端还是pc端
+export const isMobileFu = () => {
+  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
+}

+ 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,
+      },
+    });
+  },
+};

+ 27 - 0
code/tsconfig.json

@@ -0,0 +1,27 @@
+{
+  "extends": "./path.tsconfig.json",
+  "compilerOptions": {
+    "target": "es5",
+    "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"
+  ]
+}

BIN
静态资源/staticData/A1Home/pc/bg.jpg


BIN
静态资源/staticData/A1Home/pc/tab.png


+ 19 - 0
静态资源/staticData/dataTemp.js

@@ -0,0 +1,19 @@
+
+const envTemp = window.location.href.includes('http://')
+
+const baseUrlTemp = envTemp ? 'http://127.0.0.1:8080/staticData' : '/staticData'
+
+const staticDataTemp = {
+  '总览': {
+    // 电脑端
+    pc: {
+      // 左下角的开发保护数据
+
+    },
+    // 手机端
+    mobile: {
+      // 左下角的开发保护数据
+    }
+
+  }
+}