Browse Source

upp新增模块-遗存管理

shaogen1995 1 year ago
parent
commit
2c6ebd7d77

+ 6 - 2
src/components/MyTable/index.module.scss

@@ -1,5 +1,5 @@
-.MyTable{
-  :global{
+.MyTable {
+  :global {
     .ant-table-body {
       overflow-y: auto !important;
       overflow-y: overlay !important;
@@ -7,6 +7,10 @@
       .ant-table-row {
         .ant-table-cell {
           padding: 10px;
+
+          a {
+            color: var(--themeColor) !important;
+          }
         }
       }
     }

+ 35 - 15
src/components/MyTable/index.tsx

@@ -18,6 +18,20 @@ type Props = {
   merge?: { type: string; num: number; loc: "rowSpan" | "colSpan" };
   // 定制化表头
   myTitle?: { name: string; Com: React.ReactNode };
+  // 为空的定制字段
+  isNull?: string;
+};
+
+// 表格内容定制化
+const tableComObj = (key: string, val: string[]) => {
+  const obj = {
+    A: (
+      <a href={val[1]} target="_blank" title={val[1]} rel="noreferrer">
+        {val[0]}
+      </a>
+    ),
+  };
+  return Reflect.get(obj, key);
 };
 
 function MyTable({
@@ -37,6 +51,7 @@ function MyTable({
   classKey = "",
   merge,
   myTitle,
+  isNull = "(空)",
 }: Props) {
   useEffect(() => {
     const dom = document.querySelector(
@@ -58,8 +73,6 @@ function MyTable({
 
   const dataChangeFu = useCallback(
     (v: any) => {
-      const nullTxt = "(空)";
-
       /**
        * index:序号
        * txt:正常数据
@@ -71,31 +84,38 @@ function MyTable({
       const obj = {
         index: (_: any, __: any, index: number) =>
           index + 1 + (pageNum - 1) * pageSize,
-        txt: (item: any) => item[v[2]] || nullTxt,
+        txt: (item: any) => item[v[2]] || isNull,
         img: (item: any) => (
           <div className="tableImgAuto">
             <ImageLazy width={60} height={60} src={item.thumb} />
           </div>
         ),
         txtChange: (item: any) =>
-          Reflect.get(v[3], item[v[2]]) || v[4] || nullTxt,
-        text: (item: any) =>
-          item[v[2]] ? (
-            item[v[2]].length >= v[3] ? (
+          Reflect.get(v[3], item[v[2]]) || v[4] || isNull,
+        text: (item: any) => {
+          let tempCom: any = item[v[2]] || isNull;
+
+          if (tempCom.length >= v[3]) {
+            tempCom = tempCom.substring(0, v[3]) + "...";
+          }
+
+          if (v[4]) {
+            tempCom = tableComObj(v[4], [tempCom, item[v[2]]]);
+          } else if (item[v[2]].length >= v[3]) {
+            tempCom = (
               <span style={{ cursor: "pointer" }} title={item[v[2]]}>
-                {item[v[2]].substring(0, v[3]) + "..."}
+                {tempCom}
               </span>
-            ) : (
-              item[v[2]]
-            )
-          ) : (
-            nullTxt
-          ),
+            );
+          }
+
+          return tempCom;
+        },
       };
 
       return Reflect.get(obj, v[0]);
     },
-    [pageNum, pageSize]
+    [isNull, pageNum, pageSize]
   );
 
   const columns = useMemo(() => {

+ 193 - 0
src/pages/A5_1remains/A5_1edit.tsx

@@ -0,0 +1,193 @@
+import React, { useCallback, useEffect, useRef, useState } from "react";
+import styles from "./index.module.scss";
+import {
+  Button,
+  Form,
+  FormInstance,
+  Input,
+  InputNumber,
+  Modal,
+  Select,
+} from "antd";
+import { MessageFu } from "@/utils/message";
+import TextArea from "antd/es/input/TextArea";
+import ZupOne from "@/components/ZupOne";
+import MyPopconfirm from "@/components/MyPopconfirm";
+import { A5_1_APIgetInfo, A5_1_APIsave } from "@/store/action/A5_1remains";
+
+type Props = {
+  fId: number;
+  closeFu: () => void;
+  addTableFu: () => void;
+  upTableFu: () => void;
+};
+
+function A5_1edit({ fId, closeFu, addTableFu, upTableFu }: Props) {
+  // 设置表单初始数据(区分编辑和新增)
+  const FormBoxRef = useRef<FormInstance>(null);
+
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A5_1_APIgetInfo(id);
+    if (res.code === 0) {
+      const data = res.data;
+
+      FormBoxRef.current?.setFieldsValue(data);
+
+      // 设置封面图
+      ZupOneRef1.current?.setFileComFileFu({
+        fileName: "",
+        filePath: data.thumb,
+      });
+    }
+  }, []);
+
+  useEffect(() => {
+    if (fId > 0) getInfoFu(fId);
+  }, [fId, getInfoFu]);
+
+  // 附件的ref
+  const ZupOneRef1 = useRef<any>(null);
+
+  // 附件 是否 已经点击过确定
+  const [fileCheck, setFileCheck] = useState(false);
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {
+    setFileCheck(true);
+  }, []);
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      setFileCheck(true);
+      // 没有传 封面图 或者视频
+      const coverUrl1 = ZupOneRef1.current?.fileComFileResFu();
+
+      if (!coverUrl1.filePath) return;
+
+      const obj = {
+        ...values,
+        id: fId > 0 ? fId : null,
+        thumb: coverUrl1.filePath,
+      };
+
+      const res = await A5_1_APIsave(obj);
+
+      if (res.code === 0) {
+        MessageFu.success(fId > 0 ? "编辑成功!" : "新增成功!");
+        fId > 0 ? upTableFu() : addTableFu();
+        closeFu();
+      }
+    },
+    [addTableFu, closeFu, fId, upTableFu]
+  );
+
+  return (
+    <Modal
+      wrapClassName={styles.A5_1edit}
+      open={true}
+      title={fId > 0 ? "编辑" : "新增"}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className="A5_1eMain">
+        <Form
+          scrollToFirstError={true}
+          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={50} showCount placeholder="请输入内容" />
+          </Form.Item>
+
+          {/* 封面 */}
+          <div className="formRow">
+            <div className="formLeft">
+              <span>* </span>
+              封面:
+            </div>
+            <div className="formRight">
+              <ZupOne
+                ref={ZupOneRef1}
+                isLook={false}
+                fileCheck={fileCheck}
+                size={2}
+                dirCode={"remainsThumb"}
+                myUrl="cms/remains/upload"
+                format={["image/jpeg", "image/png"]}
+                formatTxt="png、jpg和jpeg"
+                checkTxt="请上传封面!"
+                upTxt="最多1张"
+                myType="thumb"
+              />
+            </div>
+          </div>
+          <Form.Item
+            label="区域"
+            name="region"
+            rules={[{ required: true, message: "请选择区域!" }]}
+          >
+            <Select
+              placeholder="请选择"
+              style={{ width: 200 }}
+              options={[
+                { value: "江阴市", label: "江阴市" },
+                { value: "宜兴市", label: "宜兴市" },
+                { value: "梁溪区", label: "梁溪区" },
+                { value: "锡山区", label: "锡山区" },
+                { value: "惠山区", label: "惠山区" },
+                { value: "滨湖区", label: "滨湖区" },
+                { value: "新吴区", label: "新吴区" },
+                { value: "经开区", label: "经开区" },
+              ]}
+            />
+          </Form.Item>
+
+          <Form.Item label="简介" name="description" className="A5ET1">
+            <TextArea maxLength={1000} showCount placeholder="请输入内容" />
+          </Form.Item>
+
+          <Form.Item label="场景链接" name="link" className="A5ET2">
+            <TextArea maxLength={200} showCount placeholder="请输入内容" />
+          </Form.Item>
+
+          <Form.Item
+            label="排序值"
+            name="sort"
+            rules={[{ required: true, message: "请输入排序值!" }]}
+          >
+            <InputNumber
+              min={1}
+              max={999}
+              precision={0}
+              placeholder="请输入1~999,数字越小,排序越前"
+            />
+          </Form.Item>
+
+          {/* 确定和取消按钮 */}
+          <Form.Item className="A5_1eBtn">
+            <Button type="primary" htmlType="submit">
+              提交
+            </Button>
+            <br />
+            <br />
+            <MyPopconfirm txtK="取消" onConfirm={closeFu} />
+          </Form.Item>
+        </Form>
+      </div>
+    </Modal>
+  );
+}
+
+const MemoA5_1edit = React.memo(A5_1edit);
+
+export default MemoA5_1edit;

+ 109 - 0
src/pages/A5_1remains/index.module.scss

@@ -0,0 +1,109 @@
+.A5_1remains {
+  border-radius: 10px;
+  background-color: #fff;
+  padding: 15px 0;
+  position: relative;
+
+  :global {
+    .A5_1top {
+      padding: 0 24px;
+      display: flex;
+      justify-content: space-between;
+    }
+
+    .A5_1tableBox {
+      border-radius: 10px;
+      overflow: hidden;
+      margin-top: 15px;
+      height: calc(100% - 32px);
+    }
+  }
+}
+
+// 新增 、 编辑
+.A5_1edit {
+  :global {
+
+    .A5ET1 {
+      textarea {
+        min-height: 150px !important;
+      }
+    }
+
+    .A5ET2 {
+      textarea {
+        min-height: 52px !important;
+        height: 52px !important;
+      }
+    }
+
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      width: 1000px !important;
+    }
+
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+    }
+
+    .A5_1eMain {
+      margin-top: 15px;
+      width: 100%;
+      height: 600px;
+      overflow-y: auto;
+
+      .ant-form {
+        width: 800px;
+
+        .ant-input-number {
+          width: 260px;
+        }
+
+
+        .formRow {
+          display: flex;
+
+          .formLeft {
+            position: relative;
+            top: 3px;
+            width: 103px;
+            text-align: right;
+
+            &>span {
+              color: #ff4d4f;
+            }
+          }
+
+          .formRight {
+            width: calc(100% - 103px);
+
+            .A5_1radio {
+              position: relative;
+              top: 3px;
+              margin-bottom: 15px;
+            }
+          }
+        }
+
+        .formRow2 {
+          margin-bottom: 14px;
+
+          .formLeft {
+            top: 0;
+          }
+        }
+
+        .A5_1eBtn {
+          position: absolute;
+          z-index: 10;
+          right: 60px;
+          top: 50%;
+          transform: translateY(-50%);
+        }
+      }
+    }
+  }
+}

+ 115 - 0
src/pages/A5_1remains/index.tsx

@@ -0,0 +1,115 @@
+import React, { useCallback, useEffect, useMemo, useState } from "react";
+import styles from "./index.module.scss";
+import { Button } from "antd";
+import MyTable from "@/components/MyTable";
+import { useDispatch, useSelector } from "react-redux";
+import { A5_1_APIdel, A5_1_APIgetList } from "@/store/action/A5_1remains";
+import { RootState } from "@/store";
+import { MessageFu } from "@/utils/message";
+import { A5_1tableType } from "@/types";
+import MyPopconfirm from "@/components/MyPopconfirm";
+import { A5_1tableC } from "@/utils/tableData";
+import A51edit from "./A5_1edit";
+function A5_1remains() {
+  const dispatch = useDispatch();
+
+  const [fromData, setFromData] = useState({
+    pageNum: 1,
+    pageSize: 10,
+  });
+
+  const getListFu = useCallback(() => {
+    dispatch(A5_1_APIgetList(fromData));
+  }, [dispatch, fromData]);
+
+  useEffect(() => {
+    getListFu();
+  }, [getListFu]);
+
+  // 点击重置
+  const resetSelectFu = useCallback(() => {
+    setFromData({
+      pageNum: 1,
+      pageSize: 10,
+    });
+  }, []);
+
+  const tableInfo = useSelector(
+    (state: RootState) => state.A5_1remains.tableInfo
+  );
+
+  // 点击删除
+  const delTableFu = useCallback(
+    async (id: number) => {
+      const res = await A5_1_APIdel(id);
+      if (res.code === 0) {
+        MessageFu.success("删除成功!");
+        getListFu();
+      }
+    },
+    [getListFu]
+  );
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: "操作",
+        render: (item: A5_1tableType) => (
+          <>
+            <Button size="small" type="text" onClick={() => setEditId(item.id)}>
+              编辑
+            </Button>
+            {item.id !== 1 ? (
+              <MyPopconfirm txtK="删除" onConfirm={() => delTableFu(item.id)} />
+            ) : null}
+          </>
+        ),
+      },
+    ];
+  }, [delTableFu]);
+
+  const [editId, setEditId] = useState(0);
+
+  return (
+    <div className={styles.A5_1remains}>
+      <div className="pageTitle">遗存管理</div>
+      <div className="A5_1top">
+        <div></div>
+        <div>
+          <Button type="primary" onClick={() => setEditId(-1)}>
+            新增
+          </Button>
+        </div>
+      </div>
+      {/* 表格主体 */}
+      <div className="A5_1tableBox">
+        <MyTable
+          yHeight={640}
+          list={tableInfo.list}
+          columnsTemp={A5_1tableC}
+          lastBtn={tableLastBtn}
+          pageNum={fromData.pageNum}
+          pageSize={fromData.pageSize}
+          total={tableInfo.total}
+          onChange={(pageNum, pageSize) =>
+            setFromData({ ...fromData, pageNum, pageSize })
+          }
+        />
+      </div>
+
+      {/* 新增 编辑 */}
+      {editId ? (
+        <A51edit
+          fId={editId}
+          closeFu={() => setEditId(0)}
+          addTableFu={() => resetSelectFu()}
+          upTableFu={()=>getListFu()}
+        />
+      ) : null}
+    </div>
+  );
+}
+
+const MemoA5_1remains = React.memo(A5_1remains);
+
+export default MemoA5_1remains;

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

@@ -161,7 +161,7 @@ function A5cash() {
 
   return (
     <div className={styles.A5cash}>
-      <div className="pageTitle">兑换记录</div>
+      <div className="pageTitle">捐赠记录</div>
 
       {/* 顶部筛选 */}
       <div className="A5top">

+ 1 - 1
src/pages/A7_1charity/A7_1edit.tsx

@@ -85,7 +85,7 @@ function A7_1edit({
 
       if (res.code === 0) {
         MessageFu.success(fId > 0 ? "编辑成功!" : "新增成功!");
-        fId > 0 ? addTableFu() : upTableFu();
+        fId > 0 ? upTableFu() : addTableFu();
         closeFu();
       }
     },

+ 1 - 1
src/pages/A7school/A7tab1M.tsx

@@ -126,7 +126,7 @@ function A7tab1M({ fId, closeFu, addTableFu, upTableFu }: Props) {
 
       if (res.code === 0) {
         MessageFu.success(fId > 0 ? "编辑成功!" : "新增成功!");
-        fId > 0 ? addTableFu() : upTableFu();
+        fId > 0 ? upTableFu() : addTableFu();
         closeFu();
       }
     },

+ 1 - 1
src/pages/A7school/A7tab2M.tsx

@@ -106,7 +106,7 @@ function A7tab2M({ fId, closeFu, addTableFu, upTableFu }: Props) {
 
       if (res.code === 0) {
         MessageFu.success(fId > 0 ? "编辑成功!" : "新增成功!");
-        fId > 0 ? addTableFu() : upTableFu();
+        fId > 0 ? upTableFu() : addTableFu();
         closeFu();
       }
     },

+ 7 - 1
src/pages/Layout/data.ts

@@ -32,11 +32,17 @@ const tabLeftArr: RouterType = [
       },
       {
         id: 500,
-        name: "兑换记录",
+        name: "捐赠记录",
         path: "/cash",
         Com: React.lazy(() => import("../A5cash")),
       },
       {
+        id: 1100,
+        name: "遗存管理",
+        path: "/remains",
+        Com: React.lazy(() => import("../A5_1remains")),
+      },
+      {
         id: 600,
         name: "留言反馈",
         path: "/message",

+ 39 - 0
src/store/action/A5_1remains.ts

@@ -0,0 +1,39 @@
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+/**
+ * 获取 留言反馈 列表
+ */
+export const A5_1_APIgetList = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("cms/remains/pageList", data);
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total,
+      };
+      dispatch({ type: "A5_1/getList", payload: obj });
+    }
+  };
+};
+
+
+/**
+ * 编辑获取详情
+ */
+export const A5_1_APIgetInfo = (id: number) => {
+  return http.get(`cms/remains/detail/${id}`);
+};
+
+/**
+ * 新增、修改
+ */
+export const A5_1_APIsave = (data: any) => {
+  return http.post("cms/remains/save", data);
+};
+
+/**
+ * 删除
+ */
+export const A5_1_APIdel = (id: number) => {
+  return http.get(`cms/remains/removes/${id}`);
+};

+ 2 - 2
src/store/action/A5cash.ts

@@ -1,7 +1,7 @@
 import http from "@/utils/http";
 import { AppDispatch } from "..";
 /**
- * 获取 兑换记录 列表
+ * 获取 捐赠记录 列表
  */
 export const A5_APIgetList = (data: any) => {
   return async (dispatch: AppDispatch) => {
@@ -17,7 +17,7 @@ export const A5_APIgetList = (data: any) => {
 };
 
 /**
- * 获取 兑换记录 列表(导出)
+ * 获取 捐赠记录 列表(导出)
  */
 export const A5_APIgetListDerive = (data: any) => {
   return http.post("cms/redeem/pageList", data);

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

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

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

@@ -7,6 +7,7 @@ import A1wxuser from "./A1wxuser";
 import A2integral from "./A2integral";
 import A3record from "./A3record";
 import A4store from "./A4store";
+import A5_1remains from "./A5_1remains";
 import A5cash from "./A5cash";
 import A6message from "./A6message";
 import A7_1charity from "./A7_1charity";
@@ -21,6 +22,7 @@ const rootReducer = combineReducers({
   A2integral,
   A3record,
   A4store,
+  A5_1remains,
   A5cash,
   A6message,
   A7_1charity,

+ 16 - 0
src/types/api/A5_1remains.d.ts

@@ -0,0 +1,16 @@
+export type A5_1tableType ={
+	createTime: string;
+	creatorName: string;
+	description: string;
+	id: number;
+	isIndex: number;
+	link: string;
+	name: string;
+	pcsVisitPc: number;
+	pcsVisitWx: number;
+	region: string;
+	thumb: string;
+	type: string;
+	updateTime: string;
+	sotr:number
+}

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

@@ -3,6 +3,7 @@ export * from './api/A1wxuser'
 export * from './api/A2integral'
 export * from './api/A3record'
 export * from './api/A4store'
+export * from './api/A5_1remains'
 export * from './api/A5cash'
 export * from './api/A6message'
 export * from './api/A7_1charity'

+ 2 - 2
src/utils/http.ts

@@ -7,8 +7,8 @@ import { domShowFu } from "./domShow";
 
 const envFlag = process.env.NODE_ENV === "development";
 
-const baseUrlTemp = "https://sit-wuxicishan.4dage.com"; // 测试环境
-// const baseUrlTemp = "http://192.168.20.61:8066"; // 线下环境
+// const baseUrlTemp = "https://sit-wuxicishan.4dage.com"; // 测试环境
+const baseUrlTemp = "http://192.168.20.61:8066"; // 线下环境
 
 const baseFlag = baseUrlTemp.includes("https://");
 

+ 9 - 0
src/utils/tableData.ts

@@ -68,6 +68,15 @@ export const A4tableC = [
   ["txtChange", "状态", "isEnabled", { 0: "下架", 1: "上架" }],
 ];
 
+export const A5_1tableC = [
+  ["txt", "标题", "name"],
+  ["img", "封面", "thumb"],
+  ["txt", "区域", "region"],
+  ["text", "简介", "description", 50],
+  ["text", "场景链接", "link", 50, "A"],
+  ["txt", "排序值", "sort"],
+];
+
 export const A5tableC = [
   ["txt", "时间", "createTime"],
   ["txt", "用户名", "creatorName"],