shaogen1995 2 năm trước cách đây
mục cha
commit
fed54939b4
62 tập tin đã thay đổi với 373 bổ sung4550 xóa
  1. BIN
      管理后台/public/favicon.ico
  2. 1 1
      管理后台/src/App.tsx
  3. BIN
      管理后台/src/assets/img/bg.jpg
  4. BIN
      管理后台/src/assets/img/bg.png
  5. 1 1
      管理后台/src/assets/styles/base.css
  6. 1 1
      管理后台/src/assets/styles/base.less
  7. 1 1
      管理后台/src/components/Message/index.tsx
  8. 1 1
      管理后台/src/components/UpAsyncLoding/index.tsx
  9. 1 1
      管理后台/src/components/VideoLookDom/index.tsx
  10. 1 1
      管理后台/src/index.tsx
  11. 5 0
      管理后台/src/pages/A1Goods/index.module.scss
  12. 14 0
      管理后台/src/pages/A1Goods/index.tsx
  13. 0 116
      管理后台/src/pages/A1Hot/index.module.scss
  14. 0 314
      管理后台/src/pages/A1Hot/index.tsx
  15. 0 181
      管理后台/src/pages/A2News/NewsAdd/index.module.scss
  16. 0 530
      管理后台/src/pages/A2News/NewsAdd/index.tsx
  17. 0 49
      管理后台/src/pages/A2News/NewsTable/index.module.scss
  18. 0 245
      管理后台/src/pages/A2News/NewsTable/index.tsx
  19. 0 20
      管理后台/src/pages/A2News/index.module.scss
  20. 0 181
      管理后台/src/pages/A2News/index.tsx
  21. 5 0
      管理后台/src/pages/A2Wall/index.module.scss
  22. 14 0
      管理后台/src/pages/A2Wall/index.tsx
  23. 0 198
      管理后台/src/pages/A3Goods/GoodsAdd/index.module.scss
  24. 0 745
      管理后台/src/pages/A3Goods/GoodsAdd/index.tsx
  25. 0 43
      管理后台/src/pages/A3Goods/index.module.scss
  26. 0 311
      管理后台/src/pages/A3Goods/index.tsx
  27. 5 0
      管理后台/src/pages/A3User/index.module.scss
  28. 14 0
      管理后台/src/pages/A3User/index.tsx
  29. 5 0
      管理后台/src/pages/A4Role/index.module.scss
  30. 14 0
      管理后台/src/pages/A4Role/index.tsx
  31. 0 139
      管理后台/src/pages/A4Venue/VenueEdit/index.module.scss
  32. 0 317
      管理后台/src/pages/A4Venue/VenueEdit/index.tsx
  33. 0 49
      管理后台/src/pages/A4Venue/VenueTable/index.module.scss
  34. 0 203
      管理后台/src/pages/A4Venue/VenueTable/index.tsx
  35. 0 20
      管理后台/src/pages/A4Venue/index.module.scss
  36. 0 122
      管理后台/src/pages/A4Venue/index.tsx
  37. 0 34
      管理后台/src/pages/A5Guest/index.module.scss
  38. 0 183
      管理后台/src/pages/A5Guest/index.tsx
  39. 33 0
      管理后台/src/pages/A5Log/index.module.scss
  40. 137 0
      管理后台/src/pages/A5Log/index.tsx
  41. 14 25
      管理后台/src/pages/Layout/index.tsx
  42. 35 46
      管理后台/src/pages/Login/index.module.scss
  43. 2 6
      管理后台/src/pages/Login/index.tsx
  44. 0 31
      管理后台/src/store/action/A1Hot.ts
  45. 0 72
      管理后台/src/store/action/A2News.ts
  46. 0 71
      管理后台/src/store/action/A3Goods.ts
  47. 0 65
      管理后台/src/store/action/A4Venue.ts
  48. 0 22
      管理后台/src/store/action/A5Guest.ts
  49. 17 0
      管理后台/src/store/action/A5Log.ts
  50. 0 29
      管理后台/src/store/reducer/A2News.ts
  51. 0 30
      管理后台/src/store/reducer/A3Goods.ts
  52. 0 21
      管理后台/src/store/reducer/A4Venue.ts
  53. 27 0
      管理后台/src/store/reducer/A5Log.ts
  54. 5 8
      管理后台/src/store/reducer/index.ts
  55. 0 8
      管理后台/src/types/api/A1Hot.d.ts
  56. 0 41
      管理后台/src/types/api/A2News.d.ts
  57. 0 33
      管理后台/src/types/api/A3Goods.d.ts
  58. 0 22
      管理后台/src/types/api/A4Venue.d.ts
  59. 11 0
      管理后台/src/types/api/A5Log.d.ts
  60. 1 5
      管理后台/src/types/index.d.ts
  61. 1 1
      管理后台/src/utils/domShow.ts
  62. 7 7
      管理后台/src/utils/http.ts

BIN
管理后台/public/favicon.ico


+ 1 - 1
管理后台/src/App.tsx

@@ -18,7 +18,7 @@ const Login = React.lazy(() => import("./pages/Login"));
 export default function App() {
   // 从仓库中获取查看图片的信息
   const lookBigImg = useSelector(
-    (state: RootState) => state.layoutStore.lookBigImg
+    (state: RootState) => state.A1Layout.lookBigImg
   );
 
   return (

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


BIN
管理后台/src/assets/img/bg.png


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

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

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

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

+ 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.A1Layout.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.A1Layout.closeUpFile
   );
 
   const btnClose = useCallback(() => {

+ 1 - 1
管理后台/src/components/VideoLookDom/index.tsx

@@ -6,7 +6,7 @@ import store, { RootState } from "@/store";
 import { baseURL } from "@/utils/http";
 function VideoLookDom() {
   const videoSrc = useSelector(
-    (state: RootState) => state.layoutStore.videoSrc
+    (state: RootState) => state.A1Layout.videoSrc
   );
   return (
     <div

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

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

+ 5 - 0
管理后台/src/pages/A1Goods/index.module.scss

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

+ 14 - 0
管理后台/src/pages/A1Goods/index.tsx

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

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

+ 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/A2Wall/index.module.scss

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

+ 14 - 0
管理后台/src/pages/A2Wall/index.tsx

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

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

+ 5 - 0
管理后台/src/pages/A3User/index.module.scss

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

+ 14 - 0
管理后台/src/pages/A3User/index.tsx

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

+ 5 - 0
管理后台/src/pages/A4Role/index.module.scss

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

+ 14 - 0
管理后台/src/pages/A4Role/index.tsx

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

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

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

+ 33 - 0
管理后台/src/pages/A5Log/index.module.scss

@@ -0,0 +1,33 @@
+.A5Log {
+  :global {
+    .logTop {
+      margin-top: 15px;
+      border-radius: 10px;
+      background-color: #fff;
+
+      .tableSelectBox {
+        padding: 20px 24px;
+        display: flex;
+        align-items: center;
+
+        .row {
+          margin-right: 20px;
+        }
+      }
+    }
+
+    .tableMain {
+      border-radius: 10px;
+      margin-top: 15px;
+      height: calc(100% - 104px);
+      background-color: #fff;
+
+      .ant-table-body {
+        height: 608px;
+        overflow-y: auto !important;
+        overflow-y: overlay !important;
+
+      }
+    }
+  }
+}

+ 137 - 0
管理后台/src/pages/A5Log/index.tsx

@@ -0,0 +1,137 @@
+import { RootState } from "@/store";
+import { getLogListAPI } from "@/store/action/A5Log";
+import { Input, DatePicker, Table } from "antd";
+import React, { useEffect, useMemo, useRef, useState } from "react";
+import { useDispatch, useSelector } from "react-redux";
+
+import styles from "./index.module.scss";
+
+const { RangePicker } = DatePicker;
+
+function A5Log() {
+  const dispatch = useDispatch();
+
+  const pageNumRef = useRef(1);
+  const pagePageRef = useRef(10);
+  // 筛选和分页
+  const [tableSelect, setTableSelect] = useState({
+    searchKey: "",
+    pageSize: 10,
+    pageNum: 1,
+    startTime: "",
+    endTime: "",
+  });
+
+  // 账号的输入
+  const nameTime = useRef(-1);
+  const nameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    clearTimeout(nameTime.current);
+    nameTime.current = window.setTimeout(() => {
+      setTableSelect({ ...tableSelect, searchKey: e.target.value, pageNum: 1 });
+    }, 500);
+  };
+  // 时间选择器改变
+  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 });
+  };
+
+  useEffect(() => {
+    pageNumRef.current = tableSelect.pageNum;
+    pagePageRef.current = tableSelect.pageSize;
+    dispatch(getLogListAPI(tableSelect));
+  }, [dispatch, tableSelect]);
+
+  // ---------关于表格
+
+  // 页码变化
+  const paginationChange = (pageNum: number, pageSize: number) => {
+    pageNumRef.current = pageNum;
+    pagePageRef.current = pageSize;
+    setTableSelect({ ...tableSelect, pageNum, pageSize });
+  };
+
+  const results = useSelector((state: RootState) => state.A5Log.tableInfo);
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "序号",
+        render: (text: any, record: any, index: any) =>
+          index + 1 + (pageNumRef.current - 1) * pagePageRef.current,
+      },
+      {
+        title: "操作者",
+        dataIndex: "userName",
+      },
+      {
+        title: "操作日期",
+        dataIndex: "createTime",
+      },
+      {
+        title: "IP记录",
+        dataIndex: "ip",
+      },
+      {
+        title: "操作模块",
+        dataIndex: "type",
+      },
+      {
+        title: "操作事件",
+        dataIndex: "description",
+      },
+    ];
+  }, []);
+
+  return (
+    <div className={styles.A5Log}>
+      <div className="pageTitlt">操作日志</div>
+      <div className="logTop">
+        <div className="tableSelectBox">
+          <div className="row">
+            <span>账号:</span>
+            <Input
+              maxLength={15}
+              style={{ width: 150 }}
+              placeholder="请输入"
+              allowClear
+              onChange={(e) => nameChange(e)}
+            />
+          </div>
+          <div className="row">
+            <span>操作日期:</span>
+            <RangePicker onChange={timeChange} />
+          </div>
+        </div>
+      </div>
+
+      {/* 表格主体 */}
+      <div className="tableMain">
+        <Table
+          scroll={{ y: 608 }}
+          dataSource={results.list}
+          columns={columns}
+          rowKey="id"
+          pagination={{
+            showQuickJumper: true,
+            position: ["bottomCenter"],
+            showSizeChanger: true,
+            current: tableSelect.pageNum,
+            pageSize: tableSelect.pageSize,
+            total: results.total,
+            onChange: paginationChange,
+          }}
+        />
+      </div>
+    </div>
+  );
+}
+
+const MemoA5Log = React.memo(A5Log);
+
+export default MemoA5Log;

+ 14 - 25
管理后台/src/pages/Layout/index.tsx

@@ -23,11 +23,6 @@ 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";
 
@@ -40,43 +35,38 @@ function Layout() {
     return [
       {
         id: 100,
-        name: "热度统计",
+        name: "馆藏管理",
         path: "/",
-        Com: React.lazy(() => import("../A1Hot")),
+        Com: React.lazy(() => import("../A1Goods")),
         inco: inco1,
-        incoAc: inco1Ac,
       },
       {
         id: 200,
-        name: "资讯管理",
-        path: "/news",
-        Com: React.lazy(() => import("../A2News")),
+        name: "万物墙管理",
+        path: "/wall",
+        Com: React.lazy(() => import("../A2Wall")),
         inco: inco2,
-        incoAc: inco2Ac,
       },
       {
         id: 300,
-        name: "馆藏管理",
-        path: "/goods",
-        Com: React.lazy(() => import("../A3Goods")),
+        name: "用户管理",
+        path: "/user",
+        Com: React.lazy(() => import("../A3User")),
         inco: inco3,
-        incoAc: inco3Ac,
       },
       {
         id: 400,
-        name: "场馆管理",
-        path: "/venue",
-        Com: React.lazy(() => import("../A4Venue")),
+        name: "角色管理",
+        path: "/role",
+        Com: React.lazy(() => import("../A4Role")),
         inco: inco4,
-        incoAc: inco4Ac,
       },
       {
         id: 500,
-        name: "游客服务",
-        path: "/guest",
-        Com: React.lazy(() => import("../A5Guest")),
+        name: "操作日志",
+        path: "/log",
+        Com: React.lazy(() => import("../A5Log")),
         inco: inco5,
-        incoAc: inco5Ac,
       },
     ];
   }, []);
@@ -161,7 +151,6 @@ function Layout() {
               )}
             >
               <img className="tabImg" src={v.inco} alt="" />
-              <img className="tabImgAc" src={v.incoAc} alt="" />
               <div className="txt">{v.name}</div>
             </div>
           ))}

+ 35 - 46
管理后台/src/pages/Login/index.module.scss

@@ -1,7 +1,7 @@
 .Login {
   width: 100%;
   height: 100%;
-  background-image: url('../../assets/img/bg.jpg');
+  background-image: url('../../assets/img/bg.png');
   background-size: cover;
   position: relative;
 
@@ -18,56 +18,45 @@
   :global {
 
     .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;
+      left: 50%;
+      transform: translate(-50%,-50%);
+      width: 600px;
+      padding: 60px;
       text-align: center;
-      background-image: url('../../assets/img/loginBox.jpg');
-      background-size: 100% 100%;
-
-      .logo {
-        margin: 30px auto 0;
-        width: 375px;
-        height: 120px;
+      background-color: rgba(238, 244, 248, 0.70);
+
+
+      .mainTitle{
+        padding-left: 50px;
+        font-size: 24px;
+        font-weight: 700;
+        color: #131C28;
+        text-align: left;
+        position: relative;
+        margin-bottom: 20px;
+        &::before{
+          content: '';
+          position: absolute;
+          top: 0;
+          left: 0;
+          width: 6px;
+          height: 100%;
+          background-color: #131C28;
+        }
       }
 
-
       .inputBox {
         width: 100%;
-
-        input::-webkit-input-placeholder {
-          /* WebKit browsers */
-          color: rgba(157, 107, 57, .5);
-        }
-
-        input:-moz-placeholder {
-          /* Mozilla Firefox 4 to 18 */
-          color: rgba(157, 107, 57, .5);
-        }
-
-        input::-moz-placeholder {
-          /* Mozilla Firefox 19+ */
-          color: rgba(157, 107, 57, .5);
-        }
-
-        input:-ms-input-placeholder {
-          /* Internet Explorer 10+ */
-          color: rgba(157, 107, 57, .5);
-        }
-
-
+        padding:  0 40px;
         .inputBoxRow {
-          width: 370px;
-          margin: 50px auto;
+          width: 100%;
+          margin:0 auto 40px;
 
           .ant-input-suffix .ant-input-password-icon {
-            color: var(--themeColor);
+            color: #131C28;
             font-size: 22px;
           }
         }
@@ -97,7 +86,7 @@
 
         input:-webkit-autofill {
           font-size: 18px !important;
-          -webkit-text-fill-color: var(--themeColor) !important;
+          -webkit-text-fill-color: #131C28 !important;
           background-image: none;
           -webkit-box-shadow: 0 0 0px 1000px transparent inset !important; //填充阴影,可以用来遮住背景色
           background-color: transparent;
@@ -111,9 +100,9 @@
           width: 100%;
           height: 60px;
           border: none;
-          border-bottom: 1px solid var(--themeColor);
+          border-bottom: 1px solid #131C28;
           border-radius: 0;
-          color: var(--themeColor);
+          color: #131C28;
 
           .ant-input {
             background-color: transparent;
@@ -128,11 +117,11 @@
       }
 
       .loginBtn {
-        margin-top: 100px;
+        margin-top: 50px;
+        padding: 0 40px;
         .ant-btn {
-          border-radius: 25px;
           font-size: 24px;
-          width: 375px;
+          width: 100%;
           height: 50px;
         }
       }

+ 2 - 6
管理后台/src/pages/Login/index.tsx

@@ -9,11 +9,10 @@ import { setTokenInfo } from "@/utils/storage";
 import history from "@/utils/history";
 import { MessageFu } from "@/utils/message";
 import { userLoginAPI } from "@/store/action/layout";
-import logoImg from "@/assets/img/logo.png";
 
 export default function Login() {
   // 账号密码
-  const [userName, setUserName] = useState("admin");
+  const [userName, setUserName] = useState("");
   const [passWord, setPassWord] = useState("");
 
   // 键盘按下回车事件
@@ -42,14 +41,11 @@ export default function Login() {
   return (
     <div className={styles.Login}>
       <div className="main">
-        <div className="logo">
-          <img src={logoImg} alt="" />
-        </div>
+        <div className="mainTitle">登 录</div>
         {/* 账号密码输入框 */}
         <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 });
-};

+ 17 - 0
管理后台/src/store/action/A5Log.ts

@@ -0,0 +1,17 @@
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+/**
+ * 获取日志表格列表
+ */
+export const getLogListAPI = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("sys/log/list", data);
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total,
+      };
+      dispatch({ type: "log/getList", 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;
-  }
-}

+ 27 - 0
管理后台/src/store/reducer/A5Log.ts

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

+ 5 - 8
管理后台/src/store/reducer/index.ts

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

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

+ 11 - 0
管理后台/src/types/api/A5Log.d.ts

@@ -0,0 +1,11 @@
+export type LogTableType = {
+  createTime: string;
+  creatorId: null;
+  creatorName: string;
+  description: string;
+  id: number;
+  ip: string;
+  type: string;
+  updateTime: null;
+  userName: string;
+}

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

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

+ 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().A1Layout.closeUpFile.state)
       store.dispatch({
         type: "layout/closeUpFile",
         payload: { fu: () => {}, state: false },

+ 7 - 7
管理后台/src/utils/http.ts

@@ -7,10 +7,10 @@ import { domShowFu } from "./domShow";
 // 请求基地址
 export const baseURL =
   // 线下的图片地址需要加上/api/
-  // process.env.NODE_ENV === "development"
-  //   ? "http://192.168.20.55:8042/api/"
-  //   : "";
-  process.env.NODE_ENV === "development" ? "https://bengbubwg.4dage.com" : "";
+  process.env.NODE_ENV === "development"
+    ? "http://192.168.20.55:8044/api/"
+    : "";
+  // process.env.NODE_ENV === "development" ? "https://bengbubwg.4dage.com" : "";
 
 // 处理  类型“AxiosResponse<any, any>”上不存在属性“code”
 declare module "axios" {
@@ -23,10 +23,10 @@ declare module "axios" {
 // 创建 axios 实例
 const http = axios.create({
   // --------线下的地址不用加/api/
-  // baseURL: baseURL,
+  baseURL: baseURL,
 
   // --------打包或线上环境接口需要加上api/
-  baseURL: baseURL + "/api/",
+  // baseURL: baseURL + "/api/",
   timeout: 5000,
 });
 
@@ -79,7 +79,7 @@ http.interceptors.response.use(
       domShowFu("#AsyncSpinLoding", false);
       // 如果因为网络原因,response没有,给提示消息
       if (!err.response) {
-        if (store.getState().layoutStore.closeUpFile.state)
+        if (store.getState().A1Layout.closeUpFile.state)
           MessageFu.warning("取消上传!");
         else MessageFu.error("网络繁忙,请稍后重试!");
       } else MessageFu.error("响应错误,请联系管理员!");