shaogen1995 пре 2 година
родитељ
комит
5a2c95373b
95 измењених фајлова са 244 додато и 4956 уклоњено
  1. BIN
      后台/public/favicon.ico
  2. 0 27
      后台/src/App.tsx
  3. BIN
      后台/src/assets/img/IMGerror.png
  4. BIN
      后台/src/assets/img/bg.jpg
  5. BIN
      后台/src/assets/img/icon-1.png
  6. BIN
      后台/src/assets/img/icon-2.png
  7. BIN
      后台/src/assets/img/icon-3.png
  8. BIN
      后台/src/assets/img/icon-4.png
  9. BIN
      后台/src/assets/img/icon-5.png
  10. BIN
      后台/src/assets/img/icon-6.png
  11. BIN
      后台/src/assets/img/inco1.png
  12. BIN
      后台/src/assets/img/inco1Ac.png
  13. BIN
      后台/src/assets/img/inco2.png
  14. BIN
      后台/src/assets/img/inco2Ac.png
  15. BIN
      后台/src/assets/img/inco3.png
  16. BIN
      后台/src/assets/img/inco3Ac.png
  17. BIN
      后台/src/assets/img/inco4.png
  18. BIN
      后台/src/assets/img/inco4Ac.png
  19. BIN
      后台/src/assets/img/inco5.png
  20. BIN
      后台/src/assets/img/inco5Ac.png
  21. BIN
      后台/src/assets/img/loading.gif
  22. BIN
      后台/src/assets/img/loginBg.png
  23. BIN
      后台/src/assets/img/logo.png
  24. BIN
      后台/src/assets/img/logo2.png
  25. BIN
      后台/src/assets/img/top.jpg
  26. BIN
      后台/src/assets/img/user.png
  27. 1 1
      后台/src/assets/styles/base.css
  28. 1 1
      后台/src/assets/styles/base.less
  29. 0 37
      后台/src/components/ImageLazy/index.module.scss
  30. 0 93
      后台/src/components/ImageLazy/index.tsx
  31. 1 1
      后台/src/components/Message/index.tsx
  32. 1 1
      后台/src/components/UpAsyncLoding/index.tsx
  33. 0 52
      后台/src/components/VideoLook/index.module.scss
  34. 0 37
      后台/src/components/VideoLook/index.tsx
  35. 0 34
      后台/src/components/VideoLookDom/index.module.scss
  36. 0 36
      后台/src/components/VideoLookDom/index.tsx
  37. 1 1
      后台/src/index.tsx
  38. 0 116
      后台/src/pages/A1Hot/index.module.scss
  39. 0 314
      后台/src/pages/A1Hot/index.tsx
  40. 5 0
      后台/src/pages/A1Stat/index.module.scss
  41. 14 0
      后台/src/pages/A1Stat/index.tsx
  42. 5 0
      后台/src/pages/A2Gather/index.module.scss
  43. 14 0
      后台/src/pages/A2Gather/index.tsx
  44. 0 181
      后台/src/pages/A2News/NewsAdd/index.module.scss
  45. 0 530
      后台/src/pages/A2News/NewsAdd/index.tsx
  46. 0 49
      后台/src/pages/A2News/NewsTable/index.module.scss
  47. 0 245
      后台/src/pages/A2News/NewsTable/index.tsx
  48. 0 20
      后台/src/pages/A2News/index.module.scss
  49. 0 181
      后台/src/pages/A2News/index.tsx
  50. 5 0
      后台/src/pages/A3Book/index.module.scss
  51. 14 0
      后台/src/pages/A3Book/index.tsx
  52. 0 198
      后台/src/pages/A3Goods/GoodsAdd/index.module.scss
  53. 0 745
      后台/src/pages/A3Goods/GoodsAdd/index.tsx
  54. 0 43
      后台/src/pages/A3Goods/index.module.scss
  55. 0 311
      后台/src/pages/A3Goods/index.tsx
  56. 0 139
      后台/src/pages/A4Venue/VenueEdit/index.module.scss
  57. 0 317
      后台/src/pages/A4Venue/VenueEdit/index.tsx
  58. 0 49
      后台/src/pages/A4Venue/VenueTable/index.module.scss
  59. 0 203
      后台/src/pages/A4Venue/VenueTable/index.tsx
  60. 0 20
      后台/src/pages/A4Venue/index.module.scss
  61. 0 122
      后台/src/pages/A4Venue/index.tsx
  62. 5 0
      后台/src/pages/A4Visit/index.module.scss
  63. 14 0
      后台/src/pages/A4Visit/index.tsx
  64. 5 0
      后台/src/pages/A5Gallery/index.module.scss
  65. 14 0
      后台/src/pages/A5Gallery/index.tsx
  66. 0 34
      后台/src/pages/A5Guest/index.module.scss
  67. 0 183
      后台/src/pages/A5Guest/index.tsx
  68. 5 0
      后台/src/pages/A6Guide/index.module.scss
  69. 14 0
      后台/src/pages/A6Guide/index.tsx
  70. 5 0
      后台/src/pages/A7Hotspot/index.module.scss
  71. 14 0
      后台/src/pages/A7Hotspot/index.tsx
  72. 5 0
      后台/src/pages/A8User/index.module.scss
  73. 14 0
      后台/src/pages/A8User/index.tsx
  74. 35 49
      后台/src/pages/Layout/index.tsx
  75. 36 43
      后台/src/pages/Login/index.module.scss
  76. 7 4
      后台/src/pages/Login/index.tsx
  77. 0 31
      后台/src/store/action/A1Hot.ts
  78. 0 72
      后台/src/store/action/A2News.ts
  79. 0 71
      后台/src/store/action/A3Goods.ts
  80. 0 65
      后台/src/store/action/A4Venue.ts
  81. 0 22
      后台/src/store/action/A5Guest.ts
  82. 1 23
      后台/src/store/action/layout.ts
  83. 0 29
      后台/src/store/reducer/A2News.ts
  84. 0 30
      后台/src/store/reducer/A3Goods.ts
  85. 0 21
      后台/src/store/reducer/A4Venue.ts
  86. 5 13
      后台/src/store/reducer/index.ts
  87. 0 27
      后台/src/store/reducer/layout.ts
  88. 0 8
      后台/src/types/api/A1Hot.d.ts
  89. 0 41
      后台/src/types/api/A2News.d.ts
  90. 0 33
      后台/src/types/api/A3Goods.d.ts
  91. 0 22
      后台/src/types/api/A4Venue.d.ts
  92. 0 24
      后台/src/types/api/layot.d.ts
  93. 1 5
      后台/src/types/index.d.ts
  94. 1 1
      后台/src/utils/domShow.ts
  95. 1 1
      后台/src/utils/http.ts

BIN
后台/public/favicon.ico


+ 0 - 27
后台/src/App.tsx

@@ -6,21 +6,12 @@ import history from "./utils/history";
 import AuthRoute from "./components/AuthRoute";
 import SpinLoding from "./components/SpinLoding";
 import AsyncSpinLoding from "./components/AsyncSpinLoding";
-import { Image } from "antd";
-import { useSelector } from "react-redux";
-import store, { RootState } from "./store";
 import UpAsyncLoding from "./components/UpAsyncLoding";
-import VideoLookDom from "./components/VideoLookDom";
 import MessageCom from "./components/Message";
 const Layout = React.lazy(() => import("./pages/Layout"));
 const Login = React.lazy(() => import("./pages/Login"));
 
 export default function App() {
-  // 从仓库中获取查看图片的信息
-  const lookBigImg = useSelector(
-    (state: RootState) => state.layoutStore.lookBigImg
-  );
-
   return (
     <>
       {/* 关于路由 */}
@@ -37,27 +28,9 @@ export default function App() {
       {/* 发送请求的加载组件 */}
       <AsyncSpinLoding />
 
-      {/* 所有图片点击预览查看大图 */}
-      <Image
-        preview={{
-          visible: lookBigImg.show,
-          src: lookBigImg.url,
-          onVisibleChange: (value) => {
-            // 清除仓库信息
-            store.dispatch({
-              type: "layout/lookBigImg",
-              payload: { url: "", show: false },
-            });
-          },
-        }}
-      />
-
       {/* 上传附件的进度条元素 */}
       <UpAsyncLoding />
 
-      {/* 点击预览视频组件 */}
-      <VideoLookDom />
-
       {/* antd 轻提示 ---兼容360浏览器 */}
       <MessageCom />
     </>

BIN
后台/src/assets/img/IMGerror.png


BIN
后台/src/assets/img/bg.jpg


BIN
后台/src/assets/img/icon-1.png


BIN
后台/src/assets/img/icon-2.png


BIN
后台/src/assets/img/icon-3.png


BIN
后台/src/assets/img/icon-4.png


BIN
后台/src/assets/img/icon-5.png


BIN
后台/src/assets/img/icon-6.png


BIN
后台/src/assets/img/inco1.png


BIN
后台/src/assets/img/inco1Ac.png


BIN
后台/src/assets/img/inco2.png


BIN
后台/src/assets/img/inco2Ac.png


BIN
后台/src/assets/img/inco3.png


BIN
后台/src/assets/img/inco3Ac.png


BIN
后台/src/assets/img/inco4.png


BIN
后台/src/assets/img/inco4Ac.png


BIN
后台/src/assets/img/inco5.png


BIN
后台/src/assets/img/inco5Ac.png


BIN
后台/src/assets/img/loading.gif


BIN
后台/src/assets/img/loginBg.png


BIN
后台/src/assets/img/logo.png


BIN
后台/src/assets/img/logo2.png


BIN
后台/src/assets/img/top.jpg


BIN
后台/src/assets/img/user.png


+ 1 - 1
后台/src/assets/styles/base.css

@@ -40,7 +40,7 @@ textarea {
 }
 /* 主题色 */
 :root {
-  --themeColor: #9d6b39;
+  --themeColor: #00A0E6;
 }
 /* 找不到页面 */
 .noFindPage {

+ 1 - 1
后台/src/assets/styles/base.less

@@ -49,7 +49,7 @@ textarea {
 
 /* 主题色 */
 :root {
-  --themeColor: #9d6b39;
+  --themeColor: #00A0E6;
 }
 
 

+ 0 - 37
后台/src/components/ImageLazy/index.module.scss

@@ -1,37 +0,0 @@
-.ImageLazy{
-  position: relative;
-  :global{
-    .lazyBox{
-      width: 100%;
-      height: 100%;
-      position: relative;
-      .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;
-        }
-      }
-    }
-  }
-
-}

+ 0 - 93
后台/src/components/ImageLazy/index.tsx

@@ -1,93 +0,0 @@
-import React, { useCallback, useEffect, useState } from "react";
-import styles from "./index.module.scss";
-import Lazyimg from "react-lazyimg-component";
-import { baseURL } from "@/utils/http";
-import imgLoding from "@/assets/img/loading.gif";
-import imgErr from "@/assets/img/IMGerror.png";
-import { EyeOutlined } from "@ant-design/icons";
-import store from "@/store";
-
-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) {
-  // 图片占位符
-  const [placeholderUrl, setPlaceholderUrl] = useState(
-    src ? imgLoding : imgErr
-  );
-
-  // 默认不能预览图片,加载成功之后能预览
-  const [lookImg, setLookImg] = useState(false);
-
-  useEffect(() => {
-    if (src) {
-      // 进页面查看图片的加载情况
-      // 创建一个img标签
-      const imgDom = document.createElement("img");
-      imgDom.src = offline ? src : baseURL + src;
-
-      // 不管图片加载成功或者失败,都删除掉,提高性能
-      // 图片加载成功
-      imgDom.onload = function () {
-        setLookImg(true);
-        imgDom.remove();
-      };
-      // 图片加载失败
-      imgDom.onerror = function () {
-        setPlaceholderUrl(imgErr);
-        imgDom.remove();
-      };
-
-      return () => {
-        // 离开页面也删掉掉元素
-        imgDom.remove();
-      };
-    }
-  }, [offline, src]);
-
-  // 点击预览图片
-  const lookBigImg = useCallback(() => {
-    store.dispatch({
-      type: "layout/lookBigImg",
-      payload: { url: offline ? src : baseURL + src, show: true },
-    });
-  }, [offline, src]);
-
-  return (
-    <div className={styles.ImageLazy} style={{ width: width, height: height }}>
-      <div className="lazyBox">
-        <Lazyimg
-          src={src ? (offline ? src : baseURL + src) : ""}
-          width={width}
-          height={height}
-          placeholder={placeholderUrl}
-          alt=""
-        />
-
-        {/* 图片预览 */}
-        {noLook || !lookImg ? null : (
-          <div className="lookImg" onClick={lookBigImg}>
-            <EyeOutlined />
-            &nbsp;
-            <div>预览</div>
-          </div>
-        )}
-      </div>
-    </div>
-  );
-}
-
-const MemoImageLazy = React.memo(ImageLazy);
-
-export default MemoImageLazy;

+ 1 - 1
后台/src/components/Message/index.tsx

@@ -6,7 +6,7 @@ import { RootState } from "@/store";
 function MessageCom() {
   // 从仓库中获取 antd 轻提示信息
   const messageReducerInfo = useSelector(
-    (state: RootState) => state.layoutStore.message
+    (state: RootState) => state.A0layout.message
   );
 
   const [messageApi, contextHolder] = message.useMessage();

+ 1 - 1
后台/src/components/UpAsyncLoding/index.tsx

@@ -6,7 +6,7 @@ import styles from "./index.module.scss";
 function UpAsyncLoding() {
   // 从仓库中获取取消上传的函数
   const closeUpFile = useSelector(
-    (state: RootState) => state.layoutStore.closeUpFile
+    (state: RootState) => state.A0layout.closeUpFile
   );
 
   const btnClose = useCallback(() => {

+ 0 - 52
后台/src/components/VideoLook/index.module.scss

@@ -1,52 +0,0 @@
-.VideoLook {
-  :global {
-    .videoLookBox {
-      cursor: pointer;
-      width: 100%;
-      height: 100%;
-      display: flex;
-      justify-content: center;
-      align-items: center;
-
-      .videoCover {
-        width: 100%;
-        height: 100%;
-        position: relative;
-
-        video {
-          width: 100%;
-          height: 100%;
-        }
-
-        .videoInco {
-          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 {
-          .videoInco {
-            opacity: 1;
-            pointer-events: auto;
-          }
-        }
-      }
-    }
-  }
-}

+ 0 - 37
后台/src/components/VideoLook/index.tsx

@@ -1,37 +0,0 @@
-import React from "react";
-import { PlayCircleOutlined } from "@ant-design/icons";
-import styles from "./index.module.scss";
-import { baseURL } from "@/utils/http";
-import store from "@/store";
-
-type Props = {
-  width?: number;
-  height?: number;
-  src: string;
-};
-
-function VideoLook({ src, width = 100, height = 100 }: Props) {
-  return (
-    <div className={styles.VideoLook} style={{ width, height }}>
-      <div
-        className="videoLookBox"
-        onClick={() =>
-          store.dispatch({ type: "layout/lookVideo", payload: src })
-        }
-      >
-        <div className="videoCover">
-          <video src={baseURL + src}></video>
-          <div className="videoInco">
-            <PlayCircleOutlined />
-            &nbsp;
-            <div>预览</div>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
-
-const MemoVideoLook = React.memo(VideoLook);
-
-export default MemoVideoLook;

+ 0 - 34
后台/src/components/VideoLookDom/index.module.scss

@@ -1,34 +0,0 @@
-.VideoLookDom{
-  transition: opacity .3s;
-  position: fixed;
-  z-index: 9991;
-  opacity: 0;
-  pointer-events: none;
-  top: 0;
-  left: 0;
-  width: 100vw;
-  height: 100vh;
-  background-color: rgba(0,0,0,.6);
-  :global{
-    .close{
-      color: #fff;
-      position: absolute;
-      right: 70px;
-      top: 70px;
-      font-size: 30px;
-      cursor: pointer;
-    }
-    .viedoBox{
-      position: absolute;
-      top: 50%;
-      left: 50%;
-      transform: translate(-50%,-50%);
-      width: 800px;
-      height: 500px;
-      video{
-        width: 100%;
-        height: 100%;
-      }
-    }
-  }
-}

+ 0 - 36
后台/src/components/VideoLookDom/index.tsx

@@ -1,36 +0,0 @@
-import React from "react";
-import { CloseCircleOutlined } from "@ant-design/icons";
-import styles from "./index.module.scss";
-import { useSelector } from "react-redux";
-import store, { RootState } from "@/store";
-import { baseURL } from "@/utils/http";
-function VideoLookDom() {
-  const videoSrc = useSelector(
-    (state: RootState) => state.layoutStore.videoSrc
-  );
-  return (
-    <div
-      className={styles.VideoLookDom}
-      style={videoSrc ? { opacity: 1, pointerEvents: "auto" } : {}}
-    >
-      <div className="viedoBox">
-        {videoSrc ? (
-          <video autoPlay controls src={baseURL + videoSrc}></video>
-        ) : null}
-      </div>
-
-      <div
-        className="close"
-        onClick={() =>
-          store.dispatch({ type: "layout/lookVideo", payload: "" })
-        }
-      >
-        <CloseCircleOutlined />
-      </div>
-    </div>
-  );
-}
-
-const MemoVideoLookDom = React.memo(VideoLookDom);
-
-export default MemoVideoLookDom;

+ 1 - 1
后台/src/index.tsx

@@ -25,7 +25,7 @@ root.render(
     locale={locale}
     theme={{
       token: {
-        colorPrimary: "#9d6b39",
+        colorPrimary: "#00A0E6",
       },
     }}
   >

+ 0 - 116
后台/src/pages/A1Hot/index.module.scss

@@ -1,116 +0,0 @@
-.Hot {
-
-  :global {
-
-    .hotTopBox {
-      background-color: #fff;
-      border-radius: 10px;
-      height: 50px;
-      position: relative;
-
-      .hotTopTime {
-        position: absolute;
-        left: 180px;
-        top: 0;
-        padding: 10px 20px;
-        height: 50px;
-        display: flex;
-        align-items: center;
-      }
-    }
-
-    .hotMainBox {
-      width: 100%;
-      height: calc(100% - 70px);
-
-      .noneInfo {
-        width: 100%;
-        height: calc(100% - 32px);
-        display: flex;
-        justify-content: center;
-        align-items: center;
-      }
-
-
-      .hotMain {
-        margin-top: 20px;
-        width: 100%;
-        height: 100%;
-        display: flex;
-
-        .hotBoxTit {
-          font-size: 18px;
-          position: relative;
-
-          .hotBoxTitRight {
-            position: absolute;
-            right: 20px;
-            top: 50%;
-            transform: translateY(-50%);
-          }
-
-
-        }
-
-        &>div {
-          padding: 10px 20px;
-          height: 100%;
-          border-radius: 10px;
-          background-color: #fff;
-        }
-
-        .hotBox1 {
-          width: 300px;
-          position: relative;
-
-          #echarts1 {
-            width: 100%;
-            height: calc(100% - 30px);
-          }
-        }
-
-        .hotBox2 {
-          width: calc(50% - 160px);
-          margin: 0 10px;
-          padding: 10px 0 10px 20px;
-        }
-
-        .hotBox3 {
-          width: calc(50% - 160px);
-          padding: 10px 0 10px 20px;
-        }
-
-
-        .hotListBox {
-          width: 100%;
-          height: calc(100% - 50px);
-          margin-top: 20px;
-          overflow-y: auto;
-          overflow-y: overlay;
-
-          .row {
-            width: calc(100% - 20px);
-
-            height: 60px;
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            padding: 0 30px 0 15px;
-            border-radius: 5px;
-            border: 1px solid #dddddd;
-            margin-bottom: 15px;
-
-            .rowLeft {
-              width: calc(100% - 100px);
-              overflow: hidden;
-              text-overflow: ellipsis;
-              white-space: nowrap;
-            }
-          }
-        }
-
-      }
-    }
-
-  }
-}

+ 0 - 314
后台/src/pages/A1Hot/index.tsx

@@ -1,314 +0,0 @@
-import { Empty, Select } from "antd";
-import React, { useCallback, useEffect, useRef, useState } from "react";
-import styles from "./index.module.scss";
-
-import * as echarts from "echarts/core";
-import {
-  ToolboxComponent,
-  LegendComponent,
-  TooltipComponent,
-} from "echarts/components";
-import { PieChart } from "echarts/charts";
-import { LabelLayout } from "echarts/features";
-import { CanvasRenderer } from "echarts/renderers";
-import {
-  getHotExhibitionAPI,
-  getHotGoodsAPI,
-  getHotModuleAPI,
-} from "@/store/action/A1Hot";
-import { HotData1Type, HotSelectTimeType, HotSelectType } from "@/types";
-
-echarts.use([
-  ToolboxComponent,
-  TooltipComponent,
-  LegendComponent,
-  PieChart,
-  CanvasRenderer,
-  LabelLayout,
-]);
-
-function Hot() {
-  // 日期下拉框
-  const [select1, setSelect1] = useState<HotSelectTimeType>(7);
-  const select1Ref = useRef<HotSelectTimeType>(7);
-
-  // 热门场馆下拉
-  const [select2, setSelect2] = useState<HotSelectType>("visit");
-  const select2Ref = useRef<HotSelectType>("");
-
-  // 热门馆藏下拉
-  const [select3, setSelect3] = useState<HotSelectType>("visit");
-  const select3Ref = useRef<HotSelectType>("");
-
-  // 获取饼图的函数
-  const getEchartsFu = useCallback(
-    (
-      data: {
-        value: number;
-        name: string;
-      }[]
-    ) => {
-      const chartDom = document.getElementById("echarts1")!;
-      const myChart = echarts.init(chartDom);
-      const option = {
-        tooltip: {
-          trigger: "item",
-        },
-        legend: {
-          orient: "vertical",
-          left: "center",
-          bottom: "12%",
-          data,
-          // 设置间距
-          itemGap: 20,
-          formatter: (name: string) => {
-            let resName = "";
-            data.forEach((v) => {
-              if (name === v.name) {
-                if (name.length > 8)
-                  resName = name.slice(0, 8) + "... " + v.value;
-                else resName = name + " " + v.value;
-              }
-            });
-
-            return resName;
-          },
-        },
-        series: [
-          {
-            name: "",
-            type: "pie",
-            radius: [60, 100],
-            center: ["50%", "30%"],
-            // 设置圆角
-            itemStyle: {
-              borderRadius: 6,
-              borderColor: "#fff",
-              borderWidth: 1,
-            },
-            label: {
-              show: false,
-              position: "center",
-            },
-            emphasis: {
-              label: {
-                show: false,
-              },
-            },
-            labelLine: {
-              show: false,
-            },
-
-            data,
-          },
-        ],
-      };
-      option && myChart.setOption(option);
-    },
-    []
-  );
-
-  // 时间改变的时候 获取3个数据
-  const getInfoAPIFu1 = useCallback(async () => {
-    const res1 = await getHotModuleAPI(select1Ref.current);
-    const data1 = res1.data.map((v: HotData1Type) => {
-      return {
-        value: v.pcs,
-        name: v.groupKey,
-        icon: "circle",
-      };
-    });
-    // console.log("1获取饼图数据", select1Ref.current);
-    getEchartsFu(data1);
-
-    // -------------
-    // console.log(
-    //   "2获取场馆数据",
-    //   select1Ref.current,
-    //   select2Ref.current ? select2Ref.current : "visit"
-    // );
-
-    const res2 = await getHotExhibitionAPI(
-      select1Ref.current,
-      select2Ref.current ? select2Ref.current : "visit"
-    );
-    const data2: HotData1Type[] = res2.data;
-
-    setList1(data2);
-
-    // ---------------
-
-    // console.log(
-    //   "3获取馆藏数据",
-    //   select1Ref.current,
-    //   select3Ref.current ? select3Ref.current : "visit"
-    // );
-
-    const res3 = await getHotGoodsAPI(
-      select1Ref.current,
-      select3Ref.current ? select3Ref.current : "visit"
-    );
-    const data3: HotData1Type[] = res3.data;
-
-    setList2(data3);
-
-    // 每次变化馆藏盒子滚动到顶部
-    const dom: HTMLDivElement = document.querySelector("#goodsSroolBox")!;
-    if (dom) dom.scrollTop = 0;
-  }, [getEchartsFu]);
-
-  // 获取热门场馆数据
-  const [list1, setList1] = useState<HotData1Type[]>([]);
-
-  const getInfoAPIFu2 = useCallback(async () => {
-    // console.log("2获取场馆数据", select1Ref.current, select2Ref.current);
-    const res = await getHotExhibitionAPI(
-      select1Ref.current,
-      select2Ref.current ? select2Ref.current : "visit"
-    );
-    const data: HotData1Type[] = res.data;
-
-    setList1(data);
-  }, []);
-
-  // 获取馆藏数据
-
-  const [list2, setList2] = useState<HotData1Type[]>([]);
-
-  const getInfoAPIFu3 = useCallback(async () => {
-    // console.log("3获取馆藏数据", select1Ref.current, select3Ref.current);
-    const res = await getHotGoodsAPI(
-      select1Ref.current,
-      select3Ref.current ? select3Ref.current : "visit"
-    );
-    const data: HotData1Type[] = res.data;
-
-    setList2(data);
-  }, []);
-
-  // 改变时间选择发送3个请求
-  useEffect(() => {
-    select1Ref.current = select1;
-    getInfoAPIFu1();
-  }, [getInfoAPIFu1, select1]);
-
-  // 热门场馆改变
-  useEffect(() => {
-    // 第一次的时候不发送请求
-    if (!select2Ref.current) select2Ref.current = select2;
-    else {
-      select2Ref.current = select2;
-      getInfoAPIFu2();
-    }
-  }, [getInfoAPIFu2, select2]);
-
-  // 热门馆藏的改变
-  useEffect(() => {
-    // 第一次的时候不发送请求
-    if (!select3Ref.current) select3Ref.current = select3;
-    else {
-      select3Ref.current = select3;
-      getInfoAPIFu3();
-    }
-    // 每次变化滚动到顶部
-    const dom: HTMLDivElement = document.querySelector("#goodsSroolBox")!;
-    if (dom) dom.scrollTop = 0;
-  }, [getInfoAPIFu3, select3]);
-
-  return (
-    <div className={styles.Hot}>
-      <div className="hotTopBox">
-        <div className="pageTitle">热度统计</div>
-        <div className="hotTopTime">
-          <Select
-            value={select1}
-            style={{ width: 100 }}
-            onChange={(e) => setSelect1(e)}
-            options={[
-              { value: 1, label: "今日" },
-              { value: 7, label: "近七天" },
-              { value: 30, label: "近三十天" },
-              { value: "", label: "全部" },
-            ]}
-          />
-        </div>
-      </div>
-
-      <div className="hotMainBox">
-        <div className="hotMain">
-          <div className="hotBox1">
-            <div className="hotBoxTit">热门板块</div>
-            {/* 第一个echarts盒子 */}
-            <div id="echarts1"></div>
-          </div>
-          <div className="hotBox2">
-            <div className="hotBoxTit">
-              热门场馆
-              <div className="hotBoxTitRight">
-                <Select
-                  value={select2}
-                  style={{ width: 100 }}
-                  onChange={(e) => setSelect2(e)}
-                  options={[
-                    { value: "visit", label: "按浏览" },
-                    { value: "star", label: "按点赞" },
-                  ]}
-                />
-              </div>
-            </div>
-            {/* 场馆数据 */}
-            <div className="hotListBox mySorrl">
-              {list1.map((v) => (
-                <div className="row" key={v.groupKey}>
-                  <div className="rowLeft" title={v.groupKey}>
-                    {v.groupKey}
-                  </div>
-                  <div className="rowRight">{v.pcs}</div>
-                </div>
-              ))}
-            </div>
-          </div>
-          <div className="hotBox3">
-            <div className="hotBoxTit">
-              热门馆藏
-              <div className="hotBoxTitRight">
-                <Select
-                  value={select3}
-                  style={{ width: 100 }}
-                  onChange={(e) => setSelect3(e)}
-                  options={[
-                    { value: "visit", label: "按浏览" },
-                    { value: "star", label: "按点赞" },
-                  ]}
-                />
-              </div>
-            </div>
-            {/* 馆藏数据 */}
-            <div className="hotListBox mySorrl" id="goodsSroolBox">
-              {list2.length ? (
-                list2.slice(0, 10).map((v) => (
-                  <div className="row" key={v.groupKey}>
-                    <div className="rowLeft" title={v.groupKey}>
-                      {v.groupKey}
-                    </div>
-                    <div className="rowRight">{v.pcs}</div>
-                  </div>
-                ))
-              ) : (
-                <div className="noneInfo">
-                  <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
-                </div>
-              )}
-
-              {}
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
-
-const MemoHot = React.memo(Hot);
-
-export default MemoHot;

+ 5 - 0
后台/src/pages/A1Stat/index.module.scss

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

+ 14 - 0
后台/src/pages/A1Stat/index.tsx

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

+ 5 - 0
后台/src/pages/A2Gather/index.module.scss

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

+ 14 - 0
后台/src/pages/A2Gather/index.tsx

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

+ 0 - 181
后台/src/pages/A2News/NewsAdd/index.module.scss

@@ -1,181 +0,0 @@
-.NewsAdd {
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  background-color: #fff;
-  border-radius: 10px;
-  z-index: 20;
-
-  :global {
-    .formBox {
-      width: 1200px;
-      margin-top: 15px;
-      height: calc(100% - 75px);
-      padding-right: 400px;
-      overflow-y: auto;
-
-
-      // 多张附件图片上传
-
-
-      .myformBox {
-        display: flex;
-        margin-bottom: 10px;
-        margin-top: 40px;
-
-        .ant-btn-default {
-          width: 100px;
-        }
-
-        .label {
-          width: 100px;
-          text-align: right;
-
-          &>span {
-            position: relative;
-            top: 2px;
-            color: #ff4d4f;
-          }
-        }
-
-        .fileBoxRow_r {
-          position: relative;
-
-          .fileBoxRow_up {
-            color: #a6a6a6;
-            border-radius: 3px;
-            cursor: pointer;
-            font-size: 30px;
-            width: 100px;
-            height: 100px;
-            border: 1px dashed #797979;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-
-
-          }
-
-          .fileBoxRow_r_img {
-            width: 100px;
-            height: 100px;
-            position: relative;
-
-            .clearCover {
-              cursor: pointer;
-              z-index: 10;
-              position: absolute;
-              width: 50px;
-              height: 50px;
-              top: 50%;
-              transform: translateY(-50%);
-              right: -50px;
-              display: flex;
-              justify-content: center;
-              align-items: center;
-              font-size: 24px;
-            }
-          }
-
-          .fileBoxRow_r_tit {
-            height: 46px;
-            margin-top: 5px;
-            font-size: 14px;
-            color: rgb(126, 124, 124);
-
-
-          }
-
-          .upImgBox {
-            display: flex;
-            flex-wrap: wrap;
-            max-width: 700px;
-
-            &>div {
-              margin: 0 15px 15px 0;
-            }
-
-            .fileBoxRow_r_img {
-              position: relative;
-
-              .clearCover {
-                right: -10px;
-                top: -10px;
-                transform: translate(0, 0);
-                background-color: rgba(0, 0, 0, .8);
-                width: 20px;
-                height: 20px;
-                border-radius: 50%;
-                font-size: 16px;
-                color: #fff;
-              }
-            }
-          }
-
-        }
-
-      }
-
-      // 视频和单个图片上传
-      .myformBox2 {
-        align-items: center;
-        height: 32px;
-
-        .label {
-          height: 32px;
-          line-height: 32px;
-        }
-
-        .fileTit {
-          margin-left: 20px;
-          font-size: 14px;
-          color: rgb(126, 124, 124);
-        }
-
-        .fileInfo {
-          height: 32px;
-          line-height: 32px;
-          display: flex;
-          font-size: 16px;
-
-          .clearCover {
-            margin-left: 20px;
-            cursor: pointer;
-            font-size: 18px;
-          }
-
-        }
-
-
-      }
-
-      .myformBox3{
-        margin-bottom: -20px;
-      }
-
-    }
-
-    .noUpThumb {
-      position: relative;
-      overflow: hidden;
-      opacity: 0;
-      transition: top .2s;
-      color: #ff4d4f;
-      top: -10px;
-    }
-
-    .noUpThumb2 {
-      position: relative;
-      padding-left: 100px;
-      margin-bottom: 12px;
-    }
-
-    .noUpThumbAc {
-      top: 0;
-      opacity: 1;
-    }
-
-  }
-}

+ 0 - 530
后台/src/pages/A2News/NewsAdd/index.tsx

@@ -1,530 +0,0 @@
-import {
-  getNewsDetailAPI,
-  newSaveAPI,
-  newsUploadAPI,
-} from "@/store/action/A2News";
-import { fileDomInitialFu } from "@/utils/domShow";
-import { MessageFu } from "@/utils/message";
-import {
-  Button,
-  DatePicker,
-  Form,
-  FormInstance,
-  Input,
-  Popconfirm,
-  Select,
-} from "antd";
-import TextArea from "antd/es/input/TextArea";
-import dayjs from "dayjs";
-import React, {
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
-import styles from "./index.module.scss";
-import {
-  PlusOutlined,
-  CloseOutlined,
-  PlayCircleOutlined,
-  CloseCircleOutlined,
-  UploadOutlined,
-} from "@ant-design/icons";
-import ImageLazy from "@/components/ImageLazy";
-import classNames from "classnames";
-import store from "@/store";
-import { ImgListType, NewsSaveApiType } from "@/types";
-
-type Props = {
-  id: number;
-  tableType: "news" | "video" | "img";
-  closePageFu: () => void;
-  editTableFu: () => void;
-  addTableFu: () => void;
-};
-
-function NewsAdd({
-  id,
-  closePageFu,
-  editTableFu,
-  addTableFu,
-  tableType,
-}: Props) {
-  // 设置表单初始数据(区分编辑和新增)
-  const FormBoxRef = useRef<FormInstance>(null);
-
-  // 通过id获取详情,回显数据
-  const getInfoFu = useCallback(
-    async (id: number) => {
-      const res = await getNewsDetailAPI(id);
-      const data = res.data.entity;
-      const fileList = res.data.file;
-      setDirCode(data.dirCode);
-
-      FormBoxRef.current?.setFieldsValue({
-        ...data,
-        newsDay: dayjs(data.newsDay, "YYYY-MM-DD"),
-      });
-      if (tableType === "news") setImgList(fileList);
-      else setFileOne(fileList[0]);
-    },
-    [tableType]
-  );
-
-  useEffect(() => {
-    if (id > 0) getInfoFu(id);
-    else {
-      setDirCode(Date.now() + "");
-      FormBoxRef.current?.setFieldsValue({
-        display: 1,
-        // 默认新闻日期为当天
-        newsDay:
-          tableType === "news"
-            ? dayjs(dayjs(new Date()).format("YYYY-MM-DD"), "YYYY-MM-DD")
-            : "",
-      });
-    }
-  }, [getInfoFu, id, tableType]);
-
-  const myInput = useRef<HTMLInputElement>(null);
-
-  // 文件的dirCode码
-  const [dirCode, setDirCode] = useState("");
-
-  // 多张图片附件
-  const [imgList, setImgList] = useState<ImgListType[]>([]);
-
-  // 单个视频或者图片上传
-  const [fileOne, setFileOne] = useState<ImgListType>({
-    fileName: "",
-    filePath: "",
-    id: 0,
-  });
-
-  // 上传附件的处理函数
-  const handeUpPhoto = useCallback(
-    async (e: React.ChangeEvent<HTMLInputElement>) => {
-      if (e.target.files) {
-        // 拿到files信息
-        const filesInfo = e.target.files[0];
-
-        let anType = ["image/jpeg", "image/png"];
-        let anTit1 = "只支持png、jpg和jpeg格式!";
-        let anTit2 = "最大支持20M!";
-        let anSize = 20 * 1024 * 1024;
-
-        if (tableType === "video") {
-          anType = ["video/mp4"];
-          anTit1 = "只支持mp4格式!";
-          anTit2 = "最大支持500M!";
-          anSize = 500 * 1024 * 1024;
-        }
-
-        // 校验格式
-        if (!anType.includes(filesInfo.type)) {
-          e.target.value = "";
-          return MessageFu.warning(anTit1);
-        }
-
-        // 校验大小
-        if (filesInfo.size > anSize) {
-          e.target.value = "";
-          return MessageFu.warning(anTit2);
-        }
-        // 创建FormData对象
-        const fd = new FormData();
-        // 把files添加进FormData对象(‘photo’为后端需要的字段)
-        fd.append(
-          "type",
-          tableType === "video"
-            ? "video"
-            : tableType === "img"
-            ? "thumb"
-            : "img"
-        );
-        fd.append("dirCode", dirCode);
-        fd.append("file", filesInfo);
-
-        e.target.value = "";
-
-        try {
-          const res = await newsUploadAPI(fd);
-
-          if (res.code === 0) {
-            MessageFu.success("上传成功!");
-            if (tableType === "news") setImgList([...imgList, res.data]);
-            else setFileOne(res.data);
-          }
-          fileDomInitialFu();
-        } catch (error) {
-          fileDomInitialFu();
-        }
-      }
-    },
-    [dirCode, imgList, tableType]
-  );
-
-  // 附件图片的拖动
-  const [dragImg, setDragImg] = useState<any>(null);
-
-  const handleDragEnter = useCallback(
-    (e: React.DragEvent<HTMLDivElement>, item: ImgListType) => {
-      e.dataTransfer.effectAllowed = "move";
-      if (item === dragImg) return;
-      const newItems = [...imgList]; //拷贝一份数据进行交换操作。
-      const src = newItems.indexOf(dragImg); //获取数组下标
-      const dst = newItems.indexOf(item);
-      newItems.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
-      setImgList(newItems);
-    },
-    [dragImg, imgList]
-  );
-
-  // 删除某一张图片
-  const delImgListFu = useCallback(
-    (id: number) => {
-      const newItems = imgList.filter((v) => v.id !== id);
-      setImgList(newItems);
-    },
-    [imgList]
-  );
-
-  const [typeOk, setTypeOk] = useState(false);
-
-  // 附件信息的校验
-  const fileCheckFu = useMemo(() => {
-    let flag = false;
-    if (tableType !== "news" && !fileOne.filePath) flag = true;
-    if (tableType === "news") flag = false;
-    return flag;
-  }, [fileOne.filePath, tableType]);
-
-  // 没有通过校验
-  const onFinishFailed = useCallback(() => {
-    setTypeOk(true);
-    // return MessageFu.warning("有表单不符号规则!");
-  }, []);
-
-  // 通过校验点击确定
-  const onFinish = useCallback(
-    async (values: NewsSaveApiType) => {
-      setTypeOk(true);
-
-      if (fileCheckFu) return;
-
-      let thumb = "";
-      if (tableType === "news") thumb = imgList[0] ? imgList[0].filePath : "";
-      else thumb = fileOne.filePath;
-      const obj = {
-        ...values,
-        id: id > 0 ? id : null,
-        dirCode,
-        newsDay: values.newsDay
-          ? dayjs(values.newsDay).format("YYYY-MM-DD")
-          : "",
-        thumb,
-        fileIds:
-          tableType === "news"
-            ? imgList.map((v) => v.id).join(",")
-            : fileOne.id + "",
-        type: tableType,
-      };
-      const res = await newSaveAPI(obj);
-      if (res.code === 0) {
-        if (id > 0) editTableFu();
-        else addTableFu();
-        MessageFu.success(id > 0 ? "编辑成功!" : "新增成功!");
-        closePageFu();
-      }
-    },
-    [
-      addTableFu,
-      closePageFu,
-      dirCode,
-      editTableFu,
-      fileCheckFu,
-      fileOne,
-      id,
-      imgList,
-      tableType,
-    ]
-  );
-
-  return (
-    <div className={styles.NewsAdd}>
-      <div className="pageTitle">{id > 0 ? "编辑资讯" : "新增资讯"}</div>
-      <div className="formBox mySorrl">
-        <Form
-          ref={FormBoxRef}
-          name="basic"
-          labelCol={{ span: 3 }}
-          onFinish={onFinish}
-          onFinishFailed={onFinishFailed}
-          autoComplete="off"
-        >
-          <Form.Item
-            label="标题"
-            name="name"
-            rules={[{ required: true, message: "请输入标题!" }]}
-            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
-          >
-            <Input maxLength={20} showCount placeholder="请输入内容" />
-          </Form.Item>
-
-          <input
-            id="upInput2"
-            type="file"
-            accept={tableType === "video" ? ".mp4" : ".png,.jpg,.jpeg"}
-            ref={myInput}
-            onChange={(e) => handeUpPhoto(e)}
-          />
-
-          {tableType === "news" ? (
-            <>
-              <Form.Item
-                label="新闻日期"
-                name="newsDay"
-                rules={[{ required: true, message: "请选择新闻日期!" }]}
-              >
-                <DatePicker />
-              </Form.Item>
-              <Form.Item
-                label="正文"
-                name="description"
-                rules={[
-                  { required: true, message: "请输入正文!" },
-                  {
-                    validator: (rule, value) => {
-                      if (value) {
-                        const txt = value
-                          .replaceAll(" ", "")
-                          .replaceAll("\n", "");
-                        return txt === ""
-                          ? Promise.reject("请输入有效字符!")
-                          : Promise.resolve();
-                      } else return Promise.resolve();
-                    },
-                  },
-                ]}
-                // getValueFromEvent={(e) => e.target.value.trim()}
-              >
-                <TextArea
-                  rows={8}
-                  placeholder="请输入内容"
-                  showCount
-                  maxLength={1000}
-                />
-              </Form.Item>
-
-              {/* 上传附件图片 */}
-              <div className="myformBox">
-                <div className="label">图片:</div>
-                <>
-                  <div className="fileBoxRow_r">
-                    <div className="upImgBox">
-                      <div
-                        hidden={imgList.length >= 9}
-                        className="fileBoxRow_up"
-                        onClick={() => myInput.current?.click()}
-                      >
-                        <PlusOutlined />
-                      </div>
-                      {imgList.map((v, i) => (
-                        <div
-                          className="fileBoxRow_r_img"
-                          key={v.id}
-                          draggable="true"
-                          onDragStart={() => setDragImg(v)}
-                          onDragOver={(e) => {
-                            e.preventDefault();
-                            e.dataTransfer.dropEffect = "move";
-                          }}
-                          onDragEnter={(e) => handleDragEnter(e, v)}
-                          onDragEnd={() => setDragImg(null)}
-                        >
-                          {i === 0 ? (
-                            <div className="myCoverBox">封面</div>
-                          ) : null}
-                          {v.filePath ? (
-                            <ImageLazy
-                              noLook={dragImg ? true : false}
-                              width={100}
-                              height={100}
-                              src={v.filePath}
-                            />
-                          ) : null}
-
-                          <Popconfirm
-                            title="删除后无法恢复,是否删除?"
-                            okText="删除"
-                            cancelText="取消"
-                            onConfirm={() => delImgListFu(v.id)}
-                          >
-                            <div className="clearCover">
-                              <CloseOutlined />
-                            </div>
-                          </Popconfirm>
-                        </div>
-                      ))}
-                    </div>
-                    <div className="fileTit">
-                      {imgList.length >= 2 ? (
-                        <>
-                          按住鼠标可拖动图片调整顺序,第一张为展示端封面。
-                          <br />
-                        </>
-                      ) : null}
-                      支持png、jpg和jpeg的图片格式;最大支持20M;最多支持9张。
-                    </div>
-                  </div>
-                </>
-              </div>
-            </>
-          ) : tableType === "video" ? (
-            // 上传视频
-            <>
-              {/* -----------视频上传 */}
-              <div className="myformBox myformBox2">
-                <div className="label">
-                  <span>*</span> 视频:
-                </div>
-                {fileOne.id ? (
-                  <div className="fileInfo">
-                    <div className="upSuccTxt">{fileOne.fileName}</div>
-                    <div
-                      className="clearCover"
-                      hidden={!fileOne.filePath}
-                      onClick={() =>
-                        store.dispatch({
-                          type: "layout/lookVideo",
-                          payload: fileOne.filePath!,
-                        })
-                      }
-                    >
-                      <PlayCircleOutlined />
-                    </div>
-
-                    <Popconfirm
-                      title="删除后无法恢复,是否删除?"
-                      okText="删除"
-                      cancelText="取消"
-                      onConfirm={() =>
-                        setFileOne({ fileName: "", filePath: "", id: 0 })
-                      }
-                    >
-                      <div className="clearCover">
-                        <CloseCircleOutlined />
-                      </div>
-                    </Popconfirm>
-                  </div>
-                ) : (
-                  <>
-                    <Button
-                      onClick={() => myInput.current?.click()}
-                      icon={<UploadOutlined />}
-                    >
-                      上传
-                    </Button>
-
-                    <div className="fileTit">
-                      仅支持MP4格式的视频文件,大小不得超过500MB。
-                    </div>
-                  </>
-                )}
-              </div>
-            </>
-          ) : (
-            <>
-              {/* 上传单张图片 */}
-              <div className="myformBox myformBox3">
-                <div className="label">
-                  <span>*</span> 图片:
-                </div>
-                <div className="fileBoxRow_r">
-                  <div
-                    hidden={!!fileOne.filePath}
-                    className="fileBoxRow_up"
-                    onClick={() => myInput.current?.click()}
-                  >
-                    <PlusOutlined />
-                  </div>
-                  <div className="fileBoxRow_r_img" hidden={!fileOne.filePath}>
-                    {fileOne.filePath ? (
-                      <ImageLazy
-                        width={100}
-                        height={100}
-                        src={fileOne.filePath}
-                      />
-                    ) : null}
-
-                    <Popconfirm
-                      title="删除后无法恢复,是否删除?"
-                      okText="删除"
-                      cancelText="取消"
-                      onConfirm={() =>
-                        setFileOne({ fileName: "", filePath: "", id: 0 })
-                      }
-                    >
-                      <div className="clearCover">
-                        <CloseCircleOutlined />
-                      </div>
-                    </Popconfirm>
-                  </div>
-                  <div className="fileBoxRow_r_tit">
-                    支持png、jpg和jpeg的图片格式;最大支持20M。
-                  </div>
-                </div>
-              </div>
-            </>
-          )}
-
-          <div
-            className={classNames(
-              "noUpThumb noUpThumb2",
-              fileCheckFu && typeOk ? "noUpThumbAc" : ""
-            )}
-          >
-            请上传附件!
-          </div>
-
-          <Form.Item
-            label="展示状态"
-            name="display"
-            rules={[{ required: true, message: "请选择展示状态!" }]}
-          >
-            <Select
-              placeholder="请选择"
-              style={{ width: 400 }}
-              options={[
-                { value: 1, label: "展示" },
-                { value: 0, label: "不展示" },
-              ]}
-            />
-          </Form.Item>
-
-          {/* 确定和取消按钮 */}
-          <br />
-          <Form.Item wrapperCol={{ offset: 10, span: 16 }}>
-            <Button type="primary" htmlType="submit">
-              提交
-            </Button>
-            &emsp;
-            <Popconfirm
-              title="放弃编辑后,信息将不会保存!"
-              okText="放弃"
-              cancelText="取消"
-              onConfirm={closePageFu}
-            >
-              <Button>取消</Button>
-            </Popconfirm>
-          </Form.Item>
-        </Form>
-      </div>
-    </div>
-  );
-}
-
-const MemoNewsAdd = React.memo(NewsAdd);
-
-export default MemoNewsAdd;

+ 0 - 49
后台/src/pages/A2News/NewsTable/index.module.scss

@@ -1,49 +0,0 @@
-.NewsTable {
-  border-radius: 10px;
-  overflow: hidden;
-  margin-top: 20px;
-  height: calc(100% - 130px);
-  background-color: #fff;
-
-  :global {
-    .ant-table-body {
-      height: 615px;
-      overflow-y: auto !important;
-      overflow-y: overlay !important;
-
-      .ant-table-row {
-        .ant-table-cell {
-          padding: 8px;
-        }
-      }
-    }
-
-    .incoTitle {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-
-      .hotTitleInco1 {
-        cursor: pointer;
-        width: 16px;
-        height: 16px;
-        border-radius: 50%;
-        background-color: #696969;
-        margin-left: 8px;
-        text-align: center;
-        line-height: 16px;
-        color: #fff;
-        font-size: 12px;
-      }
-    }
-
-    // 表头拖拽样式
-    .drop-over-downward td {
-      border-bottom: 2px dashed var(--themeColor) !important;
-    }
-
-    .drop-over-upward td {
-      border-top: 2px dashed var(--themeColor) !important;
-    }
-  }
-}

+ 0 - 245
后台/src/pages/A2News/NewsTable/index.tsx

@@ -1,245 +0,0 @@
-import ImageLazy from "@/components/ImageLazy";
-import VideoLook from "@/components/VideoLook";
-import { RootState } from "@/store";
-import { NewsTableType } from "@/types";
-import { Button, Popconfirm, Table, Tooltip } from "antd";
-import React, { useCallback, useEffect, useMemo, useRef } from "react";
-import { useSelector } from "react-redux";
-import { ExclamationOutlined } from "@ant-design/icons";
-import styles from "./index.module.scss";
-
-// 表格拖动排序-----------------
-import { DndProvider, useDrag, useDrop } from "react-dnd";
-import { HTML5Backend } from "react-dnd-html5-backend";
-import { newRemoveAPI, newSortApi } from "@/store/action/A2News";
-import { MessageFu } from "@/utils/message";
-
-type Porps = {
-  tableType: string;
-  editInfoFu: (id: number) => void;
-  delInfoFu: () => void;
-};
-
-function NewsTable({ tableType, editInfoFu, delInfoFu }: Porps) {
-  // 有关表格数据
-  const { tableInfo: results, sroolNum } = useSelector(
-    (state: RootState) => state.newsReducer
-  );
-
-  useEffect(() => {
-    if (sroolNum > 0) {
-      const dom: any = document.querySelector("#NewsTable .ant-table-body");
-      dom.scrollTop = sroolNum;
-    }
-  }, [sroolNum]);
-
-  // 点击删除
-  const delTableFu = useCallback(
-    async (id: number) => {
-      const res = await newRemoveAPI(id);
-      if (res.code === 0) {
-        MessageFu.success("删除成功!");
-        delInfoFu();
-      }
-    },
-    [delInfoFu]
-  );
-
-  const columns = useMemo(() => {
-    return [
-      {
-        title: () => (
-          <div className="incoTitle">
-            序号
-            {results.length >= 2 ? (
-              <Tooltip title="按住鼠标可拖动表格调整顺序">
-                <div className="hotTitleInco1">
-                  <ExclamationOutlined />
-                </div>
-              </Tooltip>
-            ) : null}
-          </div>
-        ),
-        width: 100,
-        render: (text: any, item: any, index: number) => index + 1,
-      },
-      {
-        title: "标题",
-        dataIndex: "name",
-      },
-      {
-        title:
-          tableType === "news"
-            ? "正文"
-            : tableType === "video"
-            ? "视频"
-            : "图片",
-        render: (item: NewsTableType) => {
-          if (tableType === "news") {
-            return item.description.length > 35 ? (
-              <span style={{ cursor: "pointer" }} title={item.description}>
-                {item.description.substring(0, 35) + "..."}
-              </span>
-            ) : (
-              item.description
-            );
-          } else if (tableType === "video") {
-            return (
-              <div className="tableImgAuto">
-                {item.thumb ? (
-                  <VideoLook src={item.thumb} width={60} height={60} />
-                ) : null}
-              </div>
-            );
-          } else {
-            return (
-              <div className="tableImgAuto">
-                {item.thumb ? (
-                  <ImageLazy width={60} height={60} src={item.thumb} />
-                ) : null}
-              </div>
-            );
-          }
-        },
-      },
-      {
-        title: "最近编辑时间",
-        dataIndex: "updateTime",
-      },
-      {
-        title: "展示状态",
-        render: (item: NewsTableType) =>
-          item.display === 1 ? "展示" : "不展示",
-      },
-      {
-        title: "操作",
-        render: (item: NewsTableType) => (
-          <>
-            <Button
-              size="small"
-              type="text"
-              onClick={() => editInfoFu(item.id)}
-            >
-              编辑
-            </Button>
-            <Popconfirm
-              title="删除后无法恢复,是否删除?"
-              okText="删除"
-              cancelText="取消"
-              onConfirm={() => delTableFu(item.id!)}
-            >
-              <Button size="small" type="text" danger>
-                删除
-              </Button>
-            </Popconfirm>
-          </>
-        ),
-      },
-    ];
-  }, [delTableFu, editInfoFu, results.length, tableType]);
-
-  // 表格拖动排序-----------------
-  interface DraggableBodyRowProps
-    extends React.HTMLAttributes<HTMLTableRowElement> {
-    index: number;
-    moveRow: (dragIndex: number, hoverIndex: number) => void;
-  }
-
-  const type = "DraggableBodyRow";
-
-  const DraggableBodyRow = useCallback(
-    ({
-      index,
-      moveRow,
-      className,
-      style,
-      ...restProps
-    }: DraggableBodyRowProps) => {
-      // eslint-disable-next-line react-hooks/rules-of-hooks
-      const ref = useRef<HTMLTableRowElement>(null);
-      // eslint-disable-next-line react-hooks/rules-of-hooks
-      const [{ isOver, dropClassName }, drop] = useDrop({
-        accept: type,
-        collect: (monitor) => {
-          const { index: dragIndex } = monitor.getItem() || {};
-          if (dragIndex === index) {
-            return {};
-          }
-          return {
-            isOver: monitor.isOver(),
-            dropClassName:
-              dragIndex < index ? " drop-over-downward" : " drop-over-upward",
-          };
-        },
-        drop: (item: { index: number }) => {
-          moveRow(item.index, index);
-        },
-      });
-      // eslint-disable-next-line react-hooks/rules-of-hooks
-      const [, drag] = useDrag({
-        type,
-        item: { index },
-        collect: (monitor) => ({
-          isDragging: monitor.isDragging(),
-        }),
-      });
-      drop(drag(ref));
-
-      return (
-        <tr
-          ref={ref}
-          className={`${className}${isOver ? dropClassName : ""}`}
-          style={{ cursor: "move", ...style }}
-          {...restProps}
-        />
-      );
-    },
-    []
-  );
-
-  const components = {
-    body: {
-      row: DraggableBodyRow,
-    },
-  };
-
-  const moveRow = useCallback(
-    async (dragIndex: number, hoverIndex: number) => {
-      if (dragIndex === hoverIndex) return;
-      // 交互位置-之前的id
-      const beforeId = results[dragIndex].id;
-      const afterId = results[hoverIndex].id;
-
-      const res = await newSortApi(beforeId, afterId);
-
-      if (res.code === 0) delInfoFu();
-    },
-    [delInfoFu, results]
-  );
-
-  return (
-    <div className={styles.NewsTable} id="NewsTable">
-      <DndProvider backend={HTML5Backend}>
-        <Table
-          scroll={{ y: 615 }}
-          dataSource={results}
-          columns={columns}
-          rowKey="id"
-          pagination={false}
-          components={components}
-          onRow={(_, index) => {
-            const attr = {
-              index,
-              moveRow,
-            };
-            return attr as React.HTMLAttributes<any>;
-          }}
-        />
-      </DndProvider>
-    </div>
-  );
-}
-
-const MemoNewsTable = React.memo(NewsTable);
-
-export default MemoNewsTable;

+ 0 - 20
后台/src/pages/A2News/index.module.scss

@@ -1,20 +0,0 @@
-.News {
-  position: relative;
-  :global {
-    .newTop {
-      background-color: #fff;
-      border-radius: 10px;
-
-      .searchBox {
-        position: relative;
-        padding: 10px 20px 20px;
-        display: flex;
-        align-items: center;
-
-        .row {
-          margin-right: 50px;
-        }
-      }
-    }
-  }
-}

+ 0 - 181
后台/src/pages/A2News/index.tsx

@@ -1,181 +0,0 @@
-import store, { RootState } from "@/store";
-import { getNewsListAPI } from "@/store/action/A2News";
-import { NewsButtonType, NewsTableApiType } from "@/types";
-import { MessageFu } from "@/utils/message";
-import { Button, Input, Select } from "antd";
-import React, {
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
-import { useDispatch, useSelector } from "react-redux";
-import styles from "./index.module.scss";
-import NewsAdd from "./NewsAdd";
-import NewsTable from "./NewsTable";
-function News() {
-  const dispatch = useDispatch();
-
-  // 顶部筛选的数据
-  const [tableSelect, setTableSelect] = useState<NewsTableApiType>({
-    type: "news",
-    searchKey: "",
-    display: -1,
-    pageSize: 50,
-    pageNum: 1,
-  });
-
-  const buttonData = useMemo<NewsButtonType[]>(() => {
-    return [
-      { id: 1, name: "新闻", type: "news" },
-      { id: 2, name: "视频", type: "video" },
-      { id: 3, name: "图片", type: "img" },
-    ];
-  }, []);
-
-  const getTableInfoFu = useCallback(() => {
-    const obj = {
-      ...tableSelect,
-      display: tableSelect.display === -1 ? null : tableSelect.display,
-    };
-    dispatch(getNewsListAPI(obj));
-  }, [dispatch, tableSelect]);
-
-  useEffect(() => {
-    getTableInfoFu();
-  }, [getTableInfoFu]);
-
-  // 名称的输入
-  const nameTime = useRef(-1);
-  const nameChange = useCallback(
-    (e: React.ChangeEvent<HTMLInputElement>) => {
-      clearTimeout(nameTime.current);
-      nameTime.current = window.setTimeout(() => {
-        setTableSelect({
-          ...tableSelect,
-          searchKey: e.target.value,
-          pageNum: 1,
-        });
-      }, 500);
-    },
-    [tableSelect]
-  );
-
-  // 点击重置
-  const [inputKey, setInputKey] = useState(1);
-  const resetSelectFu = useCallback(() => {
-    // 新增成功把表格滚动到顶部
-    store.dispatch({ type: "news/setSroolNum", payload: 0 });
-
-    // 把2个输入框和时间选择器清空
-    setInputKey(Date.now());
-    setTableSelect({
-      type: tableSelect.type,
-      searchKey: "",
-      display: -1,
-      pageSize: 50,
-      pageNum: 1,
-    });
-  }, [tableSelect.type]);
-
-  // 新增或者编辑的id
-  const [editId, setEditId] = useState(0);
-
-  // 有关表格数据
-  const results = useSelector(
-    (state: RootState) => state.newsReducer.tableInfo
-  );
-
-  // 点击新增或者编辑
-  const addInfoFu = useCallback(
-    (id: number) => {
-      if (id === -1 && results.length >= 50)
-        return MessageFu.warning("最多可录入50条信息!");
-
-      const dom: HTMLDivElement = document.querySelector(
-        "#NewsTable .ant-table-body"
-      )!;
-      // 设置当前表格滚动位置
-      store.dispatch({ type: "news/setSroolNum", payload: dom.scrollTop });
-
-      setEditId(id);
-    },
-    [results.length]
-  );
-
-  return (
-    <div className={styles.News}>
-      <div className="newTop">
-        <div className="pageTitle">资讯管理</div>
-        <div className="searchBox">
-          <div className="row">
-            {buttonData.map((v) => (
-              <Button
-                key={v.id}
-                onClick={() => setTableSelect({ ...tableSelect, type: v.type })}
-                type={tableSelect.type === v.type ? "primary" : "default"}
-              >
-                {v.name}
-              </Button>
-            ))}
-          </div>
-          <div className="row">
-            <span>标题或正文:</span>
-            <Input
-              key={inputKey}
-              maxLength={20}
-              style={{ width: 200 }}
-              placeholder="请输入关键字"
-              allowClear
-              onChange={(e) => nameChange(e)}
-            />
-          </div>
-          <div className="row">
-            <span>展示状态:</span>
-            <Select
-              placeholder="请选择"
-              style={{ width: 100 }}
-              value={tableSelect.display}
-              onChange={(e) =>
-                setTableSelect({ ...tableSelect, display: e, pageNum: 1 })
-              }
-              options={[
-                { value: -1, label: "全部" },
-                { value: 1, label: "开启" },
-                { value: 0, label: "关闭" },
-              ]}
-            />
-          </div>
-          <div className="row">
-            <Button onClick={resetSelectFu}>重置</Button>
-            &emsp;&emsp;&emsp;&emsp;
-            <Button type="primary" onClick={() => addInfoFu(-1)}>
-              新增
-            </Button>
-          </div>
-        </div>
-      </div>
-      {/* 新增和编辑 和 表格主体 (拖动有冲突,所以只能同时渲染一个)*/}
-      {editId ? (
-        <NewsAdd
-          id={editId}
-          tableType={tableSelect.type}
-          closePageFu={() => setEditId(0)}
-          editTableFu={getTableInfoFu}
-          addTableFu={resetSelectFu}
-        />
-      ) : (
-        <NewsTable
-          tableType={tableSelect.type}
-          editInfoFu={(id) => addInfoFu(id)}
-          delInfoFu={getTableInfoFu}
-        />
-      )}
-    </div>
-  );
-}
-
-const MemoNews = React.memo(News);
-
-export default MemoNews;

+ 5 - 0
后台/src/pages/A3Book/index.module.scss

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

+ 14 - 0
后台/src/pages/A3Book/index.tsx

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

+ 0 - 198
后台/src/pages/A3Goods/GoodsAdd/index.module.scss

@@ -1,198 +0,0 @@
-.GoodsAdd {
-  position: absolute;
-  z-index: 20;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-
-  border-radius: 10px;
-  background-color: #fff;
-
-  :global {
-    .main {
-      margin-top: 5px;
-      width: 1200px;
-      padding-right: 400px;
-      padding-left:15px;
-      height: calc(100% - 66px);
-      overflow-y: auto;
-      overflow-y: overlay;
-      .myformBox0 {
-        margin-top: 0px;
-      }
-
-      .myformBox {
-        .ant-btn-default {
-          width: 100px;
-        }
-
-        display: flex;
-        margin-bottom: 20px;
-
-        .label {
-          width: 100px;
-          text-align: right;
-
-          &>span {
-            position: relative;
-            top: 2px;
-            color: #ff4d4f;
-          }
-        }
-
-      }
-
-      .myformBox2 {
-        align-items: center;
-        height: 32px;
-
-        .label {
-          height: 32px;
-          line-height: 32px;
-        }
-
-        .fileTit {
-          margin-left: 20px;
-          font-size: 14px;
-          color: rgb(126, 124, 124);
-        }
-
-        .fileInfo {
-          height: 32px;
-          line-height: 32px;
-          display: flex;
-          font-size: 16px;
-
-          .clearCover {
-            margin-left: 20px;
-            cursor: pointer;
-            font-size: 18px;
-          }
-
-        }
-
-
-      }
-
-      .myformBox3 {
-        margin-top: 20px;
-
-        .upImgBox {
-          display: flex;
-          flex-wrap: wrap;
-
-          &>div {
-            margin: 0 15px 15px 0;
-          }
-
-          .fileBoxRow_r_img {
-            position: relative;
-
-
-            .clearCover {
-              right: -10px;
-              top: -10px;
-              transform: translate(0, 0);
-              background-color: rgba(0, 0, 0, .8);
-              width: 20px;
-              height: 20px;
-              border-radius: 50%;
-              font-size: 16px;
-              color: #fff;
-            }
-          }
-        }
-
-        .fileTit {
-          font-size: 14px;
-          color: rgb(126, 124, 124);
-        }
-      }
-
-      .fileBoxRow_r {
-        position: relative;
-
-        .fileBoxRow_up {
-          color: #a6a6a6;
-          border-radius: 3px;
-          cursor: pointer;
-          font-size: 30px;
-          width: 100px;
-          height: 100px;
-          border: 1px dashed #797979;
-          display: flex;
-          justify-content: center;
-          align-items: center;
-
-
-        }
-
-        .fileBoxRow_r_img {
-          width: 100px;
-          height: 100px;
-          position: relative;
-
-          .clearCover {
-            cursor: pointer;
-            z-index: 10;
-            position: absolute;
-            width: 50px;
-            height: 50px;
-            top: 50%;
-            transform: translateY(-50%);
-            right: -50px;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            font-size: 24px;
-          }
-        }
-
-        .fileBoxRow_r_tit {
-          height: 46px;
-          margin-top: 5px;
-          font-size: 14px;
-          color: rgb(126, 124, 124);
-
-
-        }
-      }
-
-      .noUpThumb {
-        position: relative;
-        overflow: hidden;
-        opacity: 0;
-        transition: top .2s;
-        color: #ff4d4f;
-        top: -10px;
-      }
-
-      .noUpThumb2 {
-        margin-top: -10px;
-        position: relative;
-        padding-left: 100px;
-        margin-bottom: 12px;
-      }
-
-      .noUpThumbAc {
-        top: 0;
-        opacity: 1;
-      }
-
-      .myformBox {
-        .laseFormRight {
-          .laseFormRightRow {
-            display: flex;
-            align-items: center;
-          }
-
-          .laseFormRightTit {
-            font-size: 14px;
-            color: rgb(126, 124, 124);
-          }
-        }
-      }
-    }
-  }
-}

+ 0 - 745
后台/src/pages/A3Goods/GoodsAdd/index.tsx

@@ -1,745 +0,0 @@
-import store, { RootState } from "@/store";
-import {
-  Button,
-  Checkbox,
-  Form,
-  FormInstance,
-  Input,
-  Popconfirm,
-  Select,
-} from "antd";
-import React, {
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
-import { useSelector } from "react-redux";
-import TextArea from "antd/es/input/TextArea";
-import styles from "./index.module.scss";
-import { MessageFu } from "@/utils/message";
-import ImageLazy from "@/components/ImageLazy";
-import classNames from "classnames";
-import {
-  PlusOutlined,
-  CloseCircleOutlined,
-  UploadOutlined,
-  CloseOutlined,
-  PlayCircleOutlined,
-} from "@ant-design/icons";
-import {
-  getGoodsInfoByIdAPI,
-  getGoodsSaveAPI,
-  goodsUploadAPI,
-} from "@/store/action/A3Goods";
-import { baseURL } from "@/utils/http";
-import { FileListType, GoodsTableType } from "@/types";
-import { fileDomInitialFu } from "@/utils/domShow";
-
-type Props = {
-  id: number;
-  closeMoalFu: () => void;
-  addListFu: () => void;
-  editListFu: () => void;
-};
-
-function GoodsAdd({ id, closeMoalFu, addListFu, editListFu }: Props) {
-  // 上传附件的信息
-  const [fileList, setFileList] = useState({
-    model: {} as FileListType,
-    img: [] as FileListType[],
-    audio: {} as FileListType,
-    video: {} as FileListType,
-  });
-
-  // 表单的ref
-  const FormBoxRef = useRef<FormInstance>(null);
-
-  // 文件的dirCode码
-  const [dirCode, setDirCode] = useState("");
-
-  const getInfoInAPIFu = useCallback(async (id: number) => {
-    const res = await getGoodsInfoByIdAPI(id);
-    FormBoxRef.current?.setFieldsValue(res.data.entity);
-    setCover(res.data.entity.thumb);
-
-    if (res.data.entity.type) setTypeCheck(res.data.entity.type.split(","));
-
-    const data: FileListType[] = res.data.file;
-    const obj = {
-      model: {} as FileListType,
-      img: [] as FileListType[],
-      audio: {} as FileListType,
-      video: {} as FileListType,
-    };
-
-    data.forEach((v) => {
-      if (v.type === "img") obj.img.push(v);
-      else obj[v.type!] = v;
-    });
-    setFileList(obj);
-    setDirCode(res.data.entity.dirCode);
-  }, []);
-
-  useEffect(() => {
-    if (id > 0) getInfoInAPIFu(id);
-    else {
-      setDirCode(Date.now() + "");
-      FormBoxRef.current?.setFieldsValue({
-        display: 1,
-      });
-    }
-  }, [getInfoInAPIFu, id]);
-
-  // 从仓库获取下拉列表数据
-  const dictList = useSelector(
-    (state: RootState) => state.layoutStore.dictList
-  );
-
-  // 上传封面图的ref
-  const [coverCheck, setCoverCheck] = useState(false);
-  const [cover, setCover] = useState("");
-  const myInput = useRef<HTMLInputElement>(null);
-
-  // 上传封面图
-  const handeUpPhoto = useCallback(
-    async (e: React.ChangeEvent<HTMLInputElement>) => {
-      if (e.target.files) {
-        // 拿到files信息
-        const filesInfo = e.target.files[0];
-        // 校验格式
-        const type = ["image/jpeg", "image/png"];
-        if (!type.includes(filesInfo.type)) {
-          e.target.value = "";
-          return MessageFu.warning("只支持jpg、png格式!");
-        }
-        // 校验大小
-        if (filesInfo.size > 20 * 1024 * 1024) {
-          e.target.value = "";
-          return MessageFu.warning("最大支持20M!");
-        }
-        // 创建FormData对象
-        const fd = new FormData();
-        // 把files添加进FormData对象(‘photo’为后端需要的字段)
-        fd.append("type", "thumb");
-        fd.append("dirCode", dirCode);
-        fd.append("file", filesInfo);
-
-        e.target.value = "";
-
-        try {
-          const res = await goodsUploadAPI(fd);
-          if (res.code === 0) {
-            MessageFu.success("上传成功!");
-            setCover(res.data.filePath);
-          }
-          fileDomInitialFu();
-        } catch (error) {
-          fileDomInitialFu();
-        }
-      }
-    },
-    [dirCode]
-  );
-
-  // 选中附件类型
-  const [typeCheck, setTypeCheck] = useState<any>([]);
-  const [typeOk, setTypeOk] = useState(false);
-
-  const typeCheckArr = useMemo(() => {
-    return [
-      { label: "模型", value: "model" },
-      { label: "图片", value: "img" },
-      { label: "音频", value: "audio" },
-      { label: "视频", value: "video" },
-    ];
-  }, []);
-
-  // 附件信息的校验
-
-  const fileCheckFu = useMemo(() => {
-    let flag = false;
-    if (typeCheck.length === 0) flag = true;
-    if (typeCheck.includes("model") && !fileList.model.id) flag = true;
-    if (typeCheck.includes("img") && fileList.img.length === 0) flag = true;
-    if (typeCheck.includes("audio") && !fileList.audio.id) flag = true;
-    if (typeCheck.includes("video") && !fileList.video.id) flag = true;
-    return flag;
-  }, [fileList, typeCheck]);
-
-  // 点击上传附件按钮
-  const myInput2 = useRef<HTMLInputElement>(null);
-
-  const [fileOneType, setFileOneType] = useState("");
-
-  useEffect(() => {
-    if (fileOneType) myInput2.current?.click();
-  }, [fileOneType]);
-
-  const upFileFu = useCallback((type: string) => {
-    setFileOneType("");
-    window.setTimeout(() => {
-      setFileOneType(type);
-    }, 100);
-  }, []);
-
-  // 上传附件的处理函数
-  const handeUpPhoto2 = useCallback(
-    async (e: React.ChangeEvent<HTMLInputElement>) => {
-      if (e.target.files) {
-        // 拿到files信息
-        const filesInfo = e.target.files[0];
-
-        let anType = ["image/jpeg", "image/png", "image/gif"];
-        let anTit1 = "只支持png、jpg、gif和jpeg格式!";
-        let anTit2 = "最大支持20M!";
-        let anSize = 20 * 1024 * 1024;
-
-        if (fileOneType === "audio") {
-          anType = ["audio/mpeg"];
-          anTit1 = "只支持mp3格式!";
-          anTit2 = "最大支持10M!";
-          anSize = 10 * 1024 * 1024;
-        } else if (fileOneType === "video") {
-          anType = ["video/mp4"];
-          anTit1 = "只支持mp4格式!";
-          anTit2 = "最大支持500M!";
-          anSize = 500 * 1024 * 1024;
-        } else if (fileOneType === "model") {
-          anType = [""];
-          anTit1 = "只支持4dage格式!";
-          anTit2 = "最大支持500M!";
-          anSize = 500 * 1024 * 1024;
-        }
-
-        // 校验格式
-        if (fileOneType !== "model") {
-          if (!anType.includes(filesInfo.type)) {
-            e.target.value = "";
-            return MessageFu.warning(anTit1);
-          }
-        } else {
-          if (!filesInfo.name.includes(".4dage")) {
-            e.target.value = "";
-            return MessageFu.warning(anTit1);
-          }
-        }
-
-        // 校验大小
-        if (filesInfo.size > anSize) {
-          e.target.value = "";
-          return MessageFu.warning(anTit2);
-        }
-        // 创建FormData对象
-        const fd = new FormData();
-        // 把files添加进FormData对象(‘photo’为后端需要的字段)
-        fd.append("type", fileOneType);
-        fd.append("dirCode", dirCode);
-        fd.append("file", filesInfo);
-
-        e.target.value = "";
-
-        try {
-          const res = await goodsUploadAPI(fd);
-
-          if (res.code === 0) {
-            MessageFu.success("上传成功!");
-            if (fileOneType === "img")
-              setFileList({ ...fileList, img: [...fileList.img, res.data] });
-            else setFileList({ ...fileList, [fileOneType]: res.data });
-          }
-          fileDomInitialFu();
-        } catch (error) {
-          fileDomInitialFu();
-        }
-      }
-    },
-    [dirCode, fileList, fileOneType]
-  );
-
-  // 附件图片的拖动
-  const [dragImg, setDragImg] = useState<any>(null);
-
-  const handleDragEnter = useCallback(
-    (e: React.DragEvent<HTMLDivElement>, item: FileListType) => {
-      e.dataTransfer.effectAllowed = "move";
-      if (item === dragImg) return;
-      const newItems = [...fileList.img]; //拷贝一份数据进行交换操作。
-      const src = newItems.indexOf(dragImg); //获取数组下标
-      const dst = newItems.indexOf(item);
-      newItems.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
-      setFileList({ ...fileList, img: newItems });
-    },
-    [dragImg, fileList]
-  );
-
-  // 删除某一张图片
-  const delImgListFu = useCallback(
-    (id: number) => {
-      const newItems = fileList.img.filter((v) => v.id !== id);
-      setFileList({ ...fileList, img: newItems });
-    },
-    [fileList]
-  );
-
-  // 没有通过校验
-  const onFinishFailed = useCallback(() => {
-    setCoverCheck(true);
-    setTypeOk(true);
-    return MessageFu.warning("有表单不符号规则!");
-  }, []);
-
-  // 通过校验点击确定
-  const onFinish = useCallback(
-    async (value: GoodsTableType) => {
-      console.log("通过校验,点击确定");
-      setCoverCheck(true);
-      setTypeOk(true);
-      if (typeCheck.length === 0 || cover === "" || fileCheckFu)
-        return MessageFu.warning("有表单不符号规则!");
-
-      const fileIds = [];
-      if (fileList.model.id && typeCheck.includes("model"))
-        fileIds.push(fileList.model.id);
-      if (fileList.audio.id && typeCheck.includes("audio"))
-        fileIds.push(fileList.audio.id);
-      if (fileList.video.id && typeCheck.includes("video"))
-        fileIds.push(fileList.video.id);
-      if (typeCheck.includes("img")) {
-        fileList.img.forEach((v) => {
-          if (v.id) fileIds.push(v.id);
-        });
-      }
-
-      const obj = {
-        ...value,
-        id: id > 0 ? id : null,
-        dirCode,
-        fileIds: fileIds.join(","),
-        thumb: cover,
-        type: typeCheck.join(","),
-      } as GoodsTableType;
-      const res = await getGoodsSaveAPI(obj);
-      if (res.code === 0) {
-        MessageFu.success(id > 0 ? "编辑成功!" : "新增成功!");
-        closeMoalFu();
-        if (id > 0) editListFu();
-        else addListFu();
-      }
-    },
-    [
-      typeCheck,
-      cover,
-      fileCheckFu,
-      fileList.model.id,
-      fileList.audio.id,
-      fileList.video.id,
-      fileList.img,
-      id,
-      dirCode,
-      closeMoalFu,
-      editListFu,
-      addListFu,
-    ]
-  );
-
-  return (
-    <div className={styles.GoodsAdd}>
-      <div className="pageTitle">{id > 0 ? "编辑馆藏" : "新增馆藏"}</div>
-      <div className="main mySorrl">
-        <Form
-          ref={FormBoxRef}
-          name="basic"
-          labelCol={{ span: 3 }}
-          onFinish={onFinish}
-          onFinishFailed={onFinishFailed}
-          autoComplete="off"
-        >
-          <Form.Item
-            label="名称"
-            name="name"
-            rules={[{ required: true, message: "请输入名称!" }]}
-            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
-          >
-            <Input maxLength={25} showCount placeholder="请输入内容" />
-          </Form.Item>
-
-          <Form.Item
-            label="类别"
-            name="dictTexture"
-            rules={[{ required: true, message: "请选择类别!" }]}
-          >
-            <Select
-              placeholder="请选择"
-              style={{ width: 400 }}
-              options={dictList["texture"].slice(1)}
-            />
-          </Form.Item>
-
-          <Form.Item
-            label="年代"
-            name="dictAge"
-            rules={[{ required: true, message: "请选择年代!" }]}
-          >
-            <Select
-              placeholder="请选择"
-              style={{ width: 400 }}
-              options={dictList["age"].slice(1)}
-            />
-          </Form.Item>
-
-          <Form.Item
-            label="简介"
-            name="description"
-            // getValueFromEvent={(e) => e.target.value.trim()}
-          >
-            <TextArea
-              rows={4}
-              placeholder="请输入内容"
-              showCount
-              maxLength={200}
-            />
-          </Form.Item>
-
-          {/* -----上传封面图片 */}
-          <div className="myformBox myformBox0">
-            <input
-              id="upInput"
-              type="file"
-              accept=".png,.jpg,.jpeg"
-              ref={myInput}
-              onChange={(e) => handeUpPhoto(e)}
-            />
-            <input
-              id="upInput2"
-              type="file"
-              accept={
-                fileOneType === "img"
-                  ? ".gif,.png,.jpg,.jpeg"
-                  : fileOneType === "audio"
-                  ? ".mp3"
-                  : fileOneType === "model"
-                  ? ".4dage"
-                  : ".mp4"
-              }
-              ref={myInput2}
-              onChange={(e) => handeUpPhoto2(e)}
-            />
-            <div className="label">
-              <span>*</span> 封面图:
-            </div>
-            <div className="fileBoxRow_r">
-              <div
-                hidden={cover !== ""}
-                className="fileBoxRow_up"
-                onClick={() => myInput.current?.click()}
-              >
-                <PlusOutlined />
-              </div>
-              <div className="fileBoxRow_r_img" hidden={cover === ""}>
-                {cover ? (
-                  <ImageLazy width={100} height={100} src={cover} />
-                ) : null}
-
-                <Popconfirm
-                  title="删除后无法恢复,是否删除?"
-                  okText="删除"
-                  cancelText="取消"
-                  onConfirm={() => setCover("")}
-                >
-                  <div className="clearCover">
-                    <CloseCircleOutlined />
-                  </div>
-                </Popconfirm>
-              </div>
-              <div className="fileBoxRow_r_tit">
-                支持png、jpg和jpeg的图片格式;最大支持20M。
-                <br />
-                <div
-                  className={classNames(
-                    "noUpThumb",
-                    !cover && coverCheck ? "noUpThumbAc" : ""
-                  )}
-                >
-                  请上传封面图!
-                </div>
-              </div>
-            </div>
-          </div>
-
-          {/* 选中文件类型和上传附件 */}
-          <div className="myformBox">
-            <div className="label">
-              <span>*</span> 文件类型:
-            </div>
-            <div className="myformBoxR">
-              <Checkbox.Group
-                options={typeCheckArr}
-                value={typeCheck}
-                onChange={(e) => setTypeCheck(e)}
-                // onChange={(e) => console.log(e)}
-              />
-            </div>
-          </div>
-
-          {/* -----------模型上传 */}
-          <div
-            className="myformBox myformBox2"
-            hidden={!typeCheck.includes("model")}
-          >
-            <div className="label">
-              <span>*</span> 模型:
-            </div>
-            {fileList.model.id ? (
-              <div className="fileInfo">
-                <a
-                  href={baseURL + fileList.model.filePath}
-                  download
-                  target="_blank"
-                  className="upSuccTxt"
-                  rel="noreferrer"
-                >
-                  {fileList.model.fileName}
-                </a>
-
-                <Popconfirm
-                  title="删除后无法恢复,是否删除?"
-                  okText="删除"
-                  cancelText="取消"
-                  onConfirm={() => setFileList({ ...fileList, model: {} })}
-                >
-                  <div className="clearCover">
-                    <CloseCircleOutlined />
-                  </div>
-                </Popconfirm>
-              </div>
-            ) : (
-              <>
-                <Button
-                  onClick={() => upFileFu("model")}
-                  icon={<UploadOutlined />}
-                >
-                  上传
-                </Button>
-
-                <div className="fileTit">
-                  仅支持4dage格式的模型文件,大小不能超过500M。
-                </div>
-              </>
-            )}
-          </div>
-
-          {/* -----------图片上传 */}
-          <div
-            className="myformBox myformBox3"
-            hidden={!typeCheck.includes("img")}
-          >
-            <div className="label">
-              <span>*</span> 图片:
-            </div>
-            <>
-              <div className="fileBoxRow_r">
-                <div className="upImgBox">
-                  <div
-                    hidden={!!fileList.img.length && fileList.img.length >= 9}
-                    className="fileBoxRow_up"
-                    onClick={() => upFileFu("img")}
-                  >
-                    <PlusOutlined />
-                  </div>
-                  {fileList.img.map((v, i) => (
-                    <div
-                      className="fileBoxRow_r_img"
-                      key={v.id}
-                      draggable="true"
-                      onDragStart={() => setDragImg(v)}
-                      onDragOver={(e) => {
-                        e.dataTransfer.dropEffect = "move";
-                        e.preventDefault();
-                      }}
-                      onDragEnter={(e) => handleDragEnter(e, v)}
-                      onDragEnd={() => setDragImg(null)}
-                    >
-                      {v.filePath ? (
-                        <ImageLazy
-                          noLook={dragImg ? true : false}
-                          width={100}
-                          height={100}
-                          src={v.filePath}
-                        />
-                      ) : null}
-
-                      <Popconfirm
-                        title="删除后无法恢复,是否删除?"
-                        okText="删除"
-                        cancelText="取消"
-                        onConfirm={() => delImgListFu(v.id!)}
-                      >
-                        <div className="clearCover">
-                          <CloseOutlined />
-                        </div>
-                      </Popconfirm>
-                    </div>
-                  ))}
-                </div>
-                <div className="fileTit">
-                  {fileList.img.length && fileList.img.length >= 2 ? (
-                    <>
-                      按住鼠标可拖动图片调整顺序。
-                      <br />
-                    </>
-                  ) : null}
-                  支持png、jpg、gif和jpeg的图片格式;最大支持20M;最多支持9张。
-                </div>
-              </div>
-            </>
-          </div>
-
-          {/* -----------音频上传 */}
-          <div
-            className="myformBox myformBox2"
-            hidden={!typeCheck.includes("audio")}
-          >
-            <div className="label">
-              <span>*</span> 音频:
-            </div>
-            {fileList.audio.id ? (
-              <div className="fileInfo">
-                <a
-                  href={baseURL + fileList.audio.filePath}
-                  download
-                  target="_blank"
-                  className="upSuccTxt"
-                  rel="noreferrer"
-                >
-                  {fileList.audio.fileName}
-                </a>
-
-                <Popconfirm
-                  title="删除后无法恢复,是否删除?"
-                  okText="删除"
-                  cancelText="取消"
-                  onConfirm={() => setFileList({ ...fileList, audio: {} })}
-                >
-                  <div className="clearCover">
-                    <CloseCircleOutlined />
-                  </div>
-                </Popconfirm>
-              </div>
-            ) : (
-              <>
-                <Button
-                  onClick={() => upFileFu("audio")}
-                  icon={<UploadOutlined />}
-                >
-                  上传
-                </Button>
-
-                <div className="fileTit">
-                  仅支持MP3格式的音频文件,大小不得超过10MB。
-                </div>
-              </>
-            )}
-          </div>
-
-          {/* -----------视频上传 */}
-          <div
-            className="myformBox myformBox2"
-            hidden={!typeCheck.includes("video")}
-          >
-            <div className="label">
-              <span>*</span> 视频:
-            </div>
-            {fileList.video.id ? (
-              <div className="fileInfo">
-                <div className="upSuccTxt">{fileList.video.fileName}</div>
-                <div
-                  className="clearCover"
-                  hidden={!fileList.video.filePath}
-                  onClick={() =>
-                    store.dispatch({
-                      type: "layout/lookVideo",
-                      payload: fileList.video.filePath!,
-                    })
-                  }
-                >
-                  <PlayCircleOutlined />
-                </div>
-
-                <Popconfirm
-                  title="删除后无法恢复,是否删除?"
-                  okText="删除"
-                  cancelText="取消"
-                  onConfirm={() => setFileList({ ...fileList, video: {} })}
-                >
-                  <div className="clearCover">
-                    <CloseCircleOutlined />
-                  </div>
-                </Popconfirm>
-              </div>
-            ) : (
-              <>
-                <Button
-                  onClick={() => upFileFu("video")}
-                  icon={<UploadOutlined />}
-                >
-                  上传
-                </Button>
-
-                <div className="fileTit">
-                  仅支持MP4格式的视频文件,大小不得超过500MB。
-                </div>
-              </>
-            )}
-          </div>
-
-          <div
-            className={classNames(
-              "noUpThumb noUpThumb2",
-              fileCheckFu && typeOk ? "noUpThumbAc" : ""
-            )}
-          >
-            请至少选择一个文件类型,并上传对应附件!
-          </div>
-
-          <Form.Item
-            label="展示状态"
-            name="display"
-            rules={[{ required: true, message: "请选择展示状态!" }]}
-          >
-            <Select
-              placeholder="请选择"
-              style={{ width: 400 }}
-              options={[
-                { value: 1, label: "展示" },
-                { value: 0, label: "不展示" },
-              ]}
-            />
-          </Form.Item>
-
-          {/* 确定和取消按钮 */}
-          <br />
-          <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
-            <Button type="primary" htmlType="submit">
-              提交
-            </Button>
-            &emsp;
-            <Popconfirm
-              title="放弃编辑后,信息将不会保存!"
-              okText="放弃"
-              cancelText="取消"
-              onConfirm={closeMoalFu}
-            >
-              <Button>取消</Button>
-            </Popconfirm>
-          </Form.Item>
-        </Form>
-      </div>
-    </div>
-  );
-}
-
-const MemoGoodsAdd = React.memo(GoodsAdd);
-
-export default MemoGoodsAdd;

+ 0 - 43
后台/src/pages/A3Goods/index.module.scss

@@ -1,43 +0,0 @@
-.Goods {
-  position: relative;
-  :global {
-    .goodsTop {
-      border-radius: 10px;
-      background-color: #fff;
-    }
-
-    .searchBox {
-      padding: 10px 15px 0;
-      display: flex;
-      flex-wrap: wrap;
-
-      .searchRow {
-        margin-bottom: 20px;
-        margin-right: 20px;
-      }
-      .searchRow2{
-        margin-right: 0;
-      }
-    }
-
-    .tableBox {
-      border-radius: 10px;
-      overflow: hidden;
-      margin-top: 20px;
-      height: calc(100% - 128px);
-      background-color: #fff;
-
-      .ant-table-body {
-        height: 560px;
-        overflow-y: auto !important;
-        overflow-y: overlay !important;
-
-        .ant-table-row {
-          .ant-table-cell {
-            padding: 8px;
-          }
-        }
-      }
-    }
-  }
-}

+ 0 - 311
后台/src/pages/A3Goods/index.tsx

@@ -1,311 +0,0 @@
-import { RootState } from "@/store";
-import { getGoodsListAPI, goodsRemoveAPI } from "@/store/action/A3Goods";
-import { MessageFu } from "@/utils/message";
-import { Input, Select, DatePicker, Button, Table, Popconfirm } from "antd";
-import React, {
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
-import { useDispatch, useSelector } from "react-redux";
-import styles from "./index.module.scss";
-import ImageLazy from "@/components/ImageLazy";
-import { GoodsTableType } from "@/types";
-import GoodsAdd from "./GoodsAdd";
-
-const { RangePicker } = DatePicker;
-function Goods() {
-  const dispatch = useDispatch();
-
-  // 从仓库获取下拉列表数据
-  const dictList = useSelector(
-    (state: RootState) => state.layoutStore.dictList
-  );
-
-  // 从仓库获取表格列表信息
-  const tableInfo = useSelector(
-    (state: RootState) => state.goodsReducer.tableInfo
-  );
-
-  // 顶部筛选
-  const [tableSelect, setTableSelect] = useState({
-    searchKey: "",
-    dictTexture: "",
-    dictAge: "",
-    startTime: "",
-    endTime: "",
-    display: -1,
-    pageSize: 10,
-    pageNum: 1,
-  });
-
-  // 封装发送请求的函数
-
-  const getList = useCallback(async () => {
-    const data = {
-      ...tableSelect,
-      display: tableSelect.display === -1 ? null : tableSelect.display,
-    };
-    dispatch(getGoodsListAPI(data));
-  }, [dispatch, tableSelect]);
-
-  useEffect(() => {
-    getList();
-  }, [getList]);
-
-  // 名称的输入
-  const nameTime = useRef(-1);
-  const nameChange = useCallback(
-    (e: React.ChangeEvent<HTMLInputElement>) => {
-      clearTimeout(nameTime.current);
-      nameTime.current = window.setTimeout(() => {
-        setTableSelect({
-          ...tableSelect,
-          searchKey: e.target.value,
-          pageNum: 1,
-        });
-      }, 500);
-    },
-    [tableSelect]
-  );
-
-  // 时间选择器改变
-  const timeChange = (date: any, dateString: any) => {
-    let startTime = "";
-    let endTime = "";
-    if (dateString[0] && dateString[1]) {
-      startTime = dateString[0] + " 00:00:00";
-      endTime = dateString[1] + " 23:59:59";
-    }
-    setTableSelect({ ...tableSelect, startTime, endTime, pageNum: 1 });
-  };
-
-  // 点击重置
-  const [inputKey, setInputKey] = useState(1);
-  const resetSelectFu = useCallback(() => {
-    // 把2个输入框和时间选择器清空
-    setInputKey(Date.now());
-    setTableSelect({
-      searchKey: "",
-      dictTexture: "",
-      dictAge: "",
-      startTime: "",
-      endTime: "",
-      display: -1,
-      pageSize: 10,
-      pageNum: 1,
-    });
-  }, []);
-
-  // ----------关于表格的数据
-
-  // 页码变化
-  const paginationChange = useCallback(
-    () => (pageNum: number, pageSize: number) => {
-      setTableSelect({ ...tableSelect, pageNum, pageSize });
-    },
-    [tableSelect]
-  );
-
-  // 点击删除
-  const delTableFu = useCallback(
-    async (id: number) => {
-      const res = await goodsRemoveAPI(id);
-      if (res.code === 0) {
-        MessageFu.success("删除成功!");
-        getList();
-      }
-    },
-    [getList]
-  );
-
-  const columns = useMemo(() => {
-    return [
-      {
-        title: "名称",
-        dataIndex: "name",
-      },
-
-      {
-        title: "类别",
-        dataIndex: "dictTexture",
-      },
-      {
-        title: "年代",
-        dataIndex: "dictAge",
-      },
-      {
-        title: "简介",
-        render: (item: GoodsTableType) =>
-          item.description ? (
-            item.description.length >= 25 ? (
-              <span style={{ cursor: "pointer" }} title={item.description}>
-                {item.description.substring(0, 25) + "..."}
-              </span>
-            ) : (
-              item.description
-            )
-          ) : (
-            "(空)"
-          ),
-      },
-      {
-        title: "图片",
-        render: (item: GoodsTableType) => (
-          <div className="tableImgAuto">
-            <ImageLazy width={60} height={60} src={item.thumb!} />
-          </div>
-        ),
-      },
-      {
-        title: "最近编辑时间",
-        dataIndex: "updateTime",
-      },
-
-      {
-        title: "展示状态",
-        render: (item: GoodsTableType) =>
-          item.display === 1 ? "展示" : "不展示",
-      },
-
-      {
-        title: "操作",
-        render: (item: GoodsTableType) => (
-          <>
-            <Button size="small" type="text" onClick={() => setAddId(item.id!)}>
-              编辑
-            </Button>
-            <Popconfirm
-              title="删除后无法恢复,是否删除?"
-              okText="删除"
-              cancelText="取消"
-              onConfirm={() => delTableFu(item.id!)}
-            >
-              <Button size="small" type="text" danger>
-                删除
-              </Button>
-            </Popconfirm>
-          </>
-        ),
-      },
-    ];
-  }, [delTableFu]);
-
-  // 新增或者编辑的弹窗
-  const [addId, setAddId] = useState(0);
-
-  return (
-    <div className={styles.Goods}>
-      <div className="goodsTop">
-        <div className="pageTitle">馆藏管理</div>
-        {/* 搜索信息 */}
-        <div className="searchBox">
-          <div className="searchRow">
-            <span>名称:</span>
-            <Input
-              key={inputKey}
-              maxLength={25}
-              style={{ width: 140 }}
-              placeholder="请输入关键字"
-              allowClear
-              onChange={(e) => nameChange(e)}
-            />
-          </div>
-
-          <div className="searchRow">
-            <span>类别:</span>
-            <Select
-              placeholder="请选择"
-              style={{ width: 140 }}
-              value={tableSelect.dictTexture}
-              onChange={(e) =>
-                setTableSelect({ ...tableSelect, dictTexture: e, pageNum: 1 })
-              }
-              options={dictList["texture"]}
-            />
-          </div>
-
-          <div className="searchRow">
-            <span>年代:</span>
-            <Select
-              placeholder="请选择"
-              style={{ width: 140 }}
-              value={tableSelect.dictAge}
-              onChange={(e) =>
-                setTableSelect({ ...tableSelect, dictAge: e, pageNum: 1 })
-              }
-              options={dictList["age"]}
-            />
-          </div>
-
-          <div className="searchRow">
-            <span>最近编辑日期:</span>
-            <RangePicker
-              style={{ width: 230 }}
-              key={inputKey}
-              onChange={timeChange}
-            />
-          </div>
-
-          <div className="searchRow">
-            <span>展示状态:</span>
-            <Select
-              placeholder="请选择"
-              style={{ width: 80 }}
-              value={tableSelect.display}
-              onChange={(e) =>
-                setTableSelect({ ...tableSelect, display: e, pageNum: 1 })
-              }
-              options={[
-                { value: -1, label: "全部" },
-                { value: 1, label: "开启" },
-                { value: 0, label: "关闭" },
-              ]}
-            />
-          </div>
-
-          <div className="searchRow searchRow2">
-            <Button onClick={resetSelectFu}>重置</Button>&emsp;&emsp;
-            <Button type="primary" onClick={() => setAddId(-1)}>
-              新增
-            </Button>
-          </div>
-        </div>
-      </div>
-      {/* 表格主体 */}
-      <div className="tableBox">
-        <Table
-          scroll={{ y: 560 }}
-          dataSource={tableInfo.list}
-          columns={columns}
-          rowKey="id"
-          pagination={{
-            showQuickJumper: true,
-            position: ["bottomCenter"],
-            showSizeChanger: true,
-            current: tableSelect.pageNum,
-            pageSize: tableSelect.pageSize,
-            total: tableInfo.total,
-            onChange: paginationChange(),
-          }}
-        />
-      </div>
-
-      {/* 新增和编辑的弹窗 */}
-      {addId !== 0 ? (
-        <GoodsAdd
-          id={addId}
-          closeMoalFu={() => setAddId(0)}
-          addListFu={resetSelectFu}
-          editListFu={getList}
-        />
-      ) : null}
-    </div>
-  );
-}
-
-const MemoGoods = React.memo(Goods);
-
-export default MemoGoods;

+ 0 - 139
后台/src/pages/A4Venue/VenueEdit/index.module.scss

@@ -1,139 +0,0 @@
-.VenueEdit {
-  position: absolute;
-  z-index: 20;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  background-color: #fff;
-  border-radius: 10px;
-
-  :global {
-    .formBox {
-      margin-top: 10px;
-      width: 1200px;
-      height: calc(100% - 70px);
-      padding-right: 400px;
-      overflow-y: auto;
-
-      // 多张附件图片上传
-      .myformBox {
-        display: flex;
-        margin-bottom: 10px;
-        margin-top: 40px;
-
-        .ant-btn-default {
-          width: 100px;
-        }
-
-        .label {
-          width: 100px;
-          text-align: right;
-
-          &>span {
-            position: relative;
-            top: 2px;
-            color: #ff4d4f;
-          }
-        }
-
-        .fileBoxRow_r {
-          position: relative;
-
-          .fileBoxRow_up {
-            color: #a6a6a6;
-            border-radius: 3px;
-            cursor: pointer;
-            font-size: 30px;
-            width: 100px;
-            height: 100px;
-            border: 1px dashed #797979;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-
-
-          }
-
-          .fileBoxRow_r_img {
-            width: 100px;
-            height: 100px;
-            position: relative;
-
-            .clearCover {
-              cursor: pointer;
-              z-index: 10;
-              position: absolute;
-              width: 50px;
-              height: 50px;
-              top: 50%;
-              transform: translateY(-50%);
-              right: -50px;
-              display: flex;
-              justify-content: center;
-              align-items: center;
-              font-size: 24px;
-            }
-          }
-
-          .fileBoxRow_r_tit {
-            height: 46px;
-            margin-top: 5px;
-            font-size: 14px;
-            color: rgb(126, 124, 124);
-
-
-          }
-
-          .upImgBox {
-            display: flex;
-            flex-wrap: wrap;
-            max-width: 700px;
-
-            &>div {
-              margin: 0 15px 15px 0;
-            }
-
-            .fileBoxRow_r_img {
-              position: relative;
-
-              .clearCover {
-                right: -10px;
-                top: -10px;
-                transform: translate(0, 0);
-                background-color: rgba(0, 0, 0, .8);
-                width: 20px;
-                height: 20px;
-                border-radius: 50%;
-                font-size: 16px;
-                color: #fff;
-              }
-            }
-          }
-
-        }
-
-      }
-
-      .noUpThumb {
-        position: relative;
-        overflow: hidden;
-        opacity: 0;
-        transition: top .2s;
-        color: #ff4d4f;
-        top: -10px;
-      }
-
-      .noUpThumb2 {
-        position: relative;
-        padding-left: 100px;
-        margin-bottom: 12px;
-      }
-
-      .noUpThumbAc {
-        top: 0;
-        opacity: 1;
-      }
-    }
-  }
-}

+ 0 - 317
后台/src/pages/A4Venue/VenueEdit/index.tsx

@@ -1,317 +0,0 @@
-import {
-  getVenueDetailAPI,
-  setVenueSaveApi,
-  venueUploadAPI,
-} from "@/store/action/A4Venue";
-import { ImgListType, VenueTableType } from "@/types";
-import { fileDomInitialFu } from "@/utils/domShow";
-import { MessageFu } from "@/utils/message";
-import { Button, Form, FormInstance, Input, Popconfirm } from "antd";
-import { PlusOutlined, CloseOutlined } from "@ant-design/icons";
-import TextArea from "antd/es/input/TextArea";
-import classNames from "classnames";
-import React, {
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
-import styles from "./index.module.scss";
-import ImageLazy from "@/components/ImageLazy";
-
-type Props = {
-  id: number;
-  closePageFu: () => void;
-  editTableFu: () => void;
-};
-
-function VenueEdit({ id, closePageFu, editTableFu }: Props) {
-  // 设置表单初始数据(区分编辑和新增)
-  const FormBoxRef = useRef<FormInstance>(null);
-
-  // 文件的dirCode码
-  const [dirCode, setDirCode] = useState("");
-
-  const myInput = useRef<HTMLInputElement>(null);
-
-  // 通过id获取详情,回显数据
-  const getInfoFu = useCallback(async (id: number) => {
-    const res = await getVenueDetailAPI(id);
-    const data: VenueTableType = res.data.entity;
-    const fileList: ImgListType[] = res.data.file;
-    setDirCode(data.dirCode);
-    FormBoxRef.current?.setFieldsValue(data);
-    setImgList(fileList);
-  }, []);
-
-  useEffect(() => {
-    if (id) getInfoFu(id);
-    else {
-      setDirCode(Date.now() + "");
-    }
-  }, [getInfoFu, id]);
-
-  // 多张图片附件
-  const [imgList, setImgList] = useState<ImgListType[]>([]);
-
-  // 上传附件的处理函数
-  const handeUpPhoto = useCallback(
-    async (e: React.ChangeEvent<HTMLInputElement>) => {
-      if (e.target.files) {
-        // 拿到files信息
-        const filesInfo = e.target.files[0];
-
-        let anType = ["image/jpeg", "image/png"];
-        let anTit1 = "只支持png、jpg和jpeg格式!";
-        let anTit2 = "最大支持20M!";
-        let anSize = 20 * 1024 * 1024;
-
-        // 校验格式
-        if (!anType.includes(filesInfo.type)) {
-          e.target.value = "";
-          return MessageFu.warning(anTit1);
-        }
-
-        // 校验大小
-        if (filesInfo.size > anSize) {
-          e.target.value = "";
-          return MessageFu.warning(anTit2);
-        }
-        // 创建FormData对象
-        const fd = new FormData();
-        // 把files添加进FormData对象(‘photo’为后端需要的字段)
-        fd.append("type", "img");
-        fd.append("dirCode", dirCode);
-        fd.append("file", filesInfo);
-
-        e.target.value = "";
-
-        try {
-          const res = await venueUploadAPI(fd);
-
-          if (res.code === 0) {
-            MessageFu.success("上传成功!");
-            setImgList([...imgList, res.data]);
-          }
-          fileDomInitialFu();
-        } catch (error) {
-          fileDomInitialFu();
-        }
-      }
-    },
-    [dirCode, imgList]
-  );
-
-  // 附件图片的拖动
-  const [dragImg, setDragImg] = useState<any>(null);
-
-  const handleDragEnter = useCallback(
-    (e: React.DragEvent<HTMLDivElement>, item: ImgListType) => {
-      e.dataTransfer.effectAllowed = "move";
-      if (item === dragImg) return;
-      const newItems = [...imgList]; //拷贝一份数据进行交换操作。
-      const src = newItems.indexOf(dragImg); //获取数组下标
-      const dst = newItems.indexOf(item);
-      newItems.splice(dst, 0, ...newItems.splice(src, 1)); //交换位置
-      setImgList(newItems);
-    },
-    [dragImg, imgList]
-  );
-
-  // 删除某一张图片
-  const delImgListFu = useCallback(
-    (id: number) => {
-      const newItems = imgList.filter((v) => v.id !== id);
-      setImgList(newItems);
-    },
-    [imgList]
-  );
-
-  const [typeOk, setTypeOk] = useState(false);
-
-  // 附件信息的校验
-  const fileCheckFu = useMemo(() => {
-    let flag = false;
-    if (imgList.length === 0) flag = true;
-    return flag;
-  }, [imgList.length]);
-
-  // 没有通过校验
-  const onFinishFailed = useCallback(() => {
-    setTypeOk(true);
-    // return MessageFu.warning("有表单不符号规则!");
-  }, []);
-
-  // 通过校验点击确定
-  const onFinish = useCallback(
-    async (values: VenueTableType) => {
-      setTypeOk(true);
-
-      if (fileCheckFu) return;
-
-      const obj = {
-        ...values,
-        id: id > 0 ? id : null,
-        dirCode,
-        fileIds: imgList.map((v) => v.id).join(","),
-        thumb: imgList[0].filePath,
-      };
-      // console.log(obj);
-      const res = await setVenueSaveApi(obj);
-      if (res.code === 0) {
-        MessageFu.success("编辑成功!");
-        editTableFu();
-        closePageFu();
-      }
-    },
-    [closePageFu, dirCode, editTableFu, fileCheckFu, id, imgList]
-  );
-
-  return (
-    <div className={styles.VenueEdit}>
-      <div className="pageTitle">编辑场馆</div>
-      <div className="formBox mySorrl">
-        <Form
-          ref={FormBoxRef}
-          name="basic"
-          labelCol={{ span: 3 }}
-          onFinish={onFinish}
-          onFinishFailed={onFinishFailed}
-          autoComplete="off"
-        >
-          <Form.Item
-            label="名称"
-            name="name"
-            rules={[{ required: true, message: "请输入标题!" }]}
-          >
-            <Input disabled />
-          </Form.Item>
-
-          <Form.Item
-            label="位置"
-            name="location"
-            rules={[{ required: true, message: "请输入位置!" }]}
-            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
-          >
-            <Input maxLength={8} showCount placeholder="请输入内容" />
-          </Form.Item>
-
-          <Form.Item
-            label="简介"
-            name="description"
-            // getValueFromEvent={(e) => e.target.value.trim()}
-          >
-            <TextArea
-              rows={5}
-              placeholder="请输入内容"
-              showCount
-              maxLength={200}
-            />
-          </Form.Item>
-
-          {/* 上传附件图片 */}
-          <div className="myformBox">
-            <input
-              id="upInput2"
-              type="file"
-              accept=".png,.jpg,.jpeg"
-              ref={myInput}
-              onChange={(e) => handeUpPhoto(e)}
-            />
-
-            <div className="label">
-              <span>*</span> 图片:
-            </div>
-            <>
-              <div className="fileBoxRow_r">
-                <div className="upImgBox">
-                  <div
-                    hidden={imgList.length >= 9}
-                    className="fileBoxRow_up"
-                    onClick={() => myInput.current?.click()}
-                  >
-                    <PlusOutlined />
-                  </div>
-                  {imgList.map((v, i) => (
-                    <div
-                      className="fileBoxRow_r_img"
-                      key={v.id}
-                      draggable="true"
-                      onDragStart={() => setDragImg(v)}
-                      onDragOver={(e) => {
-                        e.dataTransfer.dropEffect = "move";
-                        e.preventDefault();
-                      }}
-                      onDragEnter={(e) => handleDragEnter(e, v)}
-                      onDragEnd={() => setDragImg(null)}
-                    >
-                      {i === 0 ? <div className="myCoverBox">封面</div> : null}
-                      {v.filePath ? (
-                        <ImageLazy
-                          noLook={dragImg ? true : false}
-                          width={100}
-                          height={100}
-                          src={v.filePath}
-                        />
-                      ) : null}
-
-                      <Popconfirm
-                        title="删除后无法恢复,是否删除?"
-                        okText="删除"
-                        cancelText="取消"
-                        onConfirm={() => delImgListFu(v.id)}
-                      >
-                        <div className="clearCover">
-                          <CloseOutlined />
-                        </div>
-                      </Popconfirm>
-                    </div>
-                  ))}
-                </div>
-                <div className="fileTit">
-                  {imgList.length >= 2 ? (
-                    <>
-                      按住鼠标可拖动图片调整顺序,第一张为展示端封面。
-                      <br />
-                    </>
-                  ) : null}
-                  支持png、jpg和jpeg的图片格式;最大支持20M;最多支持9张。
-                </div>
-              </div>
-            </>
-          </div>
-          <div
-            className={classNames(
-              "noUpThumb noUpThumb2",
-              fileCheckFu && typeOk ? "noUpThumbAc" : ""
-            )}
-          >
-            请上传图片!
-          </div>
-
-          {/* 确定和取消按钮 */}
-          <br />
-          <Form.Item wrapperCol={{ offset: 10, span: 16 }}>
-            <Button type="primary" htmlType="submit">
-              提交
-            </Button>
-            &emsp;
-            <Popconfirm
-              title="放弃编辑后,信息将不会保存!"
-              okText="放弃"
-              cancelText="取消"
-              onConfirm={closePageFu}
-            >
-              <Button>取消</Button>
-            </Popconfirm>
-          </Form.Item>
-        </Form>
-      </div>
-    </div>
-  );
-}
-
-const MemoVenueEdit = React.memo(VenueEdit);
-
-export default MemoVenueEdit;

+ 0 - 49
后台/src/pages/A4Venue/VenueTable/index.module.scss

@@ -1,49 +0,0 @@
-.VenueTable {
-  border-radius: 10px;
-  overflow: hidden;
-  margin-top: 20px;
-  height: calc(100% - 130px);
-  background-color: #fff;
-
-  :global {
-    .ant-table-body {
-      height: 615px;
-      overflow-y: auto !important;
-      overflow-y: overlay !important;
-
-      .ant-table-row {
-        .ant-table-cell {
-          padding: 8px;
-        }
-      }
-    }
-
-    .incoTitle {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-
-      .hotTitleInco1 {
-        cursor: pointer;
-        width: 16px;
-        height: 16px;
-        border-radius: 50%;
-        background-color: #696969;
-        margin-left: 8px;
-        text-align: center;
-        line-height: 16px;
-        color: #fff;
-        font-size: 12px;
-      }
-    }
-
-    // 表头拖拽样式
-    .drop-over-downward td {
-      border-bottom: 2px dashed var(--themeColor) !important;
-    }
-
-    .drop-over-upward td {
-      border-top: 2px dashed var(--themeColor) !important;
-    }
-  }
-}

+ 0 - 203
后台/src/pages/A4Venue/VenueTable/index.tsx

@@ -1,203 +0,0 @@
-import ImageLazy from "@/components/ImageLazy";
-import { RootState } from "@/store";
-import { VenueTableType } from "@/types";
-import { Button, Table, Tooltip } from "antd";
-import React, { useCallback, useMemo, useRef } from "react";
-import { useSelector } from "react-redux";
-import { ExclamationOutlined } from "@ant-design/icons";
-import styles from "./index.module.scss";
-
-// 表格拖动排序-----------------
-import { DndProvider, useDrag, useDrop } from "react-dnd";
-import { HTML5Backend } from "react-dnd-html5-backend";
-import { venueSortApi } from "@/store/action/A4Venue";
-
-type Porps = {
-  editInfoFu: (id: number) => void;
-  delInfoFu:()=>void
-};
-
-function VenueTable({ editInfoFu,delInfoFu }: Porps) {
-  // 有关表格数据
-  const results = useSelector(
-    (state: RootState) => state.venueReducer.tableInfo
-  );
-
-  const columns = useMemo(() => {
-    return [
-      {
-        title: () => (
-          <div className="incoTitle">
-            序号
-            {results.length >= 2 ? (
-              <Tooltip title="按住鼠标可拖动表格调整顺序">
-                <div className="hotTitleInco1">
-                  <ExclamationOutlined />
-                </div>
-              </Tooltip>
-            ) : null}
-          </div>
-        ),
-        width: 100,
-        render: (text: any, item: any, index: number) => index + 1,
-      },
-      {
-        title: "名称",
-        dataIndex: "name",
-      },
-      {
-        title: "位置",
-        render: (item: VenueTableType) =>
-          item.location ? item.location : "(空)",
-      },
-      {
-        title: "简介",
-        render: (item: VenueTableType) =>
-          item.description ? (
-            item.description.length >= 25 ? (
-              <span style={{ cursor: "pointer" }} title={item.description}>
-                {item.description.substring(0, 25) + "..."}
-              </span>
-            ) : (
-              item.description
-            )
-          ) : (
-            "(空)"
-          ),
-      },
-      {
-        title: "图片",
-        render: (item: VenueTableType) => (
-          <div className="tableImgAuto">
-            <ImageLazy width={60} height={60} src={item.thumb} />
-          </div>
-        ),
-      },
-
-      {
-        title: "最近编辑时间",
-        dataIndex: "updateTime",
-      },
-
-      {
-        title: "操作",
-        render: (item: VenueTableType) => (
-          <>
-            <Button
-              size="small"
-              type="text"
-              onClick={() => editInfoFu(item.id!)}
-            >
-              编辑
-            </Button>
-          </>
-        ),
-      },
-    ];
-  }, [editInfoFu, results.length]);
-
-  // 表格拖动排序-----------------
-  interface DraggableBodyRowProps
-    extends React.HTMLAttributes<HTMLTableRowElement> {
-    index: number;
-    moveRow: (dragIndex: number, hoverIndex: number) => void;
-  }
-
-  const type = "DraggableBodyRow";
-
-  const DraggableBodyRow = useCallback(
-    ({
-      index,
-      moveRow,
-      className,
-      style,
-      ...restProps
-    }: DraggableBodyRowProps) => {
-      // eslint-disable-next-line react-hooks/rules-of-hooks
-      const ref = useRef<HTMLTableRowElement>(null);
-      // eslint-disable-next-line react-hooks/rules-of-hooks
-      const [{ isOver, dropClassName }, drop] = useDrop({
-        accept: type,
-        collect: (monitor) => {
-          const { index: dragIndex } = monitor.getItem() || {};
-          if (dragIndex === index) {
-            return {};
-          }
-          return {
-            isOver: monitor.isOver(),
-            dropClassName:
-              dragIndex < index ? " drop-over-downward" : " drop-over-upward",
-          };
-        },
-        drop: (item: { index: number }) => {
-          moveRow(item.index, index);
-        },
-      });
-      // eslint-disable-next-line react-hooks/rules-of-hooks
-      const [, drag] = useDrag({
-        type,
-        item: { index },
-        collect: (monitor) => ({
-          isDragging: monitor.isDragging(),
-        }),
-      });
-      drop(drag(ref));
-
-      return (
-        <tr
-          ref={ref}
-          className={`${className}${isOver ? dropClassName : ""}`}
-          style={{ cursor: "move", ...style }}
-          {...restProps}
-        />
-      );
-    },
-    []
-  );
-
-  const components = {
-    body: {
-      row: DraggableBodyRow,
-    },
-  };
-
-  const moveRow = useCallback(
-    async (dragIndex: number, hoverIndex: number) => {
-      if (dragIndex === hoverIndex) return;
-      // 交互位置-之前的id
-      const beforeId = results[dragIndex].id;
-      const afterId = results[hoverIndex].id;
-
-      const res = await venueSortApi(beforeId!, afterId!);
-
-      if (res.code === 0) delInfoFu()
-    },
-    [delInfoFu, results]
-  );
-
-  return (
-    <div className={styles.VenueTable}>
-      <DndProvider backend={HTML5Backend}>
-        <Table
-          scroll={{ y: 615 }}
-          dataSource={results}
-          columns={columns}
-          rowKey="id"
-          pagination={false}
-          components={components}
-          onRow={(_, index) => {
-            const attr = {
-              index,
-              moveRow,
-            };
-            return attr as React.HTMLAttributes<any>;
-          }}
-        />
-      </DndProvider>
-    </div>
-  );
-}
-
-const MemoVenueTable = React.memo(VenueTable);
-
-export default MemoVenueTable;

+ 0 - 20
后台/src/pages/A4Venue/index.module.scss

@@ -1,20 +0,0 @@
-.Venue{
-  position: relative;
-  :global{
-    .venueTop {
-      background-color: #fff;
-      border-radius: 10px;
-
-      .searchBox {
-        position: relative;
-        padding: 10px 20px 20px;
-        display: flex;
-        align-items: center;
-
-        .row {
-          margin-right: 50px;
-        }
-      }
-    }
-  }
-}

+ 0 - 122
后台/src/pages/A4Venue/index.tsx

@@ -1,122 +0,0 @@
-import { getVenueListAPI } from "@/store/action/A4Venue";
-import { Button, DatePicker, Input } from "antd";
-import React, { useCallback, useEffect, useRef, useState } from "react";
-import { useDispatch } from "react-redux";
-import styles from "./index.module.scss";
-import VenueEdit from "./VenueEdit";
-import VenueTable from "./VenueTable";
-const { RangePicker } = DatePicker;
-
-function Venue() {
-  const dispatch = useDispatch();
-  // 顶部筛选的数据
-  const [tableSelect, setTableSelect] = useState({
-    searchKey: "",
-    startTime: "",
-    endTime: "",
-    pageSize: 50,
-    pageNum: 1,
-  });
-
-  useEffect(() => {
-    dispatch(getVenueListAPI(tableSelect));
-  }, [dispatch, tableSelect]);
-
-  // 名称的输入
-  const nameTime = useRef(-1);
-  const nameChange = useCallback(
-    (e: React.ChangeEvent<HTMLInputElement>) => {
-      clearTimeout(nameTime.current);
-      nameTime.current = window.setTimeout(() => {
-        setTableSelect({
-          ...tableSelect,
-          searchKey: e.target.value,
-          pageNum: 1,
-        });
-      }, 500);
-    },
-    [tableSelect]
-  );
-
-  // 时间选择器改变
-  const timeChange = (date: any, dateString: any) => {
-    let startTime = "";
-    let endTime = "";
-    if (dateString[0] && dateString[1]) {
-      startTime = dateString[0] + " 00:00:00";
-      endTime = dateString[1] + " 23:59:59";
-    }
-    setTableSelect({ ...tableSelect, startTime, endTime, pageNum: 1 });
-  };
-
-  // 点击重置
-  const [inputKey, setInputKey] = useState(1);
-  const resetSelectFu = useCallback(() => {
-    // 把2个输入框和时间选择器清空
-    setInputKey(Date.now());
-    setTableSelect({
-      searchKey: "",
-      startTime: "",
-      endTime: "",
-      pageSize: 50,
-      pageNum: 1,
-    });
-  }, []);
-
-  const addInfoFu = useCallback((id: number) => {
-    setEditId(id);
-  }, []);
-
-  const [editId, setEditId] = useState(0);
-
-  return (
-    <div className={styles.Venue}>
-      <div className="venueTop">
-        <div className="pageTitle">场馆管理</div>
-        <div className="searchBox">
-          <div className="row">
-            <span>名称:</span>
-            <Input
-              key={inputKey}
-              maxLength={20}
-              style={{ width: 200 }}
-              placeholder="请输入关键字"
-              allowClear
-              onChange={(e) => nameChange(e)}
-            />
-          </div>
-          <div className="row">
-            <span>最近编辑日期:</span>
-            <RangePicker
-              style={{ width: 230 }}
-              key={inputKey}
-              onChange={timeChange}
-            />
-          </div>
-          <div className="row">
-            &emsp;&emsp;&emsp;&emsp;
-            <Button onClick={resetSelectFu}>重置</Button>
-          </div>
-        </div>
-      </div>
-
-      {/* 新增和编辑 和 表格主体 (拖动有冲突,所以只能同时渲染一个)*/}
-      {editId ? (
-        <VenueEdit
-          id={editId}
-          closePageFu={() => setEditId(0)}
-          editTableFu={() => dispatch(getVenueListAPI(tableSelect))}
-        />
-      ) : (
-        <VenueTable
-          editInfoFu={(id) => addInfoFu(id)}
-          delInfoFu={() => dispatch(getVenueListAPI(tableSelect))}
-        />
-      )}
-    </div>
-  );
-}
-
-const MemoVenue = React.memo(Venue);
-
-export default MemoVenue;

+ 5 - 0
后台/src/pages/A4Visit/index.module.scss

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

+ 14 - 0
后台/src/pages/A4Visit/index.tsx

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

+ 5 - 0
后台/src/pages/A5Gallery/index.module.scss

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

+ 14 - 0
后台/src/pages/A5Gallery/index.tsx

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

+ 0 - 34
后台/src/pages/A5Guest/index.module.scss

@@ -1,34 +0,0 @@
-.Guest {
-  :global {
-    .guetsMain {
-      margin-top: 20px;
-      width: 100%;
-      height: calc(100% - 70px);
-      overflow-y: auto;
-
-      .guetsMainBox {
-        padding: 15px 30px 30px;
-        background-color: #fff;
-        border-radius: 10px;
-        min-height: 200px;
-
-        &:nth-of-type(1) {
-          margin-bottom: 20px;
-        }
-
-        .tit {
-          font-size: 16px;
-          .time{
-            font-size: 14px;
-            color: #999;
-          }
-        }
-        .txt{
-          margin-top: 20px;
-          font-size: 14px;
-          line-height: 30px;
-        }
-      }
-    }
-  }
-}

+ 0 - 183
后台/src/pages/A5Guest/index.tsx

@@ -1,183 +0,0 @@
-import {
-  getGuestInfoAPI,
-  setGuestGuideAPI,
-  setGuestNoticeAPI,
-} from "@/store/action/A5Guest";
-import { MessageFu } from "@/utils/message";
-import { Button, Popconfirm } from "antd";
-import TextArea from "antd/es/input/TextArea";
-import dayjs from "dayjs";
-import React, { useCallback, useEffect, useMemo, useState } from "react";
-import styles from "./index.module.scss";
-function Guest() {
-  const [edit1, setEdit1] = useState({
-    show: false,
-    txt: "",
-  });
-  const [value1, setValue1] = useState({
-    txt: "",
-    time: "",
-  });
-  const [edit2, setEdit2] = useState({
-    show: false,
-    txt: "",
-  });
-  const [value2, setValue2] = useState({
-    txt: "",
-    time: "",
-  });
-
-  // 进页面获取信息
-  const getInfoFu = useCallback(async () => {
-    const res = await getGuestInfoAPI();
-    setValue1(JSON.parse(res.data[0].content))
-    setValue2(JSON.parse(res.data[1].content))
-  }, []);
-
-  useEffect(() => {
-    getInfoFu();
-  }, [getInfoFu]);
-
-  const txt1 = useMemo(() => {
-    if (value1.txt.replaceAll(" ", "").replaceAll("\n", "") === "") return "";
-    return value1.txt.replaceAll(" ", "&emsp;").replaceAll("\n", "<br/>");
-  }, [value1.txt]);
-
-  const txt2 = useMemo(() => {
-    if (value2.txt.replaceAll(" ", "").replaceAll("\n", "") === "") return "";
-    return value2.txt.replaceAll(" ", "&emsp;").replaceAll("\n", "<br/>");
-  }, [value2.txt]);
-
-  const editFu = useCallback(
-    (val: number) => {
-      if (val === 1) setEdit1({ show: true, txt: value1.txt });
-      else setEdit2({ show: true, txt: value2.txt });
-    },
-    [value1.txt, value2.txt]
-  );
-
-  const btnOk = useCallback(
-    async (val: number) => {
-      const data = {
-        txt: val === 1 ? edit1.txt : edit2.txt,
-        time: dayjs(new Date()).format("YYYY-MM-DD HH:mm"),
-      };
-
-      const res =
-        val === 1
-          ? await setGuestGuideAPI(JSON.stringify(data))
-          : await setGuestNoticeAPI(JSON.stringify(data));
-
-      if (res.code === 0) {
-        val === 1
-          ? setEdit1({ txt: "", show: false })
-          : setEdit2({ txt: "", show: false });
-        MessageFu.success("修改成功!");
-        getInfoFu()
-      }
-    },
-    [edit1.txt, edit2.txt, getInfoFu]
-  );
-
-  return (
-    <div className={styles.Guest}>
-      <div className="pageTitle">游客服务</div>
-      <div className="guetsMain mySorrl">
-        <div className="guetsMainBox">
-          <div className="tit">
-            参观指南:&emsp;
-            {edit1.show ? (
-              <>
-                <Button type="primary" onClick={() => btnOk(1)}>
-                  保存
-                </Button>
-                &emsp;
-                <Popconfirm
-                  title="放弃编辑后,信息将不会保存!"
-                  okText="放弃"
-                  cancelText="取消"
-                  onConfirm={() => setEdit1({ ...edit1, show: false })}
-                >
-                  <Button>取消</Button>
-                </Popconfirm>
-                <br />
-                <br />
-                <TextArea
-                  value={edit1.txt}
-                  onChange={(e) =>
-                    setEdit1({ show: true, txt: e.target.value })
-                  }
-                  autoSize
-                  placeholder="请输入内容"
-                  showCount
-                  maxLength={500}
-                />
-              </>
-            ) : (
-              <>
-                <Button type="primary" onClick={() => editFu(1)}>
-                  修改
-                </Button>
-                &emsp;&emsp;
-                <span className="time">最近编辑时间:{value1.time}</span>
-                <div
-                  className="txt"
-                  dangerouslySetInnerHTML={{ __html: txt1 ? txt1 : "(空)" }}
-                ></div>
-              </>
-            )}
-          </div>
-        </div>
-        <div className="guetsMainBox">
-          <div className="tit">
-            参观须知:&emsp;
-            {edit2.show ? (
-              <>
-                <Button type="primary" onClick={() => btnOk(2)}>
-                  保存
-                </Button>
-                &emsp;
-                <Popconfirm
-                  title="放弃编辑后,信息将不会保存!"
-                  okText="放弃"
-                  cancelText="取消"
-                  onConfirm={() => setEdit2({ ...edit2, show: false })}
-                >
-                  <Button>取消</Button>
-                </Popconfirm>
-                <br />
-                <br />
-                <TextArea
-                  value={edit2.txt}
-                  onChange={(e) =>
-                    setEdit2({ show: true, txt: e.target.value })
-                  }
-                  autoSize
-                  placeholder="请输入内容"
-                  showCount
-                  maxLength={500}
-                />
-              </>
-            ) : (
-              <>
-                <Button type="primary" onClick={() => editFu(2)}>
-                  修改
-                </Button>
-                &emsp;&emsp;
-                <span className="time">最近编辑时间:{value2.time}</span>
-                <div
-                  className="txt"
-                  dangerouslySetInnerHTML={{ __html: txt2 ? txt2 : "(空)" }}
-                ></div>
-              </>
-            )}
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}
-
-const MemoGuest = React.memo(Guest);
-
-export default MemoGuest;

+ 5 - 0
后台/src/pages/A6Guide/index.module.scss

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

+ 14 - 0
后台/src/pages/A6Guide/index.tsx

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

+ 5 - 0
后台/src/pages/A7Hotspot/index.module.scss

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

+ 14 - 0
后台/src/pages/A7Hotspot/index.tsx

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

+ 5 - 0
后台/src/pages/A8User/index.module.scss

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

+ 14 - 0
后台/src/pages/A8User/index.tsx

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

+ 35 - 49
后台/src/pages/Layout/index.tsx

@@ -15,77 +15,67 @@ import history from "@/utils/history";
 import { Button, Form, Input, Modal, Popconfirm } from "antd";
 import { Base64 } from "js-base64";
 import encodeStr from "@/utils/pass";
-import { getDictListAPI, passWordEditAPI } from "@/store/action/layout";
+import { passWordEditAPI } from "@/store/action/layout";
 import { getTokenInfo, removeTokenInfo } from "@/utils/storage";
-import { useDispatch } from "react-redux";
-import inco1 from "@/assets/img/inco1.png";
-import inco2 from "@/assets/img/inco2.png";
-import inco3 from "@/assets/img/inco3.png";
-import inco4 from "@/assets/img/inco4.png";
-import inco5 from "@/assets/img/inco5.png";
-import inco1Ac from "@/assets/img/inco1Ac.png";
-import inco2Ac from "@/assets/img/inco2Ac.png";
-import inco3Ac from "@/assets/img/inco3Ac.png";
-import inco4Ac from "@/assets/img/inco4Ac.png";
-import inco5Ac from "@/assets/img/inco5Ac.png";
-import logonImg from "@/assets/img/logo2.png";
 import { MessageFu } from "@/utils/message";
+import logonImg from "@/assets/img/logo.png";
 
 const NotFound = React.lazy(() => import("@/components/NotFound"));
 
 function Layout() {
-  const dispatch = useDispatch();
-
   const list = useMemo(() => {
     return [
       {
         id: 100,
-        name: "热度统计",
+        name: "统计看板",
         path: "/",
-        Com: React.lazy(() => import("../A1Hot")),
-        inco: inco1,
-        incoAc: inco1Ac,
+        Com: React.lazy(() => import("../A1Stat")),
       },
       {
         id: 200,
-        name: "资讯管理",
-        path: "/news",
-        Com: React.lazy(() => import("../A2News")),
-        inco: inco2,
-        incoAc: inco2Ac,
+        name: "收集问卷",
+        path: "/gather",
+        Com: React.lazy(() => import("../A2Gather")),
       },
       {
         id: 300,
-        name: "馆藏管理",
-        path: "/goods",
-        Com: React.lazy(() => import("../A3Goods")),
-        inco: inco3,
-        incoAc: inco3Ac,
+        name: "产品手册",
+        path: "/book",
+        Com: React.lazy(() => import("../A3Book")),
       },
       {
         id: 400,
-        name: "场馆管理",
-        path: "/venue",
-        Com: React.lazy(() => import("../A4Venue")),
-        inco: inco4,
-        incoAc: inco4Ac,
+        name: "访问量",
+        path: "/visit",
+        Com: React.lazy(() => import("../A4Visit")),
       },
       {
         id: 500,
-        name: "游客服务",
-        path: "/guest",
-        Com: React.lazy(() => import("../A5Guest")),
-        inco: inco5,
-        incoAc: inco5Ac,
+        name: "线上展厅访问量",
+        path: "/gallery",
+        Com: React.lazy(() => import("../A5Gallery")),
+      },
+      {
+        id: 600,
+        name: "导航区域访问量",
+        path: "/guide",
+        Com: React.lazy(() => import("../A6Guide")),
+      },
+      {
+        id: 700,
+        name: "热点访问量",
+        path: "/hotspot",
+        Com: React.lazy(() => import("../A7Hotspot")),
+      },
+      {
+        id: 800,
+        name: "用户管理",
+        path: "/user",
+        Com: React.lazy(() => import("../A8User")),
       },
     ];
   }, []);
 
-  // 进页面获取所有下拉信息
-  useEffect(() => {
-    dispatch(getDictListAPI());
-  }, [dispatch]);
-
   // 点击跳转
   const pathCutFu = useCallback((path: string) => {
     history.push(path);
@@ -137,9 +127,7 @@ function Layout() {
   // 点击退出登录
   const loginExit = () => {
     removeTokenInfo();
-    // history.push("/login");
-    // 跳到前台页面
-    window.location.href = "/web/index.html";
+    history.push("/login");
   };
 
   return (
@@ -160,8 +148,6 @@ function Layout() {
                 v.path === path ? "active" : ""
               )}
             >
-              <img className="tabImg" src={v.inco} alt="" />
-              <img className="tabImgAc" src={v.incoAc} alt="" />
               <div className="txt">{v.name}</div>
             </div>
           ))}

+ 36 - 43
后台/src/pages/Login/index.module.scss

@@ -1,73 +1,66 @@
 .Login {
   width: 100%;
   height: 100%;
-  background-image: url('../../assets/img/bg.jpg');
+  background-image: url('../../assets/img/loginBg.png');
   background-size: cover;
   position: relative;
 
-  &::before {
-    content: '';
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    background-color: rgba(0, 0, 0, .4);
-  }
 
   :global {
+    .bottomLogo {
+      position: absolute;
+      bottom: 50px;
+      left: 50%;
+      transform: translateX(-50%);
+
+      &>img {
+        width: 180px;
+      }
+    }
 
     .main {
-      border-top: 3px solid rgba(200, 185, 146, .8);
-      border-radius: 6px;
       position: absolute;
-      top: 50%;
-      right: 240px;
-      transform: translateY(-50%);
-      width: 530px;
-      height: 720px;
-      padding-top: 60px;
+      top: 48%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+      width: 400px;
       text-align: center;
-      background-image: url('../../assets/img/loginBox.jpg');
-      background-size: 100% 100%;
 
-      .logo {
-        margin: 30px auto 0;
-        width: 375px;
-        height: 120px;
+      &>h3 {
+        font-size: 24px;
+        letter-spacing: 6px;
+        color: #fff;
       }
 
-
       .inputBox {
         width: 100%;
 
         input::-webkit-input-placeholder {
           /* WebKit browsers */
-          color: rgba(157, 107, 57, .5);
+          color: rgba(255, 255, 255, .5);
         }
 
         input:-moz-placeholder {
           /* Mozilla Firefox 4 to 18 */
-          color: rgba(157, 107, 57, .5);
+          color: rgba(255, 255, 255, .5);
         }
 
         input::-moz-placeholder {
           /* Mozilla Firefox 19+ */
-          color: rgba(157, 107, 57, .5);
+          color: rgba(255, 255, 255, .5);
         }
 
         input:-ms-input-placeholder {
           /* Internet Explorer 10+ */
-          color: rgba(157, 107, 57, .5);
+          color: rgba(255, 255, 255, .5);
         }
 
 
         .inputBoxRow {
-          width: 370px;
-          margin: 50px auto;
+          margin-top: 30px;
 
           .ant-input-suffix .ant-input-password-icon {
-            color: var(--themeColor);
+            color: #fff;
             font-size: 22px;
           }
         }
@@ -88,6 +81,7 @@
         }
 
         .ant-input {
+          color: #fff;
           font-size: 18px;
           width: 45%;
           height: 60px;
@@ -97,7 +91,7 @@
 
         input:-webkit-autofill {
           font-size: 18px !important;
-          -webkit-text-fill-color: var(--themeColor) !important;
+          -webkit-text-fill-color: #fff !important;
           background-image: none;
           -webkit-box-shadow: 0 0 0px 1000px transparent inset !important; //填充阴影,可以用来遮住背景色
           background-color: transparent;
@@ -111,9 +105,8 @@
           width: 100%;
           height: 60px;
           border: none;
-          border-bottom: 1px solid var(--themeColor);
-          border-radius: 0;
-          color: var(--themeColor);
+          border: 1px solid #fff;
+          color: #fff;
 
           .ant-input {
             background-color: transparent;
@@ -122,17 +115,17 @@
           }
         }
 
-        .ant-input-affix-wrapper-focused {
-          box-shadow: none
-        }
+        // .ant-input-affix-wrapper-focused {
+        //   box-shadow: none
+        // }
       }
 
       .loginBtn {
-        margin-top: 100px;
+        margin-top: 30px;
+
         .ant-btn {
-          border-radius: 25px;
-          font-size: 24px;
-          width: 375px;
+          width: 100%;
+          font-size: 20px;
           height: 50px;
         }
       }

+ 7 - 4
后台/src/pages/Login/index.tsx

@@ -41,15 +41,18 @@ export default function Login() {
 
   return (
     <div className={styles.Login}>
+
+    {/* 底部logo */}
+    <div className="bottomLogo">
+      <img src={logoImg} alt="" />
+    </div>
+
       <div className="main">
-        <div className="logo">
-          <img src={logoImg} alt="" />
-        </div>
+      <h3>后台管理系统</h3>
         {/* 账号密码输入框 */}
         <div className="inputBox">
           <div className="inputBoxRow">
             <Input
-              disabled
               onKeyUp={(e) => keyUpEntFu(e)}
               value={userName}
               onChange={(e) => setUserName(e.target.value.trim())}

+ 0 - 31
后台/src/store/action/A1Hot.ts

@@ -1,31 +0,0 @@
-import { HotSelectTimeType, HotSelectType } from "@/types";
-import http from "@/utils/http";
-
-/**
- * 统计热门板块
- */
-export const getHotModuleAPI = (dayScope: HotSelectTimeType) => {
-  return http.get(`cms/report/ranking/module?dayScope=${dayScope}`);
-};
-
-/**
- * 统计-热门场馆
- */
-export const getHotExhibitionAPI = (
-  dayScope: HotSelectTimeType,
-  type: HotSelectType
-) => {
-  return http.get(
-    `cms/report/ranking/exhibition?dayScope=${dayScope}&type=${type}`
-  );
-};
-
-/**
- * 统计-热门场馆
- */
-export const getHotGoodsAPI = (
-  dayScope: HotSelectTimeType,
-  type: HotSelectType
-) => {
-  return http.get(`cms/report/ranking/goods?dayScope=${dayScope}&type=${type}`);
-};

+ 0 - 72
后台/src/store/action/A2News.ts

@@ -1,72 +0,0 @@
-import { NewsSaveApiType, NewsTableApiType } from "@/types";
-import { domShowFu, progressDomFu } from "@/utils/domShow";
-import http from "@/utils/http";
-import axios from "axios";
-import store, { AppDispatch } from "..";
-
-const CancelToken = axios.CancelToken;
-/**
- * 上传封面图和附件
- */
-export const newsUploadAPI = (data: any) => {
-  domShowFu("#UpAsyncLoding", true);
-
-  return http.post("cms/news/upload", data, {
-    timeout: 0,
-    // 显示进度条
-    onUploadProgress: (e: any) => {
-      const complete = (e.loaded / e.total) * 100 || 0;
-      progressDomFu(complete + "%");
-    },
-    // 取消上传
-    cancelToken: new CancelToken(function executor(c) {
-      store.dispatch({
-        type: "layout/closeUpFile",
-        payload: { fu: c, state: true },
-      });
-    }),
-  });
-};
-
-/**
- * 新增|编辑
- */
-export const newSaveAPI = (data: NewsSaveApiType) => {
-  return http.post("cms/news/save", data);
-};
-
-/**
- * 获取列表数据
- */
-export const getNewsListAPI = (data: NewsTableApiType) => {
-  return async (dispatch: AppDispatch) => {
-    const res = await http.post("cms/news/getList", data);
-    if (res.code === 0) {
-      dispatch({
-        type: "news/getList",
-        payload: res.data,
-      });
-    }
-  };
-};
-
-/**
- * 删除
- */
-export const newRemoveAPI = (id: number) => {
-  return http.get(`cms/news/remove/${id}`);
-};
-
-/**
- * 详情
- */
-export const getNewsDetailAPI = (id: number) => {
-  return http.get(`cms/news/detail/${id}`);
-};
-
-/**
- * 拖动排序
- */
-export const newSortApi = (id1: number, id2: number) => {
-  return http.get(`cms/news/sort/${id1}/${id2}`);
-};

+ 0 - 71
后台/src/store/action/A3Goods.ts

@@ -1,71 +0,0 @@
-import { GoodsTableType } from "@/types";
-import { domShowFu, progressDomFu } from "@/utils/domShow";
-import http from "@/utils/http";
-import axios from "axios";
-import store, { AppDispatch } from "..";
-/**
- * 获取列表数据
- */
-export const getGoodsListAPI = (data: any) => {
-  return async (dispatch: AppDispatch) => {
-    const res = await http.post("cms/goods/pageList", data);
-    if (res.code === 0) {
-      dispatch({
-        type: "goods/getList",
-        payload: { list: res.data.records, total: res.data.total },
-      });
-    }
-  };
-};
-
-/**
- * 内容-是否显示
- */
-export const goodsDisplayAPI = (id: number, display: number) => {
-  return http.get(`cms/goods/display/${id}/${display}`);
-};
-
-/**
- * 删除藏品
- */
-export const goodsRemoveAPI = (id: number) => {
-  return http.get(`cms/goods/remove/${id}`);
-};
-
-const CancelToken = axios.CancelToken;
-/**
- * 上传封面图和附件
- */
-export const goodsUploadAPI = (data: any) => {
-  domShowFu("#UpAsyncLoding", true);
-
-  return http.post("cms/goods/upload", data, {
-    timeout: 0,
-    // 显示进度条
-    onUploadProgress: (e: any) => {
-      const complete = (e.loaded / e.total) * 100 || 0;
-      progressDomFu(complete + "%");
-    },
-    // 取消上传
-    cancelToken: new CancelToken(function executor(c) {
-      store.dispatch({
-        type: "layout/closeUpFile",
-        payload: { fu: c, state: true },
-      });
-    }),
-  });
-};
-
-/**
- * 新增|编辑
- */
-export const getGoodsSaveAPI = (data: GoodsTableType) => {
-  return http.post("cms/goods/save", data);
-};
-
-/**
- * 通过id获取详情
- */
-export const getGoodsInfoByIdAPI = (id: number) => {
-  return http.get(`cms/goods/detail/${id}`);
-};

+ 0 - 65
后台/src/store/action/A4Venue.ts

@@ -1,65 +0,0 @@
-import { VenueTableApiType, VenueTableType } from "@/types";
-import { domShowFu, progressDomFu } from "@/utils/domShow";
-import http from "@/utils/http";
-import axios from "axios";
-import store, { AppDispatch } from "..";
-
-const CancelToken = axios.CancelToken;
-/**
- * 上传封面图和附件
- */
-export const venueUploadAPI = (data: any) => {
-  domShowFu("#UpAsyncLoding", true);
-
-  return http.post("cms/exhibition/upload", data, {
-    timeout: 0,
-    // 显示进度条
-    onUploadProgress: (e: any) => {
-      const complete = (e.loaded / e.total) * 100 || 0;
-      progressDomFu(complete + "%");
-    },
-    // 取消上传
-    cancelToken: new CancelToken(function executor(c) {
-      store.dispatch({
-        type: "layout/closeUpFile",
-        payload: { fu: c, state: true },
-      });
-    }),
-  });
-};
-
-/**
- * 获取列表数据
- */
-export const getVenueListAPI = (data: VenueTableApiType) => {
-  return async (dispatch: AppDispatch) => {
-    const res = await http.post("cms/exhibition/getList", data);
-    if (res.code === 0) {
-      dispatch({
-        type: "venue/getList",
-        payload: res.data,
-      });
-    }
-  };
-};
-
-/**
- * 详情
- */
-export const getVenueDetailAPI = (id: number) => {
-  return http.get(`cms/exhibition/detail/${id}`);
-};
-
-/**
- * 拖动排序
- */
-export const venueSortApi = (id1: number, id2: number) => {
-  return http.get(`cms/exhibition/sort/${id1}/${id2}`);
-};
-
-/**
- * 新增|编辑
- */
-export const setVenueSaveApi = (data: VenueTableType) => {
-  return http.post("cms/exhibition/save", data);
-};

+ 0 - 22
后台/src/store/action/A5Guest.ts

@@ -1,22 +0,0 @@
-import http from "@/utils/http";
-
-/**
- * 配置-获取
- */
-export const getGuestInfoAPI = () => {
-  return http.get("cms/visitor/getConfig");
-};
-
-/**
- * 修改参观指南
- */
-export const setGuestGuideAPI = (data: string) => {
-  return http.post("cms/visitor/setConfigByGuide", { content: data });
-};
-
-/**
- * 参观须知-修改
- */
-export const setGuestNoticeAPI = (data: string) => {
-  return http.post("cms/visitor/setConfigByNotice", { content: data });
-};

+ 1 - 23
后台/src/store/action/layout.ts

@@ -1,6 +1,5 @@
-import { DictListTypeAPI, DictListTypeObj } from "@/types";
 import http from "@/utils/http";
-import { AppDispatch } from "..";
+// import { AppDispatch } from "..";
 
 /**
  * 用户登录接口
@@ -16,24 +15,3 @@ export const passWordEditAPI = (data: any) => {
   return http.post("sys/user/updatePwd", { ...data });
 };
 
-/**
- * 获取下拉框数据
- */
-export const getDictListAPI = () => {
-  return async (dispatch: AppDispatch) => {
-    const res = await http.get("cms/dict/getList");
-    if (res.code === 0) {
-      const list: DictListTypeAPI[] = res.data;
-      const obj = {
-        age: [{ label: "全部", value: "", type: "age" }],
-        texture: [{ label: "全部", value: "", type: "texture" }],
-      } as DictListTypeObj;
-      list.forEach((v) => {
-        if (obj[v.type])
-          obj[v.type].push({ label: v.name, value: v.name, type: v.type });
-      });
-
-      dispatch({ type: "layout/getDictList", payload: obj });
-    }
-  };
-};

+ 0 - 29
后台/src/store/reducer/A2News.ts

@@ -1,29 +0,0 @@
-import { NewsTableType } from "@/types";
-
-// 初始化状态
-const initState = {
-  // 表格数据
-  tableInfo: [] as NewsTableType[],
-
-  // 表格的滚动位置
-  sroolNum: 0,
-};
-
-// 定义 action 类型
-type NewsActionType =
-  | { type: "news/getList"; payload: NewsTableType[] }
-  | { type: "news/setSroolNum"; payload: number };
-// 频道 reducer
-export default function newsReducer(state = initState, action: NewsActionType) {
-  switch (action.type) {
-    // 表格数据
-    case "news/getList":
-      return { ...state, tableInfo: action.payload };
-    // 表格的滚动位置
-    case "news/setSroolNum":
-      return { ...state, sroolNum: action.payload };
-
-    default:
-      return state;
-  }
-}

+ 0 - 30
后台/src/store/reducer/A3Goods.ts

@@ -1,30 +0,0 @@
-import { GoodsTableType } from "@/types";
-
-// 初始化状态
-const initState = {
-  // 列表数据
-  tableInfo: {
-    list: [] as GoodsTableType[],
-    total: 0,
-  },
-};
-
-// 定义 action 类型
-type GoodsActionType = {
-  type: "goods/getList";
-  payload: { list: GoodsTableType[]; total: number };
-};
-
-// 频道 reducer
-export default function goodsReducer(
-  state = initState,
-  action: GoodsActionType
-) {
-  switch (action.type) {
-    // 获取列表数据
-    case "goods/getList":
-      return { ...state, tableInfo: action.payload };
-    default:
-      return state;
-  }
-}

+ 0 - 21
后台/src/store/reducer/A4Venue.ts

@@ -1,21 +0,0 @@
-import { VenueTableType } from "@/types";
-
-// 初始化状态
-const initState = {
-  // 表格数据
-  tableInfo: [] as VenueTableType[],
-};
-
-// 定义 action 类型
-type VenueActionType = { type: "venue/getList"; payload: VenueTableType[] };
-
-// 频道 reducer
-export default function venueReducer(state = initState, action: VenueActionType) {
-  switch (action.type) {
-    // 表格数据
-    case "venue/getList":
-      return { ...state, tableInfo: action.payload };
-    default:
-      return state;
-  }
-}

+ 5 - 13
后台/src/store/reducer/index.ts

@@ -1,19 +1,11 @@
-// 导入合并reducer的依赖
-import { combineReducers } from 'redux'
-import newsReducer from './A2News'
-import goodsReducer from './A3Goods'
-import venueReducer from './A4Venue'
+import { combineReducers } from "redux";
 
-// 导入 登录 模块的 reducer
-import layoutReducer from './layout'
+import A0layout from "./layout";
 
 // 合并 reducer
 const rootReducer = combineReducers({
-  layoutStore: layoutReducer,
-  newsReducer:newsReducer,
-  goodsReducer:goodsReducer,
-  venueReducer:venueReducer
-})
+  A0layout,
+});
 
 // 默认导出
-export default rootReducer
+export default rootReducer;

+ 0 - 27
后台/src/store/reducer/layout.ts

@@ -1,22 +1,7 @@
-import { DictListTypeObj } from "@/types";
 import { MessageType } from "@/utils/message";
 
 // 初始化状态
 const initState = {
-  // 所有图片点击预览查看大图
-  lookBigImg: {
-    url: "",
-    show: false,
-  },
-  // 视频的src
-  videoSrc: "",
-
-  // 所有的下拉框数据
-  dictList: {
-    age: [],
-    texture: [],
-  } as DictListTypeObj,
-
   message: {
     txt: "",
     type: "info",
@@ -31,10 +16,7 @@ const initState = {
 
 // 定义 action 类型
 type LayoutActionType =
-  | { type: "layout/lookBigImg"; payload: { url: string; show: boolean } }
-  | { type: "layout/lookVideo"; payload: string }
   | { type: "layout/message"; payload: MessageType }
-  | { type: "layout/getDictList"; payload: DictListTypeObj }
   | {
       type: "layout/closeUpFile";
       payload: {
@@ -49,15 +31,6 @@ export default function layoutReducer(
   action: LayoutActionType
 ) {
   switch (action.type) {
-    // 所有图片点击预览查看大图
-    case "layout/lookBigImg":
-      return { ...state, lookBigImg: action.payload };
-    // 查看视频
-    case "layout/lookVideo":
-      return { ...state, videoSrc: action.payload };
-    // 所有的下拉框数据
-    case "layout/getDictList":
-      return { ...state, dictList: action.payload };
     // antd轻提示(兼容360浏览器)
     case "layout/message":
       return { ...state, message: action.payload };

+ 0 - 8
后台/src/types/api/A1Hot.d.ts

@@ -1,8 +0,0 @@
-export type HotSelectType = "visit" | "star" | "";
-
-export type HotSelectTimeType = 1 | 7 | 30 | "";
-
-export type HotData1Type = {
-  pcs: number;
-  groupKey: string;
-};

+ 0 - 41
后台/src/types/api/A2News.d.ts

@@ -1,41 +0,0 @@
-export type NewsTableType = {
-	createTime: string;
-	creatorId: number;
-	creatorName: string;
-	description: string;
-	dirCode: string;
-	display: number;
-	fileIds: string;
-	id: number;
-	name: string;
-	newsDay: string;
-	thumb: string;
-	type: string;
-	updateTime: string;
-}
-
-export type NewsSaveApiType = {
-  description?: string;
-  dirCode: string;
-  display: number;
-  fileIds: string;
-  id: number | null;
-  name: string;
-  newsDay: string;
-  thumb: string;
-  type: "news" | "video" | "img";
-};
-
-export type NewsTableApiType = {
-  type: "news" | "video" | "img";
-  searchKey: string;
-  display: number|null;
-  pageSize: number;
-  pageNum: number;
-};
-
-export type NewsButtonType = {
-  id: number;
-  name: string;
-  type: "news" | "video" | "img";
-};

+ 0 - 33
后台/src/types/api/A3Goods.d.ts

@@ -1,33 +0,0 @@
-export type GoodsTableType = {
-  createTime: string;
-  creatorId: number;
-  creatorName: string;
-  description: string;
-  dictAge: string;
-  dictLevel: string;
-  dictSource: string;
-  dictTexture: string;
-  dirCode: string;
-  display: number;
-  fileIds: string;
-  id: number;
-  isBarrage: number;
-  name: string;
-  num: string;
-  thumb: string;
-  topic: string;
-  type: string;
-  updateTime: string;
-  tagType?:string
-  tagCountry?:string
-};
-
-export type FileListType = {
-  fileName?: string;
-  filePath?: string;
-  id?: number;
-  isFrame?: boolean;
-  done?: boolean;
-  type?: "model" | "img" | "audio" | "video";
-};
-

+ 0 - 22
后台/src/types/api/A4Venue.d.ts

@@ -1,22 +0,0 @@
-export type VenueTableType = {
-  createTime: string;
-  creatorId?: any;
-  creatorName: string;
-  description: string;
-  dirCode: string;
-  fileIds: string;
-  id: number|null;
-  location: string;
-  name: string;
-  sort?: any;
-  thumb: string;
-  updateTime: string;
-};
-
-export type VenueTableApiType = {
-  searchKey: string;
-  startTime: string;
-  endTime: string;
-  pageSize: number;
-  pageNum: number;
-};

+ 0 - 24
后台/src/types/api/layot.d.ts

@@ -1,24 +0,0 @@
-
-export type DictListTypeObj = {
-  age: DictListType[];
-  texture: DictListType[];
-};
-
-export type DictListTypeAPI = {
-  createTime: null;
-  creatorId: null;
-  creatorName: string;
-  display: number;
-  id: string;
-  name: string;
-  parentId: null;
-  sort: null;
-  type: "age" | "texture" 
-  updateTime: null;
-};
-
-export type ImgListType = {
-  fileName: string;
-  filePath: string;
-  id: number;
-};

+ 1 - 5
后台/src/types/index.d.ts

@@ -1,6 +1,2 @@
-export * from './api/layot'
-export * from './api/A1Hot'
+// export * from './api/layot'
 
-export * from './api/A2News'
-export * from './api/A3Goods'
-export * from './api/A4Venue'

+ 1 - 1
后台/src/utils/domShow.ts

@@ -26,7 +26,7 @@ export const fileDomInitialFu = () => {
   progressDomFu("0%");
   // 初始化 上传附件 的状态
   setTimeout(() => {
-    if (store.getState().layoutStore.closeUpFile.state)
+    if (store.getState().A0layout.closeUpFile.state)
       store.dispatch({
         type: "layout/closeUpFile",
         payload: { fu: () => {}, state: false },

+ 1 - 1
后台/src/utils/http.ts

@@ -79,7 +79,7 @@ http.interceptors.response.use(
       domShowFu("#AsyncSpinLoding", false);
       // 如果因为网络原因,response没有,给提示消息
       if (!err.response) {
-        if (store.getState().layoutStore.closeUpFile.state)
+        if (store.getState().A0layout.closeUpFile.state)
           MessageFu.warning("取消上传!");
         else MessageFu.error("网络繁忙,请稍后重试!");
       } else MessageFu.error("响应错误,请联系管理员!");