shaogen1995 2 лет назад
Родитель
Сommit
dcbe7c1b97

+ 13 - 5
src/components/Z_upFileOne/index.tsx

@@ -7,13 +7,14 @@ import {
   CloseOutlined,
   DownloadOutlined,
 } from "@ant-design/icons";
-import store from "@/store";
+import store, { RootState } from "@/store";
 import { baseURL } from "@/utils/http";
 import classNames from "classnames";
 import { Popconfirm } from "antd";
 import { MessageFu } from "@/utils/message";
 import { fileDomInitialFu } from "@/utils/domShow";
 import { API_upFile } from "@/store/action/layout";
+import { useSelector } from "react-redux";
 
 type Props = {
   cover: string; //封面图
@@ -44,6 +45,11 @@ function Z_upFileOne({
   sizeTxt,
   fromData,
 }: Props) {
+  // isFileDonw 全局的是否允许下载
+  const isFileDonw = useSelector(
+    (state: RootState) => state.A0Layout.isFileDonw
+  );
+
   const myInput = useRef<HTMLInputElement>(null);
 
   // 上传封面图
@@ -139,13 +145,15 @@ function Z_upFileOne({
             }
             rev={undefined}
           />
-          <a href={baseURL + cover} download target="_blank" rel="noreferrer">
-            <DownloadOutlined rev={undefined} />
-          </a>
+          {isFileDonw ? (
+            <a href={baseURL + cover} download target="_blank" rel="noreferrer">
+              <DownloadOutlined rev={undefined} />
+            </a>
+          ) : null}
         </div>
       </div>
       <div className="fileBoxRow_r_tit" hidden={isLook}>
-      格式要求:支持{formatTxt}的图片格式;最大支持{size}M,最多1张。
+        格式要求:支持{formatTxt}的图片格式;最大支持{size}M,最多1张。
         {sizeTxt ? `建议尺寸${sizeTxt}` : null}
         <br />
         <div

+ 24 - 10
src/components/Z_upFileOtherList/index.tsx

@@ -1,4 +1,4 @@
-import React, { useCallback, useRef, useState } from "react";
+import React, { useCallback, useEffect, useRef, useState } from "react";
 import styles from "./index.module.scss";
 import { Button, Popconfirm } from "antd";
 import { forwardRef, useImperativeHandle } from "react";
@@ -12,6 +12,8 @@ import {
 } from "@ant-design/icons";
 import filesLookFu from "@/utils/filesLook";
 import { baseURL } from "@/utils/http";
+import { useSelector } from "react-redux";
+import { RootState } from "@/store";
 
 export type FileListType = {
   id: number;
@@ -27,12 +29,22 @@ type Props = {
   myUrl: string;
   fromData?: any;
   ref: any; //当前自己的ref,给父组件调用
+  oldFileList: FileListType[]; //就附件数组,用来回显数据
 };
 
 function Z_upFileOtherList(
-  { max, isLook, size, dirCode, myUrl, fromData }: Props,
+  { max, isLook, size, dirCode, myUrl, fromData, oldFileList }: Props,
   ref: any
 ) {
+  // isFileDonw 全局的是否允许下载
+  const isFileDonw = useSelector(
+    (state: RootState) => state.A0Layout.isFileDonw
+  );
+
+  useEffect(() => {
+    if (oldFileList && oldFileList.length) setFileList(oldFileList);
+  }, [oldFileList]);
+
   // 附件数组
   const [fileList, setFileList] = useState<FileListType[]>([]);
 
@@ -119,14 +131,16 @@ function Z_upFileOtherList(
                 </span>
               ) : null}
 
-              <a
-                href={baseURL + v.filePath}
-                download={v.name}
-                target="_blank"
-                rel="noreferrer"
-              >
-                <DownloadOutlined rev={undefined} />
-              </a>
+              {isFileDonw ? (
+                <a
+                  href={baseURL + v.filePath}
+                  download={v.name}
+                  target="_blank"
+                  rel="noreferrer"
+                >
+                  <DownloadOutlined rev={undefined} />
+                </a>
+              ) : null}
 
               {isLook ? null : (
                 <Popconfirm

+ 34 - 12
src/pages/A2Goods/A2Register/A2AddModal.tsx

@@ -13,19 +13,37 @@ import {
 import { A2addInfoType, A2inTableType, options1 } from "../data";
 import TextArea from "antd/es/input/TextArea";
 import ZupFileOne from "@/components/Z_upFileOne";
-import ZupFileOtherList from "@/components/Z_upFileOtherList";
-import { A2_APIaddSon } from "@/store/action/A2Goods";
+import ZupFileOtherList, { FileListType } from "@/components/Z_upFileOtherList";
+import { A2_APIaddSon, A2_APIgetInfoSon } from "@/store/action/A2Goods";
 import { MessageFu } from "@/utils/message";
 
 type Props = {
   addInfo: A2addInfoType;
-  upTableFu: (item: A2inTableType) => void;
+  upTableFu: (item: A2inTableType, flag: "新增" | "编辑") => void;
   closeFu: () => void;
 };
 
 function A2AddModal({ addInfo, upTableFu, closeFu }: Props) {
   // 获取详情的方法
-  const getInfoFu = useCallback((id: number) => {}, []);
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A2_APIgetInfoSon(id);
+    const info = res.data.entity as A2inTableType;
+    const file = res.data.file as FileListType[];
+
+    // size 参数
+    const sizeArr = info.size.split(",");
+
+    FormBoxRef.current?.setFieldsValue({
+      ...info,
+      sizeChang: sizeArr[0] || "",
+      sizeKuang: sizeArr[1] || "",
+      sizeGao: sizeArr[2] || "",
+    });
+
+    setDirCode(info.dirCode);
+    setThumb(info.thumb);
+    setOldFileList(file);
+  }, []);
 
   useEffect(() => {
     if (addInfo.txt === "新增") {
@@ -35,7 +53,6 @@ function A2AddModal({ addInfo, upTableFu, closeFu }: Props) {
 
   // 表单的ref
   const FormBoxRef = useRef<FormInstance>(null);
-  // FormBoxRef.current?.setFieldsValue(res.data);
 
   // 目录码
   const [dirCode, setDirCode] = useState("");
@@ -49,6 +66,9 @@ function A2AddModal({ addInfo, upTableFu, closeFu }: Props) {
   // 附件的ref
   const fileRef = useRef<any>(null);
 
+  // 回显附件数据
+  const [oldFileList, setOldFileList] = useState<FileListType[]>([]);
+
   // 没有通过校验
   const onFinishFailed = useCallback(() => {
     setIsOk(true);
@@ -80,7 +100,7 @@ function A2AddModal({ addInfo, upTableFu, closeFu }: Props) {
       const res = await A2_APIaddSon(obj);
       if (res.code === 0) {
         MessageFu.success(`${addInfo.txt}成功!`);
-        upTableFu(res.data);
+        upTableFu(res.data, addInfo.txt === "新增" ? "新增" : "编辑");
         closeFu();
       }
     },
@@ -172,12 +192,13 @@ function A2AddModal({ addInfo, upTableFu, closeFu }: Props) {
             >
               <Input maxLength={8} showCount placeholder="请输入内容" />
             </Form.Item>
-            <Form.Item
-              className="A2RArowLabel"
-              label="实际数量"
-              name="pcs"
-            >
-              <InputNumber style={{width:256}} min={1} max={8} placeholder="请输入数字" />
+            <Form.Item className="A2RArowLabel" label="实际数量" name="pcs">
+              <InputNumber
+                style={{ width: 256 }}
+                min={1}
+                max={9999}
+                placeholder="请输入数字"
+              />
               {/* <Input maxLength={8} showCount /> */}
             </Form.Item>
           </div>
@@ -270,6 +291,7 @@ function A2AddModal({ addInfo, upTableFu, closeFu }: Props) {
                 dirCode={dirCode}
                 myUrl="cms/goods/file/upload"
                 ref={fileRef}
+                oldFileList={oldFileList}
               />
             </div>
           </div>

+ 13 - 2
src/pages/A2Goods/A2Register/index.module.scss

@@ -13,7 +13,18 @@
       margin-bottom: 15px;
       background-color: #fff;
       border-radius: 10px;
-      padding: 24px;
+      padding: 24px 24px 24px 60px;
+      position: relative;
+
+      .A2RTitle{
+        position: absolute;
+        top: 14px;
+        left: 20px;
+        width: 30px;
+        font-weight: 700;
+        font-size: 22px;
+        color: var(--themeColor);
+      }
 
       .A2Rtop1 {
         width: 80px;
@@ -25,7 +36,7 @@
     }
 
     .A2Rtable {
-      height: calc(100% - 160px);
+      height: calc(100% - 165px);
       background-color: #fff;
       border-radius: 10px;
       padding: 24px;

+ 54 - 12
src/pages/A2Goods/A2Register/index.tsx

@@ -17,20 +17,35 @@ import {
 import A2AddModal from "./A2AddModal";
 import { MessageFu } from "@/utils/message";
 import ImageLazy from "@/components/ImageLazy";
-import { A2_APIaddWai, A2_APIinDels } from "@/store/action/A2Goods";
+import {
+  A2_APIaddWai,
+  A2_APIgetInfoWai,
+  A2_APIinDels,
+} from "@/store/action/A2Goods";
 import history from "@/utils/history";
 
 type Props = {
   closeFu: () => void;
+  upInfoFu: () => void;
   outInfo: A2addInfoType;
 };
 
-function A2Register({ closeFu, outInfo }: Props) {
+function A2Register({ closeFu, outInfo, upInfoFu }: Props) {
   // 记录删除了的所有id集合
   const delIdArr = useRef<number[]>([]);
 
+  // 当前审批的状态
+  const statusRef = useRef(0);
+
   // 获取详情
-  const getInfoFu = useCallback((id: number) => {}, []);
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A2_APIgetInfoWai(id);
+    if (res.code === 0) {
+      setTopValue(res.data.entity.description);
+      statusRef.current = res.data.entity.status;
+      setTableList(res.data.child);
+    }
+  }, []);
 
   useEffect(() => {
     if (outInfo.txt !== "新增") getInfoFu(outInfo.id);
@@ -46,7 +61,8 @@ function A2Register({ closeFu, outInfo }: Props) {
   const btnOkFu = useCallback(
     async (status: 0 | 1) => {
       const obj = {
-        id: outInfo.txt === "新增" ? null : outInfo.id,
+        id:
+          outInfo.txt === "新增" || statusRef.current === 2 ? null : outInfo.id,
         description: topValue,
         goodsIds: tableList.map((v) => v.id).join(","),
         status,
@@ -56,16 +72,19 @@ function A2Register({ closeFu, outInfo }: Props) {
       const res1 = await A2_APIaddWai(obj);
 
       // 删除id集合
-      if(delIdArr.current.length>0){
-         await A2_APIinDels(delIdArr.current.join(","));
+      if (delIdArr.current.length > 0) {
+        await A2_APIinDels(delIdArr.current.join(","));
       }
 
       if (res1.code === 0) {
         MessageFu.success(`${outInfo.txt}成功!`);
-        history.push("/submit");
+        if (window.location.hash.includes("/submit")) {
+          upInfoFu();
+          closeFu();
+        } else history.push("/submit");
       }
     },
-    [outInfo.id, outInfo.txt, tableList, topValue]
+    [closeFu, outInfo.id, outInfo.txt, tableList, topValue, upInfoFu]
   );
 
   const columns = useMemo(() => {
@@ -104,7 +123,11 @@ function A2Register({ closeFu, outInfo }: Props) {
         title: "备注",
         render: (item: A2inTableType) => (
           <>
-            <Button size="small" type="text">
+            <Button
+              size="small"
+              type="text"
+              onClick={() => setAddInfo({ id: item.id, txt: "编辑" })}
+            >
               编辑
             </Button>
             <Popconfirm
@@ -131,9 +154,21 @@ function A2Register({ closeFu, outInfo }: Props) {
   // 新增和编辑
   const [addInfo, setAddInfo] = useState<A2addInfoType>({ id: 0, txt: "" });
 
+  // 从里面的弹窗 新增 / 编辑完工
+  const addOrEditSuccFu = useCallback(
+    (item: A2inTableType, flag: "新增" | "编辑") => {
+      if (flag === "新增") setTableList([...tableList, item]);
+      else {
+        setTableList(tableList.map((v) => (v.id === item.id ? item : v)));
+      }
+    },
+    [tableList]
+  );
+
   return (
     <div className={styles.A2Register}>
       <div className="A2Rtop">
+        <div className="A2RTitle">登记申请</div>
         <div className="A2Rtop1">申请说明:</div>
         <div className="A2Rtop2">
           <TextArea
@@ -166,11 +201,18 @@ function A2Register({ closeFu, outInfo }: Props) {
           />
         </div>
         <div className="A2Rtable3">
-          <Button type="primary" onClick={() => btnOkFu(1)}>
+          <Button
+            disabled={!tableList.length}
+            type="primary"
+            onClick={() => btnOkFu(1)}
+          >
             提交
           </Button>
           &emsp;
-          <Button onClick={() => btnOkFu(0)}>存草稿</Button>&emsp;
+          <Button disabled={!tableList.length} onClick={() => btnOkFu(0)}>
+            存草稿
+          </Button>
+          &emsp;
           <Popconfirm
             title="放弃编辑后,信息将不会保存!"
             okText="放弃"
@@ -188,7 +230,7 @@ function A2Register({ closeFu, outInfo }: Props) {
         <A2AddModal
           addInfo={addInfo}
           closeFu={() => setAddInfo({ id: 0, txt: "" })}
-          upTableFu={(item) => setTableList([...tableList, item])}
+          upTableFu={(item, flag) => addOrEditSuccFu(item, flag)}
         />
       ) : null}
     </div>

+ 3 - 6
src/pages/A2Goods/index.tsx

@@ -65,9 +65,7 @@ function A2Goods() {
 
   return (
     <div className={styles.A2Goods}>
-      <div className="pageTitle">
-        藏品清单{outInfo.txt === "新增" ? "/申请登记" : null}
-      </div>
+      <div className="pageTitle">藏品清单</div>
       {/* 顶部筛选 */}
       <div className="A2top">
         {/* 左侧输入框 */}
@@ -152,13 +150,12 @@ function A2Goods() {
         /> */}
       </div>
 
-      {/* 申请编辑出来的页面 */}
+      {/* 申请登记出来的页面 */}
       {outInfo.id ? (
         <A2Register
           closeFu={() => setOutInfo({ id: 0, txt: "" })}
           outInfo={outInfo}
-          // addTableFu={resetSelectFu}
-          // editTableFu={getListFu}
+          upInfoFu={() => {}}
         />
       ) : null}
     </div>

+ 14 - 1
src/pages/B1Submit/B1Info/index.module.scss

@@ -13,12 +13,25 @@
       position: absolute;
       right: 24px;
       top: 14px;
+      z-index: 10;
     }
 
     .B1ItopBox {
-      padding: 24px;
+      padding: 24px 24px 24px 60px;
       background-color: #fff;
       border-radius: 10px;
+      position: relative;
+
+      .B1Ititle{
+        position: absolute;
+        top: 20px;
+        left: 20px;
+        width: 30px;
+        font-weight: 700;
+        font-size: 22px;
+        color: var(--themeColor);
+      }
+
       .B1IBox {
         margin-bottom: 10px;
         display: flex;

+ 60 - 22
src/pages/B1Submit/B1Info/index.tsx

@@ -1,9 +1,10 @@
 import React, { useCallback, useEffect, useMemo, useState } from "react";
 import styles from "./index.module.scss";
 import { B1tableType } from "@/types";
-import { B1StatusObj, antdTagColorFObj } from "../data";
+import { B1StatusObj, B1TieleObj, antdTagColorFObj } from "../data";
 import { Button, Popconfirm, Table, Tag } from "antd";
 import {
+  A2addInfoType,
   A2inTableType,
   statusTxtObj,
   storageStatusTxtObj,
@@ -11,36 +12,63 @@ import {
 import ImageLazy from "@/components/ImageLazy";
 import { A2_APIgetInfo } from "@/store/action/B1Submit";
 import B1Look from "../B1Look";
+import A2Register from "@/pages/A2Goods/A2Register";
+import { A2_APIaudit } from "@/store/action/A2Goods";
+import { MessageFu } from "@/utils/message";
 
 type Props = {
   closeFu: () => void;
-  info: B1tableType;
+  lookId: number;
   pageKey: "我提交的" | "我审核的";
+  upTableFu: () => void;
 };
 
-function B1Info({ closeFu, info, pageKey }: Props) {
-  const getInfoFu = useCallback(async (id: number) => {
-    const res = await A2_APIgetInfo(id);
-    if (res.code === 0) {
-      setTableList(res.data.child);
-    }
-  }, []);
+function B1Info({ closeFu, lookId, pageKey, upTableFu }: Props) {
+  const [info, setInfo] = useState({} as B1tableType);
+
+  const getInfoFu = useCallback(
+    async (id: number, flag?: boolean) => {
+      const res = await A2_APIgetInfo(id);
+      if (res.code === 0) {
+        setTableList(res.data.child);
+        setInfo(res.data.entity);
+        // 通知 列表 页面 更新
+        if (flag) upTableFu();
+      }
+    },
+    [upTableFu]
+  );
 
   useEffect(() => {
-    getInfoFu(info.id);
-  }, [getInfoFu, info.id]);
+    getInfoFu(lookId);
+  }, [getInfoFu, lookId]);
 
   // 点击编辑
-  const editFu = useCallback(() => {}, []);
+  const [outInfo, setOutInfo] = useState<A2addInfoType>({ id: 0, txt: "" });
+  const editFu = useCallback(() => {
+    setOutInfo({ id: info.id, txt: "编辑" });
+  }, [info.id]);
 
   // 点击删除
   const delFu = useCallback(() => {}, []);
 
   // 点击撤回
-  const annulFu = useCallback(() => {}, []);
+  const annulFu = useCallback(async () => {
+    const res = await A2_APIaudit({
+      auditDesc: info.auditDesc,
+      id: info.id,
+      status: 0,
+    });
+
+    if (res.code === 0) {
+      MessageFu.success("操作成功!");
+      upTableFu();
+      closeFu();
+    }
+  }, [closeFu, info.auditDesc, info.id, upTableFu]);
 
   // 表格里面的查看信息
-  const [lookInfo, setLookInfo] = useState({} as A2inTableType);
+  const [goodsId, setGoodsId] = useState(0);
 
   // 能够出现的 按钮
   const btnArr = useMemo(() => {
@@ -56,9 +84,7 @@ function B1Info({ closeFu, info, pageKey }: Props) {
         cancelText="取消"
         onConfirm={delFu}
       >
-        <Button danger onClick={editFu}>
-          删除
-        </Button>
+        <Button danger>删除</Button>
       </Popconfirm>
     );
     const btn3 = <Button onClick={annulFu}>撤回</Button>;
@@ -121,7 +147,11 @@ function B1Info({ closeFu, info, pageKey }: Props) {
         title: "备注",
         render: (item: A2inTableType) => (
           <>
-            <Button size="small" type="text" onClick={() => setLookInfo(item)}>
+            <Button
+              size="small"
+              type="text"
+              onClick={() => setGoodsId(item.id)}
+            >
               查看
             </Button>
           </>
@@ -138,6 +168,8 @@ function B1Info({ closeFu, info, pageKey }: Props) {
       </div>
 
       <div className="B1ItopBox">
+        {/* 标题 */}
+        <div className="B1Ititle">{Reflect.get(B1TieleObj, info.type)}</div>
         {/* 顶部信息 */}
         <div className="B1IBox">
           <div className="B1IRow">
@@ -201,10 +233,16 @@ function B1Info({ closeFu, info, pageKey }: Props) {
         />
       </div>
       {/* 点击表格里面的查看出来的页面 */}
-      {lookInfo.id ? (
-        <B1Look
-          info={lookInfo}
-          closeFu={() => setLookInfo({} as A2inTableType)}
+      {goodsId ? (
+        <B1Look goodsId={goodsId} closeFu={() => setGoodsId(0)} />
+      ) : null}
+
+      {/* 点击编辑按钮出来的页面 */}
+      {outInfo.id ? (
+        <A2Register
+          closeFu={() => setOutInfo({ id: 0, txt: "" })}
+          outInfo={outInfo}
+          upInfoFu={() => getInfoFu(info.id, true)}
         />
       ) : null}
     </div>

+ 101 - 16
src/pages/B1Submit/B1Look/index.module.scss

@@ -1,4 +1,4 @@
-.B1Look{
+.B1Look {
   position: absolute;
   top: 0;
   left: 0;
@@ -8,35 +8,120 @@
   background-color: #fff;
   border-radius: 10px;
   padding: 24px;
-  :global{
-    .B1Ltop{
+
+  :global {
+    .B1Ltop {
       display: flex;
-      .B1Ltop1{
-        width: 270px;
-        height: 270px;
-        background-color: #aaaaaa;
+      height: 320px;
+
+      .B1Ltop1 {
+        width: 300px;
+        height: 100%;
         margin-right: 15px;
-        img{
-          object-fit: contain !important;
-        }
+        border: 1px solid #aaaaaa;
+        // img {
+        //   object-fit: contain !important;
+        // }
       }
-      .B1Ltop2{
-        width: calc(100% - 285px);
-        .B1Ltop2_1{
+
+      .B1Ltop2 {
+        height: 100%;
+        width: calc(100% - 315px);
+
+        .B1Ltop2_1 {
           display: flex;
           justify-content: space-between;
-          &>div{
+
+          &>div {
             display: flex;
             align-items: center;
-            .B1Ltop2_1Name{
+
+            .B1Ltop2_1Name {
               display: inline-block;
               font-weight: 700;
               font-size: 20px;
             }
           }
         }
-        .B1Ltop2_2{
 
+        .B1Ltop2_2 {
+          margin-top: 15px;
+          height: calc(100% - 140px);
+          display: flex;
+          justify-content: space-between;
+          .B1LcRow{
+            width: 48%;
+            height: 100%;
+            font-size: 16px;
+  
+            .B1LcRowIn{
+              display: flex;
+              height: 30px;
+              line-height: 30px;
+              &>div{
+                &:nth-of-type(1){
+                  width: 50px;
+                  text-align: right;
+                }
+                &:nth-of-type(2){
+                  width: calc(100% - 50px);
+                }
+              }
+            }
+          }
+          .B1LcRow2{
+            .B1LcRowIn{
+              &>div{
+                &:nth-of-type(1){
+                  width: 80px;
+                }
+                &:nth-of-type(2){
+                  width: calc(100% - 80px);
+                }
+              }
+            }
+          }
+        }
+        // 简介
+        .B1LcTxt{
+          font-size: 16px;
+          display: flex;
+          margin-top: 5px;
+          &>div{
+            &:nth-of-type(1){
+              width: 50px;
+              text-align: right;
+            }
+            &:nth-of-type(2){
+              padding-right: 4px;
+              width: calc(100% - 50px);
+              height: 88px;
+              white-space: pre-wrap;
+              overflow-y: auto;
+            }
+          }
+        }
+      }
+    }
+
+    .B1Lfoll {
+      margin-top: 15px;
+      height: calc(100% - 335px);
+      .B1LfollTit{
+        font-size: 20px;
+        font-weight: 700;
+      }
+      .B1LfollTable {
+        height: calc(100% - 40px);
+        margin-top: 12px;
+
+        .ant-table-body {
+          height: 370px;
+          overflow-y: auto !important;
+          overflow-y: overlay !important;
+          // .ant-table-cell{
+          //   padding: 4px 6px !important;
+          // }
         }
       }
     }

+ 161 - 8
src/pages/B1Submit/B1Look/index.tsx

@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useCallback, useEffect, useMemo, useState } from "react";
 import styles from "./index.module.scss";
 import {
   A2inTableType,
@@ -6,21 +6,100 @@ import {
   statusTxtObj,
   storageStatusTxtObj,
 } from "@/pages/A2Goods/data";
-import { Button, Popover, Tag } from "antd";
+import { Button, Popover, Table, Tag } from "antd";
 import ImageLazy from "@/components/ImageLazy";
 import { CaretDownOutlined } from "@ant-design/icons";
+import { A2_APIgetInfoSon } from "@/store/action/A2Goods";
+import { FileListType } from "@/components/Z_upFileOtherList";
+import { useSelector } from "react-redux";
+import { RootState } from "@/store";
+import filesLookFu from "@/utils/filesLook";
+import { baseURL } from "@/utils/http";
 
 type Props = {
-  info: A2inTableType;
+  goodsId: number;
   closeFu: () => void;
 };
 
-function B1Look({ info, closeFu }: Props) {
+function B1Look({ closeFu, goodsId }: Props) {
+  // isFileDonw 全局的是否允许下载
+  const isFileDonw = useSelector(
+    (state: RootState) => state.A0Layout.isFileDonw
+  );
+
+  const [info, setInfo] = useState({} as A2inTableType);
+  const [file, setFile] = useState([] as FileListType[]);
+
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A2_APIgetInfoSon(id);
+
+    if (res.code === 0) {
+      setInfo(res.data.entity);
+      setFile(res.data.file);
+    }
+  }, []);
+
+  useEffect(() => {
+    getInfoFu(goodsId);
+  }, [getInfoFu, goodsId]);
+
+  // 尺寸的信息
+  const sizeRes = useMemo(() => {
+    let temp = info.size || " , , ";
+    const temp2 = temp.split(",");
+    return temp2.map((v) => v.replace(" ", ""));
+  }, [info.size]);
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "附件名称",
+        dataIndex: "name",
+      },
+      {
+        title: "上传人",
+        dataIndex: "creatorName",
+      },
+      {
+        title: "上传时间",
+        dataIndex: "createTime",
+      },
+      {
+        title: "操作",
+        render: (item: FileListType) => (
+          <>
+            {filesLookFu(item.name) ? (
+              <Button
+                size="small"
+                type="text"
+                onClick={() => filesLookFu(item.name, item.filePath)}
+              >
+                预览
+              </Button>
+            ) : null}
+            {isFileDonw ? (
+              <a
+                href={baseURL + item.filePath}
+                download={item.name}
+                target="_blank"
+                rel="noreferrer"
+              >
+                <Button size="small" type="text">
+                  下载
+                </Button>
+              </a>
+            ) : null}
+          </>
+        ),
+      },
+    ];
+  }, [isFileDonw]);
+
   return (
     <div className={styles.B1Look}>
       <div className="B1Ltop">
         <div className="B1Ltop1">
-          <ImageLazy width={270} height={270} src={info.thumb} />
+          <ImageLazy width={298} height={318} src={info.thumb} />
         </div>
         <div className="B1Ltop2">
           <div className="B1Ltop2_1">
@@ -36,20 +115,94 @@ function B1Look({ info, closeFu }: Props) {
               </Tag>
             </div>
             <div>
+              {/* 待完善 */}
               <Button type="primary">藏品日志</Button>&emsp;
               <Popover placement="bottom" content={"666"}>
                 <Button type="primary">
                   操作
                   <CaretDownOutlined rev={undefined} />
                 </Button>
-              </Popover>&emsp;
+              </Popover>
+              &emsp;
               <Button onClick={closeFu}>返回</Button>
             </div>
           </div>
-          <div className="B1Ltop2_2"></div>
+          <div className="B1Ltop2_2">
+            {/* 左侧信息 */}
+            <div className="B1LcRow">
+              <div className="B1LcRowIn">
+                <div>名称:</div>
+                <div>{info.name}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>编号:</div>
+                <div>{info.num}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>时代:</div>
+                <div>{info.dictAge || "(空)"}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>质地:</div>
+                <div>{info.dictTexture || "(空)"}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>尺寸:</div>
+                <div>
+                  <span>长:{sizeRes[0] || "(空)"}</span>&emsp;
+                  <span>宽:{sizeRes[1] || "(空)"}</span>&emsp;
+                  <span>高:{sizeRes[2] || "(空)"}</span>
+                </div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>重量:</div>
+                <div>{info.quality || "(空)"}</div>
+              </div>
+            </div>
+            {/* 右侧信息 */}
+            <div className="B1LcRow B1LcRow2">
+              <div className="B1LcRowIn">
+                <div>实际数量:</div>
+                <div>{info.pcs || "(空)"}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>来源:</div>
+                <div>{info.source || "(空)"}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>完残程度:</div>
+                <div>{info.complete || "(空)"}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>级别:</div>
+                <div>{info.dictLevel || "(空)"}</div>
+              </div>
+              <div className="B1LcRowIn">
+                <div>定级时间:</div>
+                <div>{info.levelTime || "(空)"}</div>
+              </div>
+            </div>
+          </div>
+          {/* 简介 */}
+          <div className="B1LcTxt">
+            <div>简介:</div>
+            <div className="mySorrl">{info.description || "(空)"}</div>
+          </div>
+        </div>
+      </div>
+      <div className="B1Lfoll">
+        <div className="B1LfollTit">附件:</div>
+        <div className="B1LfollTable">
+          <Table
+            size="small"
+            scroll={{ y: 370 }}
+            dataSource={file}
+            columns={columns}
+            rowKey="id"
+            pagination={false}
+          />
         </div>
       </div>
-      <div className="B1Lfoll"></div>
     </div>
   );
 }

+ 9 - 0
src/pages/B1Submit/data.ts

@@ -76,6 +76,15 @@ export const B1TypeObj = {
   CK: "藏品出库",
 };
 
+export const B1TieleObj= {
+  DJ: "登记申请",
+  BJ: "编辑申请",
+  ZX: "注销申请",
+  RK: "入库申请",
+  YK: "移库申请",
+  CK: "出库申请",
+};
+
 export const antdTagColorFObj={
   4:'',
   3:'green',

+ 7 - 11
src/pages/B1Submit/index.tsx

@@ -123,7 +123,7 @@ function B1Submit() {
       {
         title: "操作",
         render: (item: B1tableType) => (
-          <Button size="small" type="text" onClick={() => setLookInfo(item)}>
+          <Button size="small" type="text" onClick={() => setLookId(item.id)}>
             查看
           </Button>
         ),
@@ -132,16 +132,11 @@ function B1Submit() {
   }, []);
 
   // 点击查看打开的页面
-  const [lookInfo, setLookInfo] = useState({} as B1tableType);
+  const [lookId, setLookId] = useState(0);
 
   return (
     <div className={styles.B1Submit}>
-      <div className="pageTitle">
-        我提交的
-        {lookInfo.id
-          ? `/查看 - ${Reflect.get(B1TypeObj, lookInfo.type)}`
-          : null}
-      </div>
+      <div className="pageTitle">我提交的</div>
       {/* 顶部筛选 */}
       <div className="B1top">
         {/* 左侧输入框 */}
@@ -206,11 +201,12 @@ function B1Submit() {
           }}
         />
       </div>
-      {lookInfo.id ? (
+      {lookId ? (
         <B1Info
           pageKey="我提交的"
-          closeFu={() => setLookInfo({} as B1tableType)}
-          info={lookInfo}
+          closeFu={() => setLookId(0)}
+          lookId={lookId}
+          upTableFu={getListFu}
         />
       ) : null}
     </div>

+ 84 - 0
src/pages/C1User/AddUser/index.module.scss

@@ -0,0 +1,84 @@
+.AddUser {
+  position: absolute;
+  z-index: 10;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  border-radius: 10px;
+  background-color: #fff;
+  padding: 24px;
+
+
+
+  :global {
+    .C1addMain {
+      overflow-y: auto;
+      width: 100%;
+      height: calc(100% - 80px);
+      .ant-form{
+        width: 800px;
+      }
+
+      .C1addBtn {
+        position: absolute;
+        bottom: 0px;
+        left: 50%;
+        transform: translateX(-50%);
+   
+      }
+
+      .e_row {
+        display: flex;
+        font-size: 14px;
+        margin-bottom: 24px;
+
+        .e_rowL {
+          width: 100px;
+          text-align: right;
+
+          &>span {
+            color: #ff4d4f;
+            position: relative;
+            top: 3px;
+          }
+        }
+
+        .e_rowR {
+          width: calc(100% - 100px);
+        }
+      }
+
+      .e_rowCenten {
+        align-items: center;
+
+        .e_rowR {
+          display: flex;
+          align-items: center;
+
+          .e_rowRtit {
+            color: #ff4d4f;
+            opacity: 0;
+            transition: all .3s;
+            position: relative;
+            top: -3px;
+          }
+
+          .e_rowRtitShow {
+            opacity: 1;
+            top: 0;
+          }
+        }
+      }
+
+      .e_rowCity {
+        padding-left: 100px;
+
+        .e_rowRList {
+          margin-bottom: 10px;
+        }
+
+      }
+    }
+  }
+}

+ 159 - 0
src/pages/C1User/AddUser/index.tsx

@@ -0,0 +1,159 @@
+import React, { useCallback, useEffect, useRef } from "react";
+import styles from "./index.module.scss";
+import { C1openInfoType } from "../data";
+import { Button, Form, FormInstance, Input, Popconfirm } from "antd";
+import classNames from "classnames";
+import { C1_APIadd, C1_APIgetInfo } from "@/store/action/C1User";
+import { MessageFu } from "@/utils/message";
+
+type Props = {
+  openInfo: C1openInfoType;
+  closeFu: () => void;
+  upTableFu: () => void;
+  addTableFu: () => void;
+};
+
+function AddUser({ openInfo, closeFu, upTableFu, addTableFu }: Props) {
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await C1_APIgetInfo(id);
+    if (res.code === 0) {
+      FormBoxRef.current?.setFieldsValue(res.data);
+    }
+  }, []);
+
+  useEffect(() => {
+    if (openInfo.txt === "编辑用户") {
+      // 发接口拿详情
+      getInfoFu(openInfo.id);
+    }
+  }, [getInfoFu, openInfo]);
+
+  // 表单的ref
+  const FormBoxRef = useRef<FormInstance>(null);
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(() => {}, []);
+
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (value: any) => {
+      const obj = {
+        ...value,
+        id: openInfo.txt === "新增用户" ? null : openInfo.id,
+        roleId: 2,
+      };
+
+      const res = await C1_APIadd(obj);
+
+      if (res.code === 0) {
+        MessageFu.success(
+          openInfo.txt === "新增用户" ? "新增成功!" : "编辑成功!"
+        );
+        openInfo.txt === "新增用户" ? addTableFu() : upTableFu();
+        closeFu();
+      }
+    },
+    [addTableFu, closeFu, openInfo.id, openInfo.txt, upTableFu]
+  );
+
+  return (
+    <div className={classNames(styles.AddUser)}>
+      <div className="C1addMain">
+        <Form
+          scrollToFirstError={true}
+          ref={FormBoxRef}
+          labelCol={{ span: 3 }}
+          name="basic"
+          onFinish={onFinish}
+          onFinishFailed={onFinishFailed}
+          autoComplete="off"
+        >
+          <Form.Item
+            label="用户名"
+            name="userName"
+            rules={[
+              { required: true, message: "请输入内容,6-15字" },
+              {
+                validator: (_: any, value: any) => {
+                  if (value) {
+                    const reg = new RegExp(/^[a-zA-Z0-9_]{6,15}$/);
+                    const flag = reg.test(value);
+                    if (flag) return Promise.resolve(value);
+                    else
+                      return Promise.reject(
+                        "用户名只包含字母、数字和下划线,最少 6 个字符!"
+                      );
+                  } else return Promise.resolve(value);
+                },
+              },
+            ]}
+            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+          >
+            <Input
+              disabled={openInfo.txt === "编辑用户"}
+              maxLength={15}
+              showCount
+              placeholder="请输入内容,6-15字"
+            />
+          </Form.Item>
+
+          <div className="e_row" hidden={openInfo.txt === "编辑用户"}>
+            <div className="e_rowL">
+              <span> </span>初始密码:
+            </div>
+            <div className="e_rowR">123456</div>
+          </div>
+
+          <Form.Item
+            label="真实姓名"
+            name="realName"
+            rules={[{ required: true, message: "请输入真实姓名!" }]}
+            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+          >
+            <Input
+              maxLength={10}
+              showCount
+              placeholder="请输入内容,最多10字"
+            />
+          </Form.Item>
+
+          <Form.Item
+            label="联系方式"
+            name="phone"
+            rules={[
+              {
+                pattern: /^1[3-9][0-9]{9}$/,
+                message: "请输入正确格式的手机号!",
+              },
+            ]}
+            getValueFromEvent={(e) => e.target.value.replace(/\s+/g, "")}
+          >
+            <Input maxLength={11} showCount placeholder="请输入11位手机号" />
+          </Form.Item>
+
+          {/* 确定和取消按钮 */}
+          <br />
+          <Form.Item className="C1addBtn">
+            <Button type="primary" htmlType="submit">
+              提交
+            </Button>
+            &emsp;
+            <Popconfirm
+              title="放弃编辑后,信息将不会保存!"
+              okText="放弃"
+              cancelText="取消"
+              onConfirm={closeFu}
+              okButtonProps={{ loading: false }}
+            >
+              <Button>取消</Button>
+            </Popconfirm>
+          </Form.Item>
+        </Form>
+      </div>
+    </div>
+  );
+}
+
+const MemoAddUser = React.memo(AddUser);
+
+export default MemoAddUser;

+ 167 - 0
src/pages/C1User/C1Power.tsx

@@ -0,0 +1,167 @@
+import React, { useCallback, useEffect, useMemo, useState } from "react";
+import styles from "./index.module.scss";
+import { Button, Checkbox, Modal, Popconfirm } from "antd";
+import { C1_APIgetUserProwerById, C1_APIuserAuth } from "@/store/action/C1User";
+import { C1PowerListType } from "./data";
+import classNames from "classnames";
+import { MessageFu } from "@/utils/message";
+
+type Props = {
+  closeFu: () => void;
+  userId: number;
+  upTableFu:()=>void
+};
+
+function C1Power({ closeFu, userId,upTableFu }: Props) {
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await C1_APIgetUserProwerById(id);
+    if (res.code === 0) {
+      setPowerList(res.data);
+    }
+  }, []);
+
+  useEffect(() => {
+    getInfoFu(userId);
+  }, [getInfoFu, userId]);
+
+  const [isOk, setIsOk] = useState(false);
+
+  // 多选框列表
+  const [powerList, setPowerList] = useState<C1PowerListType[]>([]);
+
+  // 多选框改变
+  const checkChangeFu = useCallback(
+    (id1: number, id2: number, val: boolean) => {
+      setIsOk(true);
+      setPowerList(
+        powerList.map((v1) => ({
+          ...v1,
+          children:
+            id1 === v1.id
+              ? v1.children.map((v2) => ({
+                  ...v2,
+                  authority: v2.id === id2 ? val : v2.authority,
+                }))
+              : v1.children,
+        }))
+      );
+    },
+    [powerList]
+  );
+
+  // 最后发送请求的 勾选了的 id集合数组
+  const resList = useMemo(() => {
+    const tempArr = [] as number[];
+    powerList.forEach((v1) => {
+      v1.children.forEach((v2) => {
+        if (v2.authority) tempArr.push(v2.id);
+      });
+    });
+    return tempArr;
+  }, [powerList]);
+
+  // 判断是否 选中了 一个功能权限
+  const chenckOne1 = useMemo(() => {
+    const tempArr = [101, 102, 201, 202, 203, 204];
+    return !resList.some((v) => tempArr.includes(v));
+  }, [resList]);
+
+  // 判断是否 选中了 一个功能权限
+  const chenckOne2 = useMemo(() => {
+    const tempArr = [301, 302, 303];
+    return !resList.some((v) => tempArr.includes(v));
+  }, [resList]);
+
+  // 点击确定
+  const btnOkFu = useCallback(async () => {
+    setIsOk(true);
+    if (chenckOne1 || chenckOne2) return;
+    const res =await C1_APIuserAuth({
+      resources:resList,
+      userId
+    })
+
+    if(res.code===0){
+      MessageFu.success('授权成功!')
+      upTableFu()
+      closeFu()
+    }
+
+  }, [chenckOne1, chenckOne2, closeFu, resList, upTableFu, userId]);
+
+  return (
+    <Modal
+      wrapClassName={styles.C1Power}
+      open={true}
+      title="设置权限"
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className="C1Pmain">
+        <div className="C1PRowBox">
+          <div className="C1PRowTitle">
+            功能权限
+            <span
+              className={classNames(isOk && chenckOne1 ? "C1PRowTitleErr" : "")}
+            >
+              &emsp;&emsp;&emsp;至少选择一个功能权限
+            </span>
+          </div>
+          <div className="C1PRowTitle C1PRowTitle2">
+            数据权限
+            <span
+              className={classNames(isOk && chenckOne2 ? "C1PRowTitleErr" : "")}
+            >
+              &emsp;&emsp;&emsp;至少选择一个数据权限
+            </span>
+          </div>
+          {powerList.map((v1) => (
+            <div className="C1PRow" key={v1.id}>
+              <div className="C1PRowll">{v1.name}:</div>
+              <div className="C1PRowrr">
+                {v1.children.map((v2) => (
+                  <span key={v2.id}>
+                    <Checkbox
+                      checked={v2.authority}
+                      onChange={(e) =>
+                        checkChangeFu(v1.id, v2.id, e.target.checked)
+                      }
+                    >
+                      {v2.name}
+                    </Checkbox>
+                    &emsp;
+                  </span>
+                ))}
+              </div>
+            </div>
+          ))}
+        </div>
+
+        <div className="C1Pbtn">
+          <Button
+            type="primary"
+            disabled={isOk && (chenckOne1 || chenckOne2)}
+            onClick={btnOkFu}
+          >
+            提交
+          </Button>
+          &emsp;
+          <Popconfirm
+            title="放弃编辑后,信息将不会保存!"
+            okText="放弃"
+            cancelText="取消"
+            onConfirm={closeFu}
+            okButtonProps={{ loading: false }}
+          >
+            <Button>取消</Button>
+          </Popconfirm>
+        </div>
+      </div>
+    </Modal>
+  );
+}
+
+const MemoC1Power = React.memo(C1Power);
+
+export default MemoC1Power;

+ 11 - 0
src/pages/C1User/data.ts

@@ -0,0 +1,11 @@
+export type C1openInfoType = {
+  id: number;
+  txt: "新增用户" | "编辑用户" | "";
+};
+
+export type C1PowerListType = {
+  authority: boolean;
+  children: C1PowerListType[];
+  id: number;
+  name: string;
+};

+ 97 - 3
src/pages/C1User/index.module.scss

@@ -1,5 +1,99 @@
-.C1User{
-  :global{
-    
+.C1User {
+  :global {
+    .C1top {
+      display: flex;
+      justify-content: space-between;
+      border-radius: 10px;
+      background-color: #fff;
+      padding: 15px 24px;
+
+      &>div {
+        display: flex;
+
+        .C1topRow {
+          margin-right: 20px;
+        }
+      }
+    }
+
+    .tableMain {
+      border-radius: 10px;
+      margin-top: 15px;
+      height: calc(100% - 80px);
+      background-color: #fff;
+
+      .ant-table-body {
+        height: 625px;
+        overflow-y: auto !important;
+        overflow-y: overlay !important;
+
+      }
+    }
+  }
+}
+
+.C1Power {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      width: 800px !important;
+    }
+    .C1Pmain{
+      padding-top: 15px;
+      border-top: 1px solid #ccc;
+
+      .C1PRowBox{
+        position: relative;
+        padding-top: 50px;
+        .C1PRowTitle{
+          position: absolute;
+          top: 0;
+          left: 0;
+          font-weight: 700;
+          font-size: 20px;
+          color: var(--themeColor);
+          &>span{
+            opacity: 0;
+            position: relative;
+            top: 5px;
+            transition: all .3s;
+            font-size: 14px;
+            color: #ff4d4f;
+          }
+          .C1PRowTitleErr{
+            opacity: 1;
+            top: 0;
+          }
+        } 
+
+        .C1PRowTitle2{
+          top: 160px;
+        }
+
+        .C1PRow{
+          display: flex;
+          margin-bottom: 20px;
+          &:nth-of-type(4){
+            margin-bottom: 100px;
+          }
+
+          .C1PRowll{
+            width: 120px;
+          }
+          .C1PRowrr{
+            width: calc(100% - 120px);
+
+          }
+        }
+      }
+
+      .C1Pbtn{
+        margin-top: 20px;
+        text-align: center;
+      }
+    }
   }
 }

+ 234 - 5
src/pages/C1User/index.tsx

@@ -1,12 +1,241 @@
-import React from "react";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
 import styles from "./index.module.scss";
- function C1User() {
-  
+import { Button, Input, Popconfirm, Table } from "antd";
+import { C1openInfoType } from "./data";
+import { useDispatch, useSelector } from "react-redux";
+import {
+  C1_APIgetlist,
+  C1_APIpassReset,
+  C1_APIremoves,
+} from "@/store/action/C1User";
+import { RootState } from "@/store";
+import { C1ListType } from "@/types";
+import { MessageFu } from "@/utils/message";
+import AddUser from "./AddUser";
+import C1Power from "./C1Power";
+function C1User() {
+  const dispatch = useDispatch();
+  // 筛选和分页
+  const [tableSelect, setTableSelect] = useState({
+    searchKey: "",
+    pageSize: 10,
+    pageNum: 1,
+  });
+
+  // 发送接口的函数
+  const getListFu = useCallback(() => {
+    dispatch(C1_APIgetlist(tableSelect));
+  }, [dispatch, tableSelect]);
+
+  useEffect(() => {
+    getListFu();
+  }, [getListFu]);
+
+  // 输入框的改变
+  const txtTimeRef = useRef(-1);
+  const txtChangeFu = useCallback(
+    (txt: string, key: "searchKey") => {
+      clearTimeout(txtTimeRef.current);
+      txtTimeRef.current = window.setTimeout(() => {
+        setTableSelect({ ...tableSelect, [key]: txt, pageNum: 1 });
+      }, 500);
+    },
+    [tableSelect]
+  );
+
+  // 点击重置
+  const [inputKey, setInputKey] = useState(1);
+  const resetSelectFu = useCallback(() => {
+    // 把2个输入框和时间选择器清空
+    setInputKey(Date.now());
+    setTableSelect({
+      searchKey: "",
+      pageSize: 10,
+      pageNum: 1,
+    });
+  }, []);
+
+  // 从仓库获取列表
+  const C1TableList = useSelector(
+    (state: RootState) => state.C1User.C1TableList
+  );
+  // 页码变化
+  const paginationChange = useCallback(
+    () => (pageNum: number, pageSize: number) => {
+      setTableSelect({ ...tableSelect, pageNum, pageSize });
+    },
+    [tableSelect]
+  );
+
+  // 点击删除
+  const delByIdFu = useCallback(
+    async (id: number) => {
+      const res = await C1_APIremoves(id);
+      if (res.code === 0) {
+        MessageFu.success("删除成功!");
+        getListFu();
+      }
+    },
+    [getListFu]
+  );
+
+  // 点击重置密码
+  const resetPassFu = useCallback(async (id: number) => {
+    const res: any = await C1_APIpassReset(id);
+    if (res.code === 0) MessageFu.success("重置成功!");
+  }, []);
+
+  const columns = useMemo(() => {
+    return [
+      {
+        title: "用户名",
+        dataIndex: "userName",
+      },
+      {
+        title: "真实姓名",
+        render: (item: C1ListType) => (item.realName ? item.realName : "匿名"),
+      },
+      {
+        title: "联系方式",
+        render: (item: C1ListType) => (item.phone ? item.phone : "(空)"),
+      },
+      {
+        title: "创建日期",
+        dataIndex: "createTime",
+      },
+
+      {
+        title: "操作",
+        render: (item: C1ListType) =>
+          item.isAdmin === 1 ? (
+            "-"
+          ) : (
+            <>
+              <Popconfirm
+                title="密码重制后为123456,确定重置吗?"
+                okText="重置"
+                cancelText="取消"
+                onConfirm={() => resetPassFu(item.id!)}
+                okButtonProps={{ loading: false }}
+              >
+                <Button size="small" type="text">
+                  重置密码
+                </Button>
+              </Popconfirm>
+              <Button
+                size="small"
+                type="text"
+                onClick={() => setOpenInfo({ id: item.id, txt: "编辑用户" })}
+              >
+                编辑
+              </Button>
+              <Button
+                size="small"
+                type="text"
+                onClick={() => setPowerId(item.id)}
+              >
+                设置权限
+              </Button>
+              <Popconfirm
+                title="删除后无法恢复,是否删除?"
+                okText="删除"
+                cancelText="取消"
+                onConfirm={() => delByIdFu(item.id)}
+                okButtonProps={{ loading: false }}
+              >
+                <Button size="small" type="text" danger>
+                  删除
+                </Button>
+              </Popconfirm>
+            </>
+          ),
+      },
+    ];
+  }, [delByIdFu, resetPassFu]);
+
+  // 点击 新增/编辑 出来的信息
+  const [openInfo, setOpenInfo] = useState<C1openInfoType>({ id: 0, txt: "" });
+
+  // 点击权限设置
+  const [powerId, setPowerId] = useState(0);
+
   return (
     <div className={styles.C1User}>
-      <div className="pageTitle">用户管理</div>
+      <div className="pageTitle">
+        {openInfo.txt ? openInfo.txt : "用户管理"}
+      </div>
+      {/* 顶部筛选 */}
+      <div className="C1top">
+        {/* 左侧输入框 */}
+        <div className="C1top1">
+          <div className="C1topRow">
+            <span>搜索项:</span>
+            <Input
+              key={inputKey}
+              maxLength={15}
+              style={{ width: 200 }}
+              placeholder="请输入用户名/真实姓名"
+              allowClear
+              onChange={(e) => txtChangeFu(e.target.value, "searchKey")}
+            />
+          </div>
+        </div>
+        {/* 右侧按钮 */}
+        <div className="C1top2">
+          <Button onClick={resetSelectFu}>重置</Button>&emsp;
+          <Button
+            type="primary"
+            onClick={() => setOpenInfo({ id: -1, txt: "新增用户" })}
+          >
+            新增
+          </Button>
+        </div>
+      </div>
+      {/* 表格主体 */}
+      <div className="tableMain">
+        <Table
+          scroll={{ y: 625 }}
+          dataSource={C1TableList.list}
+          columns={columns}
+          rowKey="id"
+          pagination={{
+            showQuickJumper: true,
+            position: ["bottomCenter"],
+            showSizeChanger: true,
+            current: tableSelect.pageNum,
+            pageSize: tableSelect.pageSize,
+            total: C1TableList.total,
+            onChange: paginationChange(),
+          }}
+        />
+      </div>
+
+      {/* 新增的编辑 */}
+      {openInfo.id ? (
+        <AddUser
+          openInfo={openInfo}
+          closeFu={() => setOpenInfo({ id: 0, txt: "" })}
+          upTableFu={getListFu}
+          addTableFu={resetSelectFu}
+        />
+      ) : null}
+
+      {/* 设置权限 */}
+      {powerId ? (
+        <C1Power
+          userId={powerId}
+          closeFu={() => setPowerId(0)}
+          upTableFu={getListFu}
+        />
+      ) : null}
     </div>
-  )
+  );
 }
 
 const MemoC1User = React.memo(C1User);

+ 19 - 20
src/pages/Layout/data.ts

@@ -3,79 +3,78 @@ import React from "react";
 
 const tabLeftArr: RouterType = [
   {
-    id: "1",
+    id: 1,
     name: "藏品管理",
     son: [
       {
-        id: "1.1",
+        id: 201,
         name: "藏品统计",
         path: "/",
         Com: React.lazy(() => import("../A1Stat")),
-        done: true,
+        done: false,
       },
       {
-        id: "1.2",
+        id: 202,
         name: "藏品清单",
         path: "/goods",
         Com: React.lazy(() => import("../A2Goods")),
-        done: true,
+        done: false,
       },
       {
-        id: "1.3",
+        id: 203,
         name: "库存清单",
         path: "/stock",
         Com: React.lazy(() => import("../A3Stock")),
-        done: true,
+        done: false,
       },
       {
-        id: "1.4",
+        id: 204,
         name: "库存设置",
         path: "/roomset",
         Com: React.lazy(() => import("../A4Roomset")),
-        done: true,
+        done: false,
       },
     ],
   },
 
   {
-    id: "2",
+    id: 2,
     name: "事务管理",
     son: [
       {
-        id: "2.1",
+        id: 101,
         name: "我提交的",
         path: "/submit",
         Com: React.lazy(() => import("../B1Submit")),
-        done: true,
+        done: false,
       },
       {
-        id: "2.2",
+        id: 102,
         name: "我审核的",
         path: "/audit",
         Com: React.lazy(() => import("../B2Audit")),
-        done: true,
+        done: false,
       },
-
     ],
   },
 
   {
-    id: "3",
+    id: 3,
     name: "系统管理",
     son: [
       {
-        id: "3.1",
+        id: 3.1,
         name: "用户管理",
         path: "/user",
         Com: React.lazy(() => import("../C1User")),
-        done: true,
+        done: false,
       },
       {
-        id: "3.2",
+        id: 3.2,
         name: "系统日志",
         path: "/log",
         Com: React.lazy(() => import("../C2Log")),
-        done: true,
+        done: false,
       },
     ],
   },

+ 62 - 15
src/pages/Layout/index.tsx

@@ -23,15 +23,55 @@ import NotFound from "@/components/NotFound";
 
 import { RouterType, RouterTypeRow } from "@/types";
 import tabLeftArr from "./data";
+import { API_getUserPrower } from "@/store/action/C1User";
+import store from "@/store";
 
 function Layout() {
   // 左侧菜单 和 路由 信息
   const [list, setList] = useState([] as RouterType);
+  const listFlag = useRef(false);
 
-  useEffect(() => {
-    setList(tabLeftArr);
+  const getUserProwerFu = useCallback(async () => {
+    const res = await API_getUserPrower();
+    if (res.code === 0) {
+      const tempArr = [] as number[];
+      res.data.forEach((v: any) => {
+        if (v.children && v.children.length > 0) {
+          v.children.forEach((v2: any) => {
+            if (v2.authority) tempArr.push(v2.id);
+            // 是否是管理员
+            if (getTokenInfo().user && getTokenInfo().user.isAdmin === 1) {
+              tempArr.push(3.1);
+              tempArr.push(3.2);
+            }
+
+            // 附件是否允许下载
+            if (v2.id === 401)
+              store.dispatch({
+                type: "layout/isFileDonw",
+                payload: v2.authority,
+              });
+          });
+        }
+      });
+
+      const resArr = tabLeftArr.map((v) => ({
+        ...v,
+        son: v.son.map((v2) => ({
+          ...v2,
+          done: tempArr.includes(v2.id),
+        })),
+      }));
+
+      listFlag.current = true;
+      setList(resArr);
+    }
   }, []);
 
+  useEffect(() => {
+    getUserProwerFu();
+  }, [getUserProwerFu]);
+
   // 用户名
   const [userName, setUserName] = useState("-");
 
@@ -113,7 +153,12 @@ function Layout() {
 
   // 第一个页面不是 项目 管理 的时候 动态 跳转
   useEffect(() => {
-    if (RouterCom && RouterCom[0] && RouterCom[0].id !== "1.1")
+    if (
+      listFlag.current &&
+      RouterCom &&
+      RouterCom[0] &&
+      RouterCom[0].id !== 201
+    )
       history.replace(RouterCom[0].path);
   }, [RouterCom]);
 
@@ -133,18 +178,20 @@ function Layout() {
               hidden={v.son.every((c) => !c.done)}
             >
               <div className="layoutLRowBoxTxt">{v.name}</div>
-              {v.son.map((v2) => (
-                <div
-                  key={v2.id}
-                  className={classNames(
-                    "layoutLRowBoxRow",
-                    path === v2.path ? "active" : ""
-                  )}
-                  onClick={() => pathCutFu(v2.path)}
-                >
-                  {v2.name}
-                </div>
-              ))}
+              {v.son
+                .filter((c) => c.done)
+                .map((v2) => (
+                  <div
+                    key={v2.id}
+                    className={classNames(
+                      "layoutLRowBoxRow",
+                      path === v2.path ? "active" : ""
+                    )}
+                    onClick={() => pathCutFu(v2.path)}
+                  >
+                    {v2.name}
+                  </div>
+                ))}
             </div>
           ))}
         </div>

+ 21 - 0
src/store/action/A2Goods.ts

@@ -25,6 +25,13 @@ export const A2_APIaddSon = (data: any) => {
 };
 
 /**
+ * 通过id获取单个藏品详情(内)
+ */
+export const A2_APIgetInfoSon = (id:number) => {
+  return http.get(`cms/goods/detail/${id}`);
+};
+
+/**
  * 删除里面的列表的藏品
  */
 export const A2_APIinDels = (ids: string) => {
@@ -37,3 +44,17 @@ export const A2_APIinDels = (ids: string) => {
 export const A2_APIaddWai = (data: any) => {
   return http.post("cms/order/save/registerOrCancel", data);
 };
+
+/**
+ * 通过id获取详情(外 1对多)
+ */
+export const A2_APIgetInfoWai = (orderId:number) => {
+  return http.get(`cms/order/detail/${orderId}`);
+};
+
+/**
+ * 待审核  撤回 =》待提交 (审核 撤回)
+ */
+export const A2_APIaudit = (data:any) => {
+  return http.post('cms/order/audit',data);
+};

+ 77 - 0
src/store/action/C1User.ts

@@ -0,0 +1,77 @@
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+/**
+ * 获取 用户管理 表格列表(存到仓库)
+ */
+export const C1_APIgetlist = (data: any, falg?: boolean) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("sys/user//list", data);
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total,
+      };
+      if (falg) {
+        dispatch({
+          type: "C1/getListAll",
+          payload: obj.list.map((v: any) => ({
+            value: v.id,
+            label: `${v.userName} - ${v.roleName}${
+              v.realName ? " - " + v.realName : ""
+            }`,
+          })),
+        });
+      } else dispatch({ type: "C1/getList", payload: obj });
+    }
+  };
+};
+
+/**
+ * 重置密码
+ */
+export const C1_APIpassReset = (id: number) => {
+  return http.get(`sys/user/resetPass/${id}`);
+};
+
+/**
+ * 删除用户
+ */
+export const C1_APIremoves = (id: number) => {
+  return http.get(`sys/user/removes/${id}`);
+};
+
+/**
+ * 新增/编辑
+ */
+export const C1_APIadd = (data: any) => {
+  return http.post("sys/user/save", data);
+};
+
+/**
+ * 通过id获取详情
+ */
+export const C1_APIgetInfo = (id: number) => {
+  return http.get(`sys/user/detail/${id}`);
+};
+
+/**
+ * 进页面获取用户权限
+ */
+export const API_getUserPrower = () => {
+  return http.get("sys/menu/getTreePermissions");
+};
+
+/**
+ * 通过用户id获取权限
+ */
+export const C1_APIgetUserProwerById = (userId: number) => {
+  return http.get(`sys/user/getTreeUserPermissions/${userId}`);
+};
+
+
+/**
+ * 用户授权
+ */
+export const C1_APIuserAuth = (data:any) => {
+  return http.post('sys/user/auth',data);
+};

+ 29 - 0
src/store/reducer/C1User.ts

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

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

@@ -5,6 +5,7 @@ import { combineReducers } from "redux";
 import A0Layout from "./layout";
 import A2Goods from "./A2Goods";
 import B1Submit from "./B1Submit";
+import C1User from "./C1User";
 import C2Log from "./C2Log";
 
 // 合并 reducer
@@ -12,6 +13,7 @@ const rootReducer = combineReducers({
   A0Layout,
   A2Goods,
   B1Submit,
+  C1User,
   C2Log,
 });
 

+ 9 - 2
src/store/reducer/layout.ts

@@ -25,6 +25,9 @@ const initState = {
     fu: () => {},
     state: false,
   },
+
+  // 全局的附件是否允许下载
+  isFileDonw: false,
 };
 
 // 定义 action 类型
@@ -38,9 +41,10 @@ type LayoutActionType =
         fu: () => void;
         state: boolean;
       };
-    };
+    }
+  | { type: "layout/isFileDonw"; payload: boolean };
 
-// 频道 reducer
+// reducer
 export default function layoutReducer(
   state = initState,
   action: LayoutActionType
@@ -59,6 +63,9 @@ export default function layoutReducer(
     // 上传文件点击取消
     case "layout/closeUpFile":
       return { ...state, closeUpFile: action.payload };
+    // 全局的附件是否允许下载
+    case "layout/isFileDonw":
+      return { ...state, isFileDonw: action.payload };
     default:
       return state;
   }

+ 20 - 0
src/types/api/C1User.d.ts

@@ -0,0 +1,20 @@
+export type C1ListType ={
+	createTime: string;
+	creatorId: number;
+	creatorName: string;
+	deptAncestors: string;
+	deptId: number;
+	deptName: string;
+	id: number;
+	isAdmin: number;
+	isEnabled: number;
+	nickName: string;
+	phone: string;
+	realName: string;
+	roleId: number;
+	roleName: string;
+	sex: string;
+	thumb: string;
+	updateTime: string;
+	userName: string;
+}

+ 2 - 2
src/types/api/layot.d.ts

@@ -5,7 +5,7 @@ export type LookDomType = {
 };
 
 export type RouterTypeRow = {
-  id: string;
+  id: number;
   name: string;
   path: string;
   Com: React.LazyExoticComponent<React.MemoExoticComponent<() => JSX.Element>>;
@@ -13,7 +13,7 @@ export type RouterTypeRow = {
 }[];
 
 export type RouterType = {
-  id: string;
+  id: number;
   name: string;
   son: RouterTypeRow;
 }[];

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

@@ -1,4 +1,5 @@
 export * from './api/layot'
 export * from './api/A2Goods'
 export * from './api/B1Submit'
+export * from './api/C1User'
 export * from './api/C2Log'

+ 1 - 1
src/utils/storage.ts

@@ -1,7 +1,7 @@
 // ------------------------------------token的本地存储------------------------------------
 
 // 用户 Token 的本地缓存键名,自己定义
-const TOKEN_KEY = "ZGTT3D_HT_USER_INFO";
+const TOKEN_KEY = "QHQYGOODS_HT_USER_INFO";
 
 /**
  * 从本地缓存中获取 用户 信息