shaogen1995 před 1 rokem
rodič
revize
0b02ca0342

+ 21 - 11
src/components/ZupOne/index.tsx

@@ -6,11 +6,12 @@ import {
   EyeOutlined,
   CloseOutlined,
   DownloadOutlined,
+  UploadOutlined,
 } from "@ant-design/icons";
 import store from "@/store";
 import { baseURL } from "@/utils/http";
 import classNames from "classnames";
-import { Popconfirm } from "antd";
+import { Button, Popconfirm } from "antd";
 import { MessageFu } from "@/utils/message";
 import { fileDomInitialFu } from "@/utils/domShow";
 import { API_upFile } from "@/store/action/layout";
@@ -139,14 +140,23 @@ function ZupOne(
         ref={myInput}
         onChange={(e) => handeUpPhoto(e)}
       />
-
-      <div
-        hidden={fileUrl.filePath !== ""}
-        className="file_upIcon"
-        onClick={() => myInput.current?.click()}
-      >
-        <PlusOutlined rev={undefined} />
-      </div>
+      {myType === "thumb" ? (
+        <div
+          hidden={fileUrl.filePath !== ""}
+          className="file_upIcon"
+          onClick={() => myInput.current?.click()}
+        >
+          <PlusOutlined rev={undefined} />
+        </div>
+      ) : (
+        <Button
+          hidden={fileUrl.filePath !== ""}
+          onClick={() => myInput.current?.click()}
+          icon={<UploadOutlined rev={undefined} />}
+        >
+          上传
+        </Button>
+      )}
 
       {/* 为图片的情况-------------- */}
       {myType === "thumb" ? (
@@ -173,13 +183,13 @@ function ZupOne(
               onClick={() =>
                 store.dispatch({
                   type: "layout/lookBigImg",
-                  payload: { url: baseURL + fileUrl, show: true },
+                  payload: { url: baseURL + fileUrl.filePath, show: true },
                 })
               }
               rev={undefined}
             />
             <a
-              href={baseURL + fileUrl}
+              href={baseURL + fileUrl.filePath}
               download
               target="_blank"
               rel="noreferrer"

+ 21 - 7
src/pages/A1video/A1add/index.module.scss

@@ -1,4 +1,4 @@
-.A1add{
+.A1add {
   position: absolute;
   top: 0;
   left: 0;
@@ -8,24 +8,38 @@
   padding: 20px;
   width: 100%;
   height: 100%;
-  :global{
-    .A1Amain{
+
+  :global {
+    .A1Amain {
       width: 800px;
-      .formRow{
+      position: relative;
+
+      .formRow {
         display: flex;
-        .formLeft{
+
+        .formLeft {
           position: relative;
           top: 3px;
           width: 100px;
           text-align: right;
-          &>span{
+
+          &>span {
             color: #ff4d4f;
           }
         }
-        .formRight{
+
+        .formRight {
           width: calc(100% - 100px);
         }
       }
+
+      .formLastTit {
+        position: absolute;
+        left: 100px;
+        bottom: 52px;
+        font-size: 14px;
+        color: rgb(126, 124, 124);
+      }
     }
   }
 }

+ 4 - 2
src/pages/A1video/A1add/index.tsx

@@ -132,7 +132,7 @@ function A1add({ addId, closeFu, addTableFu, type }: Props) {
                 format={["image/jpeg", "image/png"]}
                 formatTxt="png、jpg和jpeg"
                 checkTxt="请上传封面图"
-                upTxt="最多张"
+                upTxt="最多1张"
                 myType="thumb"
               />
             </div>
@@ -155,7 +155,7 @@ function A1add({ addId, closeFu, addTableFu, type }: Props) {
                   format={["video/mp4"]}
                   formatTxt="mp4"
                   checkTxt="请上传视频"
-                  upTxt="最多个"
+                  upTxt="最多1个"
                   myType="video"
                 />
               </div>
@@ -177,6 +177,8 @@ function A1add({ addId, closeFu, addTableFu, type }: Props) {
             />
           </Form.Item>
 
+          <div className="formLastTit">当设为“是”时,该内容将参与自动播放</div>
+
           {/* 确定和取消按钮 */}
           <br />
           <Form.Item wrapperCol={{ offset: 9, span: 16 }}>

+ 14 - 3
src/pages/A1video/A1main/index.tsx

@@ -66,6 +66,10 @@ function A1main({ type }: Props) {
         ),
       },
       {
+        title: "自动播放",
+        render: (item: A1TableType) => (item.display ? "是" : "否"),
+      },
+      {
         title: "创建日期",
         dataIndex: "createTime",
       },
@@ -115,11 +119,18 @@ function A1main({ type }: Props) {
   return (
     <div className={styles.A1main}>
       <div className="pageTitle">
-        {type === "video" ? "视频" : "海报"}管理{" "}
-        {addId ? (addId > 0 ? "- 编辑" : "- 新增") : ""}
+        {type === "video" ? "视频" : "海报"}管理
+        {addId ? (addId > 0 ? " - 编辑" : " - 新增") : ""}
       </div>
       <div className="A1addBtn">
-        <Button type="primary" onClick={() => setAddId(-1)}>
+        <Button
+          type="primary"
+          onClick={() => {
+            if (tableList.length >= 20)
+              return MessageFu.warning("最多新增20条数据!");
+            setAddId(-1);
+          }}
+        >
           新增
         </Button>
       </div>

+ 32 - 3
src/pages/A3play/index.module.scss

@@ -1,5 +1,34 @@
-.A3play{
-  :global{
-    
+.A3play {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 20px 30px;
+
+  :global {
+    .A3row {
+      font-size: 16px;
+      display: flex;
+      line-height: 32px;
+      margin-bottom: 40px;
+
+      .A3row2 {
+        margin: 0 25px 0 15px;
+        position: relative;
+
+        .A3row2Input {
+          position: absolute;
+          top: 40px;
+          left: 0;
+          width: 280px;
+          display: flex;
+          align-items: center;
+          .A3row2InputTit{
+            font-size: 14px;
+            &>span{
+              color: #ff4d4f;
+            }
+          }
+        }
+      }
+    }
   }
 }

+ 185 - 5
src/pages/A3play/index.tsx

@@ -1,12 +1,192 @@
-import React from "react";
+import React, { useCallback, useEffect, useRef, useState } from "react";
 import styles from "./index.module.scss";
- function A3play() {
-  
+import { A3_APIgetConfig, A3_APIsaveConfig } from "@/store/action/A3play";
+import { Button, InputNumber, Popconfirm, Radio } from "antd";
+import { MessageFu } from "@/utils/message";
+
+const arr1 = [
+  "无",
+  "飞入",
+  "劈裂",
+  "百叶窗",
+  "落叶式",
+  "规则图形路径",
+  "圆形展开",
+];
+
+const arr2 = ["关", "海报", "视频"];
+
+function A3play() {
+  const getConfigFu = useCallback(async () => {
+    const res = await A3_APIgetConfig();
+    if (res.code === 0) {
+      const info1 = JSON.parse(res.data[0].content || '{"val":"无"}');
+      setVal1(info1.val || "无");
+      val1Ref.current = info1.val || "无";
+
+      const info2 = JSON.parse(res.data[1].content || '{"val":"关","time":1}');
+      const obj = { val: info2.val || "关", time: info2.time || 1 };
+      setVal2(obj);
+      val2Ref.current = obj;
+    }
+  }, []);
+
+  useEffect(() => {
+    getConfigFu();
+  }, [getConfigFu]);
+
+  // 播放动画的设置
+  const [val1, setVal1] = useState("无");
+  const val1Ref = useRef("无");
+
+  const [edit1, setEdit1] = useState(false);
+
+  // 自动播放的设置
+  const [val2, setVal2] = useState({ val: "关", time: 1 });
+  const val2Ref = useRef({ val: "关", time: 1 });
+
+  const [edit2, setEdit2] = useState(false);
+
+  // 点击提交
+  const btnOkFu = useCallback(
+    async (id: 1 | 2) => {
+      const content1 = JSON.stringify({ val: val1 });
+
+      const content2 = JSON.stringify({ val: val2.val, time: val2.time });
+
+      const res = await A3_APIsaveConfig({
+        id,
+        content: id === 1 ? content1 : content2,
+      });
+
+      if (res.code === 0) {
+        MessageFu.success("设置成功");
+        id === 1 ? setEdit1(false) : setEdit2(false);
+        getConfigFu();
+      }
+    },
+    [getConfigFu, val1, val2.time, val2.val]
+  );
+
   return (
     <div className={styles.A3play}>
-      <h1>A3play</h1>
+      <div className="pageTitle">播放管理</div>
+
+      <div className="A3row">
+        <div className="A3row1">播放动画:</div>
+
+        {edit1 ? (
+          <div className="A3row2">
+            {arr1.map((v) => (
+              <Radio
+                key={v}
+                value={val1}
+                onClick={() => setVal1(v)}
+                checked={v === val1}
+              >
+                {v}
+              </Radio>
+            ))}
+          </div>
+        ) : (
+          <div className="A3row2">{val1}</div>
+        )}
+
+        <div className="A3row3">
+          {edit1 ? (
+            <>
+              <Popconfirm
+                title="放弃编辑后,信息将不会保存!"
+                okText="放弃"
+                cancelText="取消"
+                onConfirm={() => {
+                  setVal1(val1Ref.current);
+                  setEdit1(false);
+                }}
+              >
+                <Button>取消</Button>
+              </Popconfirm>
+              &emsp;
+              <Button type="primary" onClick={() => btnOkFu(1)}>
+                提交
+              </Button>
+            </>
+          ) : (
+            <Button type="primary" onClick={() => setEdit1(true)}>
+              设置
+            </Button>
+          )}
+        </div>
+      </div>
+
+      <div className="A3row">
+        <div className="A3row1">自动播放:</div>
+        {edit2 ? (
+          <div className="A3row2">
+            {arr2.map((v) => (
+              <Radio
+                key={v}
+                value={val2}
+                onClick={() => setVal2({ val: v, time: val2.time })}
+                checked={v === val2.val}
+              >
+                {v}
+              </Radio>
+            ))}
+            {/* 选中海报的时候出来的 输入框 */}
+            {val2.val === "海报" ? (
+              <div className="A3row2Input">
+                <div className="A3row2InputTit">
+                  <span>* </span>轮播间隔:
+                </div>
+                <InputNumber
+                  style={{ width: 160 }}
+                  min={1}
+                  max={99}
+                  placeholder="请输入1~99整数"
+                  precision={0}
+                  value={val2.time}
+                  onChange={(e) => setVal2({ val: val2.val, time: e || 1 })}
+                />
+                &nbsp;秒
+              </div>
+            ) : null}
+          </div>
+        ) : (
+          <div className="A3row2">
+            {val2.val}
+            {val2.val === "海报" ? <>&emsp;&emsp;轮播间隔:{val2.time}秒</> : ""}
+          </div>
+        )}
+
+        <div className="A3row3">
+          {edit2 ? (
+            <>
+              <Popconfirm
+                title="放弃编辑后,信息将不会保存!"
+                okText="放弃"
+                cancelText="取消"
+                onConfirm={() => {
+                  setVal2(val2Ref.current);
+                  setEdit2(false);
+                }}
+              >
+                <Button>取消</Button>
+              </Popconfirm>
+              &emsp;
+              <Button type="primary" onClick={() => btnOkFu(2)}>
+                提交
+              </Button>
+            </>
+          ) : (
+            <Button type="primary" onClick={() => setEdit2(true)}>
+              设置
+            </Button>
+          )}
+        </div>
+      </div>
     </div>
-  )
+  );
 }
 
 const MemoA3play = React.memo(A3play);

+ 42 - 0
src/pages/A4exhibit/A4add/index.module.scss

@@ -0,0 +1,42 @@
+.A4add {
+  position: absolute;
+  z-index: 10;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 20px;
+
+  :global {
+    .A4Amain {
+      width: 800px;
+
+      .A4link {
+        textarea {
+          min-height: 60px !important;
+        }
+      }
+
+      .formRow {
+        display: flex;
+
+        .formLeft {
+          position: relative;
+          top: 3px;
+          width: 100px;
+          text-align: right;
+
+          &>span {
+            color: #ff4d4f;
+          }
+        }
+
+        .formRight {
+          width: calc(100% - 100px);
+        }
+      }
+    }
+  }
+}

+ 218 - 0
src/pages/A4exhibit/A4add/index.tsx

@@ -0,0 +1,218 @@
+import React, { useCallback, useEffect, useRef, useState } from "react";
+import styles from "./index.module.scss";
+import { A4_APIgetInfo, A4_APIsave } from "@/store/action/A4exhibit";
+import {
+  Button,
+  DatePicker,
+  Form,
+  FormInstance,
+  Input,
+  Popconfirm,
+} from "antd";
+import TextArea from "antd/es/input/TextArea";
+import ZupOne from "@/components/ZupOne";
+import dayjs from "dayjs";
+import { MessageFu } from "@/utils/message";
+
+type Props = {
+  addId: number;
+  closeFu: () => void;
+  addTableFu: () => void;
+  editTableFu: () => void;
+};
+
+function A4add({ addId, closeFu, addTableFu, editTableFu }: Props) {
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A4_APIgetInfo(id);
+    if (res.code === 0) {
+      const data = res.data;
+
+      FormBoxRef.current?.setFieldsValue({
+        ...data,
+        myTime: dayjs(data.releaseDate),
+      });
+
+      // 设置封面图
+      ZupOneRef1.current?.setFileComFileFu({
+        fileName: "",
+        filePath: data.thumb,
+      });
+      // 设置二维码
+      if (data.qrCode) {
+        ZupOneRef2.current?.setFileComFileFu({
+          fileName: "",
+          filePath: data.qrCode,
+        });
+      }
+    }
+  }, []);
+
+  useEffect(() => {
+    if (addId > 0) {
+      // 编辑
+      getInfoFu(addId);
+    } else {
+      // 新增
+      FormBoxRef.current?.setFieldsValue({ myTime: dayjs(Date.now()) });
+    }
+  }, [addId, getInfoFu]);
+
+  // 附件 是否 已经点击过确定
+  const [fileCheck, setFileCheck] = useState(false);
+
+  // 表单的ref
+  const FormBoxRef = useRef<FormInstance>(null);
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    setFileCheck(true);
+  }, []);
+
+  //  通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      setFileCheck(true);
+
+      const coverUrl1 = ZupOneRef1.current?.fileComFileResFu();
+      // 没有传 封面图
+      if (!coverUrl1.filePath) return;
+      // 发布日期
+      const releaseDate = dayjs(values.myTime).format("YYYY-MM-DD");
+
+      const qrCodeTemp = ZupOneRef2.current?.fileComFileResFu();
+
+      const obj = {
+        ...values,
+        id: addId > 0 ? addId : null,
+        qrCode: qrCodeTemp.filePath ? qrCodeTemp.filePath : null,
+        releaseDate,
+        thumb: coverUrl1.filePath,
+      };
+      const res = await A4_APIsave(obj);
+      if (res.code === 0) {
+        MessageFu.success(addId > 0 ? "编辑成功!" : "新增成功!");
+        addId > 0 ? editTableFu() : addTableFu();
+        closeFu();
+      }
+    },
+    [addId, addTableFu, closeFu, editTableFu]
+  );
+
+  // 上传附件的ref
+  const ZupOneRef1 = useRef<any>(null);
+  const ZupOneRef2 = useRef<any>(null);
+
+  return (
+    <div className={styles.A4add}>
+      <div className="A4Amain">
+        <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>
+
+          <Form.Item label="简介" name="description">
+            <TextArea placeholder="请输入内容" showCount maxLength={200} />
+          </Form.Item>
+
+          <Form.Item
+            label="场景链接"
+            name="link"
+            rules={[{ required: true, message: "请输入场景链接!" }]}
+            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+          >
+            <TextArea
+              className="A4link"
+              placeholder="请输入内容"
+              showCount
+              maxLength={200}
+            />
+          </Form.Item>
+
+          {/* 封面 */}
+          <div className="formRow">
+            <div className="formLeft">
+              <span>* </span>
+              封面图:
+            </div>
+            <div className="formRight">
+              <ZupOne
+                ref={ZupOneRef1}
+                isLook={false}
+                fileCheck={fileCheck}
+                size={5}
+                dirCode="tab4Exhibit"
+                myUrl="cms/exhibition/upload"
+                format={["image/jpeg", "image/png"]}
+                formatTxt="png、jpg和jpeg"
+                checkTxt="请上传封面图"
+                upTxt="最多1张"
+                myType="thumb"
+              />
+            </div>
+          </div>
+
+          <Form.Item
+            label="发布日期"
+            name="myTime"
+            rules={[{ required: true, message: "请选择发布日期!" }]}
+          >
+            <DatePicker />
+          </Form.Item>
+
+          {/* 封面 */}
+          <div className="formRow">
+            <div className="formLeft">二维码:</div>
+            <div className="formRight">
+              <ZupOne
+                ref={ZupOneRef2}
+                isLook={false}
+                fileCheck={false}
+                size={5}
+                dirCode="tab4ExhibitCode"
+                myUrl="cms/exhibition/upload"
+                format={["image/jpeg", "image/png"]}
+                formatTxt="png、jpg和jpeg"
+                checkTxt="请上传二维码"
+                upTxt="最多1张"
+                myType="thumb"
+              />
+            </div>
+          </div>
+
+          {/* 确定和取消按钮 */}
+          <br />
+          <Form.Item wrapperCol={{ offset: 9, span: 16 }}>
+            <Button type="primary" htmlType="submit">
+              提交
+            </Button>
+            &emsp;
+            <Popconfirm
+              title="放弃编辑后,信息将不会保存!"
+              okText="放弃"
+              cancelText="取消"
+              onConfirm={closeFu}
+            >
+              <Button>取消</Button>
+            </Popconfirm>
+          </Form.Item>
+        </Form>
+      </div>
+    </div>
+  );
+}
+
+const MemoA4add = React.memo(A4add);
+
+export default MemoA4add;

+ 29 - 3
src/pages/A4exhibit/index.module.scss

@@ -1,5 +1,31 @@
-.A4exhibit{
-  :global{
-    
+.A4exhibit {
+  :global {
+    .A4top {
+      padding: 15px 24px;
+      border-radius: 10px;
+      background-color: #fff;
+      display: flex;
+      justify-content: space-between;
+    }
+
+    .A4tableBox {
+      border-radius: 10px;
+      overflow: hidden;
+      margin-top: 15px;
+      height: calc(100% - 77px);
+      background-color: #fff;
+
+      .ant-table-body {
+        height: 625px;
+        overflow-y: auto !important;
+        overflow-y: overlay !important;
+
+        .ant-table-row {
+          .ant-table-cell {
+            padding: 10px;
+          }
+        }
+      }
+    }
   }
 }

+ 198 - 5
src/pages/A4exhibit/index.tsx

@@ -1,12 +1,205 @@
-import React from "react";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
 import styles from "./index.module.scss";
- function A4exhibit() {
-  
+import { Button, Input, Popconfirm, Table } from "antd";
+import { useDispatch, useSelector } from "react-redux";
+import { A4_APIdel, A4_APIgetList } from "@/store/action/A4exhibit";
+import { RootState } from "@/store";
+import { A4tableType } from "@/types";
+import ImageLazy from "@/components/ImageLazy";
+import { MessageFu } from "@/utils/message";
+import A4add from "./A4add";
+
+function A4exhibit() {
+  const dispatch = useDispatch();
+
+  const [fromData, setFromData] = useState({
+    pageNum: 1,
+    pageSize: 10,
+    searchKey: "",
+  });
+
+  const getListFu = useCallback(() => {
+    dispatch(A4_APIgetList(fromData));
+  }, [dispatch, fromData]);
+
+  useEffect(() => {
+    getListFu();
+  }, [getListFu]);
+
+  const [inputKey, setInputKey] = useState(1);
+
+  // 标题的输入
+  const timeRef = useRef(-1);
+  const fromKeyChangeFu = useCallback(
+    (e: React.ChangeEvent<HTMLInputElement>, key: "searchKey") => {
+      clearTimeout(timeRef.current);
+      timeRef.current = window.setTimeout(() => {
+        setFromData({ ...fromData, [key]: e.target.value, pageNum: 1 });
+      }, 500);
+    },
+    [fromData]
+  );
+
+  // 点击重置
+  const resetSelectFu = useCallback(() => {
+    setInputKey(Date.now());
+    setFromData({
+      pageNum: 1,
+      pageSize: 10,
+      searchKey: "",
+    });
+  }, []);
+
+  // 页码变化
+  const paginationChange = useCallback(
+    () => (pageNum: number, pageSize: number) => {
+      setFromData({ ...fromData, pageNum, pageSize });
+    },
+    [fromData]
+  );
+
+  const tableInfo = useSelector(
+    (state: RootState) => state.A4exhibit.tableInfo
+  );
+
+  // 点击删除
+  const delTableFu = useCallback(
+    async (id: number) => {
+      const res = await A4_APIdel(id);
+      if (res.code === 0) {
+        MessageFu.success("删除成功!");
+        getListFu();
+      }
+    },
+    [getListFu]
+  );
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "名称",
+        dataIndex: "name",
+      },
+      {
+        title: "封面",
+        render: (item: A4tableType) => (
+          <div className="tableImgAuto">
+            <ImageLazy width={60} height={60} src={item.thumb} />
+          </div>
+        ),
+      },
+      {
+        title: "简介",
+        render: (item: A4tableType) =>
+          item.description ? (
+            item.description.length >= 50 ? (
+              <span style={{ cursor: "pointer" }} title={item.description}>
+                {item.description.substring(0, 50) + "..."}
+              </span>
+            ) : (
+              item.description
+            )
+          ) : (
+            "(空)"
+          ),
+      },
+      {
+        title: "发布日期",
+        dataIndex: "releaseDate",
+      },
+      {
+        title: "点赞数",
+        dataIndex: "pcs",
+      },
+      {
+        title: "操作",
+        render: (item: A4tableType) => (
+          <>
+            <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.A4exhibit}>
-      <h1>A4exhibit</h1>
+      <div className="pageTitle">云展管理</div>
+
+      {/* 顶部筛选 */}
+      <div className="A4top">
+        <div>
+          <span>搜索项:</span>
+          <Input
+            key={inputKey}
+            maxLength={20}
+            style={{ width: 300 }}
+            placeholder="请输入名称"
+            allowClear
+            onChange={(e) => fromKeyChangeFu(e, "searchKey")}
+          />
+        </div>
+        <div>
+          <Button onClick={resetSelectFu}>重置</Button>
+          &emsp;&emsp;
+          <Button type="primary" onClick={() => setAddId(-1)}>
+            新增
+          </Button>
+        </div>
+      </div>
+
+      {/* 表格主体 */}
+      <div className="A4tableBox">
+        <Table
+          scroll={{ y: 625 }}
+          dataSource={tableInfo.list}
+          columns={columns}
+          rowKey="id"
+          pagination={{
+            showQuickJumper: true,
+            position: ["bottomCenter"],
+            showSizeChanger: true,
+            current: fromData.pageNum,
+            pageSize: fromData.pageSize,
+            total: tableInfo.total,
+            onChange: paginationChange(),
+          }}
+        />
+      </div>
+
+      {/* 新增和编辑 */}
+      {addId ? (
+        <A4add
+          addId={addId}
+          closeFu={() => setAddId(0)}
+          addTableFu={() => resetSelectFu()}
+          editTableFu={() => getListFu()}
+        />
+      ) : null}
     </div>
-  )
+  );
 }
 
 const MemoA4exhibit = React.memo(A4exhibit);

+ 1 - 1
src/pages/A7user/index.tsx

@@ -181,7 +181,7 @@ function A7user() {
             <span>搜索项:</span>
             <Input
               key={inputKey}
-              maxLength={8}
+              maxLength={15}
               style={{ width: 300 }}
               placeholder="请输入用户名"
               allowClear

+ 15 - 0
src/store/action/A3play.ts

@@ -0,0 +1,15 @@
+import http from "@/utils/http";
+
+/**
+ * 获取配置
+ */
+export const A3_APIgetConfig = () => {
+  return http.get("cms/config/getConfig");
+};
+
+/**
+ * 设置配置
+ */
+export const A3_APIsaveConfig = (data: { id: 1 | 2; content: string }) => {
+  return http.post("cms/config/save", data);
+};

+ 38 - 0
src/store/action/A4exhibit.ts

@@ -0,0 +1,38 @@
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+/**
+ * 获取 视频 / 海报 列表
+ */
+export const A4_APIgetList = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("cms/exhibition/pageList", data);
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total,
+      };
+      dispatch({ type: "A4/getList", payload: obj });
+    }
+  };
+};
+
+/**
+ * 删除
+ */
+export const A4_APIdel = (id: number) => {
+  return http.get(`cms/exhibition/remove/${id}`);
+};
+
+/**
+ * 通过id获取详情
+ */
+export const A4_APIgetInfo = (id: number) => {
+  return http.get(`cms/exhibition/detail/${id}`);
+};
+
+/**
+ * 新增|编辑
+ */
+export const A4_APIsave = (data: any) => {
+  return http.post("cms/exhibition/save", data);
+};

+ 28 - 0
src/store/reducer/A4exhibit.ts

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

+ 2 - 0
src/store/reducer/index.ts

@@ -5,6 +5,7 @@ import { combineReducers } from "redux";
 import A0Layout from "./layout";
 import A1video from "./A1video";
 import A2poster from "./A2poster";
+import A4exhibit from "./A4exhibit";
 import A7user from "./A7user";
 import A8log from "./A8log";
 
@@ -14,6 +15,7 @@ const rootReducer = combineReducers({
   A0Layout,
   A1video,
   A2poster,
+  A4exhibit,
   A7user,
   A8log
 });

+ 14 - 0
src/types/api/A4exhibit.d.ts

@@ -0,0 +1,14 @@
+export type A4tableType = {
+	createTime: string;
+	creatorId: number;
+	creatorName: string;
+	description: string;
+	id: number;
+	link: string;
+	name: string;
+	pcs: number;
+	qrCode: string;
+	releaseDate: string;
+	thumb: string;
+	updateTime: string;
+}

+ 1 - 0
src/types/index.d.ts

@@ -1,4 +1,5 @@
 export * from './api/layot'
 export * from './api/A1video'
+export * from './api/A4exhibit'
 export * from './api/A7user'
 export * from './api/A8log'