shaogen1995 2 gadi atpakaļ
vecāks
revīzija
f8b3c3d12b
32 mainītis faili ar 3036 papildinājumiem un 72 dzēšanām
  1. 22 0
      src/pages/Home/index.module.scss
  2. 62 24
      src/pages/Home/index.tsx
  3. 12 5
      src/pages/Layout/index.tsx
  4. 16 1
      src/pages/Object/index.tsx
  5. 2 2
      src/pages/ObjectSon/Object1/AddObject1/index.tsx
  6. 19 5
      src/pages/ObjectSon/Object2/LookObject2/index.tsx
  7. 1 1
      src/pages/ObjectSon/Object3/AuditObject3/index.tsx
  8. 1 1
      src/pages/ObjectSon/Object4/AuditObject4/index.tsx
  9. 164 0
      src/pages/ObjectSon/Object6/AddObject6/GoodsAll.tsx
  10. 87 0
      src/pages/ObjectSon/Object6/AddObject6/index.module.scss
  11. 282 0
      src/pages/ObjectSon/Object6/AddObject6/index.tsx
  12. 86 0
      src/pages/ObjectSon/Object6/AuditObject6/index.module.scss
  13. 233 0
      src/pages/ObjectSon/Object6/AuditObject6/index.tsx
  14. 56 0
      src/pages/ObjectSon/Object6/LookObject6/index.module.scss
  15. 196 0
      src/pages/ObjectSon/Object6/LookObject6/index.tsx
  16. 293 4
      src/pages/ObjectSon/Object6/index.tsx
  17. 22 1
      src/pages/Stores/index.tsx
  18. 93 3
      src/pages/StoresSon/Stores2/index.module.scss
  19. 234 5
      src/pages/StoresSon/Stores2/index.tsx
  20. 96 0
      src/pages/StoresSon/Stores3/AuditStores3/index.module.scss
  21. 217 0
      src/pages/StoresSon/Stores3/AuditStores3/index.tsx
  22. 97 0
      src/pages/StoresSon/Stores3/LookStores3/index.module.scss
  23. 170 0
      src/pages/StoresSon/Stores3/LookStores3/index.tsx
  24. 293 7
      src/pages/StoresSon/Stores3/index.tsx
  25. 14 8
      src/store/action/login.ts
  26. 81 0
      src/store/action/object6.ts
  27. 26 1
      src/store/action/stores1.ts
  28. 62 0
      src/store/action/stores3.ts
  29. 4 0
      src/store/reducer/index.ts
  30. 52 0
      src/store/reducer/object6.ts
  31. 39 0
      src/store/reducer/stores3.ts
  32. 4 4
      src/utils/dataChange.ts

+ 22 - 0
src/pages/Home/index.module.scss

@@ -72,6 +72,17 @@
               color: var(--themeColor);
             }
           }
+
+          .noAuth {
+            opacity: .5;
+            cursor: no-drop;
+            -webkit-filter: grayscale(100%);
+            -moz-filter: grayscale(100%);
+            -ms-filter: grayscale(100%);
+            -o-filter: grayscale(100%);
+            filter: grayscale(100%);
+            filter: gray;
+          }
         }
       }
 
@@ -177,6 +188,17 @@
               border: none;
             }
           }
+
+          .noAuth {
+            opacity: .5;
+            cursor: no-drop !important;
+            -webkit-filter: grayscale(100%);
+            -moz-filter: grayscale(100%);
+            -ms-filter: grayscale(100%);
+            -o-filter: grayscale(100%);
+            filter: grayscale(100%);
+            filter: gray;
+          }
         }
       }
     }

+ 62 - 24
src/pages/Home/index.tsx

@@ -1,13 +1,16 @@
 import { getTokenInfo } from "@/utils/storage";
-import { useEffect, useMemo, useRef, useState } from "react";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
 import styles from "./index.module.scss";
 import dayjs from "dayjs";
-import { Button } from "antd";
+import { Button, message } from "antd";
 import classNames from "classnames";
 import * as echarts from "echarts/core";
 import { TooltipComponent, GridComponent } from "echarts/components";
 import { BarChart } from "echarts/charts";
 import { CanvasRenderer } from "echarts/renderers";
+import history from "@/utils/history";
+import { getStores2API1 } from "@/store/action/stores1";
+import { getHomeNumsAPI } from "@/store/action/login";
 
 echarts.use([TooltipComponent, GridComponent, BarChart, CanvasRenderer]);
 
@@ -20,14 +23,20 @@ export default function Home() {
   // 头部右侧
   const tabList = useMemo(() => {
     return [
-      { id: 1, path: "/", name: "藏品登记" },
-      { id: 2, path: "/object", name: "藏品总账" },
-      { id: 3, path: "/stores", name: "入库管理" },
-      { id: 4, path: "/system", name: "出库管理" },
-      { id: 5, path: "/system", name: "藏品注销" },
+      { id: 1, path: "/object", name: "藏品登记" },
+      { id: 2, path: "/object/2", name: "藏品总账" },
+      { id: 3, path: "/object/3", name: "入库管理" },
+      { id: 4, path: "/object/4", name: "出库管理" },
+      { id: 5, path: "/object/6", name: "藏品注销" },
     ];
   }, []);
 
+  // 点击头部右侧和下面右侧
+  const toPageFu = useCallback((path: string, flag: boolean) => {
+    if (flag) return message.warning("没有该模块权限!");
+    history.push(path);
+  }, []);
+
   const timeRef = useRef(-1);
   useEffect(() => {
     timeRef.current = window.setInterval(() => {
@@ -45,7 +54,8 @@ export default function Home() {
   }, []);
 
   // -----------图表
-  useEffect(() => {
+  const echartsFu = useCallback(async () => {
+    const res = await getStores2API1();
     const chartDom: any = document.querySelector(".chart");
     const myChart = echarts.init(chartDom);
     const option = {
@@ -65,7 +75,7 @@ export default function Home() {
       xAxis: [
         {
           type: "category",
-          data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+          data: res.data.map((v: any) => v.groupKey),
           axisTick: {
             show: false,
             alignWithLabel: false,
@@ -112,8 +122,8 @@ export default function Home() {
         {
           name: "",
           type: "bar",
-          barWidth: "60%",
-          data: [10, 52, 200, 334, 390, 330, 220],
+          barWidth: "20%",
+          data: res.data.map((v: any) => v.count),
           itemStyle: {
             normal: {
               color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
@@ -139,18 +149,37 @@ export default function Home() {
     option && myChart.setOption(option);
   }, []);
 
-  // -------代办提醒
-  // 头部右侧
-  const doneList = useMemo(() => {
+  const tempDone = useMemo(() => {
     return [
-      { id: 1, num: 0, name: "藏品登记" },
-      { id: 2, num: 7, name: "入库管理" },
-      { id: 3, num: 5, name: "出库管理" },
-      { id: 4, num: 0, name: "藏品修改" },
-      { id: 5, num: 21, name: "藏品注销" },
+      { id: 1, path: "/object", num: 0, name: "藏品登记" },
+      { id: 2, path: "/object/3", num: 0, name: "入库管理" },
+      { id: 3, path: "/object/4", num: 0, name: "出库管理" },
+      { id: 4, path: "/object/5", num: 0, name: "藏品修改" },
+      { id: 5, path: "/object/6", num: 0, name: "藏品注销" },
     ];
   }, []);
 
+  // 代办提醒
+  const [doneList, setDoneList] = useState(tempDone);
+
+  const doneNumsAPIFu = useCallback(async () => {
+    const res = await getHomeNumsAPI();
+    const data = [...tempDone];
+    res.data.forEach((v: any) => {
+      if (v.groupKey === "register") data[0].num = v.count;
+      else if (v.groupKey === "in") data[1].num = v.count;
+      else if (v.groupKey === "out") data[2].num = v.count;
+      else if (v.groupKey === "edit") data[3].num = v.count;
+      else if (v.groupKey === "cancel") data[4].num = v.count;
+    });
+    setDoneList(data);
+  }, [tempDone]);
+
+  useEffect(() => {
+    echartsFu();
+    doneNumsAPIFu();
+  }, [doneNumsAPIFu, echartsFu]);
+
   return (
     <div className={styles.Home}>
       <div className="homeMain">
@@ -167,8 +196,12 @@ export default function Home() {
             <p>{nowTime}</p>
           </div>
           <div className="titleR">
-            {tabList.map((v) => (
-              <div className="row" key={v.id}>
+            {tabList.map((v, i) => (
+              <div
+                onClick={() => toPageFu(v.path, i === 1)}
+                className={classNames("row", i === 1 ? "noAuth" : "")}
+                key={v.id}
+              >
                 <div className={`bac${v.id}`}></div>
                 <p>{v.name}</p>
               </div>
@@ -190,17 +223,22 @@ export default function Home() {
           </div>
           <div className="flooBoxR">
             <div className="flooTit">
-              <div>代办提醒</div>
+              <div>审核提醒</div>
             </div>
             <div className="doneBox">
               {doneList.map((v, i) => (
                 <div
-                  className={classNames("doneRow", i >= 4 ? "noneRow" : "")}
+                  onClick={() => toPageFu(v.path, i === 1)}
+                  className={classNames(
+                    "doneRow",
+                    i >= 4 ? "noneRow" : "",
+                    i === 1 ? "noAuth" : ""
+                  )}
                   key={v.id}
                 >
                   <div className="doneRow_tit">{v.name}</div>
                   <div className="doneRow_txt">
-                    共有&emsp;<span>{v.num}</span>&emsp;代办事项
+                    共有&emsp;<span>{v.num}</span>&emsp;待审核事项
                   </div>
                 </div>
               ))}

+ 12 - 5
src/pages/Layout/index.tsx

@@ -15,7 +15,7 @@ import { useDispatch } from "react-redux";
 
 const NotFound = React.lazy(() => import("../../components/NotFound"));
 
-export default function Layout() {
+function Layout() {
   const location = useLocation();
   const [path, setPath] = useState("");
 
@@ -32,7 +32,7 @@ export default function Layout() {
   }, []);
 
   const tabList = useMemo(() => {
-    return [
+    const tempArr = [
       {
         id: 1,
         Com: React.lazy(() => import("../Home")),
@@ -51,13 +51,16 @@ export default function Layout() {
         path: "/stores",
         name: "库房管理",
       },
-      {
+    ];
+    const temp = getTokenInfo().user.isAdmin;
+    if (temp === 1 && tempArr.length <= 3)
+      tempArr.push({
         id: 4,
         Com: React.lazy(() => import("../System")),
         path: "/system",
         name: "系统管理",
-      },
-    ];
+      });
+    return tempArr;
   }, []);
 
   // 顶部路由跳转
@@ -208,3 +211,7 @@ export default function Layout() {
     </div>
   );
 }
+
+const MemoLayout = React.memo(Layout);
+
+export default MemoLayout;

+ 16 - 1
src/pages/Object/index.tsx

@@ -23,7 +23,9 @@ const LookObject4 = React.lazy(
 const LookObject5 = React.lazy(
   () => import("../ObjectSon/Object5/LookObject5")
 );
-
+const LookObject6 = React.lazy(
+  () => import("../ObjectSon/Object6/LookObject6")
+);
 
 export default function Object() {
   const data = useMemo(() => {
@@ -111,6 +113,18 @@ export default function Object() {
         Com: React.lazy(() => import("../ObjectSon/Object5/AuditObject5")),
         path: "/object/5/audit",
       },
+      {
+        id: 6001,
+        name: "藏品注销新增",
+        Com: React.lazy(() => import("../ObjectSon/Object6/AddObject6")),
+        path: "/object/6/add",
+      },
+      {
+        id: 6002,
+        name: "藏品注销审核",
+        Com: React.lazy(() => import("../ObjectSon/Object6/AuditObject6")),
+        path: "/object/6/audit",
+      },
     ];
   }, []);
 
@@ -145,6 +159,7 @@ export default function Object() {
             <AuthRoute path="/object/3/look" component={LookObject3} />
             <AuthRoute path="/object/4/look" component={LookObject4} />
             <AuthRoute path="/object/5/look" component={LookObject5} />
+            <AuthRoute path="/object/6/look" component={LookObject6} />
 
             {/* 新增 */}
             {dataIn.map((v) => (

+ 2 - 2
src/pages/ObjectSon/Object1/AddObject1/index.tsx

@@ -202,11 +202,11 @@ function AddObject1() {
         if (delIds.current.length) {
           const res2: any = await delInTablesAPI(delIds.current.join(","));
           if (res2.code === 0) {
-            message.warning("操作成功!");
+            message.success("操作成功!");
             cancelFu();
           }
         } else {
-          message.warning("操作成功!");
+          message.success("操作成功!");
           cancelFu();
         }
       }

+ 19 - 5
src/pages/ObjectSon/Object2/LookObject2/index.tsx

@@ -183,9 +183,16 @@ function LookObject2() {
     (state: RootState) => state.stores1Store.infoList
   );
 
+  const moveLocRef = useRef("");
   const [moveLoc, setMoveLoc] = useState<any>([]);
-  const moveLocChangeFu = (val: any) => {
+  const moveLocChangeFu = (val: any, names: any) => {
     setMoveLoc(val);
+    let temp = "";
+    names.forEach((v: any, i: number) => {
+      if (i < names.length - 1) temp += v.name + "/";
+      else temp += v.name;
+    });
+    moveLocRef.current = temp;
   };
 
   const moveBtnOk = useCallback(async () => {
@@ -194,10 +201,11 @@ function LookObject2() {
     if (!newLoc) return message.warning("请选择移库位置!");
     if (oldLoc === newLoc) return message.warning("位置不能相同!");
     const obj = {
-      after: oldLoc,
-      before: newLoc,
+      beforeJson: { id: oldLoc, name: info.storageAncestorName },
+      afterJson: { id: newLoc, name: moveLocRef.current },
       goodsIds: info.id,
     };
+
     const res: any = await editObj2StoresAPI(obj);
     if (res.code === 0) {
       message.success("申请移库成功!");
@@ -207,7 +215,13 @@ function LookObject2() {
     }
 
     console.log("移库点击提交", oldLoc, newLoc);
-  }, [getObj2InfoInAPIFu, info.id, info.storageAncestor, moveLoc]);
+  }, [
+    getObj2InfoInAPIFu,
+    info.id,
+    info.storageAncestor,
+    info.storageAncestorName,
+    moveLoc,
+  ]);
 
   return (
     <div className={styles.LookObject2}>
@@ -505,7 +519,7 @@ function LookObject2() {
         {titCut === "3" ? (
           <div className="logBox">
             {/* 表格 */}
-            <LookObject2Log id={info.id}/>
+            <LookObject2Log id={info.id} />
           </div>
         ) : null}
       </Modal>

+ 1 - 1
src/pages/ObjectSon/Object3/AuditObject3/index.tsx

@@ -149,7 +149,7 @@ function AuditObject3() {
         </BreadTit>
       </div>
       <div className="objectSonMain">
-        <div className="topTit">登记信息</div>
+        <div className="topTit">入库信息</div>
         <div className="topInfo">
           <div className="topInfoRow">
             <div>

+ 1 - 1
src/pages/ObjectSon/Object4/AuditObject4/index.tsx

@@ -149,7 +149,7 @@ function AuditObject4() {
         </BreadTit>
       </div>
       <div className="objectSonMain">
-        <div className="topTit">登记信息</div>
+        <div className="topTit">出库信息</div>
         <div className="topInfo">
           <div className="topInfoRow">
             <div>

+ 164 - 0
src/pages/ObjectSon/Object6/AddObject6/GoodsAll.tsx

@@ -0,0 +1,164 @@
+import { Button, Input, message, Modal, Table } from "antd";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import styles from "./index.module.scss";
+import "../../Object3/AddObject3/GoodsAll.css";
+import { getGoodsListAllAPI } from "@/store/action/object6";
+import { useDispatch, useSelector } from "react-redux";
+import { RootState } from "@/store";
+import ImageLazy from "@/components/ImageLazy";
+
+type Props = {
+  colsePage: any;
+};
+function GoodsAll({ colsePage }: Props) {
+  const dispatch = useDispatch();
+
+  // 进页面获取列表
+  useEffect(() => {
+    dispatch(getGoodsListAllAPI(""));
+  }, [dispatch]);
+
+  // 藏品名称
+  const [name, setName] = useState("");
+  const nameTime = useRef(-1);
+  const nameChange = useCallback(
+    (e: React.ChangeEvent<HTMLInputElement>) => {
+      setName(e.target.value);
+      clearTimeout(nameTime.current);
+      nameTime.current = window.setTimeout(() => {
+        dispatch(getGoodsListAllAPI(e.target.value));
+      }, 500);
+    },
+    [dispatch]
+  );
+
+  // 有关表格
+  const results = useSelector(
+    (state: RootState) => state.object6Store.goodsAllList
+  );
+
+  // 已经选中的表格数据
+  const resultsAc = useSelector(
+    (state: RootState) => state.object6Store.goodsTableList
+  );
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "缩略图",
+        render: (item: any) => (
+          <ImageLazy width={120} height={70} src={item.thumb} />
+        ),
+      },
+      {
+        title: "藏品编号名称",
+        dataIndex: "dictNum",
+      },
+      {
+        title: "藏品编号",
+        render: (item: any) => (item.num ? item.num : "-"),
+      },
+      {
+        title: "藏品名称",
+        dataIndex: "name",
+      },
+      {
+        title: "类别",
+        dataIndex: "dictGoodType",
+      },
+    ];
+  }, []);
+
+  // 选中的表格数据
+  const [tableSelectList, setTableSelectList] = useState([]);
+  // 表格的多选
+
+  const rowSelection = useMemo(() => {
+    return {
+      onChange: (selectedRowKeys: any, selectedRows: any) => {
+        setTableSelectList(selectedRows);
+      },
+      // 默认选中
+      defaultSelectedRowKeys: resultsAc.map((v: any) => v.id),
+    };
+  }, [resultsAc]);
+
+  // 点击确定
+  const btnOkFu = useCallback(() => {
+    dispatch({
+      type: "object6/getGoodsTableList",
+      payload: tableSelectList.map((v:any)=>{
+        return {
+          ...v,
+          storageAncestor:'',
+          storageAncestorName:''
+        }
+      }),
+    });
+    message.success("添加成功!");
+    colsePage();
+  }, [colsePage, dispatch, tableSelectList]);
+
+  return (
+    <div className={styles.GoodsAll}>
+      <Modal
+        open={true}
+        destroyOnClose
+        wrapClassName="GoodsAllModel"
+        title="添加藏品"
+        onCancel={colsePage}
+        footer={
+          [] // 设置footer为空,去掉 取消 确定默认按钮
+        }
+      >
+        <div className="ObjectAddTit">
+          <div className="topSearch">
+            <span>藏品名称:</span>
+            <Input
+              value={name}
+              maxLength={10}
+              style={{ width: 300 }}
+              placeholder="请输入"
+              allowClear
+              onChange={(e) => nameChange(e)}
+            />
+          </div>
+        </div>
+        <div className="tableBox">
+          <Table
+            size="small"
+            scroll={{ y: 500 }}
+            rowSelection={{
+              type: "checkbox",
+              ...rowSelection,
+            }}
+            dataSource={results}
+            columns={columns}
+            rowKey="id"
+            pagination={false}
+          />
+        </div>
+        <br />
+        <div className="moveBtn">
+          <Button
+            type="primary"
+            onClick={btnOkFu}
+            disabled={tableSelectList.length === 0}
+          >
+            提交
+          </Button>
+        </div>
+      </Modal>
+    </div>
+  );
+}
+
+const MemoGoodsAll = React.memo(GoodsAll);
+
+export default MemoGoodsAll;

+ 87 - 0
src/pages/ObjectSon/Object6/AddObject6/index.module.scss

@@ -0,0 +1,87 @@
+.AddObject6 {
+  :global {
+    .objectSonMain {
+      padding: 10px 30px;
+
+      .addInfoTop {
+        .row {
+          display: flex;
+          justify-content: space-between;
+          height: 50px;
+
+          &>div {
+            width: 45%;
+            height: 50px;
+            align-items: center;
+            display: flex;
+
+            &>span {
+              width: 80px;
+            }
+
+            .bs {
+              position: relative;
+
+              &::before {
+                content: '*';
+                position: absolute;
+                z-index: 10;
+                top: 2px;
+                left: -10px;
+                color: #ff4d4f;
+
+              }
+            }
+          }
+        }
+
+        .rowAll {
+          display: flex;
+          margin-top: 6px;
+
+          &>span {
+            width: 80px;
+          }
+
+          .ant-input-textarea {
+            width: calc(100% - 80px);
+          }
+        }
+      }
+
+      .addTableBox {
+        margin-top: 30px;
+        width: 100%;
+        height: 485px;
+
+        .addTableBox_Tit {
+          height: 40px;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+
+          .addTableBox_TitL {
+            display: flex;
+            align-items: center;
+            color: var(--themeColor);
+            font-size: 20px;
+            font-weight: 700;
+          }
+        }
+
+        .addTableBox_table {
+          width: 100%;
+          height: calc(100% - 90px);
+        }
+
+        .addTableBox_btn {
+          width: 100%;
+          height: 40px;
+          display: flex;
+          justify-content: center;
+          margin-top: 10px;
+        }
+      }
+    }
+  }
+}

+ 282 - 0
src/pages/ObjectSon/Object6/AddObject6/index.tsx

@@ -0,0 +1,282 @@
+import BreadTit from "@/components/BreadTit";
+import { object6AddAPI, object6infoOutAPI } from "@/store/action/object6";
+import history, { urlParameter } from "@/utils/history";
+import { Button,  Input, message, Popconfirm, Table } from "antd";
+import TextArea from "antd/es/input/TextArea";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import { useLocation } from "react-router-dom";
+import _ from "lodash";
+import styles from "./index.module.scss";
+import { useDispatch, useSelector } from "react-redux";
+import { RootState } from "@/store";
+import ImageLazy from "@/components/ImageLazy";
+import GoodsAll from "./GoodsAll";
+import LookModal from "@/components/LookObjTable/LookModal";
+function AddObject6() {
+  const dispatch = useDispatch();
+
+  // 从仓库拿表格信息
+  const results = useSelector(
+    (state: RootState) => state.object6Store.goodsTableList
+  );
+
+  // 顶部数据
+  const [addInfoTop, setAddInfoTop] = useState<any>({});
+
+  // 进入页面新增请求函数
+  const object6AddAPIFu = useCallback(async () => {
+    const res = await object6AddAPI();
+    setAddInfoTop(res.data);
+    // 初始化表格数据
+    dispatch({
+      type: "object6/getGoodsTableList",
+      payload: [],
+    });
+  }, [dispatch]);
+
+  // 通过id获取详情函数
+  const object6infoOutAPIFu = useCallback(
+    async (id: number) => {
+      const res = await object6infoOutAPI(id);
+      setAddInfoTop(res.data.entity);
+      // 设置表格信息
+      dispatch({
+        type: "object6/getGoodsTableList",
+        payload: res.data.child,
+      });
+    },
+    [dispatch]
+  );
+
+  // 获取地址栏参数
+  const location = useLocation();
+  const [urlParam, setUrlParam] = useState<any>({});
+  useEffect(() => {
+    const obj = urlParameter(location.search);
+    setUrlParam(obj);
+
+    if (obj.id) {
+      // 如果是编辑
+      object6infoOutAPIFu(obj.id);
+    } else object6AddAPIFu();
+  }, [location, object6AddAPIFu, object6infoOutAPIFu]);
+  // 点击返回
+  const cancelFu = useCallback(() => {
+    history.push({
+      pathname: `/object/6`,
+      state: { k: urlParam.k ? urlParam.k : "1", d: urlParam.d },
+    });
+  }, [urlParam.d, urlParam.k]);
+
+  // 点击提交
+  const submitFu = useCallback(async () => {
+    if (results.length === 0)
+      return message.warning("至少需要添加一条藏品信息!");
+
+
+    const obj = {
+      description: addInfoTop.description,
+      id: addInfoTop.id,
+      goodsIds: results.map((v: any) => v.id).join(","),
+    };
+
+    const res: any = await object6AddAPI(obj);
+    if (res.code === 0) {
+      message.success("操作成功!");
+      cancelFu();
+    }
+  }, [addInfoTop.description, addInfoTop.id, cancelFu, results]);
+
+  // 点击添加或者编辑出来页面
+  const [addPage, setAddPage] = useState(false);
+
+  // 表格的多选
+  const rowSelection = {
+    onChange: (selectedRowKeys: any, selectedRows: any) => {
+      setTableSelectList(selectedRows);
+    },
+  };
+
+  // 点击添加
+  const addPageFu = useCallback((id?: any) => {
+    setAddPage(true);
+  }, []);
+
+  // 选中的表格数据
+  const [tableSelectList, setTableSelectList] = useState([]);
+
+  // 点击删除
+  const delTableListFu = useCallback(() => {
+    console.log("多个删除", tableSelectList);
+    const data = _.differenceBy(results, tableSelectList, "id");
+    dispatch({ type: "object6/getGoodsTableList", payload: data });
+    setTableSelectList(data);
+  }, [dispatch, results, tableSelectList]);
+
+  // 控制弹窗的显示隐藏
+  const [show, setShow] = useState(false);
+  // 点击表格里面的查看
+  const lookIdRef = useRef(-1);
+  const lookGoods = useCallback((id: number) => {
+    lookIdRef.current = id;
+    setShow(true);
+  }, []);
+
+  // 表格数据
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "缩略图",
+        render: (item: any) => (
+          <ImageLazy width={120} height={70} src={item.thumb} />
+        ),
+      },
+
+      {
+        title: "藏品编号名称",
+        dataIndex: "dictNum",
+      },
+      {
+        title: "藏品编号",
+        render: (item: any) => (item.num ? item.num : "-"),
+      },
+      {
+        title: "藏品名称",
+        dataIndex: "name",
+      },
+      {
+        title: "类别",
+        dataIndex: "dictGoodType",
+      },
+      {
+        title: "完残程度",
+        dataIndex: "complete",
+      },
+      {
+        title: "年代",
+        dataIndex:'dictAge'
+      },
+      {
+        title: "操作",
+        render: (item: any) => (
+          <>
+            <Button type="text" danger onClick={() => lookGoods(item.id)}>
+              查看
+            </Button>
+          </>
+        ),
+      },
+    ];
+  }, [lookGoods]);
+
+  return (
+    <div className={styles.AddObject6}>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow">藏品注销</div>
+          <div className="splitStr">/</div>
+          <div className="breadTitRow active">
+            {urlParam.id ? "编辑" : "新增"}
+          </div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        {/* 上面的信息展示 */}
+        <div className="addInfoTop">
+          <div className="row">
+            <div>
+              <span className="bs">注销编号:</span>
+              <Input style={{ width: 400 }} value={addInfoTop.num} disabled />
+            </div>
+            <div>
+              <span className="bs">登记人员:</span>
+              <Input
+                style={{ width: 400 }}
+                value={addInfoTop.creatorName}
+                disabled
+              />
+            </div>
+          </div>
+          <div className="rowAll">
+            <span>注销说明:</span>
+            <TextArea
+              value={addInfoTop.description}
+              onChange={(e) =>
+                setAddInfoTop({ ...addInfoTop, description: e.target.value })
+              }
+              rows={3}
+              placeholder="请输入"
+              showCount
+              maxLength={255}
+            />
+          </div>
+        </div>
+        {/* 下面的表格 */}
+        <div className="addTableBox">
+          <div className="addTableBox_Tit">
+            <div className="addTableBox_TitL">藏品信息</div>
+            <div className="addTableBox_TitR">
+              <Button onClick={() => addPageFu(null)}>添加</Button>
+              &emsp;
+              <Popconfirm
+                disabled={tableSelectList.length === 0}
+                title="确定删除吗?"
+                okText="确定"
+                cancelText="取消"
+                onConfirm={delTableListFu}
+              >
+                <Button disabled={tableSelectList.length === 0}>删除</Button>
+              </Popconfirm>
+            </div>
+          </div>
+
+          {/* 表格主体 */}
+          <div className="addTableBox_table">
+            <Table
+              size="small"
+              scroll={{ y: 355 }}
+              rowSelection={{
+                type: "checkbox",
+                ...rowSelection,
+              }}
+              dataSource={results}
+              columns={columns}
+              rowKey="id"
+              pagination={false}
+            />
+          </div>
+
+          {/* 返回按钮 */}
+          <div className="addTableBox_btn">
+            <Button type="primary" onClick={submitFu}>
+              提交
+            </Button>
+            &emsp;
+            <Button onClick={cancelFu}>返回</Button>
+          </div>
+        </div>
+      </div>
+      {/* 点击添加或者编辑出来的页面 */}
+      {addPage ? <GoodsAll colsePage={() => setAddPage(false)} /> : null}
+
+      {/* 点击查看出来的对话框 */}
+      {show ? (
+        <LookModal
+          id={lookIdRef.current}
+          show={show}
+          closeShow={() => setShow(false)}
+        />
+      ) : null}
+    </div>
+  );
+}
+
+const MemoAddObject6 = React.memo(AddObject6);
+
+export default MemoAddObject6;

+ 86 - 0
src/pages/ObjectSon/Object6/AuditObject6/index.module.scss

@@ -0,0 +1,86 @@
+.AuditObject6 {
+  :global {
+    .objectSonMain {
+      padding: 10px 30px;
+
+      .topTit {
+        font-size: 16px;
+        font-weight: 700;
+        color: var(--themeColor);
+        margin-bottom: 12px;
+      }
+
+      .topInfo {
+        .topInfoRow {
+          display: flex;
+
+          &>div {
+            width: 50%;
+            border: 1px solid #ccc;
+            height: 34px;
+            line-height: 32px;
+            display: flex;
+
+            .one {
+              font-weight: 700;
+              width: 80px;
+              text-align: right;
+            }
+          }
+        }
+
+        .topInfoTex {
+          cursor: pointer;
+          border: 1px solid #ccc;
+          padding: 5px 10px 4px;
+          display: -webkit-box;
+          overflow: hidden;
+          white-space: normal !important;
+          text-overflow: ellipsis;
+          word-wrap: break-word;
+          -webkit-line-clamp: 2;
+          -webkit-box-orient: vertical;
+
+          &>span {
+            font-weight: 700;
+          }
+        }
+
+      }
+
+      .goodsInfo {
+        .inputBox1 {
+          margin-bottom: 10px;
+          display: flex;
+          align-items: center;
+
+          .inputBoxTit {
+            font-weight: 700;
+            width: 90px;
+
+            &>span {
+              position: relative;
+              top: 3px;
+              color: #ff4d4f;
+            }
+          }
+
+          .inputBoxText {
+            width: calc(100% - 90px);
+          }
+        }
+
+        .inputBox2 {
+          align-items: flex-start;
+        }
+      }
+
+      .backBtn {
+        margin-top: 12px;
+        display: flex;
+        justify-content: center;
+      }
+
+    }
+  }
+}

+ 233 - 0
src/pages/ObjectSon/Object6/AuditObject6/index.tsx

@@ -0,0 +1,233 @@
+import BreadTit from "@/components/BreadTit";
+import ImageLazy from "@/components/ImageLazy";
+import LookModal from "@/components/LookObjTable/LookModal";
+import { RootState } from "@/store";
+import { auditObject6API, object6infoOutAPI } from "@/store/action/object6";
+import { statusObj } from "@/utils/dataChange";
+import history, { urlParameter } from "@/utils/history";
+import { Button, message, Select, Table } from "antd";
+import TextArea from "antd/es/input/TextArea";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { useLocation } from "react-router-dom";
+import styles from "./index.module.scss";
+const { Option } = Select;
+
+function AuditObject6() {
+  const dispatch = useDispatch();
+
+  // 获取地址栏参数
+  const location = useLocation();
+  const urlParamRef = useRef<any>({});
+  useEffect(() => {
+    urlParamRef.current = urlParameter(location.search);
+    // console.log("地址栏参数", urlParamRef.current);
+  }, [location]);
+
+  const { info, list: tableList } = useSelector(
+    (state: RootState) => state.object6Store.lookInfo
+  );
+
+  // 审核结果筛选
+  const [value, setValue] = useState(3);
+  const valueChangeFu = (val: number) => {
+    setValue(val);
+  };
+  // 审核说明
+  const [value2, setValue2] = useState("");
+
+  const getInfo = useCallback(async () => {
+    const id = urlParamRef.current.id;
+    const res1 = await object6infoOutAPI(id);
+    const info = res1.data.entity;
+    const list = res1.data.child;
+    info.statusTxt = statusObj[info.status];
+    dispatch({ type: "object6/getLookInfo", payload: { info, list } });
+  }, [dispatch]);
+
+  useEffect(() => {
+    getInfo();
+  }, [getInfo]);
+
+  // 控制弹窗的显示隐藏
+  const [show, setShow] = useState(false);
+  // 点击表格里面的查看
+  const lookIdRef = useRef(-1);
+
+  const lookGoods = useCallback((id: number) => {
+    lookIdRef.current = id;
+    setShow(true);
+  }, []);
+
+  // 点击返回
+  const cancelFu = useCallback(() => {
+    history.push({
+      pathname: `/object/6`,
+      state: {
+        k: urlParamRef.current.k ? urlParamRef.current.k : "1",
+        d: urlParamRef.current.d,
+      },
+    });
+  }, []);
+
+  // 点击确定
+  const btnOkFu = useCallback(async () => {
+    const txt = value2.replaceAll(" ", "").replaceAll("\n", "");
+    if (txt === "") return message.warning("审核说明不能为空!");
+    const res: any = await auditObject6API({
+      id: Number(urlParamRef.current.id),
+      reason: value2,
+      status: value,
+    });
+    if (res.code === 0) {
+      message.success("操作成功!");
+      cancelFu();
+    }
+  }, [cancelFu, value, value2]);
+
+  // 表格格式
+  const columns = useMemo(() => {
+    const tempArr = [
+      {
+        title: "缩略图",
+        render: (item: any) => (
+          <ImageLazy width={120} height={70} src={item.thumb} />
+        ),
+      },
+      {
+        title: "藏品编号名称",
+        dataIndex: "dictNum",
+      },
+      {
+        title: "藏品编号",
+        render: (item: any) => (item.num ? item.num : "-"),
+      },
+      {
+        title: "藏品名称",
+        dataIndex: "name",
+      },
+      {
+        title: "类别",
+        dataIndex: "dictGoodType",
+      },
+      {
+        title: "完残程度",
+        dataIndex: "complete",
+      },
+      {
+        title: "年代",
+        dataIndex: "dictAge",
+      },
+      {
+        title: "操作",
+        render: (item: any) => (
+          <>
+            <Button type="text" danger onClick={() => lookGoods(item.id)}>
+              查看
+            </Button>
+          </>
+        ),
+      },
+    ];
+
+    return tempArr;
+  }, [lookGoods]);
+
+  return (
+    <div className={styles.AuditObject6}>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow">藏品注销</div>
+          <div className="splitStr">/</div>
+          <div className="breadTitRow active">审核</div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        <div className="topTit">注销信息</div>
+        <div className="topInfo">
+          <div className="topInfoRow">
+            <div>
+              <div className="one">注销编号:</div>
+              <div>{info.num}</div>
+            </div>
+            <div>
+              <div className="one">登记人员:</div>
+              <div>{info.creatorName}</div>
+            </div>
+          </div>
+          <div className="topInfoTex" title={info.description}>
+            <span>注销说明:</span>
+            {info.description ? info.description : "-"}
+          </div>
+        </div>
+        <br />
+        <div className="topTit">藏品信息</div>
+        <div className="goodsInfo">
+          {/* 表格信息 */}
+          <Table
+            size="small"
+            scroll={{ y: 245 }}
+            dataSource={tableList}
+            columns={columns}
+            rowKey="id"
+            pagination={false}
+          />
+          <br />
+          <div className="inputBox1">
+            <div className="inputBoxTit">
+              <span>* </span>审核结果:
+            </div>
+            <Select
+              style={{ width: 150 }}
+              value={value}
+              onChange={(val) => valueChangeFu(val)}
+            >
+              <Option value={3}>通过</Option>
+              <Option value={2}>不通过</Option>
+            </Select>
+          </div>
+          <div className="inputBox1 inputBox2">
+            <div className="inputBoxTit">
+              <span>* </span>审核说明:
+            </div>
+            <div className="inputBoxText">
+              <TextArea
+                value={value2}
+                onChange={(e) => setValue2(e.target.value)}
+                rows={3}
+                placeholder="请输入"
+                showCount
+                maxLength={255}
+              />
+            </div>
+          </div>
+        </div>
+        <div className="backBtn">
+          <Button onClick={btnOkFu} type="primary">
+            提交
+          </Button>
+          &emsp;
+          <Button onClick={cancelFu}>返回</Button>
+        </div>
+      </div>
+      {/* 点击查看出来的对话框 */}
+      {show ? (
+        <LookModal
+          id={lookIdRef.current}
+          show={show}
+          closeShow={() => setShow(false)}
+        />
+      ) : null}
+    </div>
+  );
+}
+
+const MemoAuditObject6 = React.memo(AuditObject6);
+
+export default MemoAuditObject6;

+ 56 - 0
src/pages/ObjectSon/Object6/LookObject6/index.module.scss

@@ -0,0 +1,56 @@
+.LookObject6 {
+  :global {
+    .objectSonMain {
+      padding: 10px 30px;
+
+      .topTit {
+        font-size: 16px;
+        font-weight: 700;
+        color: var(--themeColor);
+        margin-bottom: 12px;
+      }
+
+      .topInfo {
+        .topInfoRow {
+          display: flex;
+          &>div {
+            width: 33.33%;
+            border: 1px solid #ccc;
+            height: 34px;
+            line-height: 32px;
+            display: flex;
+
+            .one {
+              font-weight: 700;
+              width: 80px;
+              text-align: right;
+            }
+          }
+        }
+
+        .topInfoTex {
+          cursor: pointer;
+          border: 1px solid #ccc;
+          padding: 5px 10px 4px;
+          display: -webkit-box;
+          overflow: hidden;
+          white-space: normal !important;
+          text-overflow: ellipsis;
+          word-wrap: break-word;
+          -webkit-line-clamp: 2;
+          -webkit-box-orient: vertical;
+
+          &>span {
+            font-weight: 700;
+          }
+        }
+
+      }
+      .backBtn{
+        margin-top: 12px;
+        display: flex;
+        justify-content: center;
+      }
+    }
+  }
+}

+ 196 - 0
src/pages/ObjectSon/Object6/LookObject6/index.tsx

@@ -0,0 +1,196 @@
+import AuthButton from "@/components/AuthButton";
+import BreadTit from "@/components/BreadTit";
+import ImageLazy from "@/components/ImageLazy";
+import LookModal from "@/components/LookObjTable/LookModal";
+import { RootState } from "@/store";
+import { object6infoOutAPI } from "@/store/action/object6";
+import { statusObj } from "@/utils/dataChange";
+import history, { urlParameter } from "@/utils/history";
+import { Button, Table } from "antd";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { useLocation } from "react-router-dom";
+import styles from "./index.module.scss";
+function LookObject6() {
+  const dispatch = useDispatch();
+
+  // 获取地址栏参数
+  const location = useLocation();
+  const urlParamRef = useRef<any>({});
+  useEffect(() => {
+    urlParamRef.current = urlParameter(location.search);
+    // console.log("地址栏参数", urlParamRef.current);
+  }, [location]);
+
+  const getInfo = useCallback(async () => {
+    const id = urlParamRef.current.id;
+    const res1 = await object6infoOutAPI(id);
+    const info = res1.data.entity;
+    const list = res1.data.child;
+    info.statusTxt = statusObj[info.status];
+    dispatch({ type: "object6/getLookInfo", payload: { info, list } });
+  }, [dispatch]);
+
+  useEffect(() => {
+    getInfo();
+  }, [getInfo]);
+
+  const { info, list: tableList } = useSelector(
+    (state: RootState) => state.object6Store.lookInfo
+  );
+
+  // 点击返回
+  const cancelFu = () => {
+    history.push({
+      pathname: `/object/6`,
+      state: {
+        k: urlParamRef.current.k ? urlParamRef.current.k : "1",
+        d: urlParamRef.current.d,
+      },
+    });
+  };
+
+  // 控制弹窗的显示隐藏
+  const [show, setShow] = useState(false);
+  // 点击表格里面的查看
+  const lookIdRef = useRef(-1);
+
+  const lookGoods = useCallback((id: number) => {
+    lookIdRef.current = id;
+    setShow(true);
+  }, []);
+
+  // 表格格式
+  const columns = useMemo(() => {
+    const tempArr = [
+      {
+        title: "缩略图",
+        render: (item: any) => (
+          <ImageLazy width={120} height={70} src={item.thumb} />
+        ),
+      },
+      {
+        title: "藏品编号名称",
+        dataIndex: "dictNum",
+      },
+      {
+        title: "藏品编号",
+        render: (item: any) => (item.num ? item.num : "-"),
+      },
+      {
+        title: "藏品名称",
+        dataIndex: "name",
+      },
+      {
+        title: "类别",
+        dataIndex: "dictGoodType",
+      },
+      {
+        title: "完残程度",
+        dataIndex: "complete",
+      },
+      {
+        title: "年代",
+        dataIndex: "dictAge",
+      },
+      {
+        title: "操作",
+        render: (item: any) => (
+          <>
+            <Button type="text" danger onClick={() => lookGoods(item.id)}>
+              查看
+            </Button>
+          </>
+        ),
+      },
+    ];
+
+    return tempArr;
+  }, [lookGoods]);
+
+  return (
+    <div className={styles.LookObject6}>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow">藏品注销</div>
+          <div className="splitStr">/</div>
+          <div className="breadTitRow active">查看</div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        <div className="topTit">注销信息</div>
+        <div className="topInfo">
+          <div className="topInfoRow">
+            <div>
+              <div className="one">注销编号:</div>
+              <div>{info.num}</div>
+            </div>
+            <div>
+              <div className="one">注销人员:</div>
+              <div>{info.creatorName}</div>
+            </div>
+            <div>
+              <div className="one">审核结果:</div>
+              <div>{info.statusTxt}</div>
+            </div>
+          </div>
+          <div className="topInfoTex" title={info.description}>
+            <span>登记说明:</span>
+            {info.description ? info.description : "-"}
+          </div>
+          <div className="topInfoTex" title={info.reason}>
+            <span>审核说明:</span>
+            {info.reason ? info.reason : "-"}
+          </div>
+        </div>
+        <br />
+        <div className="topTit">藏品信息</div>
+        <div className="goodsInfo">
+          {/* 表格信息 */}
+          <Table
+            size="small"
+            scroll={{ y: 360 }}
+            dataSource={tableList}
+            columns={columns}
+            rowKey="id"
+            pagination={false}
+          />
+        </div>
+        <div className="backBtn">
+          {info.status === 2 ? (
+            <AuthButton
+              type="primary"
+              onClick={() =>
+                history.push(
+                  `/object/6/add?k=${urlParamRef.current.k}&d=${urlParamRef.current.d}&id=${urlParamRef.current.id}`
+                )
+              }
+            >
+              编辑
+            </AuthButton>
+          ) : null}
+          &emsp;
+          <Button onClick={cancelFu}>返回</Button>
+        </div>
+      </div>
+      {/* 点击查看出来的对话框 */}
+      {show ? (
+        <LookModal
+          id={lookIdRef.current}
+          show={show}
+          closeShow={() => setShow(false)}
+        />
+      ) : null}
+    </div>
+  );
+}
+
+const MemoLookObject6 = React.memo(LookObject6);
+
+export default MemoLookObject6;

+ 293 - 4
src/pages/ObjectSon/Object6/index.tsx

@@ -1,9 +1,298 @@
+import BreadTit from "@/components/BreadTit";
+import classNames from "classnames";
+import { useEffect, useMemo, useRef, useState } from "react";
 import styles from "./index.module.scss";
+import { Input, DatePicker, Table, Button, Popconfirm, message } from "antd";
+import AuthButton from "@/components/AuthButton";
+import history from "@/utils/history";
+import { useLocation } from "react-router-dom";
+import { useDispatch, useSelector } from "react-redux";
+import { RootState } from "@/store";
+import {
+  getObject6List,
+  getObject6ListNum,
+  object6DelAPI,
+} from "@/store/action/object6";
+
+const { RangePicker } = DatePicker;
+
 export default function Object6() {
-  
+  const dispatch = useDispatch();
+
+  // 获取顶部数量
+
+  useEffect(() => {
+    dispatch(getObject6ListNum());
+  }, [dispatch]);
+
+  // 顶部的状态改变了,统一管理,传到二级页码
+  const statusRef = useRef<null | number>(null);
+
+  const dataTit = useSelector(
+    (state: RootState) => state.object6Store.infoNum6
+  );
+
+  // 封装发送请求的函数
+  const getList = () => {
+    const data = {
+      ...tableSelect,
+      pageNum: pageNumRef.current,
+      status: statusRef.current,
+    };
+    dispatch(getObject6List(data));
+  };
+
+  // 获取地址栏参数
+  const location = useLocation();
+
+  const pageNumRef = useRef(1);
+
+  // 如果有参数 根据参数页码在次发送请求
+  useEffect(() => {
+    const urlParam = location.state || {};
+    setTableSelect({
+      ...tableSelect,
+      pageNum: Number(urlParam.k) ? Number(urlParam.k) : 1,
+      // eslint-disable-next-line eqeqeq
+      status: urlParam.d && urlParam.d != "null" ? Number(urlParam.d) : null,
+    });
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [location]);
+
+  // 顶部筛选
+  const [tableSelect, setTableSelect] = useState({
+    status: null as null | number,
+    searchKey: "",
+    startTime: "",
+    endTime: "",
+    pageSize: 10,
+    pageNum: 1,
+  });
+
+  // 当前页码统一
+  useEffect(() => {
+    pageNumRef.current = tableSelect.pageNum;
+  }, [tableSelect.pageNum]);
+
+  // 顶部状态统一
+  useEffect(() => {
+    statusRef.current = tableSelect.status;
+  }, [tableSelect.status]);
+
+  // 防止返回的时候发送了2次请求来对应页码
+
+  const getListRef = useRef(-1);
+
+  useEffect(() => {
+    clearTimeout(getListRef.current);
+    getListRef.current = window.setTimeout(() => {
+      getList();
+    }, 100);
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [tableSelect]);
+
+  // 登记人员输入
+  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 });
+  };
+
+  // 点击新增或者编辑按钮
+  const addObject = (id?: any) => {
+    if (id)
+      history.push(
+        `/object/6/add?k=${pageNumRef.current}&d=${statusRef.current}&id=${id}`
+      );
+    else
+      history.push(
+        `/object/6/add?k=${pageNumRef.current}&d=${statusRef.current}`
+      );
+  };
+
+  // 点击删除按钮
+  const delOne = async (id: number) => {
+    const res: any = await object6DelAPI(id);
+    if (res.code === 0) {
+      message.success("删除成功!");
+      getList();
+      dispatch(getObject6ListNum());
+    }
+  };
+
+  // ---------关于表格
+
+  // 页码变化
+  const paginationChange = (pageNum: number, pageSize: number) => {
+    setTableSelect({ ...tableSelect, pageNum, pageSize });
+  };
+
+  const results = useSelector((state: RootState) => state.object6Store.info6);
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "入库编号",
+        dataIndex: "num",
+      },
+      {
+        title: "登记人员",
+        dataIndex: "creatorName",
+      },
+      {
+        title: "入库说明",
+        render: (item: any) => (item.description ? item.description : "-"),
+      },
+      {
+        title: "创建日期",
+        dataIndex: "createTime",
+      },
+      {
+        title: "完成日期",
+        render: (item: any) => (item.day && item.status === 3 ? item.day : "-"),
+      },
+      {
+        title: "状态",
+        dataIndex: "statusTxt",
+      },
+
+      {
+        title: "操作",
+        render: (item: any) => (
+          <>
+            <Button
+              type="text"
+              danger
+              onClick={() =>
+                history.push(
+                  `/object/6/look?k=${pageNumRef.current}&d=${statusRef.current}&id=${item.id}`
+                )
+              }
+            >
+              查看
+            </Button>
+
+            {item.status === 0 || item.status === 2 ? (
+              <AuthButton type="text" danger onClick={() => addObject(item.id)}>
+                编辑
+              </AuthButton>
+            ) : null}
+
+            {item.status === 1 ? (
+              <AuthButton
+                onClick={() =>
+                  history.push(
+                    `/object/6/audit?k=${pageNumRef.current}&d=${statusRef.current}&id=${item.id}`
+                  )
+                }
+                type="text"
+                danger
+              >
+                审核
+              </AuthButton>
+            ) : null}
+
+            {item.status === 0 || item.status === 2 ? (
+              <Popconfirm
+                title="确定删除吗?"
+                okText="确定"
+                cancelText="取消"
+                onConfirm={() => delOne(item.id)}
+              >
+                <AuthButton type="text" danger>
+                  删除
+                </AuthButton>
+              </Popconfirm>
+            ) : null}
+          </>
+        ),
+      },
+    ];
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, []);
+
   return (
-    <div className={styles.Object6}>
-      <h1>Object6</h1>
+    <div className={styles.Object1}>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow active">藏品注销</div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        {/* 顶部筛选 */}
+        <div className="objectSonMainTit">
+          {dataTit.map((v: any) => (
+            <div
+              key={v.id}
+              onClick={() =>
+                setTableSelect({ ...tableSelect, status: v.id, pageNum: 1 })
+              }
+              className={classNames(
+                v.id === tableSelect.status ? "active" : ""
+              )}
+            >
+              {v.name}({v.num})
+            </div>
+          ))}
+        </div>
+        <div className="objectSonMainTable">
+          {/* 表格数据筛选 */}
+          <div className="tableSelectBox">
+            <div className="row">
+              <span>登记人员:</span>
+              <Input
+                maxLength={10}
+                style={{ width: 150 }}
+                placeholder="请输入"
+                allowClear
+                onChange={(e) => nameChange(e)}
+              />
+            </div>
+            <div className="row">
+              <span>创建日期:</span>
+              <RangePicker onChange={timeChange} />
+            </div>
+            <div className="row">
+              <AuthButton type="primary" onClick={() => addObject()}>
+                申请注销
+              </AuthButton>
+            </div>
+          </div>
+
+          {/* 表格主体 */}
+          <div className="tableMain">
+            <Table
+              scroll={{ y: 428 }}
+              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>
+      </div>
     </div>
-  )
+  );
 }

+ 22 - 1
src/pages/Stores/index.tsx

@@ -7,6 +7,11 @@ import React, { useEffect } from "react";
 import { useMemo } from "react";
 import { Route, Switch } from "react-router-dom";
 import styles from "./index.module.scss";
+
+const LookStores3 = React.lazy(
+  () => import("../StoresSon/Stores3/LookStores3")
+);
+
 export default function Stores() {
   const data = useMemo(() => {
     return [
@@ -31,6 +36,17 @@ export default function Stores() {
     ];
   }, []);
 
+  const dataIn = useMemo(() => {
+    return [
+      {
+        id: 1001,
+        name: "藏品移库审核",
+        Com: React.lazy(() => import("../StoresSon/Stores3/AuditStores3")),
+        path: "/stores/3/audit",
+      },
+    ];
+  }, []);
+
   // 没有库房设置页面的权限 跳到有权限的页面
   useEffect(() => {
     if (data[0].id !== 1) {
@@ -56,7 +72,12 @@ export default function Stores() {
                 component={v.Com}
               />
             ))}
-
+            {/* 查看页面,无需权限 */}
+            <AuthRoute path="/stores/3/look" component={LookStores3} />
+            {/* 新增 */}
+            {dataIn.map((v) => (
+              <AuthRoute key={v.id} path={v.path} component={v.Com} />
+            ))}
             <Route path="*" component={NotFound} />
           </Switch>
         </React.Suspense>

+ 93 - 3
src/pages/StoresSon/Stores2/index.module.scss

@@ -1,5 +1,95 @@
-.Stores2{
-  :global{
-    
+.Stores2 {
+  :global {
+    .objectSonMain {
+      padding: 10px 30px;
+
+      .mainBox {
+        width: 100%;
+        height: 100%;
+        overflow-y: auto;
+      }
+
+      .stores2Tit {
+        height: 40px;
+        display: flex;
+        align-items: center;
+
+        .stores2Tit_row {
+          cursor: pointer;
+          width: 80px;
+          height: 32px;
+          background-color: #f5f5f5;
+          border: 1px solid #ccc;
+          border-radius: 6px;
+          margin-left: 18px;
+          text-align: center;
+          line-height: 30px;
+        }
+
+        .active {
+          background-color: var(--themeColor);
+          color: #fff;
+        }
+      }
+
+      .stores2Main {
+        margin-top: 15px;
+        width: 100%;
+
+        .stores2Main_top {
+          display: flex;
+          flex-wrap: wrap;
+
+          .rowTop {
+            border-radius: 5px;
+            border: 1px solid #ccc;
+            width: 49%;
+            height: 300px;
+            position: relative;
+            margin-right: 1%;
+            margin-bottom: 1%;
+
+            .rowTopTit {
+              position: absolute;
+              top: 10px;
+              left: 10px;
+
+              .rowTopTit_2 {
+                font-size: 14px;
+                color: #999;
+              }
+            }
+
+            .rowTopBtn {
+              z-index: 10;
+              position: absolute;
+              right: 30px;
+              top: 10px;
+            }
+
+            .echartsBox {
+              position: absolute;
+              top: 40px;
+              left: 0;
+              width: 100%;
+              height: calc(100% - 40px);
+            }
+          }
+        }
+
+        .stores2Main_table {
+          border-radius: 5px;
+          width: calc(100% - 13px);
+          padding:10px 10px 20px;
+          border: 1px solid #ccc;
+          .stores2Main_tableTit {
+            font-size: 16px;
+            font-weight: 700;
+            color: var(--themeColor);
+            margin-bottom: 12px;
+          }
+        }
+      }
+    }
   }
 }

+ 234 - 5
src/pages/StoresSon/Stores2/index.tsx

@@ -1,12 +1,241 @@
-import React from "react";
+import BreadTit from "@/components/BreadTit";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
 import styles from "./index.module.scss";
- function Stores2() {
-  
+import classNames from "classnames";
+import dayjs from "dayjs";
+import * as echarts from "echarts/core";
+import {
+  TitleComponent,
+  TooltipComponent,
+  LegendComponent,
+} from "echarts/components";
+import { PieChart } from "echarts/charts";
+import { LabelLayout } from "echarts/features";
+import { CanvasRenderer } from "echarts/renderers";
+import { Button, message, Table } from "antd";
+import {
+  getStores2API1,
+  getStores2API2,
+  getStores2API3,
+  getStores2API4,
+} from "@/store/action/stores1";
+import ExportJsonExcel from "js-export-excel";
+
+echarts.use([
+  TitleComponent,
+  TooltipComponent,
+  LegendComponent,
+  PieChart,
+  CanvasRenderer,
+  LabelLayout,
+]);
+
+function Stores2() {
+  const [titData, setTitData] = useState([
+    { id: 1, name: "文物类别", domId: "echarts1", done: true, ref: "one" },
+    { id: 2, name: "藏品级别", domId: "echarts2", done: true, ref: "tow" },
+    { id: 3, name: "藏品来源", domId: "echarts3", done: true, ref: "three" },
+    { id: 4, name: "完残程度", domId: "echarts4", done: true, ref: "four" },
+  ]);
+
+  // 生成图表的函数
+  const echartsFu = useCallback((dom: any, data: any) => {
+    const chartDom: any = document.getElementById(dom);
+    const myChart = echarts.init(chartDom);
+    const option = {
+      tooltip: {
+        trigger: "item",
+      },
+
+      series: [
+        {
+          type: "pie",
+          radius: ["40%", "70%"],
+          data,
+          emphasis: {
+            itemStyle: {
+              shadowBlur: 10,
+              shadowOffsetX: 0,
+              shadowColor: "rgba(0, 0, 0, 0.5)",
+            },
+          },
+        },
+      ],
+    };
+    option && myChart.setOption(option);
+  }, []);
+
+  const dataRef = useRef<any>({});
+  const [results, setResults] = useState<any>([]);
+  // 获取数据的函数
+  const getInfo = useCallback(async () => {
+    const res1 = await getStores2API1();
+    setResults(res1.data);
+    const data1 = res1.data.map((v: any) => {
+      return {
+        value: v.count,
+        name: v.groupKey + Number(v.percent * 100).toFixed(1) + "%",
+      };
+    });
+    dataRef.current.one = data1;
+    echartsFu("echarts1", data1);
+
+    const res2 = await getStores2API2();
+    const data2 = res2.data.map((v: any) => {
+      return {
+        value: v.count,
+        name: v.groupKey + Number(v.percent * 100).toFixed(1) + "%",
+      };
+    });
+    dataRef.current.tow = data2;
+    echartsFu("echarts2", data2);
+
+    const res3 = await getStores2API3();
+    const data3 = res3.data.map((v: any) => {
+      return {
+        value: v.count,
+        name: v.groupKey + Number(v.percent * 100).toFixed(1) + "%",
+      };
+    });
+    dataRef.current.three = data3;
+    echartsFu("echarts3", data3);
+
+    const res4 = await getStores2API4();
+    const data4 = res4.data.map((v: any) => {
+      return {
+        value: v.count,
+        name: v.groupKey + Number(v.percent * 100).toFixed(1) + "%",
+      };
+    });
+    dataRef.current.four = data4;
+    echartsFu("echarts4", data4);
+
+    // 获取到所有数据并且渲染完图表之后在隐藏
+    setTitData([
+      { id: 1, name: "文物类别", domId: "echarts1", done: true, ref: "one" },
+      { id: 2, name: "藏品级别", domId: "echarts2", done: true, ref: "tow" },
+      { id: 3, name: "藏品来源", domId: "echarts3", done: false, ref: "three" },
+      { id: 4, name: "完残程度", domId: "echarts4", done: false, ref: "four" },
+    ]);
+  }, [echartsFu]);
+
+  useEffect(() => {
+    getInfo();
+  }, [getInfo]);
+
+  // 图表的显示和隐藏
+  const showEchartFu = useCallback(
+    (id: number) => {
+      const data = titData.map((v) => {
+        return {
+          ...v,
+          done: id === v.id ? !v.done : v.done,
+        };
+      });
+      setTitData(data);
+    },
+    [titData]
+  );
+
+  // 表格数据
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "文物类别",
+        dataIndex: "groupKey",
+      },
+      {
+        title: "数量",
+        dataIndex: "count",
+      },
+    ];
+  }, []);
+
+  // 点击导出
+  const deriveFu = useCallback((ref: string, name: string) => {
+    const data = dataRef.current[ref];
+    if (data && data.length === 0) return message.warning("当前没有数据!");
+    const option = {
+      fileName: name,
+      datas: [
+        {
+          sheetData: data,
+          sheetName: name,
+          sheetFilter: ["name", "value"],
+          sheetHeader: [name + "和占比", "数量"],
+          columnWidths: [20, 20],
+        },
+      ],
+    };
+
+    const toExcel = new ExportJsonExcel(option); //new
+    toExcel.saveExcel(); //保存
+  }, []);
+
   return (
     <div className={styles.Stores2}>
-      <h1>Stores2</h1>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow active">统计报表</div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        <div className="mainBox">
+          <div className="stores2Tit">
+            <span>统计类型:</span>
+            {titData.map((v) => (
+              <div
+                onClick={() => showEchartFu(v.id)}
+                key={v.id}
+                className={classNames("stores2Tit_row", v.done ? "active" : "")}
+              >
+                {v.name}
+              </div>
+            ))}
+          </div>
+          <div className="stores2Main">
+            <div className="stores2Main_top">
+              {titData.map((v) => (
+                <div className="rowTop" key={v.id} hidden={!v.done}>
+                  <div className="rowTopTit">
+                    <p>{v.name + "发布"}</p>
+                    <p className="rowTopTit_2">
+                      {dayjs(Date.now()).format("YYYY年MM月DD")} | 每日0:00刷新
+                    </p>
+                  </div>
+                  <div className="rowTopBtn">
+                    <Button onClick={() => deriveFu(v.ref, v.name)}>
+                      导出
+                    </Button>
+                  </div>
+                  <div className="echartsBox" id={v.domId}></div>
+                </div>
+              ))}
+            </div>
+            {/* 表格 */}
+            <div className="stores2Main_table">
+              <div className="stores2Main_tableTit">藏品报表</div>
+              {results ? (
+                <Table
+                  size="small"
+                  dataSource={results}
+                  columns={columns}
+                  rowKey="groupKey"
+                  pagination={false}
+                />
+              ) : null}
+            </div>
+          </div>
+        </div>
+      </div>
     </div>
-  )
+  );
 }
 
 const MemoStores2 = React.memo(Stores2);

+ 96 - 0
src/pages/StoresSon/Stores3/AuditStores3/index.module.scss

@@ -0,0 +1,96 @@
+.AuditStores3 {
+  :global {
+    .objectSonMain {
+      padding: 10px 30px;
+
+      .topTit {
+        font-size: 16px;
+        font-weight: 700;
+        color: var(--themeColor);
+        margin-bottom: 12px;
+      }
+      .topTit2 {
+        position: relative;
+        margin-bottom: 18px;
+
+        .titBtn {
+          position: absolute;
+          right: 5px;
+          top: 0px;
+        }
+      }
+
+      .topInfo {
+        .topInfoRow {
+          display: flex;
+
+          &>div {
+            width: 50%;
+            border: 1px solid #ccc;
+            height: 34px;
+            line-height: 32px;
+            display: flex;
+
+            .one {
+              font-weight: 700;
+              width: 80px;
+              text-align: right;
+            }
+          }
+        }
+
+        .topInfoTex {
+          cursor: pointer;
+          border: 1px solid #ccc;
+          padding: 5px 10px 4px;
+          display: -webkit-box;
+          overflow: hidden;
+          white-space: normal !important;
+          text-overflow: ellipsis;
+          word-wrap: break-word;
+          -webkit-line-clamp: 2;
+          -webkit-box-orient: vertical;
+
+          &>span {
+            font-weight: 700;
+          }
+        }
+
+      }
+
+      .goodsInfo {
+        .inputBox1 {
+          margin-bottom: 10px;
+          display: flex;
+          align-items: center;
+
+          .inputBoxTit {
+            font-weight: 700;
+            width: 90px;
+
+            &>span {
+              position: relative;
+              top: 3px;
+              color: #ff4d4f;
+            }
+          }
+
+          .inputBoxText {
+            width: calc(100% - 90px);
+          }
+        }
+
+        .inputBox2 {
+          align-items: flex-start;
+        }
+      }
+
+      .backBtn {
+        margin-top: 12px;
+        display: flex;
+        justify-content: center;
+      }
+
+    }
+  }
+}

+ 217 - 0
src/pages/StoresSon/Stores3/AuditStores3/index.tsx

@@ -0,0 +1,217 @@
+import BreadTit from "@/components/BreadTit";
+import LookModal from "@/components/LookObjTable/LookModal";
+import { RootState } from "@/store";
+import { auditStores3API, stores3infoOutAPI } from "@/store/action/stores3";
+import history, { urlParameter } from "@/utils/history";
+import { Button, message, Select, Table } from "antd";
+import TextArea from "antd/es/input/TextArea";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { useLocation } from "react-router-dom";
+import styles from "./index.module.scss";
+const { Option } = Select;
+
+function AuditStores3() {
+  const dispatch = useDispatch();
+
+  // 获取地址栏参数
+  const location = useLocation();
+  const urlParamRef = useRef<any>({});
+  useEffect(() => {
+    urlParamRef.current = urlParameter(location.search);
+    // console.log("地址栏参数", urlParamRef.current);
+  }, [location]);
+
+  const { info, list: tableList } = useSelector(
+    (state: RootState) => state.stores3Store.lookInfo
+  );
+
+  // 审核结果筛选
+  const [value, setValue] = useState(3);
+  const valueChangeFu = (val: number) => {
+    setValue(val);
+  };
+  // 审核说明
+  const [value2, setValue2] = useState("");
+
+  const getInfo = useCallback(async () => {
+    const id = urlParamRef.current.id;
+    const res = await stores3infoOutAPI(id);
+    const info = res.data.child[0];
+    info.creatorName = res.data.entity.creatorName;
+    info.create_time = res.data.entity.createTime;
+    // 表格信息的整理
+    const list = [] as any;
+    const oldData = info.storageAncestorName;
+    const newData = JSON.parse(res.data.entity.afterJson).name;
+    console.log(123, oldData, newData);
+    list.push({
+      oldData,
+      newData,
+    });
+    dispatch({ type: "stores3/getLookInfo", payload: { info, list } });
+  }, [dispatch]);
+
+  useEffect(() => {
+    getInfo();
+  }, [getInfo]);
+
+  // 控制弹窗的显示隐藏
+  const [show, setShow] = useState(false);
+  // 点击表格里面的查看
+  const lookIdRef = useRef(-1);
+
+  const lookGoods = useCallback((id: number) => {
+    lookIdRef.current = id;
+    setShow(true);
+  }, []);
+
+  // 点击返回
+  const cancelFu = useCallback(() => {
+    history.push({
+      pathname: `/stores/3`,
+      state: {
+        k: urlParamRef.current.k ? urlParamRef.current.k : "1",
+        d: urlParamRef.current.d,
+      },
+    });
+  }, []);
+
+  // 点击确定
+  const btnOkFu = useCallback(async () => {
+    const txt = value2.replaceAll(" ", "").replaceAll("\n", "");
+    if (txt === "") return message.warning("审核说明不能为空!");
+    const res: any = await auditStores3API({
+      id: Number(urlParamRef.current.id),
+      reason: value2,
+      status: value,
+    });
+    if (res.code === 0) {
+      message.success("操作成功!");
+      cancelFu();
+    }
+  }, [cancelFu, value, value2]);
+
+  // 表格格式
+  const columns = useMemo(() => {
+    const tempArr = [
+      {
+        title: "原来位置",
+        dataIndex: "oldData",
+      },
+      {
+        title: "移库位置",
+        dataIndex: "newData",
+      },
+    ];
+
+    return tempArr;
+  }, []);
+
+  return (
+    <div className={styles.AuditStores3}>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow">藏品移库</div>
+          <div className="splitStr">/</div>
+          <div className="breadTitRow active">审核</div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        <div className="topTit">移库信息</div>
+        <div className="topInfo">
+          <div className="topInfoRow">
+            <div>
+              <div className="one">藏品名称:</div>
+              <div>{info.name}</div>
+            </div>
+            <div>
+              <div className="one">藏品编号:</div>
+              <div>{info.dictNum}</div>
+            </div>
+          </div>
+          <div className="topInfoRow">
+            <div>
+              <div className="one">登记人员:</div>
+              <div>{info.creatorName}</div>
+            </div>
+            <div>
+              <div className="one">创建日期:</div>
+              <div>{info.create_time}</div>
+            </div>
+          </div>
+        </div>
+        <br />
+        <div className="topTit topTit2">
+          移库记录
+          <div className="titBtn">
+            <Button onClick={() => lookGoods(info.id)}>查看</Button>
+          </div>
+        </div>
+        <div className="goodsInfo">
+          {/* 表格信息 */}
+          <Table
+            dataSource={tableList}
+            columns={columns}
+            rowKey="oldData"
+            pagination={false}
+          />
+          <br />
+          <div className="inputBox1">
+            <div className="inputBoxTit">
+              <span>* </span>审核结果:
+            </div>
+            <Select
+              style={{ width: 150 }}
+              value={value}
+              onChange={(val) => valueChangeFu(val)}
+            >
+              <Option value={3}>通过</Option>
+              <Option value={2}>不通过</Option>
+            </Select>
+          </div>
+          <div className="inputBox1 inputBox2">
+            <div className="inputBoxTit">
+              <span>* </span>审核说明:
+            </div>
+            <div className="inputBoxText">
+              <TextArea
+                value={value2}
+                onChange={(e) => setValue2(e.target.value)}
+                rows={3}
+                placeholder="请输入"
+                showCount
+                maxLength={255}
+              />
+            </div>
+          </div>
+        </div>
+        <div className="backBtn">
+          <Button onClick={btnOkFu} type="primary">
+            提交
+          </Button>
+          &emsp;
+          <Button onClick={cancelFu}>返回</Button>
+        </div>
+      </div>
+      {/* 点击查看出来的对话框 */}
+      {show ? (
+        <LookModal
+          id={lookIdRef.current}
+          show={show}
+          closeShow={() => setShow(false)}
+        />
+      ) : null}
+    </div>
+  );
+}
+
+const MemoAuditStores3 = React.memo(AuditStores3);
+
+export default MemoAuditStores3;

+ 97 - 0
src/pages/StoresSon/Stores3/LookStores3/index.module.scss

@@ -0,0 +1,97 @@
+.LookStores3 {
+  :global {
+    .objectSonMain {
+      padding: 10px 30px;
+
+      .topTit {
+        font-size: 16px;
+        font-weight: 700;
+        color: var(--themeColor);
+        margin-bottom: 12px;
+      }
+      .topTit2 {
+        position: relative;
+        margin-bottom: 18px;
+
+        .titBtn {
+          position: absolute;
+          right: 5px;
+          top: 0px;
+        }
+      }
+
+      .topInfo {
+        .topInfoRow {
+          display: flex;
+
+          &>div {
+            width: 50%;
+            border: 1px solid #ccc;
+            height: 34px;
+            line-height: 32px;
+            display: flex;
+
+            .one {
+              font-weight: 700;
+              width: 80px;
+              text-align: right;
+            }
+          }
+        }
+
+        .topInfoTex {
+          cursor: pointer;
+          border: 1px solid #ccc;
+          padding: 5px 10px 4px;
+          display: -webkit-box;
+          overflow: hidden;
+          white-space: normal !important;
+          text-overflow: ellipsis;
+          word-wrap: break-word;
+          -webkit-line-clamp: 2;
+          -webkit-box-orient: vertical;
+
+          &>span {
+            font-weight: 700;
+          }
+        }
+
+      }
+
+      .goodsInfo {
+        min-height: 200px;
+        .inputBox1 {
+          margin-bottom: 10px;
+          display: flex;
+          align-items: center;
+
+          .inputBoxTit {
+            font-weight: 700;
+            width: 90px;
+
+            &>span {
+              position: relative;
+              top: 3px;
+              color: #ff4d4f;
+            }
+          }
+
+          .inputBoxText {
+            width: calc(100% - 90px);
+          }
+        }
+
+        .inputBox2 {
+          align-items: flex-start;
+        }
+      }
+
+      .backBtn {
+        margin-top: 12px;
+        display: flex;
+        justify-content: center;
+      }
+
+    }
+  }
+}

+ 170 - 0
src/pages/StoresSon/Stores3/LookStores3/index.tsx

@@ -0,0 +1,170 @@
+import BreadTit from "@/components/BreadTit";
+import LookModal from "@/components/LookObjTable/LookModal";
+import { RootState } from "@/store";
+import { stores3infoOutAPI } from "@/store/action/stores3";
+import { statusObj } from "@/utils/dataChange";
+import history, { urlParameter } from "@/utils/history";
+import { Button, Table } from "antd";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import { useDispatch, useSelector } from "react-redux";
+import { useLocation } from "react-router-dom";
+import styles from "./index.module.scss";
+
+function LookStores3() {
+  const dispatch = useDispatch();
+
+  // 获取地址栏参数
+  const location = useLocation();
+  const urlParamRef = useRef<any>({});
+  useEffect(() => {
+    urlParamRef.current = urlParameter(location.search);
+    // console.log("地址栏参数", urlParamRef.current);
+  }, [location]);
+
+  const { info, list: tableList } = useSelector(
+    (state: RootState) => state.stores3Store.lookInfo
+  );
+
+  const getInfo = useCallback(async () => {
+    const id = urlParamRef.current.id;
+    const res = await stores3infoOutAPI(id);
+    const info = res.data.child[0];
+    info.creatorName = res.data.entity.creatorName;
+    info.create_time = res.data.entity.createTime;
+    info.statusTxt = statusObj[res.data.entity.status];
+    info.reason=res.data.entity.reason
+    // 表格信息的整理
+    const list = [] as any;
+    const oldData = info.storageAncestorName;
+    const newData = JSON.parse(res.data.entity.afterJson).name;
+    console.log(123, oldData, newData);
+    list.push({
+      oldData,
+      newData,
+    });
+    dispatch({ type: "stores3/getLookInfo", payload: { info, list } });
+  }, [dispatch]);
+
+  useEffect(() => {
+    getInfo();
+  }, [getInfo]);
+
+  // 控制弹窗的显示隐藏
+  const [show, setShow] = useState(false);
+  // 点击表格里面的查看
+  const lookIdRef = useRef(-1);
+
+  const lookGoods = useCallback((id: number) => {
+    lookIdRef.current = id;
+    setShow(true);
+  }, []);
+
+  // 点击返回
+  const cancelFu = useCallback(() => {
+    history.push({
+      pathname: `/stores/3`,
+      state: {
+        k: urlParamRef.current.k ? urlParamRef.current.k : "1",
+        d: urlParamRef.current.d,
+      },
+    });
+  }, []);
+
+  // 表格格式
+  const columns = useMemo(() => {
+    const tempArr = [
+      {
+        title: "原来位置",
+        dataIndex: "oldData",
+      },
+      {
+        title: "移库位置",
+        dataIndex: "newData",
+      },
+    ];
+
+    return tempArr;
+  }, []);
+
+  return (
+    <div className={styles.LookStores3}>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow">藏品移库</div>
+          <div className="splitStr">/</div>
+          <div className="breadTitRow active">查看</div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        <div className="topTit">移库信息</div>
+        <div className="topInfo">
+          <div className="topInfoRow">
+            <div>
+              <div className="one">藏品名称:</div>
+              <div>{info.name}</div>
+            </div>
+            <div>
+              <div className="one">藏品编号:</div>
+              <div>{info.dictNum}</div>
+            </div>
+          </div>
+          <div className="topInfoRow">
+            <div>
+              <div className="one">登记人员:</div>
+              <div>{info.creatorName}</div>
+            </div>
+            <div>
+              <div className="one">创建日期:</div>
+              <div>{info.create_time}</div>
+            </div>
+          </div>
+          <div className="topInfoTex">
+            <span>审核结果:</span>
+            {info.statusTxt}
+          </div>
+          <div className="topInfoTex" title={info.reason}>
+            <span>审核说明:</span>
+            {info.reason ? info.reason : "-"}
+          </div>
+        </div>
+        <br />
+        <div className="topTit topTit2">
+          移库记录
+          <div className="titBtn">
+            <Button onClick={() => lookGoods(info.id)}>查看</Button>
+          </div>
+        </div>
+        <div className="goodsInfo">
+          {/* 表格信息 */}
+          <Table
+            dataSource={tableList}
+            columns={columns}
+            rowKey="oldData"
+            pagination={false}
+          />
+        </div>
+        <div className="backBtn">
+          <Button onClick={cancelFu}>返回</Button>
+        </div>
+      </div>
+      {/* 点击查看出来的对话框 */}
+      {show ? (
+        <LookModal
+          id={lookIdRef.current}
+          show={show}
+          closeShow={() => setShow(false)}
+        />
+      ) : null}
+    </div>
+  );
+}
+
+const MemoLookStores3 = React.memo(LookStores3);
+
+export default MemoLookStores3;

+ 293 - 7
src/pages/StoresSon/Stores3/index.tsx

@@ -1,13 +1,299 @@
-import React from "react";
+import BreadTit from "@/components/BreadTit";
+import classNames from "classnames";
+import { useEffect, useMemo, useRef, useState } from "react";
 import styles from "./index.module.scss";
-function Stores3() {
+import { Input, DatePicker, Table, Button, Popconfirm, message } from "antd";
+import AuthButton from "@/components/AuthButton";
+import history from "@/utils/history";
+import { useLocation } from "react-router-dom";
+import { useDispatch, useSelector } from "react-redux";
+import { RootState } from "@/store";
+import {
+  getStores3List,
+  getStores3ListNum,
+  stores3DelAPI,
+} from "@/store/action/stores3";
+
+const { RangePicker } = DatePicker;
+
+export default function Stores3() {
+  const dispatch = useDispatch();
+
+  // 获取顶部数量
+
+  useEffect(() => {
+    dispatch(getStores3ListNum());
+  }, [dispatch]);
+
+  // 顶部的状态改变了,统一管理,传到二级页码
+  const statusRef = useRef<null | number>(null);
+
+  const dataTit = useSelector(
+    (state: RootState) => state.stores3Store.infoNum3
+  );
+
+  // 封装发送请求的函数
+  const getList = () => {
+    const data = {
+      ...tableSelect,
+      pageNum: pageNumRef.current,
+      status: statusRef.current,
+    };
+    dispatch(getStores3List(data));
+  };
+
+  // 获取地址栏参数
+  const location = useLocation();
+
+  const pageNumRef = useRef(1);
+
+  // 如果有参数 根据参数页码在次发送请求
+  useEffect(() => {
+    const urlParam = location.state || {};
+    setTableSelect({
+      ...tableSelect,
+      pageNum: Number(urlParam.k) ? Number(urlParam.k) : 1,
+      // eslint-disable-next-line eqeqeq
+      status: urlParam.d && urlParam.d != "null" ? Number(urlParam.d) : null,
+    });
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [location]);
+
+  // 顶部筛选
+  const [tableSelect, setTableSelect] = useState({
+    status: null as null | number,
+    searchKey: "",
+    startTime: "",
+    endTime: "",
+    pageSize: 10,
+    pageNum: 1,
+    name: "",
+  });
+
+  // 当前页码统一
+  useEffect(() => {
+    pageNumRef.current = tableSelect.pageNum;
+  }, [tableSelect.pageNum]);
+
+  // 顶部状态统一
+  useEffect(() => {
+    statusRef.current = tableSelect.status;
+  }, [tableSelect.status]);
+
+  // 防止返回的时候发送了2次请求来对应页码
+
+  const getListRef = useRef(-1);
+
+  useEffect(() => {
+    clearTimeout(getListRef.current);
+    getListRef.current = window.setTimeout(() => {
+      getList();
+    }, 100);
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [tableSelect]);
+
+  // 登记人员输入
+  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 nameTime2 = useRef(-1);
+  const nameChange2 = (e: React.ChangeEvent<HTMLInputElement>) => {
+    clearTimeout(nameTime2.current);
+    nameTime2.current = window.setTimeout(() => {
+      setTableSelect({ ...tableSelect, name: 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 });
+  };
+
+  // 点击删除按钮
+  const delOne = async (id: number) => {
+    const res: any = await stores3DelAPI(id);
+    if (res.code === 0) {
+      message.success("删除成功!");
+      getList();
+      dispatch(getStores3ListNum());
+    }
+  };
+
+  // ---------关于表格
+
+  // 页码变化
+  const paginationChange = (pageNum: number, pageSize: number) => {
+    setTableSelect({ ...tableSelect, pageNum, pageSize });
+  };
+
+  const results = useSelector((state: RootState) => state.stores3Store.info3);
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "藏品编号名称",
+        dataIndex: "dictNum",
+      },
+      {
+        title: "藏品编号",
+        render: (item: any) => (item.num ? item.num : "-"),
+      },
+      {
+        title: "藏品名称",
+        dataIndex: "name",
+      },
+      {
+        title: "登记人员",
+        dataIndex: "creatorName",
+      },
+      {
+        title: "创建日期",
+        dataIndex: "createTime",
+      },
+      {
+        title: "完成日期",
+        render: (item: any) => (item.day && item.status === 3 ? item.day : "-"),
+      },
+      {
+        title: "状态",
+        dataIndex: "statusTxt",
+      },
+
+      {
+        title: "操作",
+        render: (item: any) => (
+          <>
+            <Button
+              type="text"
+              danger
+              onClick={() =>
+                history.push(
+                  `/stores/3/look?k=${pageNumRef.current}&d=${statusRef.current}&id=${item.id}`
+                )
+              }
+            >
+              查看
+            </Button>
+
+            {item.status === 1 ? (
+              <AuthButton
+                onClick={() =>
+                  history.push(
+                    `/stores/3/audit?k=${pageNumRef.current}&d=${statusRef.current}&id=${item.id}`
+                  )
+                }
+                type="text"
+                danger
+              >
+                审核
+              </AuthButton>
+            ) : null}
+
+            {item.status === 0 || item.status === 2 ? (
+              <Popconfirm
+                title="确定删除吗?"
+                okText="确定"
+                cancelText="取消"
+                onConfirm={() => delOne(item.id)}
+              >
+                <AuthButton type="text" danger>
+                  删除
+                </AuthButton>
+              </Popconfirm>
+            ) : null}
+          </>
+        ),
+      },
+    ];
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, []);
+
   return (
     <div className={styles.Stores3}>
-      <h1>Stores3</h1>
+      <div className="breadTit">
+        <BreadTit>
+          <div className="breadTitRow active">藏品移库</div>
+        </BreadTit>
+      </div>
+      <div className="objectSonMain">
+        {/* 顶部筛选 */}
+        <div className="objectSonMainTit">
+          {dataTit.map((v: any) => (
+            <div
+              key={v.id}
+              onClick={() =>
+                setTableSelect({ ...tableSelect, status: v.id, pageNum: 1 })
+              }
+              className={classNames(
+                v.id === tableSelect.status ? "active" : ""
+              )}
+            >
+              {v.name}({v.num})
+            </div>
+          ))}
+        </div>
+        <div className="objectSonMainTable">
+          {/* 表格数据筛选 */}
+          <div className="tableSelectBox">
+            <div className="row">
+              <span>藏品名称:</span>
+              <Input
+                maxLength={10}
+                style={{ width: 150 }}
+                placeholder="请输入"
+                allowClear
+                onChange={(e) => nameChange2(e)}
+              />
+            </div>
+            <div className="row">
+              <span>登记人员:</span>
+              <Input
+                maxLength={10}
+                style={{ width: 150 }}
+                placeholder="请输入"
+                allowClear
+                onChange={(e) => nameChange(e)}
+              />
+            </div>
+            <div className="row">
+              <span>创建日期:</span>
+              <RangePicker onChange={timeChange} />
+            </div>
+          </div>
+
+          {/* 表格主体 */}
+          <div className="tableMain">
+            <Table
+              scroll={{ y: 428 }}
+              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>
+      </div>
     </div>
   );
 }
-
-const MemoMemoStores3 = React.memo(Stores3);
-
-export default MemoMemoStores3;

+ 14 - 8
src/store/action/login.ts

@@ -22,14 +22,20 @@ export const passWordEditAPI = (data: any) => {
 export const getSelectAllAPI = () => {
   return async (dispatch: AppDispatch) => {
     const res: any = await http.post("cms/dict/getTree", {});
-    const data:any =res.data
-    const obj ={} as any
-    data.forEach((v:any)=>{
-      obj[v.name]=v.children
-    })
-  
-    
+    const data: any = res.data;
+    const obj = {} as any;
+    data.forEach((v: any) => {
+      obj[v.name] = v.children;
+    });
+
     // console.log(123, obj);
-    dispatch({type:'login/getSelectAll',payload:obj})
+    dispatch({ type: "login/getSelectAll", payload: obj });
   };
 };
+
+/**
+ * 首页的审核提醒
+ */
+export const getHomeNumsAPI = () => {
+  return http.get("cms/report/remind");
+};

+ 81 - 0
src/store/action/object6.ts

@@ -0,0 +1,81 @@
+import { statusObj } from "@/utils/dataChange";
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+
+/**
+ * 获取藏品登记列表信息
+ */
+export const getObject6List = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    // 获取列表数据
+    const res: any = await http.post("cms/cancel/pageList", data);
+    const list = res.data.records;
+    list.forEach((v: any) => {
+      v.statusTxt = statusObj[v.status];
+    });
+    const obj = {
+      list,
+      total: res.data.total,
+    };
+    dispatch({ type: "object6/getList", payload: obj });
+  };
+};
+
+/**
+ * 获取藏品登记列表顶部数字信息
+ */
+export const getObject6ListNum = () => {
+  return async (dispatch: AppDispatch) => {
+    // 获取统计数据
+    const res: any = await http.get("cms/cancel/countByStatus");
+
+    const data = [
+      { id: null, name: "全部", num: res.data.all ? res.data.all : 0 },
+      // { id: 0, name: "待办理", num: res.data[0] ? res.data[0] : 0 },
+      { id: 1, name: "待审核", num: res.data[1] ? res.data[1] : 0 },
+      { id: 2, name: "审核不通过", num: res.data[2] ? res.data[2] : 0 },
+      { id: 3, name: "已完成", num: res.data[3] ? res.data[3] : 0 },
+    ];
+    dispatch({ type: "object6/getListNum", payload: data });
+  };
+};
+
+/**
+ * 删除外层表格数据
+ */
+export const object6DelAPI = (id: number) => {
+  return http.get(`cms/cancel/remove/${id}`);
+};
+
+/**
+ * 通过id获取信息
+ */
+export const object6infoOutAPI = (id: number) => {
+  return http.get(`cms/cancel/detail/${id}`);
+};
+
+/**
+ * 进新增页面发送请求
+ */
+export const object6AddAPI = (data?: any) => {
+  return http.post("cms/cancel/save", { ...data });
+};
+
+/**
+ * 点击新增或者编辑里面的添加按钮的所有藏品列表
+ */
+export const getGoodsListAllAPI = (val: any) => {
+  return async (dispatch: AppDispatch) => {
+    // 获取统计数据
+    const res: any = await http.get(`cms/cancel/goods/list?searchKey=${val}`);
+    dispatch({ type: "object6/setGoodsListAll", payload: res.data });
+  };
+};
+
+/**
+ * 审核入库信息
+ */
+export const auditObject6API = (data: any) => {
+  return http.post("cms/cancel/audit", data);
+};
+

+ 26 - 1
src/store/action/stores1.ts

@@ -31,4 +31,29 @@ export const stores1DelAPI = (id: number) => {
  */
 export const getStores1DetailAPI = (id: number) => {
   return http.get(`cms/storage/detail/${id}`);
-};
+};
+
+/**
+ * 获取统计报表1
+ */
+export const getStores2API1 = () => {
+  return http.get("cms/report/groupByGoodType");
+};
+/**
+ * 获取统计报表2
+ */
+export const getStores2API2 = () => {
+  return http.get("cms/report/goodsLevel");
+};
+/**
+ * 获取统计报表3
+ */
+export const getStores2API3 = () => {
+  return http.get("cms/report/goodsSource");
+};
+/**
+ * 获取统计报表4
+ */
+export const getStores2API4 = () => {
+  return http.get("cms/report/goodsComplete");
+};

+ 62 - 0
src/store/action/stores3.ts

@@ -0,0 +1,62 @@
+import { statusObj } from "@/utils/dataChange";
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+
+/**
+ * 获取藏品登记列表信息
+ */
+export const getStores3List = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    // 获取列表数据
+    const res: any = await http.post("cms/move/pageList", data);
+    const list = res.data.records;
+    list.forEach((v: any) => {
+      v.statusTxt = statusObj[v.status];
+    });
+    const obj = {
+      list,
+      total: res.data.total,
+    };
+    dispatch({ type: "stores3/getList", payload: obj });
+  };
+};
+
+/**
+ * 获取藏品登记列表顶部数字信息
+ */
+export const getStores3ListNum = () => {
+  return async (dispatch: AppDispatch) => {
+    // 获取统计数据
+    const res: any = await http.get("cms/move/countByStatus");
+
+    const data = [
+      { id: null, name: "全部", num: res.data.all ? res.data.all : 0 },
+      // { id: 0, name: "待办理", num: res.data[0] ? res.data[0] : 0 },
+      { id: 1, name: "待审核", num: res.data[1] ? res.data[1] : 0 },
+      { id: 2, name: "审核不通过", num: res.data[2] ? res.data[2] : 0 },
+      { id: 3, name: "已完成", num: res.data[3] ? res.data[3] : 0 },
+    ];
+    dispatch({ type: "stores3/getListNum", payload: data });
+  };
+};
+
+/**
+ * 删除外层表格数据
+ */
+export const stores3DelAPI = (id: number) => {
+  return http.get(`cms/move/remove/${id}`);
+};
+
+/**
+ * 通过id获取信息
+ */
+export const stores3infoOutAPI = (id: number) => {
+  return http.get(`cms/move/detail/${id}`);
+};
+
+/**
+ * 审核入库信息
+ */
+export const auditStores3API = (data: any) => {
+  return http.post("cms/move/audit", data);
+};

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

@@ -5,7 +5,9 @@ import object2Reducer from "./object2";
 import object3Reducer from "./object3";
 import object4Reducer from "./object4";
 import object5Reducer from "./object5";
+import object6Reducer from "./object6";
 import stores1Reducer from "./stores1";
+import stores3Reducer from "./stores3";
 
 // 合并 reducer
 const rootReducer = combineReducers({
@@ -15,7 +17,9 @@ const rootReducer = combineReducers({
   object3Store: object3Reducer,
   object4Store: object4Reducer,
   object5Store: object5Reducer,
+  object6Store: object6Reducer,
   stores1Store: stores1Reducer,
+  stores3Store: stores3Reducer,
 });
 
 export default rootReducer;

+ 52 - 0
src/store/reducer/object6.ts

@@ -0,0 +1,52 @@
+// 初始化状态应用注解
+const initState = {
+  // 表格数据
+  info6: {
+    list: [] as any,
+    total: 0,
+  },
+  // 表格顶部数字数据
+  infoNum6: [],
+  // 查看和审核的表格信息
+  lookInfo: {
+    info: {} as any,
+    list: [] as any,
+  },
+  // 新增或者编辑的藏品信息列表
+  goodsTableList: [] as any,
+  // 点击新增或者编辑里面的添加按钮的所有藏品列表
+  goodsAllList: [] as any,
+};
+
+type LoginActionType =
+  | { type: "object6/getList"; payload: any }
+  | { type: "object6/getListNum"; payload: any }
+  | { type: "object6/getLookInfo"; payload: any }
+  | { type: "object6/getGoodsTableList"; payload: any }
+  | { type: "object6/setGoodsListAll"; payload: any };
+// 频道 reducer
+export default function object6Reducer(
+  state = initState,
+  action: LoginActionType
+) {
+  switch (action.type) {
+    // 表格数据1
+    case "object6/getList":
+      return { ...state, info6: action.payload };
+    // 表格顶部数字数据1
+    case "object6/getListNum":
+      return { ...state, infoNum6: action.payload };
+    // 查看和审核的表格数据
+    case "object6/getLookInfo":
+      return { ...state, lookInfo: action.payload };
+    // 新增或者编辑的藏品信息列表
+    case "object6/getGoodsTableList":
+      return { ...state, goodsTableList: action.payload };
+    // 点击新增或者编辑里面的添加按钮的所有藏品列表
+    case "object6/setGoodsListAll":
+      return { ...state, goodsAllList: action.payload };
+
+    default:
+      return state;
+  }
+}

+ 39 - 0
src/store/reducer/stores3.ts

@@ -0,0 +1,39 @@
+// 初始化状态应用注解
+const initState = {
+  // 表格数据
+  info3: {
+    list: [] as any,
+    total: 0,
+  },
+  // 表格顶部数字数据
+  infoNum3: [],
+  // 查看和审核的详细信息
+  lookInfo: {
+    info:{},
+    list:[]
+  } as any,
+};
+
+type LoginActionType =
+  | { type: "stores3/getList"; payload: any }
+  | { type: "stores3/getListNum"; payload: any }
+  | { type: "stores3/getLookInfo"; payload: any }
+// 频道 reducer
+export default function stores3Reducer(
+  state = initState,
+  action: LoginActionType
+) {
+  switch (action.type) {
+    // 表格数据1
+    case "stores3/getList":
+      return { ...state, info3: action.payload };
+    // 表格顶部数字数据1
+    case "stores3/getListNum":
+      return { ...state, infoNum3: action.payload };
+    // 查看和审核的详细数据
+    case "stores3/getLookInfo":
+      return { ...state, lookInfo: action.payload };
+    default:
+      return state;
+  }
+}

+ 4 - 4
src/utils/dataChange.ts

@@ -50,10 +50,10 @@ export const logTypeObj = {
 } as any;
 // 藏品总账,操作记录跳转
 export const logTypeOpenObj = {
-  in: "#/object/3/look?k=1&d=null&id=",
-  out: "出库管理",
-  move: "藏品移库",
-  edit: "藏品修改",
+  in: "#/object/3/look?k=1&d=null&id=", //入库管理的查看
+  out: "#/object/4/look?k=1&d=null&id=", //出库管理的查看
+  move: "",//藏品移库的查看
+  edit: "#/object/5/look?k=1&d=null&id=",//藏品修改的查看
 } as any;
 
 // 出库管理状态的筛选