shaogen1995 2 роки тому
батько
коміт
ba4a0ef5c9
34 змінених файлів з 973 додано та 143 видалено
  1. 117 4
      code/src/App.tsx
  2. BIN
      code/src/assets/img/back.png
  3. BIN
      code/src/assets/img/btn_active.png
  4. BIN
      code/src/assets/img/btn_normal.png
  5. BIN
      code/src/assets/img/btn_s_normal.png
  6. BIN
      code/src/assets/img/homeB.png
  7. BIN
      code/src/assets/img/homeBAc.png
  8. BIN
      code/src/assets/img/icon_menu_active.png
  9. BIN
      code/src/assets/img/icon_menu_normal.png
  10. BIN
      code/src/assets/img/icon_search.png
  11. BIN
      code/src/assets/img/line.png
  12. 119 9
      code/src/assets/styles/base.css
  13. 171 38
      code/src/assets/styles/base.less
  14. 1 1
      code/src/components/SpinLoding/index.module.scss
  15. 210 33
      code/src/pages/A1Home/index.module.scss
  16. 96 22
      code/src/pages/A1Home/index.tsx
  17. 13 0
      code/src/pages/B1Card/index.module.scss
  18. 24 0
      code/src/pages/B1Card/index.tsx
  19. 5 0
      code/src/pages/B1Village/index.module.scss
  20. 14 0
      code/src/pages/B1Village/index.tsx
  21. 5 0
      code/src/pages/C1Architec/index.module.scss
  22. 14 0
      code/src/pages/C1Architec/index.tsx
  23. 5 0
      code/src/pages/D1Build/index.module.scss
  24. 14 0
      code/src/pages/D1Build/index.tsx
  25. 22 0
      code/src/pages/Z1Search/index.module.scss
  26. 23 0
      code/src/pages/Z1Search/index.tsx
  27. 1 1
      code/src/store/reducer/layout.ts
  28. 31 21
      code/src/types/api/layot.d.ts
  29. BIN
      静态资源/staticData/A1Home/mobile/start.mp4
  30. BIN
      静态资源/staticData/A1Home/pc/hover1.png
  31. BIN
      静态资源/staticData/A1Home/pc/map.jpg
  32. BIN
      静态资源/staticData/A1Home/pc/start.mp4
  33. BIN
      静态资源/staticData/Z1Search/pc/bg.jpg
  34. 88 14
      静态资源/staticData/dataTemp.js

+ 117 - 4
code/src/App.tsx

@@ -1,22 +1,79 @@
 import "@/assets/styles/base.css";
 // 关于路由
-import React from "react";
+import React, { useCallback, useEffect, useState } 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";
+import { baseUrl } from ".";
+import classNames from "classnames";
+import Z1Search from "./pages/Z1Search";
+import B1Card from "./pages/B1Card";
 const A1Home = React.lazy(() => import("./pages/A1Home"));
+const B1Village = React.lazy(() => import("./pages/B1Village"));
+const C1Architec = React.lazy(() => import("./pages/C1Architec"));
+const D1Build = React.lazy(() => import("./pages/D1Build"));
+
+const tabList = [
+  { id: 1, name: "总览", path: "/" },
+  { id: 2, name: "村落", path: "/village" },
+  { id: 3, name: "建筑", path: "/architec" },
+  { id: 4, name: "构件", path: "/build" },
+];
 
 export default function App() {
+  const [routerAc, setRouterAc] = useState("/");
+
+  // 搜查页面
+  const [searchShow, setSearchShow] = useState(false);
+
+  // 顶部tab的展开和收起
+  const [tabShow, setTabShow] = useState(true);
+
+  // 视频的播放
+  const [videoShow, setVideoShow] = useState(false);
+
+  // 是否需要显示视频
+  const [isVideoShow, setIsVideoShow] = useState(false);
+  useEffect(() => {
+    if (window.location.hash === "#/") setIsVideoShow(true);
+
+    setRouterAc(window.location.hash);
+
+    window.addEventListener(
+      "hashchange",
+      () => {
+        setRouterAc(window.location.hash);
+      },
+      true
+    );
+  }, []);
+
+  // 顶部tab的切换
+  const cutTab = useCallback((id: number, path: string) => {
+    if (id !== 2) {
+      history.push(path);
+      setTab2Show(false);
+    } else setTab2Show(true);
+  }, []);
+
+  const [tab2Show, setTab2Show] = useState(false);
+
   return (
-    <>
+    <div id="App">
       {/* 关于路由 */}
       <Router history={history}>
         <React.Suspense fallback={<SpinLoding />}>
           <Switch>
-            {/* 首页 */}
+            {/* 总览 */}
             <Route path="/" exact component={A1Home} />
+            {/* 村落 */}
+            <Route path="/village" component={B1Village} />
+            {/* 建筑 */}
+            <Route path="/architec" component={C1Architec} />
+            {/* 构件 */}
+            <Route path="/build" component={D1Build} />
 
             {/* 找不到页面 */}
             <Route path="*" component={NotFound} />
@@ -24,8 +81,64 @@ export default function App() {
         </React.Suspense>
       </Router>
 
+      {/* 视频加载中 */}
+      {videoShow && isVideoShow ? (
+        <div className="Appvideo">
+          <video
+            onEnded={() => setVideoShow(false)}
+            src={`${baseUrl}/A1Home/pc/start.mp4`}
+            autoPlay
+            muted
+          ></video>
+        </div>
+      ) : null}
+
+      {/* 顶部tab */}
+      <div
+        className="Apptab"
+        style={{ backgroundImage: `url(${baseUrl}/A1Home/pc/tab.png)` }}
+        hidden={!tabShow}
+      >
+        {tabList.map((v) => (
+          <div
+            onClick={() => cutTab(v.id, v.path)}
+            className={classNames(
+              "ApptabRow",
+              (routerAc === "#/" && v.id === 1 && !tab2Show) ||
+                (routerAc.includes("#" + v.path) && v.id !== 1 && !tab2Show) ||
+                (tab2Show && v.id === 2)
+                ? "ApptabRowAc"
+                : ""
+            )}
+            key={v.id}
+          >
+            {v.name}
+          </div>
+        ))}
+
+        {/* 搜索按钮 */}
+
+        <div className="APPtabSearch" onClick={() => setSearchShow(true)}></div>
+
+        {/* 展开和收起按钮 */}
+        <div className="APPtabShow" onClick={() => setTabShow(false)}></div>
+      </div>
+
+      {/* 展开按钮 */}
+      <div
+        className="APPtabHide"
+        onClick={() => setTabShow(true)}
+        hidden={tabShow}
+      ></div>
+
+      {/* 点击搜索出来的页面 */}
+      {searchShow ? <Z1Search colseFu={() => setSearchShow(false)} /> : null}
+
+      {/* 点击顶部的村落出来的选择卡 */}
+      <B1Card isShow={!tab2Show} closeFu={() => setTab2Show(false)} />
+
       {/* antd 轻提示 ---兼容360浏览器 */}
       <MessageCom />
-    </>
+    </div>
   );
 }

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


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


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


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


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


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


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


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


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


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


+ 119 - 9
code/src/assets/styles/base.css

@@ -41,10 +41,12 @@ textarea {
 }
 /* 主题色 */
 :root {
-  --themeColor: #FCE9AC;
+  --themeColor: #5C4B32;
+  --themeColor2: #FCE9AC;
 }
 /* 找不到页面 */
 .noFindPage {
+  padding-top: 100px;
   opacity: 0;
   transition: opacity 0.5s;
 }
@@ -57,7 +59,101 @@ textarea {
   overflow-y: overlay;
   /* antd图片预览组件 */
 }
-#root > div {
+#root #App {
+  width: 100%;
+  height: 100%;
+  position: relative;
+}
+#root #App .Appvideo {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 20;
+  overflow: hidden;
+  background-color: #e7dfdb;
+}
+#root #App .Appvideo video {
+  width: 100%;
+}
+#root #App .Apptab {
+  position: absolute;
+  z-index: 10;
+  left: 50%;
+  transform: translateX(-50%);
+  top: 20px;
+  width: 1600px;
+  height: 91px;
+  margin: 0 auto;
+  background-size: 100% 100%;
+  padding: 18px 0 0 180px;
+  display: flex;
+}
+#root #App .Apptab .ApptabRow {
+  width: 180px;
+  height: 51px;
+  font-size: 22px;
+  color: #fff;
+  line-height: 51px;
+  text-align: center;
+  cursor: pointer;
+}
+#root #App .Apptab .ApptabRow:nth-of-type(3) {
+  margin-left: 522px;
+}
+#root #App .Apptab .ApptabRowAc {
+  background-image: url('../../assets/img/active.png');
+  background-size: 100% 100%;
+  color: var(--themeColor2);
+  position: relative;
+}
+#root #App .Apptab .ApptabRowAc::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%;
+}
+#root #App .Apptab .APPtabSearch {
+  position: absolute;
+  right: 120px;
+  top: 46%;
+  transform: translateY(-50%);
+  width: 24px;
+  height: 24px;
+  background-image: url('../../assets/img/icon_search.png');
+  background-size: 100% 100%;
+  cursor: pointer;
+}
+#root #App .Apptab .APPtabShow {
+  position: absolute;
+  right: 60px;
+  top: 46%;
+  transform: translateY(-50%);
+  width: 20px;
+  height: 20px;
+  background-image: url('../../assets/img/icon_menu_active.png');
+  background-size: 100% 100%;
+  cursor: pointer;
+}
+#root #App .APPtabHide {
+  position: absolute;
+  top: 40px;
+  right: 40px;
+  z-index: 10;
+  width: 40px;
+  height: 40px;
+  border-radius: 50%;
+  background-image: url('../../assets/img/icon_menu_normal.png');
+  background-size: 100% 100%;
+  cursor: pointer;
+}
+#root #App > div {
   width: 100%;
   height: 100%;
 }
@@ -77,7 +173,7 @@ textarea {
   /*滚动条里面小方块*/
   border-radius: 10px;
   -webkit-box-shadow: inset 0 0 5px transparent;
-  background: var(--themeColor);
+  background: var(--themeColor2);
 }
 .mySorrl::-webkit-scrollbar-track {
   /*滚动条里面轨道*/
@@ -85,13 +181,17 @@ textarea {
   border-radius: 10px;
   background: transparent;
 }
-.AppM {
+#root {
+  /*横屏*/
+}
+#root .AppM {
   width: 100vw;
   max-width: 500px;
   margin: 0 auto;
   overflow: hidden;
+  position: relative;
 }
-#ScreenChange {
+#root #ScreenChange {
   position: fixed;
   top: 0;
   left: 0;
@@ -107,19 +207,29 @@ textarea {
   pointer-events: none;
   transition: all 0.5s;
 }
-#ScreenChange > img {
+#root #ScreenChange > img {
   width: 200px;
 }
-#ScreenChange > p {
+#root #ScreenChange > p {
   margin-top: 20px;
   color: #fff;
   font-size: 18px;
   height: 40px;
 }
-/*横屏*/
 @media screen and (orientation: landscape) {
-  #ScreenChange {
+  #root #ScreenChange {
     opacity: 1;
     pointer-events: auto;
   }
 }
+.A1locBoxLoc {
+  animation: moveDian 1s linear infinite alternate;
+}
+@keyframes moveDian {
+  0% {
+    transform: translateY(-6px);
+  }
+  100% {
+    transform: translateY(6px);
+  }
+}

+ 171 - 38
code/src/assets/styles/base.less

@@ -50,7 +50,8 @@ textarea {
 
 /* 主题色 */
 :root {
-  --themeColor: #FCE9AC;
+  --themeColor: #5C4B32;
+  --themeColor2: #FCE9AC;
 }
 
 
@@ -59,6 +60,7 @@ textarea {
 
 /* 找不到页面 */
 .noFindPage {
+  padding-top: 100px;
   opacity: 0;
   transition: opacity .5s;
 }
@@ -73,11 +75,123 @@ textarea {
   overflow: auto;
   overflow-y: overlay;
 
-  &>div {
+  #App {
     width: 100%;
     height: 100%;
+    position: relative;
+
+    .Appvideo {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      z-index: 20;
+      overflow: hidden;
+      background-color: #e7dfdb;
+
+      video {
+        width: 100%;
+        // height: 100%;
+      }
+    }
+
+    .Apptab {
+      position: absolute;
+      z-index: 10;
+      left: 50%;
+      transform: translateX(-50%);
+      top: 20px;
+      width: 1600px;
+      height: 91px;
+      margin: 0 auto;
+      background-size: 100% 100%;
+      padding: 18px 0 0 180px;
+      display: flex;
+
+      .ApptabRow {
+        width: 180px;
+        height: 51px;
+        font-size: 22px;
+        color: #fff;
+        line-height: 51px;
+        text-align: center;
+        cursor: pointer;
+
+        &:nth-of-type(3) {
+          margin-left: 522px;
+        }
+      }
+
+      .ApptabRowAc {
+        background-image: url('../../assets/img/active.png');
+        background-size: 100% 100%;
+        color: var(--themeColor2);
+        position: relative;
+        // pointer-events: none;
+
+        &::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%;
+        }
+      }
+
+      .APPtabSearch {
+        position: absolute;
+        right: 120px;
+        top: 46%;
+        transform: translateY(-50%);
+        width: 24px;
+        height: 24px;
+        background-image: url('../../assets/img/icon_search.png');
+        background-size: 100% 100%;
+        cursor: pointer;
+      }
+
+      .APPtabShow {
+        position: absolute;
+        right: 60px;
+        top: 46%;
+        transform: translateY(-50%);
+        width: 20px;
+        height: 20px;
+        background-image: url('../../assets/img/icon_menu_active.png');
+        background-size: 100% 100%;
+        cursor: pointer;
+      }
+
+    }
+
+    .APPtabHide {
+      position: absolute;
+      top: 40px;
+      right: 40px;
+      z-index: 10;
+      width: 40px;
+      height: 40px;
+      border-radius: 50%;
+      background-image: url('../../assets/img/icon_menu_normal.png');
+      background-size: 100% 100%;
+      cursor: pointer;
+
+
+    }
+
+    &>div {
+      width: 100%;
+      height: 100%;
+    }
   }
 
+
+
   // a {
   //   color: var(--themeColor);
   // }
@@ -109,7 +223,7 @@ textarea {
   /*滚动条里面小方块*/
   border-radius: 10px;
   -webkit-box-shadow: inset 0 0 5px transparent;
-  background: var(--themeColor);
+  background: var(--themeColor2);
 }
 
 .mySorrl::-webkit-scrollbar-track {
@@ -119,47 +233,66 @@ textarea {
   background: transparent;
 }
 
+#root {
+  .AppM {
+    width: 100vw;
+    max-width: 500px;
+    margin: 0 auto;
+    overflow: hidden;
+    position: relative;
+  }
 
-.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;
+    }
+  }
 }
 
-// 横屏 竖屏的切换
-#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;
-  }
+// pc首页箭头动画帧
+.A1locBoxLoc{
+  animation: moveDian 1s linear infinite alternate;
+}
 
-  &>p {
-    margin-top: 20px;
-    color: #fff;
-    font-size: 18px;
-    height: 40px;
+@keyframes moveDian {
+  0% {
+    transform: translateY(-6px);
   }
-}
 
-/*横屏*/
-@media screen and (orientation: landscape) {
-  #ScreenChange {
-    opacity: 1;
-    pointer-events: auto;
+  100% {
+    transform: translateY(6px);
   }
+
 }

+ 1 - 1
code/src/components/SpinLoding/index.module.scss

@@ -3,7 +3,7 @@
   z-index: 9999;
   width: 100%;
   height: 100%;
-  background-color: #fff;
+  // background-color: #fff;
   display: flex;
   justify-content: center;
   align-items: center;

+ 210 - 33
code/src/pages/A1Home/index.module.scss

@@ -1,45 +1,222 @@
-.A1Home{
+.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;
+  position: relative;
+
+  :global {
+
+
+    .A1locBox {
+      position: absolute;
+      z-index: 3;
+      width: 158px;
+      height: 129px;
+
+      .A1locBoxName {
         text-align: center;
-        cursor: pointer;
-        &:nth-of-type(3){
-          margin-left: 522px;
+        background-image: url('../../assets/img/btn_normal.png');
+        background-size: 100% 100%;
+        width: 158px;
+        height: 34px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        letter-spacing: 2px;
+        color: var(--themeColor2);
+        font-weight: 700;
+        transition: all .3s;
+      }
+
+      .A1locBoxLoc {
+        margin: 15px auto 0;
+        width: 60px;
+        height: 60px;
+        background-image: url('../../assets/img/homeB.png');
+        background-size: 100% 100%;
+        transition: all .3s;
+      }
+
+    }
+
+    .A1locBoxHide {
+
+      .A1locBoxName,
+      .A1locBoxLoc {
+        opacity: 0;
+      }
+    }
+
+    .A1locHover {
+      position: absolute;
+      z-index: 3;
+      background-size: 100% 100%;
+      opacity: 0;
+      transition: all .3s;
+      cursor: pointer;
+
+      &>div {
+        position: absolute;
+        top: -50px;
+        left: 50%;
+        transform: translateX(-50%);
+
+        width: 188px;
+        height: 50px;
+        padding-bottom: 16px;
+
+        &>div {
+          width: 100%;
+          height: 100%;
+          text-align: center;
+          background-image: url('../../assets/img/btn_active.png');
+          background-size: 100% 100%;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+          letter-spacing: 2px;
+          color: var(--themeColor);
+          font-weight: 700;
         }
       }
-      .A1tabRowAc{
-        background-image: url('../../assets/img/active.png');
+
+
+      &:hover {
+        opacity: 1;
+      }
+    }
+
+    // .A1locHoverAc {
+    //   opacity: 1;
+    // }
+
+
+
+    .A1leftBtn {
+      position: absolute;
+      left: 70px;
+      bottom: 60px;
+      z-index: 1;
+      width: 138px;
+      height: 40px;
+      line-height: 38px;
+      text-align: center;
+      color: #fff;
+      letter-spacing: 2px;
+      font-size: 18px;
+      background-image: url('../../assets/img/btn_s_normal.png');
+      background-size: 100% 100%;
+      cursor: pointer;
+    }
+
+    .A1mapBox {
+      position: absolute;
+      z-index: 20;
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      opacity: 0;
+      pointer-events: none;
+      transition: all .3s;
+
+      .A1back {
+        position: absolute;
+        top: 30px;
+        left: 30px;
+        cursor: pointer;
+        width: 60px;
+        height: 60px;
+        background-image: url('../../assets/img/back.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');
+      }
+
+      .A1mapRow {
+        position: absolute;
+        z-index: 3;
+        cursor: pointer;
+        width: 50px;
+        height: 50px;
+
+        .A1mapRowDian {
+          width: 100%;
+          height: 100%;
+          background-image: url('../../assets/img/homeB.png');
           background-size: 100% 100%;
+          margin: 0 auto 0px;
+        }
+
+        &>p {
+          padding-top: 8px;
+          color: #fff;
+        }
+
+        &:hover {
+          .A1mapRowDian {
+
+            background-image: url('../../assets/img/homeBAc.png');
+          }
+
+          &>P {
+
+            color: var(--themeColor2);
+          }
+        }
+
+        .A1mapTxt {
+          transition: all .3s;
+          opacity: 0;
+          pointer-events: none;
+          background-color: var(--themeColor);
+          padding: 6px;
+          border-radius: 4px;
+          width: 300px;
+          height: auto;
+          position: absolute;
+
+          &>div {
+            width: 100%;
+            height: 100%;
+            border: 1px solid var(--themeColor2);
+            border-radius: 4px;
+            padding: 20px 20px;
+            color: var(--themeColor2);
+
+            &>h3 {
+              font-size: 18px;
+              text-align: center;
+            }
+
+            .A1mapXian {
+              width: 100%;
+              height: 16px;
+              background-image: url('../../assets/img/line.png');
+              background-size: 100% 100%;
+              margin: 15px 0;
+            }
+
+            &>p {
+              text-indent: 2em;
+              font-size: 14px;
+              line-height: 22px;
+              letter-spacing: 2px;
+            }
+          }
+        }
+
+        &:hover {
+          .A1mapTxt {
+            opacity: 1;
+          }
         }
       }
 
+
+
     }
+
+    .A1mapBoxShow {
+      opacity: 1;
+      pointer-events: auto;
+    }
+
   }
 }

+ 96 - 22
code/src/pages/A1Home/index.tsx

@@ -1,44 +1,118 @@
-import React, { useCallback, useState } from "react";
+import React, { useMemo, 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: "构件" },
-];
+import { useSelector } from "react-redux";
+import { RootState } from "@/store";
+import history from "@/utils/history";
 
 function A1Home() {
-  const [acId, setAcId] = useState(1);
+  const { dianOut, dianIn } = useSelector(
+    (state: RootState) => state.A0Layout.dataAll.home
+  );
+
+  const [mapShow, setMapShow] = useState(false);
 
-  const cutTabFu = useCallback((id: number) => {
-    setAcId(id);
-  }, []);
+  const hoverData = useMemo(() => {
+    const arr = dianOut.map((v) => ({ name: v.name, id: v.id, ...v.hover }));
+    return arr;
+  }, [dianOut]);
+
+  // 鼠标移入的变量
+  const [hoverAc, setHoverAc] = useState(0);
 
   return (
     <div
       className={styles.A1Home}
       style={{ backgroundImage: `url(${baseUrl}/A1Home/pc/bg.jpg)` }}
     >
-      {/* 顶部tab */}
+      {/* 图标定位 */}
+      {dianOut.map((v) => (
+        <div
+          className={classNames(
+            "A1locBox",
+            hoverAc === v.id ? "A1locBoxHide" : ""
+          )}
+          key={v.id}
+          style={{ top: v.top, left: v.left, right: v.right, bottom: v.bottom }}
+        >
+          {/* 名字 */}
+          <div className="A1locBoxName">{v.name}</div>
+          {/* 标点 */}
+          <div className="A1locBoxLoc"></div>
+        </div>
+      ))}
+
+      {/* hover出来的定位 */}
+      {hoverData.map((v) => (
+        <div
+          className={classNames("A1locHover")}
+          onMouseEnter={() => setHoverAc(v.id)}
+          onMouseLeave={() => setHoverAc(0)}
+          onClick={() => history.push(`/village?id=${v.id}`)}
+          key={v.id}
+          style={{
+            backgroundImage: `url(${baseUrl}/A1Home/pc/hover${v.id}.png)`,
+            width: v.width,
+            height: v.height,
+            top: v.top,
+            left: v.left,
+          }}
+        >
+          <div>
+            <div>{v.name}</div>
+          </div>
+        </div>
+      ))}
+
+      {/* 左下角的开发保护 */}
+      <div className="A1leftBtn" onClick={() => setMapShow(true)}>
+        开发保护
+      </div>
+
+      {/* 开发保护 */}
       <div
-        className="A1tab"
-        style={{ backgroundImage: `url(${baseUrl}/A1Home/pc/tab.png)` }}
+        className={classNames("A1mapBox", mapShow ? "A1mapBoxShow" : "")}
+        style={{ backgroundImage: `url(${baseUrl}/A1Home/pc/map.jpg)` }}
       >
-        {tabList.map((v) => (
+        {/* 主要内容 */}
+        {dianIn.map((v) => (
           <div
-            onClick={() => cutTabFu(v.id)}
-            className={classNames(
-              "A1tabRow",
-              acId === v.id ? "A1tabRowAc" : ""
-            )}
+            className="A1mapRow"
             key={v.id}
+            style={{
+              top: v.top,
+              left: v.left,
+              right: v.right,
+              bottom: v.bottom,
+            }}
           >
-            {v.name}
+            <div className="A1mapRowDian"></div>
+            <p>{v.name}</p>
+
+            {/* 信息盒子 */}
+            {v.txtLoc ? (
+              <div
+                className="A1mapTxt"
+                style={{
+                  top: v.txtLoc.top,
+                  left: v.txtLoc.left,
+                  right: v.txtLoc.right,
+                  bottom: v.txtLoc.bottom,
+                }}
+              >
+                <div>
+                  <h3>历史事件</h3>
+                  <div className="A1mapXian"></div>
+                  <p>{v.txt}</p>
+                </div>
+              </div>
+            ) : null}
           </div>
         ))}
+
+        {/* 返回按钮 */}
+        <div className="A1back" onClick={() => setMapShow(false)}></div>
       </div>
     </div>
   );

+ 13 - 0
code/src/pages/B1Card/index.module.scss

@@ -0,0 +1,13 @@
+.B1Card{
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 9;
+  background-color: rgba(28, 21, 12, 0.5);
+  backdrop-filter: blur(10px);
+  :global{
+    
+  }
+}

+ 24 - 0
code/src/pages/B1Card/index.tsx

@@ -0,0 +1,24 @@
+import React from "react";
+import styles from "./index.module.scss";
+import { useSelector } from "react-redux";
+import { RootState } from "@/store";
+
+type Props = {
+  isShow: boolean;
+  closeFu: () => void;
+};
+
+function B1Card({ isShow, closeFu }: Props) {
+
+  const data =useSelector((state:RootState)=>state.A0Layout.dataAll)
+
+  return (
+    <div className={styles.B1Card} hidden={isShow} onClick={closeFu}>
+      <h1>B1Card</h1>
+    </div>
+  );
+}
+
+const MemoB1Card = React.memo(B1Card);
+
+export default MemoB1Card;

+ 5 - 0
code/src/pages/B1Village/index.module.scss

@@ -0,0 +1,5 @@
+.B1Village{
+  :global{
+    
+  }
+}

+ 14 - 0
code/src/pages/B1Village/index.tsx

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

+ 5 - 0
code/src/pages/C1Architec/index.module.scss

@@ -0,0 +1,5 @@
+.C1Architec{
+  :global{
+    
+  }
+}

+ 14 - 0
code/src/pages/C1Architec/index.tsx

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

+ 5 - 0
code/src/pages/D1Build/index.module.scss

@@ -0,0 +1,5 @@
+.D1Build{
+  :global{
+    
+  }
+}

+ 14 - 0
code/src/pages/D1Build/index.tsx

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

+ 22 - 0
code/src/pages/Z1Search/index.module.scss

@@ -0,0 +1,22 @@
+.Z1Search {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 12;
+  background-size: 100% 100%;
+
+  :global {
+    .Z1back {
+      position: absolute;
+      top: 30px;
+      left: 30px;
+      cursor: pointer;
+      width: 60px;
+      height: 60px;
+      background-image: url('../../assets/img/back.png');
+      background-size: 100% 100%;
+    }
+  }
+}

+ 23 - 0
code/src/pages/Z1Search/index.tsx

@@ -0,0 +1,23 @@
+import React from "react";
+import styles from "./index.module.scss";
+import { baseUrl } from "@/index";
+
+type Props = {
+  colseFu: () => void;
+};
+
+function Z1Search({ colseFu }: Props) {
+  return (
+    <div
+      className={styles.Z1Search}
+      style={{ backgroundImage: `url(${baseUrl}/Z1Search/pc/bg.jpg)` }}
+    >
+      {/* 返回 */}
+      <div className="Z1back" onClick={colseFu}></div>
+    </div>
+  );
+}
+
+const MemoZ1Search = React.memo(Z1Search);
+
+export default MemoZ1Search;

+ 1 - 1
code/src/store/reducer/layout.ts

@@ -11,7 +11,7 @@ const initState = {
   } as MessageType,
 
   // 所有数据
-  dataAll: { Home: {} } as DataAllType,
+  dataAll: {} as DataAllType,
 };
 
 // 定义 action 类型

+ 31 - 21
code/src/types/api/layot.d.ts

@@ -1,27 +1,37 @@
-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: {
+  home: {
+    dianOut: {
+      id: number;
+      name: string;
+      top: string;
+      left: string;
+      right: string;
+      bottom: string;
+      hover: {
+        width: string;
+        height: string;
+        top: string;
+        left: string;
+      };
+      topM: string;
+      leftM: string;
+      rightM: string;
+      bottomM: string;
+    }[];
+    dianIn: {
       id: number;
       name: string;
-      path: string;
+      txt: string;
+      top: string;
+      left: string;
+      right: string;
+      bottom: string;
+      txtLoc: {
+        top: string;
+        left: string;
+        right: string;
+        bottom: string;
+      };
     }[];
-    vr:string
   };
-  goods: Goods[];
 };

BIN
静态资源/staticData/A1Home/mobile/start.mp4


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


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


BIN
静态资源/staticData/A1Home/pc/start.mp4


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


+ 88 - 14
静态资源/staticData/dataTemp.js

@@ -1,19 +1,93 @@
+const envTemp = window.location.href.includes("http://");
 
-const envTemp = window.location.href.includes('http://')
-
-const baseUrlTemp = envTemp ? 'http://127.0.0.1:8080/staticData' : '/staticData'
+const baseUrlTemp = envTemp
+  ? "http://127.0.0.1:8080/staticData"
+  : "/staticData";
 
 const staticDataTemp = {
-  '总览': {
-    // 电脑端
-    pc: {
-      // 左下角的开发保护数据
+  // 总览
+  home: {
+    // 外面地图(村落)的标点
+    dianOut: [
+      {
+        id: 1,
+        name: "锦江里",
+        // 电脑端的定位
+        top: "53%",
+        left: "25%",
+        right: "auto",
+        bottom: "auto",
+        // 电脑端鼠标移入的设置
+        hover: {
+          width: '25%',
+          height: '26%',
+          top: '45%',
+          left: '18.5%'
+        },
+        // 手机端的定位
+        topM: "10%",
+        leftM: "20%",
+        rightM: "auto",
+        bottomM: "auto",
+      },
+      {
+        id: 2,
+        name: "三门里三门里三",
+        // 电脑端的定位
+        top: "auto",
+        left: "auto",
+        right: "30%",
+        bottom: "20%",
+        // 电脑端鼠标移入的设置
+        hover: {
+          width: '10%',
+          height: '10%',
+          top: '10%',
+          left: '10%',
+        },
+        // 手机端的定位
+        topM: "10%",
+        leftM: "20%",
+        rightM: "auto",
+        bottomM: "auto",
+      },
+    ],
+    // 里面数据的标点
+    dianIn: [
+      {
+        id: 1,
+        top: "53%",
+        left: "25%",
+        right: "auto",
+        bottom: "auto",
+        name: '1983年',
+        txt: '2001年3月,开平市成立了开平碉楼申报世界文化遗产领导小组,市主要领导亲自挂帅,从各有关部门抽出精兵强将专职开展碉楼保护和申报工作。6月25日,开平碉楼被国务院批准列入第五批全国重点文物保护单位名单。',
+        // 历史事件的定位
+        txtLoc: {
+          top: "50px",
+          left: "80px",
+          right: "auto",
+          bottom: "auto",
+        }
+      }
+    ],
 
-    },
-    // 手机端
-    mobile: {
-      // 左下角的开发保护数据
-    }
+  },
 
-  }
-}
+  // 村落(注意这里的村落id要和上面的 总览 数据 的 dianOut 里面的 id 相同)
+  village: [
+    {
+      id: 1,
+      name:'锦江里',
+      // 村落介绍
+      infoTxt: '村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍村落介绍',
+      // 村落详情
+      info: [
+        {
+          id: 1.1,
+          
+        }
+      ]
+    }
+  ]
+};