Ver código fonte

留言反馈

shaogen1995 1 ano atrás
pai
commit
15974619d7

+ 24 - 0
src/pages/A6message/index.module.scss

@@ -0,0 +1,24 @@
+.A6message{
+  :global{
+    .A6top {
+      padding: 15px 24px;
+      border-radius: 10px;
+      background-color: #fff;
+      display: flex;
+      justify-content: space-between;
+      &>div{
+        display: flex;
+        .A6row{
+          margin-right: 20px;
+        }
+      }
+    }
+    .A6tableBox {
+      border-radius: 10px;
+      overflow: hidden;
+      margin-top: 15px;
+      height: calc(100% - 77px);
+      background-color: #fff;
+    }
+  }
+}

+ 200 - 0
src/pages/A6message/index.tsx

@@ -0,0 +1,200 @@
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import styles from "./index.module.scss";
+import { useDispatch, useSelector } from "react-redux";
+import {
+  A6_APIgetInfo,
+  A6_APIgetList,
+  A6_APIgetListDerive,
+} from "@/store/action/A6message";
+import ExportJsonExcel from "js-export-excel";
+import { RootState } from "@/store";
+import dayjs from "dayjs";
+import { A6tableType } from "@/types";
+import { Button, DatePicker, Input, Switch } from "antd";
+import MyTable from "@/components/MyTable";
+import { A6tableC } from "@/utils/tableData";
+const { RangePicker } = DatePicker;
+
+function A6message() {
+  const dispatch = useDispatch();
+
+  const [fromData, setFromData] = useState({
+    pageNum: 1,
+    pageSize: 10,
+    searchKey: "",
+    startTime: "",
+    endTime: "",
+  });
+
+  const getListFu = useCallback(() => {
+    dispatch(A6_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 timeChange = useCallback(
+    (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";
+      }
+      setFromData({ ...fromData, startTime, endTime, pageNum: 1 });
+    },
+    [fromData]
+  );
+
+  // 点击重置
+  const resetSelectFu = useCallback(() => {
+    setInputKey(Date.now());
+    setFromData({
+      pageNum: 1,
+      pageSize: 10,
+      searchKey: "",
+      startTime: "",
+      endTime: "",
+    });
+  }, []);
+
+  const tableInfo = useSelector(
+    (state: RootState) => state.A6message.tableInfo
+  );
+
+  // 点击导出
+  const deriveFu = useCallback(async () => {
+    const name = "留言反馈" + dayjs(new Date()).format("YYYY-MM-DD HH:mm");
+
+    const res = await A6_APIgetListDerive({
+      ...fromData,
+      pageNum: 1,
+      pageSize: 99999,
+    });
+
+    if (res.code === 0) {
+      const option = {
+        fileName: name,
+        datas: [
+          {
+            sheetData: res.data.records.map((v: A6tableType) => ({
+              ...v,
+              status: v.status === 1 ? "已处理" : "未处理",
+            })),
+            sheetName: name,
+            sheetFilter: ["createTime", "name", "phone", "content", "status"],
+            sheetHeader: ["时间", "称呼", "联系方式", "反馈内容", "处理状态"],
+            columnWidths: [10, 10, 10, 20, 10],
+          },
+        ],
+      };
+
+      const toExcel = new ExportJsonExcel(option); //new
+      toExcel.saveExcel(); //保存
+    }
+  }, [fromData]);
+
+  // 处理状态
+  const switchChangeFu = useCallback(
+    async (val: boolean, id: number) => {
+      const res = await A6_APIgetInfo(id, val ? 1 : 2);
+      if (res.code === 0) getListFu();
+    },
+    [getListFu]
+  );
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: "处理状态",
+        render: (item: A6tableType) => (
+          <Switch
+            checkedChildren="已处理"
+            unCheckedChildren="未处理"
+            checked={item.status === 1}
+            onChange={(e) => switchChangeFu(e, item.id)}
+          />
+        ),
+      },
+    ];
+  }, [switchChangeFu]);
+
+  return (
+    <div className={styles.A6message}>
+      <div className="pageTitle">留言反馈</div>
+      {/* 顶部筛选 */}
+      <div className="A6top">
+        <div>
+          <div className="A6row">
+            <span>日期:</span>
+            <RangePicker onChange={timeChange} key={inputKey} />
+          </div>
+          <div className="A6row">
+            <span>称呼:</span>
+            <Input
+              key={inputKey}
+              maxLength={10}
+              showCount
+              style={{ width: 240 }}
+              placeholder="请输入"
+              allowClear
+              onChange={(e) => fromKeyChangeFu(e, "searchKey")}
+            />
+          </div>
+        </div>
+        <div>
+          <Button onClick={resetSelectFu}>重置</Button>&emsp;
+          <Button
+            type="primary"
+            disabled={tableInfo.list.length <= 0}
+            onClick={deriveFu}
+          >
+            导出
+          </Button>
+        </div>
+      </div>
+
+      {/* 表格主体 */}
+      <div className="A6tableBox">
+        <MyTable
+          yHeight={625}
+          list={tableInfo.list}
+          columnsTemp={A6tableC}
+          lastBtn={tableLastBtn}
+          pageNum={fromData.pageNum}
+          pageSize={fromData.pageSize}
+          total={tableInfo.total}
+          onChange={(pageNum, pageSize) =>
+            setFromData({ ...fromData, pageNum, pageSize })
+          }
+        />
+      </div>
+    </div>
+  );
+}
+
+const MemoA6message = React.memo(A6message);
+
+export default MemoA6message;

+ 6 - 8
src/pages/Layout/data.ts

@@ -35,15 +35,13 @@ const tabLeftArr: RouterType = [
         name: "兑换记录",
         path: "/cash",
         Com: React.lazy(() => import("../A5cash")),
-      
       },
-      // {
-      //   id: 600,
-      //   name: "留言反馈",
-      //   path: "/store",
-      //   Com: React.lazy(() => import("../A4store")),
-      //
-      // },
+      {
+        id: 600,
+        name: "留言反馈",
+        path: "/message",
+        Com: React.lazy(() => import("../A6message")),
+      },
       // {
       //   id: 700,
       //   name: "学习资料",

+ 0 - 6
src/store/action/A5cash.ts

@@ -30,9 +30,3 @@ export const A5_APIgetInfo = (id: number, isSend: 0 | 1) => {
   return http.get(`cms/redeem/update/${id}/${isSend}`);
 };
 
-// /**
-//  * 修改爱心币
-//  */
-// export const A5_APIsetNum = (data:any) => {
-//   return http.post('cms/user/point/add',data);
-// };

+ 31 - 0
src/store/action/A6message.ts

@@ -0,0 +1,31 @@
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+/**
+ * 获取 留言反馈 列表
+ */
+export const A6_APIgetList = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("cms/message/pageList", data);
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total,
+      };
+      dispatch({ type: "A6/getList", payload: obj });
+    }
+  };
+};
+
+/**
+ * 获取 留言反馈 列表(导出)
+ */
+export const A6_APIgetListDerive = (data: any) => {
+  return http.post("cms/message/pageList", data);
+};
+
+/**
+ * 处理状态
+ */
+export const A6_APIgetInfo = (id: number, isSend: 1 | 2) => {
+  return http.get(`cms/message/update/${id}/${isSend}`);
+};

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

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

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

@@ -8,6 +8,7 @@ import A2integral from "./A2integral";
 import A3record from "./A3record";
 import A4store from "./A4store";
 import A5cash from "./A5cash";
+import A6message from "./A6message";
 import Z1user from "./Z1user";
 import Z2log from "./Z2log";
 
@@ -19,6 +20,7 @@ const rootReducer = combineReducers({
   A3record,
   A4store,
   A5cash,
+  A6message,
   Z1user,
   Z2log,
 });

+ 10 - 0
src/types/api/A6message.d.ts

@@ -0,0 +1,10 @@
+export type A6tableType={
+	content: string;
+	createTime: string;
+	creatorName: string;
+	id: number;
+	name: string;
+	phone: string;
+	status: number;
+	updateTime: string;
+}

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

@@ -4,5 +4,6 @@ export * from './api/A2integral'
 export * from './api/A3record'
 export * from './api/A4store'
 export * from './api/A5cash'
+export * from './api/A6message'
 export * from './api/Z1user'
 export * from './api/Z2log'

+ 7 - 0
src/utils/tableData.ts

@@ -69,6 +69,13 @@ export const A5tableC = [
   ["text", "地址和留言", "description", 50],
 ];
 
+export const A6tableC = [
+  ["txt", "时间", "createTime"],
+  ["txt", "称呼", "name"],
+  ["txt", "联系方式", "phone"],
+  ["text", "反馈内容", "content", 50],
+];
+
 export const Z1tableC = [
   ["txt", "用户名", "userName"],
   ["txtChange", "角色", "isAdmin", { 1: "管理员", 0: "普通成员" }],