shaogen1995 hace 2 años
padre
commit
9274a5b7d0

+ 106 - 63
后台/src/components/ZA_Table/index.tsx

@@ -8,21 +8,25 @@ import React, {
 import styles from "./index.module.scss";
 import { Button, Input, Popconfirm, Table, Tooltip } from "antd";
 import { useDispatch } from "react-redux";
-import { A2_APIgetList, A2_APIsort } from "@/store/action/A2Country";
+import { A2_APIdel, A2_APIgetList, A2_APIsort } from "@/store/action/A2Country";
 import { A2TableType } from "@/types";
 import { ExclamationCircleFilled } from "@ant-design/icons";
+import { forwardRef, useImperativeHandle } from "react";
 
 // 表格拖动排序-----------------
 import { DndProvider, useDrag, useDrop } from "react-dnd";
 import { HTML5Backend } from "react-dnd-html5-backend";
+import { MessageFu } from "@/utils/message";
+import ImageLazy from "../ImageLazy";
 
 type Props = {
   setEditId: (id: number, flag: boolean) => void; //点击新增/编辑/查看
-  myType: "national" | "history" | "custom" | "project"; //区分各个不同板块
-  tableInfo: any; //表格数据
+  myType: "national" | "history" | "custom" | "project" | "craft" | "master"; //区分各个不同板块
+  tableInfo: { list: A2TableType[]; total: number }; //表格数据
+  ref: any;
 };
 
-function ZA_Table({ myType, setEditId, tableInfo }: Props) {
+function ZA_Table({ myType, setEditId, tableInfo }: Props, ref: any) {
   const dispatch = useDispatch();
 
   // 发送请求的数据
@@ -30,21 +34,18 @@ function ZA_Table({ myType, setEditId, tableInfo }: Props) {
     pageNum: 1,
     pageSize: 10,
     searchKey: "",
-    myType,
+    type: myType,
   });
 
   // 每次数据变化的时候发送请求
 
-  const getListFu = useCallback(
-    (data: any) => {
-      if (myType === "custom") dispatch(A2_APIgetList(data));
-    },
-    [dispatch, myType]
-  );
+  const getListFu = useCallback(() => {
+    if (myType === "national") dispatch(A2_APIgetList(getData));
+  }, [dispatch, getData, myType]);
 
   useEffect(() => {
-    getListFu(getData);
-  }, [getData, getListFu]);
+    getListFu();
+  }, [getListFu]);
 
   const [inputKey, setInputKey] = useState(1);
 
@@ -67,12 +68,26 @@ function ZA_Table({ myType, setEditId, tableInfo }: Props) {
       pageNum: 1,
       pageSize: 10,
       searchKey: "",
-      myType,
+      type: myType,
     });
   }, [myType]);
 
   // 点击删除
-  const delTableFu = useCallback((id: number) => {}, []);
+  const delTableFu = useCallback(
+    async (id: number) => {
+      let resUrl = "block";
+
+      if (myType === "master") resUrl = "master";
+      else if (myType === "craft") resUrl = "craft";
+
+      const res = await A2_APIdel(id, resUrl);
+      if (res.code === 0) {
+        MessageFu.success("删除成功!");
+        getListFu();
+      }
+    },
+    [getListFu, myType]
+  );
 
   // 页码变化
   const paginationChange = useCallback(
@@ -82,7 +97,7 @@ function ZA_Table({ myType, setEditId, tableInfo }: Props) {
     [getData]
   );
   const columns = useMemo(() => {
-    return [
+    const arr: any = [
       {
         width: 100,
         title: (
@@ -99,54 +114,74 @@ function ZA_Table({ myType, setEditId, tableInfo }: Props) {
           index + 1 + (getData.pageNum - 1) * getData.pageSize,
       },
       {
-        title: "账号名",
-        dataIndex: "userName",
-      },
-      {
-        title: "用户昵称",
-        dataIndex: "nickName",
-      },
-
-      {
-        title: "真实姓名",
-        dataIndex: "realName",
-      },
-      {
-        title: "注册时间",
-        dataIndex: "createTime",
+        title: "标题",
+        dataIndex: "name",
       },
+    ];
 
-      {
-        title: "操作",
+    if (myType !== "craft") {
+      arr.push({
+        title: "封面图",
         render: (item: A2TableType) => (
+          <div className="tableImgAuto">
+            <ImageLazy width={60} height={60} src={item.thumb} />
+          </div>
+        ),
+      });
+    }
+
+    arr.push({
+      title: "正文",
+      render: (item: A2TableType) =>
+        item.content.length >= 50 ? (
+          <span style={{ cursor: "pointer" }} title={item.content}>
+            {item.content.substring(0, 50) + "..."}
+          </span>
+        ) : (
+          item.content
+        ),
+    });
+
+    arr.push({
+      title: "操作",
+      render: (item: A2TableType) => (
+        <>
           <>
-            <>
-              <Button
-                size="small"
-                type="text"
-                onClick={() => setEditId(item.id, false)}
-              >
-                编辑
+            <Button
+              size="small"
+              type="text"
+              onClick={() => setEditId(item.id, true)}
+            >
+              查看
+            </Button>
+            <Button
+              size="small"
+              type="text"
+              onClick={() => setEditId(item.id, false)}
+            >
+              编辑
+            </Button>
+            <Popconfirm
+              title="删除后无法恢复,是否删除?"
+              okText="删除"
+              cancelText="取消"
+              onConfirm={() => delTableFu(item.id!)}
+            >
+              <Button size="small" type="text" danger>
+                删除
               </Button>
-              <Popconfirm
-                title="删除后无法恢复,是否删除?"
-                okText="删除"
-                cancelText="取消"
-                onConfirm={() => delTableFu(item.id!)}
-              >
-                <Button size="small" type="text" danger>
-                  删除
-                </Button>
-              </Popconfirm>
-            </>
+            </Popconfirm>
           </>
-        ),
-      },
-    ];
+        </>
+      ),
+    });
+
+    return arr;
   }, [
     delTableFu,
     getData.pageNum,
     getData.pageSize,
+    myType,
     setEditId,
     tableInfo.list.length,
   ]);
@@ -185,7 +220,6 @@ function ZA_Table({ myType, setEditId, tableInfo }: Props) {
           };
         },
         drop: (item: { index: number }) => {
-          console.log("pppppppppp", moveRow);
           if (moveRow) moveRow(item.index, index);
         },
       });
@@ -223,17 +257,26 @@ function ZA_Table({ myType, setEditId, tableInfo }: Props) {
       // 交互位置-之前的id
       const beforeId = tableInfo.list[dragIndex].id;
       const afterId = tableInfo.list[hoverIndex].id;
-      console.log("交换位置", beforeId, afterId);
+      // console.log("交换位置", beforeId, afterId);
 
-      const res = await A2_APIsort(beforeId, afterId);
+      let resUrl = "block";
 
-      if (res.code === 0) {
-        if (myType === "custom") dispatch(A2_APIgetList(getData));
-      }
+      if (myType === "master") resUrl = "master";
+      else if (myType === "craft") resUrl = "craft";
+
+      const res = await A2_APIsort(beforeId, afterId, resUrl);
+
+      if (res.code === 0) getListFu();
     },
-    [dispatch, getData, myType, tableInfo.list]
+    [getListFu, myType, tableInfo.list]
   );
 
+  // 可以让父组件调用子组件的方法
+  useImperativeHandle(ref, () => ({
+    getListFu,
+    resetSelectFu,
+  }));
+
   return (
     <div className={styles.ZA_Table}>
       {/* 顶部搜索 */}
@@ -286,6 +329,6 @@ function ZA_Table({ myType, setEditId, tableInfo }: Props) {
   );
 }
 
-const MemoZA_Table = React.memo(ZA_Table);
+// const MemoZA_Table = React.memo(ZA_Table);
 
-export default MemoZA_Table;
+export default forwardRef(ZA_Table);

+ 12 - 2
后台/src/components/Z_upFileMore/index.tsx

@@ -26,9 +26,11 @@ type Props = {
   fileCheck: boolean;
   size: number; //上传图片大小(M)
   dirCode: string; //文件的code码
+  myUrl: string;
   format?: string[]; //上传图片格式
   formatTxt?: string; //上传图片提示
   sizeTxt?: string; //后面的建议尺寸信息
+  fromData?: any;
 };
 
 function Z_upFileMore({
@@ -39,9 +41,11 @@ function Z_upFileMore({
   fileCheck,
   size,
   dirCode,
+  myUrl,
   format = ["image/jpeg", "image/png"],
   formatTxt = "png、jpg和jpeg",
   sizeTxt,
+  fromData,
 }: Props) {
   const myInput = useRef<HTMLInputElement>(null);
 
@@ -70,10 +74,16 @@ function Z_upFileMore({
         fd.append("typePath", "1");
         fd.append("file", filesInfo);
 
+        if (fromData) {
+          for (const k in fromData) {
+            if (fromData[k]) fd.append(k, fromData[k]);
+          }
+        }
+
         e.target.value = "";
 
         try {
-          const res = await A1_APIupFile(fd);
+          const res = await A1_APIupFile(fd, myUrl);
           if (res.code === 0) {
             MessageFu.success("上传成功!");
             setFileList([...fileList, res.data]);
@@ -84,7 +94,7 @@ function Z_upFileMore({
         }
       }
     },
-    [dirCode, fileList, format, formatTxt, setFileList, size]
+    [dirCode, fileList, format, formatTxt, fromData, myUrl, setFileList, size]
   );
 
   // 列表删除某一张图片

+ 16 - 5
后台/src/components/Z_upFileOne/index.tsx

@@ -22,9 +22,11 @@ type Props = {
   coverCheck: boolean; //有没有点击过确定
   size: number; //上传图片大小(M)
   dirCode: string; //文件的code码
+  myUrl: string;
   format?: string[]; //上传图片格式
   formatTxt?: string; //上传图片提示
-  sizeTxt?:string //后面的建议尺寸信息
+  sizeTxt?: string; //后面的建议尺寸信息
+  fromData?: any;
 };
 
 function Z_upFileOne({
@@ -34,9 +36,11 @@ function Z_upFileOne({
   coverCheck,
   size,
   dirCode,
+  myUrl,
   format = ["image/jpeg", "image/png"],
   formatTxt = "png、jpg和jpeg",
-  sizeTxt
+  sizeTxt,
+  fromData,
 }: Props) {
   const myInput = useRef<HTMLInputElement>(null);
 
@@ -64,10 +68,16 @@ function Z_upFileOne({
         fd.append("dirCode", dirCode);
         fd.append("file", filesInfo);
 
+        if (fromData) {
+          for (const k in fromData) {
+            if (fromData[k]) fd.append(k, fromData[k]);
+          }
+        }
+
         e.target.value = "";
 
         try {
-          const res = await A1_APIupFile(fd);
+          const res = await A1_APIupFile(fd, myUrl);
           if (res.code === 0) {
             MessageFu.success("上传成功!");
             setCover(res.data.filePath);
@@ -78,7 +88,7 @@ function Z_upFileOne({
         }
       }
     },
-    [dirCode, format, formatTxt, setCover, size]
+    [dirCode, format, formatTxt, fromData, myUrl, setCover, size]
   );
 
   return (
@@ -132,7 +142,8 @@ function Z_upFileOne({
         </div>
       </div>
       <div className="fileBoxRow_r_tit" hidden={isLook}>
-        支持{formatTxt}的图片格式;最大支持{size}M。{sizeTxt?`建议尺寸${sizeTxt}`:null}
+        支持{formatTxt}的图片格式;最大支持{size}M。
+        {sizeTxt ? `建议尺寸${sizeTxt}` : null}
         <br />
         <div
           className={classNames(

+ 45 - 0
后台/src/components/Z_upFileOther/index.module.scss

@@ -0,0 +1,45 @@
+.Z_upFileOther {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  top: -2px;
+
+
+  :global {
+    .fileInfo {
+      display: flex;
+      align-items: center;
+      font-size: 16px;
+
+      .clearCover {
+        margin-left: 20px;
+        cursor: pointer;
+        font-size: 16px;
+      }
+
+      &>a {
+        color: black;
+      }
+    }
+
+    .fileTxt {
+      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;
+    }
+
+    .noUpThumbAc {
+      top: 0;
+      opacity: 1;
+    }
+  }
+}

+ 186 - 0
后台/src/components/Z_upFileOther/index.tsx

@@ -0,0 +1,186 @@
+import React, { useCallback, useMemo, useRef } from "react";
+import styles from "./index.module.scss";
+import store from "@/store";
+import {
+  EyeOutlined,
+  UploadOutlined,
+  CloseOutlined,
+  DownloadOutlined,
+} from "@ant-design/icons";
+import { baseURL } from "@/utils/http";
+import { Button, Popconfirm } from "antd";
+import { MessageFu } from "@/utils/message";
+import { A1_APIupFile } from "@/store/action/A1Plate";
+import { fileDomInitialFu } from "@/utils/domShow";
+import classNames from "classnames";
+
+type FileType = {
+  name: string;
+  path: string;
+};
+
+type Props = {
+  fileUrl: FileType;
+  setFileUrl: (val: FileType) => void;
+  isLook: boolean; //是不是查看
+  fileCheck: boolean; //有没有点击过确定
+  size: number; //上传文件大小(M)
+  dirCode: string; //文件的code码
+  myUrl: string;
+  myType: "video" | "audio" | "model";
+  format: string[]; //上传格式
+  formatTxt: string; //上传提示
+  fromData?: any;
+};
+
+function Z_upFileOther({
+  fileUrl,
+  setFileUrl,
+  isLook,
+  fileCheck,
+  size,
+  dirCode,
+  myUrl,
+  myType,
+  format,
+  formatTxt,
+  fromData,
+}: Props) {
+  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 = format;
+        if (!type.includes(filesInfo.type)) {
+          e.target.value = "";
+          return MessageFu.warning(`只支持${formatTxt}格式!`);
+        }
+        // 校验大小
+        if (filesInfo.size > size * 1024 * 1024) {
+          e.target.value = "";
+          return MessageFu.warning(`最大支持${size}M!`);
+        }
+        // 创建FormData对象
+        const fd = new FormData();
+        // 把files添加进FormData对象(‘photo’为后端需要的字段)
+        fd.append("type", "thumb");
+        fd.append("dirCode", dirCode);
+        fd.append("file", filesInfo);
+
+        if (fromData) {
+          for (const k in fromData) {
+            if (fromData[k]) fd.append(k, fromData[k]);
+          }
+        }
+
+        e.target.value = "";
+
+        try {
+          const res = await A1_APIupFile(fd, myUrl);
+          if (res.code === 0) {
+            MessageFu.success("上传成功!");
+            setFileUrl({
+              name: res.data.fileName,
+              path: res.data.filePath,
+            });
+          }
+          fileDomInitialFu();
+        } catch (error) {
+          fileDomInitialFu();
+        }
+      }
+    },
+    [dirCode, format, formatTxt, fromData, myUrl, setFileUrl, size]
+  );
+
+  const acceptRes = useMemo(() => {
+    let accept = "";
+    if (myType === "video") accept = ".mp4";
+    else if (myType === "audio") accept = ".mp3";
+    else if (myType === "model") accept = ".4dage";
+    return accept;
+  }, [myType]);
+
+  return (
+    <div className={styles.Z_upFileOther}>
+      <input
+        id="upInput"
+        type="file"
+        accept={acceptRes}
+        ref={myInput}
+        onChange={(e) => handeUpPhoto(e)}
+      />
+
+      {fileUrl.path ? (
+        <div className="fileInfo">
+          <div className="upSuccTxt">{fileUrl.name}</div>
+          {/* 视频预览 */}
+          <div
+            className="clearCover"
+            hidden={!fileUrl.path}
+            onClick={() =>
+              store.dispatch({
+                type: "layout/lookDom",
+                payload: { src: fileUrl.path, type: myType },
+              })
+            }
+          >
+            <EyeOutlined />
+          </div>
+          {/* 视频下载 */}
+          <a
+            href={baseURL + fileUrl.path}
+            download
+            target="_blank"
+            className="clearCover"
+            rel="noreferrer"
+          >
+            <DownloadOutlined />
+          </a>
+          {/* 视频删除 */}
+          <Popconfirm
+            title="删除后无法恢复,是否删除?"
+            okText="删除"
+            cancelText="取消"
+            onConfirm={() => setFileUrl({ name: "", path: "" })}
+          >
+            <div className="clearCover" hidden={isLook}>
+              <CloseOutlined />
+            </div>
+          </Popconfirm>
+        </div>
+      ) : (
+        <>
+          <Button
+            onClick={() => myInput.current?.click()}
+            icon={<UploadOutlined />}
+          >
+            上传
+          </Button>
+
+          <div className="fileTxt">
+            仅支持{formatTxt}格式文件,大小不得超过{size}M。
+          </div>
+        </>
+      )}
+      <div className="fileTit">
+        <div
+          className={classNames(
+            "noUpThumb",
+            !fileUrl.path && fileCheck ? "noUpThumbAc" : ""
+          )}
+        >
+          请上传附件!
+        </div>
+      </div>
+    </div>
+  );
+}
+
+const MemoZ_upFileOther = React.memo(Z_upFileOther);
+
+export default MemoZ_upFileOther;

+ 2 - 0
后台/src/pages/A1Plate/PlateEdit/index.tsx

@@ -90,6 +90,7 @@ function PlateEdit({ editId, isLook, closeFu, editFu }: Props) {
           </div>
           <div className="e_rowR">
             <UpFileOne
+              myUrl="cms/config/upload"
               cover={cover}
               setCover={(val) => setCover(val)}
               isLook={isLook}
@@ -115,6 +116,7 @@ function PlateEdit({ editId, isLook, closeFu, editFu }: Props) {
             </div>
             <div className="e_rowR">
               <UpFileMore
+                myUrl="cms/config/upload"
                 max={15}
                 fileList={fileList}
                 setFileList={(data) => setFileList(data)}

+ 108 - 1
后台/src/pages/A2Country/A2Edit/index.module.scss

@@ -10,10 +10,117 @@
   border-radius: 10px;
 
   :global {
-    .A2Main{
+    .A2Main {
       width: 100%;
       height: 100%;
       overflow-y: auto;
+
+      .A2MainSon {
+        width: 800px;
+
+        .e_row {
+          padding-right: 50px;
+          display: flex;
+          font-size: 14px;
+          margin-bottom: 10px;
+
+          .e_rowL {
+            width: 68px;
+            text-align: right;
+
+            &>span {
+              color: #ff4d4f;
+              position: relative;
+              top: 3px;
+            }
+          }
+
+          .e_rowR {
+            width: calc(100% - 68px);
+          }
+
+        }
+      }
+    }
+
+    // 查看的情况
+    .nolyLookMain {
+
+      .ant-row {
+        pointer-events: none;
+      }
+
+      .ant-form-item-control-input {
+        pointer-events: none;
+
+        .ant-input-affix-wrapper {
+          border: transparent;
+
+          .ant-input-show-count-suffix {
+            opacity: 0;
+          }
+        }
+
+        .ant-select-selector {
+          border: transparent;
+        }
+
+        .ant-select-arrow {
+          opacity: 0;
+        }
+
+        .ant-input {
+          border: transparent;
+        }
+
+        .ant-input-data-count {
+          opacity: 0;
+        }
+
+      }
+
+      .ant-checkbox-group {
+        pointer-events: none;
+      }
+
+      .myformBox3 .upImgBox .fileImgListBox>div {
+        margin: 0px 20px 15px 0;
+        cursor: default;
+      }
+
+      .closeLook {
+        .ant-form-item-control-input {
+          pointer-events: auto;
+        }
+      }
+
+      textarea {
+        min-height: 40px !important;
+      }
+
+      textarea,
+      input {
+        &::-webkit-input-placeholder {
+          color: black;
+        }
+
+        &:-moz-placeholder {
+          color: black;
+        }
+
+        &::-moz-placeholder {
+          color: black;
+        }
+
+        &:-ms-input-placeholder {
+          color: black;
+        }
+      }
+
+      // 下拉框 placeholder 字体颜色
+      .ant-select-selection-placeholder {
+        color: black;
+      }
     }
   }
 }

+ 244 - 5
后台/src/pages/A2Country/A2Edit/index.tsx

@@ -1,5 +1,14 @@
-import React from "react";
+import React, { useCallback, useEffect, useRef, useState } from "react";
 import styles from "./index.module.scss";
+import { Button, Form, FormInstance, Input, Popconfirm } from "antd";
+import TextArea from "antd/es/input/TextArea";
+import UpFileOne from "@/components/Z_upFileOne";
+import UpFileMore from "@/components/Z_upFileMore";
+import { MessageFu } from "@/utils/message";
+import { FileImgListType } from "@/types";
+import UpFileOther from "@/components/Z_upFileOther";
+import { A2_APIgetInfo, A2_APIsave } from "@/store/action/A2Country";
+import classNames from "classnames";
 
 type Props = {
   editId: number;
@@ -7,14 +16,244 @@ type Props = {
   closeFu: () => void;
   editFu: () => void;
   addFu: () => void;
+  myType: "national" | "history" | "custom" | "project" | "craft" | "master";
 };
 
-function A2Edit({ editId, isLook, closeFu, editFu, addFu }: Props) {
+function A2Edit({ editId, isLook, closeFu, editFu, addFu, myType }: Props) {
+  const getInfoFu = useCallback(
+    async (id: number) => {
+      let resUrl = "block";
+
+      if (myType === "master") resUrl = "master";
+      else if (myType === "craft") resUrl = "craft";
+
+      const res = await A2_APIgetInfo(id, resUrl);
+      if (res.code === 0) {
+        const info = res.data.entity;
+
+        const file = res.data.file || [];
+
+        FormBoxRef.current?.setFieldsValue({
+          name: info.name,
+          content: info.content,
+        });
+        setDirCode(info.dirCode);
+        setCover(info.thumb);
+        setFileList(file);
+        setVideoFile({ name: info.videoName || "视频", path: info.video });
+      }
+    },
+    [myType]
+  );
+
+  useEffect(() => {
+    if (editId > 0) getInfoFu(editId);
+    else setDirCode(Date.now() + "");
+  }, [editId, getInfoFu]);
+
+  // 文件的code码
+  const [dirCode, setDirCode] = useState("");
+
+  // 表单的ref
+  const FormBoxRef = useRef<FormInstance>(null);
+
+  // 文件的校验
+  const [check, setCheck] = useState(false);
+
+  // 封面图
+  const [cover, setCover] = useState("");
+
+  // 多张图
+  const [fileList, setFileList] = useState([] as FileImgListType[]);
+
+  // 视频文件
+  const [videoFile, setVideoFile] = useState({ name: "", path: "" });
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    setCheck(true);
+  }, []);
+
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (value: any) => {
+      setCheck(true);
+      if (!cover) return;
+
+      const obj = {
+        ...value,
+        dirCode: dirCode,
+        id: editId > 0 ? editId : null,
+        img: fileList.map((v) => v.id).join(","),
+        thumb: cover,
+        type: myType,
+        video: videoFile.path,
+        videoName: videoFile.name,
+      };
+
+      let resUrl = "block";
+
+      if (myType === "master") resUrl = "master";
+      else if (myType === "craft") resUrl = "craft";
+
+      const res = await A2_APIsave(obj, resUrl);
+
+      if (res.code === 0) {
+        MessageFu.success(editId > 0 ? "编辑成功!" : "新增成功!");
+
+        if (editId > 0) editFu();
+        else addFu();
+        closeFu();
+      }
+
+      // console.log("通过校验,点击确定", res);
+    },
+    [
+      addFu,
+      closeFu,
+      cover,
+      dirCode,
+      editFu,
+      editId,
+      fileList,
+      myType,
+      videoFile.name,
+      videoFile.path,
+    ]
+  );
+
   return (
     <div className={styles.A2Edit}>
-      <div className="A2Main mySorrl">
-        <div onClick={addFu}> 新增</div>
-        <div onClick={editFu}> 编辑</div>
+      <div
+        className={classNames("A2Main mySorrl", isLook ? "nolyLookMain" : "")}
+      >
+        <div className="A2MainSon">
+          <Form
+            ref={FormBoxRef}
+            name="basic"
+            labelCol={{ span: 2 }}
+            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>
+
+            <Form.Item
+              label="正文"
+              name="content"
+              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();
+                  },
+                },
+              ]}
+            >
+              <TextArea
+                autoSize
+                placeholder="请输入内容"
+                showCount
+                maxLength={500}
+              />
+            </Form.Item>
+
+            {/* 封面图 */}
+            <div className="e_row">
+              <div className="e_rowL">
+                <span>* </span>封面:
+              </div>
+              <div className="e_rowR">
+                <UpFileOne
+                  myUrl={`cms/block/upload/${myType}`}
+                  cover={cover}
+                  setCover={(val) => setCover(val)}
+                  isLook={isLook}
+                  coverCheck={check}
+                  size={5}
+                  dirCode={dirCode}
+                  sizeTxt={myType === "project" ? "376 x 349" : "783 x 362"}
+                />
+              </div>
+            </div>
+
+            {/* 多张图片 */}
+            <div className="e_row" hidden={isLook && fileList.length === 0}>
+              <div className="e_rowL">图片:</div>
+              <div className="e_rowR">
+                <UpFileMore
+                  myUrl={`cms/block/upload/${myType}`}
+                  max={15}
+                  fileList={fileList}
+                  setFileList={(data) => setFileList(data)}
+                  isLook={isLook}
+                  fileCheck={false}
+                  size={5}
+                  dirCode={dirCode}
+                />
+              </div>
+            </div>
+
+            {/* 多张图片 */}
+            <div className="e_row" hidden={isLook && !videoFile.path}>
+              <div className="e_rowL">视频:</div>
+              <div className="e_rowR">
+                <UpFileOther
+                  fileUrl={videoFile}
+                  setFileUrl={(val) => setVideoFile(val)}
+                  isLook={isLook}
+                  fileCheck={false}
+                  size={500}
+                  dirCode={dirCode}
+                  myUrl={`cms/block/upload/${myType}`}
+                  myType="video"
+                  format={["video/mp4"]}
+                  formatTxt="mp4"
+                />
+              </div>
+            </div>
+
+            {/* 确定和取消按钮 */}
+            <br />
+            <Form.Item
+              wrapperCol={{ offset: 9, span: 16 }}
+              className="closeLook"
+            >
+              {isLook ? (
+                <Button onClick={closeFu}>关 闭</Button>
+              ) : (
+                <>
+                  <Button type="primary" htmlType="submit">
+                    提交
+                  </Button>
+                  &emsp;
+                  <Popconfirm
+                    title="放弃编辑后,信息将不会保存!"
+                    okText="放弃"
+                    cancelText="取消"
+                    onConfirm={closeFu}
+                  >
+                    <Button>取消</Button>
+                  </Popconfirm>
+                </>
+              )}
+            </Form.Item>
+          </Form>
+        </div>
       </div>
     </div>
   );

+ 8 - 10
后台/src/pages/A2Country/index.tsx

@@ -1,4 +1,4 @@
-import React, { useCallback, useState } from "react";
+import React, { useCallback, useRef, useState } from "react";
 import styles from "./index.module.scss";
 import ZATable from "@/components/ZA_Table";
 import { useSelector } from "react-redux";
@@ -17,22 +17,19 @@ function A2Country() {
   // 从仓库中获取数据
   const { tableInfo } = useSelector((state: RootState) => state.A2Country);
 
-  // 编辑完成
-  const editFu = useCallback(() => {}, []);
-
-  // 新增完成
-  const addFu = useCallback(() => {}, []);
+  const childRef = useRef<any>(null);
 
   return (
     <div className={styles.A2Country}>
       <div className="pageTitle">
-        {editId ? (isLook ? "查看" : "编辑") : "国礼"}
+        {editId ? (isLook ? "查看" : editId > 0 ? "编辑" : "新增") : "国礼"}
       </div>
 
       {/* 内容主体 */}
       <ZATable
+        ref={childRef}
         setEditId={(id, flag) => openPageFu(id, flag)}
-        myType="custom"
+        myType="national"
         tableInfo={tableInfo}
       />
 
@@ -42,8 +39,9 @@ function A2Country() {
           editId={editId}
           isLook={isLook}
           closeFu={() => setEditId(0)}
-          editFu={editFu}
-          addFu={addFu}
+          editFu={() => childRef.current?.getListFu()}
+          addFu={() => childRef.current?.resetSelectFu()}
+          myType="national"
         />
       ) : null}
     </div>

+ 2 - 2
后台/src/store/action/A1Plate.ts

@@ -28,10 +28,10 @@ const CancelToken = axios.CancelToken;
 /**
  * 上传封面图和附件
  */
-export const A1_APIupFile = (data: any) => {
+export const A1_APIupFile = (data: any, url: string) => {
   domShowFu("#UpAsyncLoding", true);
 
-  return http.post("cms/config/upload", data, {
+  return http.post(url, data, {
     timeout: 0,
     // 显示进度条
     onUploadProgress: (e: any) => {

+ 26 - 7
后台/src/store/action/A2Country.ts

@@ -1,7 +1,5 @@
 import http from "@/utils/http";
-import store, { AppDispatch } from "..";
-import { domShowFu, progressDomFu } from "@/utils/domShow";
-import axios from "axios";
+import { AppDispatch } from "..";
 
 /**
  * 获取 国礼-历史-定制-工程 列表
@@ -10,10 +8,10 @@ export const A2_APIgetList = (data: any) => {
   return async (dispatch: AppDispatch) => {
     const res = await http.post("cms/block/pageList", data);
     if (res.code === 0) {
-      const { orders, total } = res.data;
+      const { records, total } = res.data;
       dispatch({
         type: "A2Country/getList",
-        payload: { list: orders, total: total },
+        payload: { list: records, total: total },
       });
     }
   };
@@ -22,6 +20,27 @@ export const A2_APIgetList = (data: any) => {
 /**
  * 排序
  */
-export const A2_APIsort = (id1: number, id2: number) => {
-  return http.get(`cms/block/sort/${id1}/${id2}`);
+export const A2_APIsort = (id1: number, id2: number, resUrl: string) => {
+  return http.get(`cms/${resUrl}/sort/${id1}/${id2}`);
 };
+
+/**
+ * 新增/编辑
+ */
+export const A2_APIsave = (data: any, resUrl: string) => {
+  return http.post(`cms/${resUrl}/save`, data);
+};
+
+/**
+ * 删除
+ */
+export const A2_APIdel = (id: number, resUrl: string) => {
+  return http.get(`cms/${resUrl}/del/${id}`);
+};
+
+/**
+ * 获取详情
+ */
+export const A2_APIgetInfo = (id: number, resUrl: string) => {
+  return http.get(`cms/${resUrl}/detail/${id}`);
+};

+ 15 - 1
后台/src/types/api/A2Country.d.ts

@@ -1 +1,15 @@
-export type A2TableType = any;
+export type A2TableType = {
+  content: string;
+  createTime: string;
+  creatorId?: any;
+  creatorName: string;
+  dirCode: string;
+  id: number;
+  img: string;
+  name: string;
+  sort: number;
+  thumb: string;
+  type: string;
+  updateTime: string;
+  video: string;
+};