shaogen1995 2 年之前
父节点
当前提交
0b9e50b8f8

文件差异内容过多而无法显示
+ 466 - 408
package-lock.json


+ 1 - 1
package.json

@@ -11,7 +11,7 @@
     "@types/node": "^16.18.3",
     "@types/react": "^18.0.24",
     "@types/react-dom": "^18.0.8",
-    "antd": "^5.0.4",
+    "antd": "^5.8.3",
     "antd-mobile": "^5.30.0",
     "axios": "^1.1.3",
     "dayjs": "^1.11.7",

+ 2 - 2
src/components/ImageLazy/index.tsx

@@ -33,7 +33,7 @@ function ImageLazy({
   // 点击预览图片
   const lookBigImg = useCallback(() => {
     store.dispatch({
-      type: 'layout/lookBigImg',
+      type: "layout/lookBigImg",
       payload: { url: offline ? src : baseURL + src, show: true },
     });
   }, [offline, src]);
@@ -53,7 +53,7 @@ function ImageLazy({
         {/* 图片预览 */}
         {noLook || !lookImg ? null : (
           <div className="lookImg" onClick={lookBigImg}>
-            <EyeOutlined />
+            <EyeOutlined rev={undefined} />
             &nbsp;
             <div>预览</div>
           </div>

+ 1 - 1
src/components/LookDom/index.tsx

@@ -39,7 +39,7 @@ function LookDom() {
               })
             }
           >
-            <CloseCircleOutlined />
+            <CloseCircleOutlined rev={undefined} />
           </div>
         </>
       ) : null}

+ 4 - 3
src/components/Z1upImgs/index.tsx

@@ -141,7 +141,7 @@ function Z1upImgs(
         className="fileBoxRow_up"
         onClick={() => myInput.current?.click()}
       >
-        <PlusOutlined />
+        <PlusOutlined rev={undefined} />
       </div>
 
       <ReactSortable
@@ -167,7 +167,7 @@ function Z1upImgs(
               okButtonProps={{ loading: false }}
             >
               <div className="clearCover" hidden={isLook}>
-                <CloseOutlined />
+                <CloseOutlined rev={undefined} />
               </div>
             </Popconfirm>
 
@@ -179,6 +179,7 @@ function Z1upImgs(
             {/* 下面的预览和下载 */}
             <div className="fileImgListLDBox">
               <EyeOutlined
+                rev={undefined}
                 onClick={() =>
                   store.dispatch({
                     type: "layout/lookBigImg",
@@ -195,7 +196,7 @@ function Z1upImgs(
                 target="_blank"
                 rel="noreferrer"
               >
-                <DownloadOutlined />
+                <DownloadOutlined rev={undefined} />
               </a>
             </div>
           </div>

+ 4 - 3
src/components/Z2upVideos/index.tsx

@@ -133,7 +133,7 @@ function Z2upVideos(
         {fileList.length < max && !isLook ? (
           <Button
             onClick={() => myInput.current?.click()}
-            icon={<UploadOutlined />}
+            icon={<UploadOutlined rev={undefined} />}
           >
             上传
           </Button>
@@ -158,12 +158,13 @@ function Z2upVideos(
                 okButtonProps={{ loading: false }}
               >
                 <div className="clearCover" hidden={isLook}>
-                  <CloseOutlined />
+                  <CloseOutlined rev={undefined} />
                 </div>
               </Popconfirm>
               {/* 下面的预览和下载 */}
               <div className="fileImgListLDBox">
                 <EyeOutlined
+                  rev={undefined}
                   onClick={() =>
                     store.dispatch({
                       type: "layout/lookDom",
@@ -180,7 +181,7 @@ function Z2upVideos(
                   target="_blank"
                   rel="noreferrer"
                 >
-                  <DownloadOutlined />
+                  <DownloadOutlined rev={undefined} />
                 </a>
               </div>
             </div>

+ 4 - 3
src/components/Z3upFiles/index.tsx

@@ -106,7 +106,7 @@ function Z3upFiles(
         {fileList.length < max && !isLook ? (
           <Button
             onClick={() => myInput.current?.click()}
-            icon={<UploadOutlined />}
+            icon={<UploadOutlined rev={undefined} />}
           >
             上传
           </Button>
@@ -122,6 +122,7 @@ function Z3upFiles(
                 {filesLookFu(v.fileName) ? (
                   <>
                     <EyeOutlined
+                      rev={undefined}
                       title="查看"
                       onClick={() => filesLookFu(v.fileName, v.filePath)}
                     />
@@ -135,7 +136,7 @@ function Z3upFiles(
                   target="_blank"
                   rel="noreferrer"
                 >
-                  <DownloadOutlined />
+                  <DownloadOutlined rev={undefined} />
                 </a>
                 &emsp;
                 <Popconfirm
@@ -145,7 +146,7 @@ function Z3upFiles(
                   onConfirm={() => delImgListFu(v.id)}
                   okButtonProps={{ loading: false }}
                 >
-                  <CloseOutlined title="删除" hidden={isLook} />
+                  <CloseOutlined rev={undefined} title="删除" hidden={isLook} />
                 </Popconfirm>
               </div>
             </div>

+ 89 - 35
src/pages/A1Project/A1Down/index.tsx

@@ -1,20 +1,50 @@
 import React, { useCallback, useEffect, useState } from "react";
 import styles from "./index.module.scss";
-import { Button, Checkbox, Modal } from "antd";
+import { Button, Checkbox, Empty, Modal } from "antd";
+import { A2_APIgetDownList } from "@/store/action/A1Project";
+import { A1getStorage, A1setStorage } from "@/utils/storage";
+import { MessageFu } from "@/utils/message";
 
-const defaultCheckedList = [
-  { id: 1, label: "Apple", done: false },
-  { id: 2, label: "Pear", done: false },
-  { id: 3, label: "Orange", done: false },
-];
+type SelectType = {
+  id: number;
+  label: string;
+  done: boolean;
+};
 
 type Props = {
-  id: number;
+  downId: { id: number; txt: string };
   closeFu: () => void;
 };
 
-function A1Down({ id, closeFu }: Props) {
-  const [checkedList, setCheckedList] = useState(defaultCheckedList);
+function A1Down({ downId, closeFu }: Props) {
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A2_APIgetDownList(id);
+    if (res.code === 0) {
+      // setCheckedList(res.data || []);
+      let arr = [
+        { id: 1, label: "需求规格说明书", done: false },
+        { id: 2, label: "重要文件1", done: false },
+        { id: 3, label: "未分类", done: false },
+      ];
+
+      const storeIds = A1getStorage();
+
+      if (storeIds) {
+        arr = arr.map((v) => ({
+          ...v,
+          done: storeIds.includes(v.id) ? true : false,
+        }));
+      }
+
+      setCheckedList(arr);
+    }
+  }, []);
+
+  useEffect(() => {
+    getInfoFu(downId.id);
+  }, [getInfoFu, downId.id]);
+
+  const [checkedList, setCheckedList] = useState([] as SelectType[]);
 
   // 全选的状态
   const [indeterminate, setIndeterminate] = useState(false);
@@ -57,43 +87,67 @@ function A1Down({ id, closeFu }: Props) {
     console.log("-------", checkedList);
   }, [checkedList]);
 
+  // 点击保存设置 到 本地
+  const clickStoreFu = useCallback(() => {
+    const arr = checkedList.filter((v) => v.done).map((v) => v.id);
+    A1setStorage(arr);
+    MessageFu.success("保存设置到本地成功!");
+  }, [checkedList]);
+
   return (
     <Modal
       wrapClassName={styles.A1Down}
       destroyOnClose
       open={true}
-      title="xxx项目"
+      title={downId.txt}
       footer={
         [] // 设置footer为空,去掉 取消 确定默认按钮
       }
     >
       <div className="A1DownMain">
-        <h3>请选择下载的项目文件类型</h3>
-        <Checkbox
-          indeterminate={indeterminate}
-          onChange={(e) => onCheckAllChange(e.target.checked)}
-          checked={checkAll}
-        >
-          全选
-        </Checkbox>
-
-        <div className="A1DownMainC">
-          {checkedList.map((v) => (
-            <div className="A1DownMainCRow" key={v.id} title={v.label}>
-              <Checkbox
-                onChange={(e) => onChange(e.target.checked, v.id)}
-                checked={v.done}
-              >
-                {v.label}
-              </Checkbox>
-            </div>
-          ))}
-        </div>
+        {checkedList.length ? (
+          <>
+            <h3>请选择下载的项目文件类型</h3>
+            <Checkbox
+              indeterminate={indeterminate}
+              onChange={(e) => onCheckAllChange(e.target.checked)}
+              checked={checkAll}
+            >
+              全选
+            </Checkbox>
+          </>
+        ) : null}
+
+        {checkedList.length ? (
+          <div className="A1DownMainC">
+            {checkedList.map((v) => (
+              <div className="A1DownMainCRow" key={v.id} title={v.label}>
+                <Checkbox
+                  onChange={(e) => onChange(e.target.checked, v.id)}
+                  checked={v.done}
+                >
+                  {v.label}
+                </Checkbox>
+              </div>
+            ))}
+          </div>
+        ) : (
+          <>
+            <br />
+            <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
+          </>
+        )}
 
         <div className="A1DownBtn">
-          <div className="A1DownBtn1">
-            <Button>保存设置</Button>
-          </div>
+          {checkedList.length ? (
+            <div className="A1DownBtn1" onClick={clickStoreFu}>
+              <Button disabled={checkedList.filter((v) => v.done).length < 1}>
+                保存设置
+              </Button>
+            </div>
+          ) : (
+            <span></span>
+          )}
 
           <div className="A1DownBtn2">
             <Button onClick={closeFu}>取消</Button>
@@ -101,7 +155,7 @@ function A1Down({ id, closeFu }: Props) {
             <Button
               type="primary"
               onClick={btnOkFu}
-              disabled={checkedList.length < 1}
+              disabled={checkedList.filter((v) => v.done).length < 1}
             >
               提交
             </Button>

+ 1 - 1
src/pages/A1Project/A1Look/index.tsx

@@ -105,7 +105,7 @@ function A1Look({ pageType, closeFu, tabType, lookTit, editTopFu }: Props) {
             editFu={(val) => editSuFu(val)}
           />
         ) : topType === 2 ? (
-          <A1Outer id={pageType.id} />
+          <A1Outer projectId={pageType.id} />
         ) : null}
       </div>
     </div>

+ 28 - 17
src/pages/A1Project/A1Outer/A1OMove/index.tsx

@@ -1,31 +1,38 @@
 import React, { useCallback, useEffect, useState } from "react";
 import styles from "./index.module.scss";
 import { Button, Modal, Popconfirm } from "antd";
-import { leftTabArr } from "..";
 import classNames from "classnames";
 import { MessageFu } from "@/utils/message";
+import { useSelector } from "react-redux";
+import { RootState } from "@/store";
+import { A1OFileType } from "@/types";
+
+type Props = {
+  mId: { id: number; name: string };
+  id1: { id: number; name: string };
+  id2: { id: number; name: string };
+  closeFu: () => void;
+};
 
 const towTableArr = [
   {
     id: 2,
     name: "asdasd",
-    type: "文件夹",
+    type: 1,
   },
   {
     id: 22,
     name: "sadsssscxxxx",
-    type: "文件",
+    type: 0,
   },
-];
-
-type Props = {
-  mId: { id: number; name: string };
-  id1: { id: number; name: string };
-  id2: { id: number; name: string };
-  closeFu: () => void;
-};
+] as A1OFileType[];
 
 function A1OMove({ mId, id1, id2, closeFu }: Props) {
+  // 从仓库获取左侧写死列表
+  const A1OleftArr = useSelector(
+    (state: RootState) => state.A1Project.A1OleftArr
+  );
+
   // 一级id
   const [tab1, setTab1] = useState({ id: 0, name: "" });
 
@@ -33,7 +40,11 @@ function A1OMove({ mId, id1, id2, closeFu }: Props) {
   const [tab2, setTab2] = useState({ id: 0, name: "" });
 
   // 表格数据
-  const [tableInfo, setTableInfo] = useState(leftTabArr);
+  const [tableInfo, setTableInfo] = useState([] as A1OFileType[]);
+
+  useEffect(() => {
+    setTableInfo(A1OleftArr);
+  }, [A1OleftArr]);
 
   // 封装发送请求的函数
   const getListFu = useCallback((id: number) => {
@@ -44,8 +55,8 @@ function A1OMove({ mId, id1, id2, closeFu }: Props) {
 
   // 选中文件夹
   const cutFileFu = useCallback(
-    (id: number, name: string, type?: string) => {
-      if (type === "文件夹") {
+    (id: number, name: string, type?: 0|1) => {
+      if (type === 1) {
         if (tab1.id) {
           // 第二级
 
@@ -75,10 +86,10 @@ function A1OMove({ mId, id1, id2, closeFu }: Props) {
 
   // 面包屑的根目录
   const mianB1Fu = useCallback(() => {
-    setTableInfo(leftTabArr);
+    setTableInfo(A1OleftArr);
     setTab1({ id: 0, name: "" });
     setTab2({ id: 0, name: "" });
-  }, []);
+  }, [A1OleftArr]);
 
   const mianB2Fu = useCallback(() => {
     if (tab2.id) {
@@ -138,7 +149,7 @@ function A1OMove({ mId, id1, id2, closeFu }: Props) {
             <div
               className={classNames(
                 "A1OMArrRow",
-                v.type === "文件夹" ? "A1OMArrRowAc" : ""
+                v.type === 1 ? "A1OMArrRowAc" : ""
               )}
               key={v.id}
               onClick={() => cutFileFu(v.id, v.name, v.type)}

+ 43 - 16
src/pages/A1Project/A1Outer/A1ORenFile/index.tsx

@@ -2,26 +2,27 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
 import styles from "./index.module.scss";
 import { Button, Input, Modal, Popconfirm } from "antd";
 import { MessageFu } from "@/utils/message";
+import { A2_APIOadd } from "@/store/action/A1Project";
+import { A1OFileType } from "@/types";
 
 type Props = {
   closeFu: () => void;
-  fileInfo: {
-    id: number;
-    fileName: string;
-    type: string;
-  };
+  addFu: () => void;
+  editFu: () => void;
+  fileInfo: A1OFileType;
+  projectId: number;
 };
 
-function A1ORenFile({ closeFu, fileInfo }: Props) {
+function A1ORenFile({ closeFu, fileInfo, addFu, editFu, projectId }: Props) {
   const [value, setValue] = useState("");
 
   useEffect(() => {
-    if (fileInfo.id > 0 && fileInfo.type === "文件") {
-      const arr = fileInfo.fileName.split(".");
+    if (fileInfo.id > 0 && fileInfo.type === 0) {
+      const arr = fileInfo.name.split(".");
       const val = "." + arr[arr.length - 1];
-      const val2 = fileInfo.fileName.replace(val, "");
+      const val2 = fileInfo.name.replace(val, "");
       setValue(val2);
-    } else setValue(fileInfo.fileName);
+    } else setValue(fileInfo.name);
   }, [fileInfo]);
 
   const onChangeFu = useCallback((val: string) => {
@@ -30,19 +31,45 @@ function A1ORenFile({ closeFu, fileInfo }: Props) {
 
   const isFileType = useMemo(() => {
     let val = "";
-    if (fileInfo.type === "文件" && fileInfo.fileName) {
-      const arr = fileInfo.fileName.split(".");
+    if (fileInfo.type === 0 && fileInfo.name) {
+      const arr = fileInfo.name.split(".");
       val = arr[arr.length - 1];
     }
     return val;
   }, [fileInfo]);
 
   // 点击确定
-  const btnOkFu = useCallback(() => {
+  const btnOkFu = useCallback(async () => {
     if (!value) return MessageFu.warning("名称不能为空!");
 
-    console.log("--------点击确定", value);
-  }, [value]);
+    const obj = {
+      id: fileInfo.id === -1 ? null : fileInfo.id,
+      name: value,
+      parentId: fileInfo.parentId,
+      projectId,
+    };
+
+    const res = await A2_APIOadd(obj);
+
+    if (res.code === 0) {
+      if (fileInfo.id === -1) {
+        MessageFu.success("新增成功!");
+        addFu();
+      } else {
+        MessageFu.success("重命名成功!");
+        editFu();
+      }
+      closeFu();
+    }
+  }, [
+    addFu,
+    closeFu,
+    editFu,
+    fileInfo.id,
+    fileInfo.parentId,
+    projectId,
+    value,
+  ]);
 
   return (
     <Modal
@@ -52,7 +79,7 @@ function A1ORenFile({ closeFu, fileInfo }: Props) {
       title={
         fileInfo.id === -1
           ? "新建文件夹"
-          : fileInfo.type === "文件夹"
+          : fileInfo.type === 1
           ? "文件夹重命名"
           : "文件重命名"
       }

+ 93 - 0
src/pages/A1Project/A1Outer/A1OupFile/index.module.scss

@@ -0,0 +1,93 @@
+.A1OupFile {
+  :global {
+
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      width: 800px !important;
+    }
+
+    .A1OMain {
+      padding: 15px 40px 0;
+      margin-top: 10px;
+      border-top: 1px solid #999999;
+      position: relative;
+      height: 500px;
+      overflow-y: auto;
+
+      .ant-upload-drag {
+        height: 160px;
+      }
+
+      .ant-upload-list-item-container {
+        transition: none !important;
+      }
+
+      .ant-upload-list-item-action {
+        // display: none !important;
+        opacity: 1 !important;
+      }
+
+      .ant-upload-list-item-actions .anticon {
+        color: #ff4d4f !important;
+      }
+
+      .ant-upload-list-item-name {
+        width: calc(100% - 90px) !important;
+        transition: none !important;
+        flex: none !important;
+        margin-right: 50px;
+      }
+
+      .myIncoBox {
+        position: absolute;
+        right: 74px;
+        top: 175px;
+
+        .myIncoRow {
+          height: 30px;
+          line-height: 40px;
+          font-size: 14px;
+          display: flex;
+          justify-content: flex-end;
+          position: relative;
+
+          &>div {
+            cursor: pointer;
+            margin-left: 12px;
+
+            a {
+              position: relative;
+              top: -1px;
+              color: #333;
+            }
+          }
+
+          .mySortQ {
+            cursor: default;
+            position: absolute;
+            z-index: 15;
+            right: 470px;
+            top: -1px;
+            font-size: 12px;
+            height: 30px;
+
+          }
+        }
+      }
+
+    }
+
+    .A1OUpBtn {
+      padding-top: 20px;
+      text-align: center;
+    }
+
+    // .ant-upload-list-item-done{
+    //   justify-content: space-between !important;
+    // }
+
+  }
+}

+ 249 - 0
src/pages/A1Project/A1Outer/A1OupFile/index.tsx

@@ -0,0 +1,249 @@
+import { useCallback, useRef, useState } from "react";
+import styles from "./index.module.scss";
+
+import { InboxOutlined } from "@ant-design/icons";
+import {
+  Button,
+  message,
+  Modal,
+  Popconfirm,
+  Upload,
+  UploadFile,
+  UploadProps,
+} from "antd";
+
+import { EyeOutlined, DownloadOutlined } from "@ant-design/icons";
+
+import history from "@/utils/history";
+import React from "react";
+import { getTokenFu } from "@/utils/storage";
+import filesLookFu from "@/utils/filesLook";
+import { MessageFu } from "@/utils/message";
+import { baseURL } from "@/utils/http";
+
+const { Dragger } = Upload;
+
+type props = {
+  myUrl: string;
+  fromData: any;
+  nowLoc: string;
+  closeFu: () => void;
+};
+
+function A1OupFile({ myUrl, fromData, nowLoc, closeFu }: props) {
+  const [modal, contextHolder] = Modal.useModal();
+
+  const [fileList, setFileList] = useState<UploadFile[]>([]);
+
+  const timeRef = useRef(-1);
+
+  const FileProps: UploadProps = {
+    name: "file",
+    multiple: true,
+    action: myUrl,
+    headers: {
+      token: getTokenFu(),
+    },
+    // 支持上传文件夹
+    directory: true,
+    data: fromData,
+    fileList,
+    //不要前面的图标
+    // iconRender: () => false,
+    // 文件上传之前 -- 这里不用校验
+    // beforeUpload(file, fileList) {
+    //   // console.log("文件上传之前-用于校验", file);
+    //   // if (file.name.includes("4dage")) {
+    //   //   // console.log("校验不通过,不上传");
+    //   //   message.error(`${file.name}不符合上传需求`);
+    //   //   return Upload.LIST_IGNORE;
+    //   // }
+    // },
+    onChange(info) {
+      setFileList([...info.fileList]);
+
+      const { status } = info.file;
+      if (status !== "uploading") {
+        // 检查请求状态
+        const response = info.file.response || {};
+
+        if (response.code !== 0) {
+          clearTimeout(timeRef.current);
+
+          timeRef.current = window.setTimeout(() => {
+            setFileList(info.fileList.filter((v) => v.uid !== info.file.uid));
+          }, 100);
+        }
+        if (response.code === 5001 || response.code === 5002) {
+          message.warning("登录失效!");
+          history.push("/login");
+          return false;
+        }
+
+        // console.log(info.file, info.fileList);
+      }
+      if (status === "done") {
+        console.log(info, "上传成功");
+
+        // message.success(`${info.file.name} 上传成功.`);
+      } else if (status === "error") {
+        message.error(`${info.file.name} 上传失败.`);
+        // 去掉列表中的失败状态文件
+        clearTimeout(timeRef.current);
+
+        timeRef.current = window.setTimeout(() => {
+          setFileList(info.fileList.filter((v) => v.uid !== info.file.uid));
+        }, 100);
+      }
+    },
+    // onDrop(e) {
+    //   // console.log("拖动文件到上传区域", e.dataTransfer.files);
+    // },
+    // 点击删除
+    async onRemove(info) {
+      const promiseFu = new Promise((resolve: (value: boolean) => void) => {
+        modal.confirm({
+          title: "操作确认",
+          content: "是否确认删除?",
+          okText: "确定",
+          cancelText: "取消",
+          onOk() {
+            console.log("-----", info);
+            if (info.percent === 100) {
+              // 已经上传完成,发请求删除
+            }
+
+            MessageFu.success("删除成功!");
+
+            resolve(true);
+          },
+          onCancel() {
+            resolve(false);
+          },
+        });
+      });
+      return await promiseFu;
+    },
+
+    // 修复版本报错问题
+    // Warning: [antd: Progress] `strokeWidth` is deprecated. Please use `size` instead.
+    // progress: {
+    //   strokeColor: {
+    //     "0%": "#108ee9",
+    //     "100%": "#87d068",
+    //   },
+    //   size: 3,
+    //   format: (percent) => percent && `${parseFloat(percent.toFixed(2))}%`,
+    // },
+  };
+
+  // 点击确定
+  const btnOkFu = useCallback(() => {
+    console.log("-----", fileList);
+
+    // 拿到 后端返回 的 id列表
+    const ids = [] as Number[];
+
+    if (fileList.some((v) => v.percent !== 100))
+      return message.warning("有文件未上传完成.");
+
+    // fileList.forEach((v) => {
+    //   // 看下是否全部传输完成
+    //   if (v.percent !== 100) return message.warning("有文件未上传完成.");
+
+    //   ids.push(v.response.data.id);
+    // });
+    // console.log("点击确定", ids.join(","));
+
+    return ids.join(",");
+  }, [fileList]);
+
+  return (
+    <Modal
+      wrapClassName={styles.A1OupFile}
+      destroyOnClose
+      open={true}
+      title={"上传文件 - " + nowLoc}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className="A1OMain">
+        <Dragger {...FileProps}>
+          <p className="ant-upload-drag-icon">
+            <InboxOutlined rev={undefined} />
+          </p>
+          <br />
+          <p className="ant-upload-text">
+            点击上传整个文件夹,或拖动多个文件至此上传
+          </p>
+        </Dragger>
+        {/* 自定义 预览 下载 删除 */}
+        <div className="myIncoBox">
+          {fileList.map((v) => (
+            <div className="myIncoRow" key={v.uid}>
+              {v.percent === 100 && v.response && v.response.data ? (
+                <>
+                  {filesLookFu(v.response.data.name) ? (
+                    <>
+                      {/* // 1.预览(name里面有常用的,浏览器能识别的 图片 音频 视频 模型) */}
+                      <div title="预览文件">
+                        <EyeOutlined
+                          rev={undefined}
+                          onClick={() =>
+                            filesLookFu(
+                              v.response.data.name,
+                              v.response.data.filePath
+                            )
+                          }
+                        />
+                      </div>
+                    </>
+                  ) : null}
+                  {/* // 2.下载 */}
+                  <div title="下载文件">
+                    <a
+                      href={baseURL + v.response.data.filePath}
+                      target="blank"
+                      download
+                    >
+                      <DownloadOutlined rev={undefined} />
+                    </a>
+                  </div>
+                </>
+              ) : (
+                ""
+              )}
+
+              {/* 3.前面的序号 */}
+              {/* <div className="mySortQ" hidden={fileList.length <= 1}>
+                {i + 1}.
+              </div> */}
+            </div>
+          ))}
+        </div>
+      </div>
+
+      <div className="A1OUpBtn">
+        <Popconfirm
+          title="放弃编辑后,信息将不会保存!"
+          okText="放弃"
+          cancelText="取消"
+          onConfirm={closeFu}
+          okButtonProps={{ loading: false }}
+        >
+          <Button>取消</Button>
+        </Popconfirm>
+        &emsp;
+        <Button type="primary" onClick={btnOkFu}>
+          确定
+        </Button>
+      </div>
+
+      {contextHolder}
+    </Modal>
+  );
+}
+
+const MemoA1OupFile = React.memo(A1OupFile);
+export default MemoA1OupFile;

+ 145 - 162
src/pages/A1Project/A1Outer/index.tsx

@@ -12,53 +12,45 @@ import { baseURL } from "@/utils/http";
 import filesLookFu from "@/utils/filesLook";
 import A1ORenFile from "./A1ORenFile";
 import A1OMove from "./A1OMove";
-
-export const leftTabArr:{
-  id: number;
-  type?: string;
-  name: string;
-}[] = [
-  { id: 1, type: "文件夹", name: "重要文档-已盖章" },
-  { id: 2, type: "文件夹", name: "重要文档-未盖章" },
-  { id: 3, type: "文件夹", name: "其他过程文件" },
-];
-
-const towTableArr = [
-  {
-    id: 2,
-    b: "第二级",
-    fileName: "899845646.pdf",
-    type: "文件",
-  },
-  {
-    id: 22,
-    b: "第二级2222",
-    fileName: "899845646杀杀杀.pdf",
-    type: "文件",
-  },
-];
+import { A1OFileType } from "@/types";
+import { useDispatch, useSelector } from "react-redux";
+import { RootState } from "@/store";
+import {
+  A1_APIOgetList,
+  A2_APIOdel,
+  A2_APIOdownload,
+} from "@/store/action/A1Project";
+import { MessageFu } from "@/utils/message";
+import A1OupFile from "./A1OupFile";
 
 type Props = {
-  id: number;
+  projectId: number;
 };
 
-function A1Outer({ id }: Props) {
+function A1Outer({ projectId }: Props) {
+  const dispatch = useDispatch();
+
+  // 从仓库获取左侧写死列表 和 展示列表
+  const { A1OleftArr, A1OtableInfo } = useSelector(
+    (state: RootState) => state.A1Project
+  );
+
   const [fromData, setFromData] = useState({
-    id: 1,
-    aaaa: "",
+    parentId: 1,
+    searchKey: "",
     pageNum: 1,
     pageSize: 10,
   });
 
   // 文件名的输入
-  const aaaaTime = useRef(-1);
-  const aaaaChange = useCallback(
+  const searchKeyTime = useRef(-1);
+  const searchKeyChange = useCallback(
     (e: React.ChangeEvent<HTMLInputElement>) => {
-      clearTimeout(aaaaTime.current);
-      aaaaTime.current = window.setTimeout(() => {
+      clearTimeout(searchKeyTime.current);
+      searchKeyTime.current = window.setTimeout(() => {
         setFromData({
           ...fromData,
-          aaaa: e.target.value,
+          searchKey: e.target.value,
           pageNum: 1,
         });
       }, 500);
@@ -68,37 +60,21 @@ function A1Outer({ id }: Props) {
 
   // 封装发送请求的函数
   const getListFu = useCallback(() => {
-    console.log("tab2发送请求", fromData);
-
+    dispatch(A1_APIOgetList({ ...fromData, projectId }));
     // 清空选中
     setSelectedRowKeys([]);
-
-    setTableInfo({
-      list: [
-        {
-          id: 11,
-          c: "2020-02-02 12:34:56",
-          type: "文件夹",
-          fileName: "一个文件夹",
-          filePath: "xxx",
-        },
-        {
-          id: 2,
-          b: "阿三大苏打阿三大苏打",
-          fileName: "899845646.pdf",
-          type: "文件",
-        },
-      ],
-      total: 200,
-    });
-  }, [fromData]);
+  }, [dispatch, fromData, projectId]);
 
   useEffect(() => {
     getListFu();
   }, [getListFu]);
 
   // 一级的高亮
-  const [tab1, setTab1] = useState(leftTabArr[0]);
+  const [tab1, setTab1] = useState({} as A1OFileType);
+
+  useEffect(() => {
+    setTab1(A1OleftArr[0]);
+  }, [A1OleftArr]);
 
   // 二级的选择
   const [tab2, setTab2] = useState({ id: 0, name: "" });
@@ -107,109 +83,116 @@ function A1Outer({ id }: Props) {
   const cutTab1Fu = useCallback(
     (id: number, name: string) => {
       setTab2({ id: 0, name: "" });
-      setTab1({ id, name });
+      setTab1({ id, name } as A1OFileType);
 
-      if (id !== fromData.id) setFromData({ ...fromData, id, pageNum: 1 });
+      if (id !== fromData.parentId)
+        setFromData({ ...fromData, parentId: id, pageNum: 1 });
     },
     [fromData]
   );
 
-  // 点击表格里面的删除
-  const delById = useCallback((id: number) => {
-    console.log("---点击删除");
-  }, []);
-
-  // 点击表格里面的 文件夹 的下载
-  const downFilesFu = useCallback((id: number) => {
-    console.log("ssss,点击文件夹的下载");
-  }, []);
-
   // 点击表格里面的 文件夹 进入 2级
   const toTowFilesFu = useCallback(
-    (id: number, type: string, name: string) => {
-      if (type === "文件夹") {
+    (id: number, type: 0 | 1, name: string) => {
+      if (type === 1) {
         setTab2({ id, name });
-        setFromData({ ...fromData, id, pageNum: 1 });
-
-        // 后面调试接口的时候 删掉
-        setTimeout(() => {
-          setTableInfo({ list: towTableArr, total: 200 });
-        }, 200);
+        setFromData({ ...fromData, parentId: id, pageNum: 1 });
       }
     },
     [fromData]
   );
 
-  // 表格数据
-  const [tableInfo, setTableInfo] = useState({
-    list: [
-      {
-        id: 11,
-        c: "2020-02-02 12:34:56",
-        type: "文件夹",
-        fileName: "一个文件夹",
-        filePath: "xxx",
-      },
-      {
-        id: 2,
-        b: "阿三大苏打阿三大苏打",
-        fileName: "899845646.pdf",
-        type: "文件",
-      },
-    ],
-    total: 2,
-  });
+  // 页码变化
+  const paginationChange = useCallback(
+    () => (pageNum: number, pageSize: number) => {
+      setFromData({ ...fromData, pageNum, pageSize });
+    },
+    [fromData]
+  );
+
+  // 关于表格的多选
+  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
+
+  // 新建文件夹或者 重命名
+  const [renFile, setRenFile] = useState({} as A1OFileType);
+
+  // 点击移动之后出来的数据
+  const [moveId, setMoveId] = useState({ id: 0, name: "" });
+
+  // 点击表格里面的删除
+  const delById = useCallback(
+    async (id: number) => {
+      const res = await A2_APIOdel(id);
+      if (res.code === 0) {
+        MessageFu.success("删除成功!");
+        getListFu();
+      }
+    },
+    [getListFu]
+  );
+
+  // 点击表格里面的 文件夹 的下载
+  const downFilesFu = useCallback((id: number) => {
+    console.log("ssss,点击文件夹的下载", id);
+  }, []);
+
+  // 点击批量下载
+  const downSelectFu = useCallback(async () => {
+    const res = await A2_APIOdownload(selectedRowKeys.join(","));
+    if (res.code === 0) {
+      console.log("批量下载", res);
+    }
+  }, [selectedRowKeys]);
+
+  // 点击-批量上传
+  const [upFileId, setUpFileId] = useState(0);
 
   const columns = useMemo(() => {
     return [
       {
         title: "文件名",
-        render: (item: any) =>
-          item.fileName.length >= 30 ? (
-            <span style={{ cursor: "pointer" }} title={item.fileName}>
+        render: (item: A1OFileType) =>
+          item.name.length >= 30 ? (
+            <span style={{ cursor: "pointer" }} title={item.name}>
               <span
-                onClick={() => toTowFilesFu(item.id, item.type, item.fileName)}
-                className={classNames(
-                  item.type === "文件夹" ? "A1OfilesTable" : ""
-                )}
+                onClick={() => toTowFilesFu(item.id, item.type, item.name)}
+                className={classNames(item.type === 1 ? "A1OfilesTable" : "")}
               >
-                {item.fileName.substring(0, 30) + "..."}
+                {item.name.substring(0, 30) + "..."}
               </span>
             </span>
           ) : (
             <span
-              onClick={() => toTowFilesFu(item.id, item.type, item.fileName)}
-              className={classNames(
-                item.type === "文件夹" ? "A1OfilesTable" : ""
-              )}
+              onClick={() => toTowFilesFu(item.id, item.type, item.name)}
+              className={classNames(item.type === 1 ? "A1OfilesTable" : "")}
             >
-              {item.fileName}
+              {item.name}
             </span>
           ),
       },
       {
         title: "创建用户",
-        dataIndex: "b",
+        dataIndex: "creatorName",
       },
       {
         title: "创建时间",
-        dataIndex: "c",
+        dataIndex: "createTime",
       },
       {
         title: "操作",
-        render: (item: any) => (
+        render: (item: A1OFileType) => (
           <>
-            {filesLookFu(item.fileName) ? (
+            {filesLookFu(item.name) ? (
               <Button
                 size="small"
                 type="text"
-                onClick={() => filesLookFu(item.fileName, item.filePath)}
+                onClick={() => filesLookFu(item.name, item.filePath)}
               >
                 查看
               </Button>
             ) : null}
 
-            {item.type === "文件夹" ? (
+            {item.type === 1 ? (
               <Button
                 size="small"
                 type="text"
@@ -220,7 +203,7 @@ function A1Outer({ id }: Props) {
             ) : (
               <a
                 href={baseURL + item.filePath}
-                download={item.fileName}
+                download={item.name}
                 target="_blank"
                 rel="noreferrer"
               >
@@ -230,24 +213,14 @@ function A1Outer({ id }: Props) {
               </a>
             )}
 
-            <Button
-              size="small"
-              type="text"
-              onClick={() =>
-                setRenFile({
-                  id: item.id,
-                  fileName: item.fileName,
-                  type: item.type,
-                })
-              }
-            >
+            <Button size="small" type="text" onClick={() => setRenFile(item)}>
               重命名
             </Button>
-            {item.type === "文件夹" ? null : (
+            {item.type === 1 ? null : (
               <Button
                 size="small"
                 type="text"
-                onClick={() => setMoveId({ id: item.id, name: item.fileName })}
+                onClick={() => setMoveId({ id: item.id, name: item.name })}
               >
                 移动
               </Button>
@@ -270,26 +243,10 @@ function A1Outer({ id }: Props) {
     ];
   }, [delById, downFilesFu, toTowFilesFu]);
 
-  // 页码变化
-  const paginationChange = useCallback(
-    () => (pageNum: number, pageSize: number) => {
-      setFromData({ ...fromData, pageNum, pageSize });
-    },
-    [fromData]
-  );
-
-  // 关于表格的多选
-  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
-
-  // 新建文件夹或者 重命名
-  const [renFile, setRenFile] = useState({
-    id: 0,
-    fileName: "",
-    type: "",
-  });
-
-  // 点击移动之后出来的数据
-  const [moveId, setMoveId] = useState({ id: 0, name: "" });
+  // 当前位置
+  const nowLoc = useMemo(() => {
+    return tab1.name + (tab2.id ? ` / ${tab2.name}` : "");
+  }, [tab1.name, tab2.id, tab2.name]);
 
   return (
     <div className={styles.A1Outer}>
@@ -301,13 +258,10 @@ function A1Outer({ id }: Props) {
             style={{ width: 300 }}
             placeholder="请输入文件名称,最多30字"
             allowClear
-            onChange={(e) => aaaaChange(e)}
+            onChange={(e) => searchKeyChange(e)}
           />
           &emsp;&emsp;
-          <span className="A1OnowLoc">
-            <span>当前位置:{tab1.name}</span>
-            {tab2.id ? <> / {tab2.name}</> : null}
-          </span>
+          <span className="A1OnowLoc">当前位置:{nowLoc}</span>
         </div>
         <div className="A1Otop2">
           {tab2.id ? null : (
@@ -315,7 +269,12 @@ function A1Outer({ id }: Props) {
               <Button
                 type="primary"
                 onClick={() =>
-                  setRenFile({ id: -1, fileName: "", type: "文件夹" })
+                  setRenFile({
+                    id: -1,
+                    name: "",
+                    type: 1,
+                    parentId: tab1.id,
+                  } as A1OFileType)
                 }
               >
                 新建文件夹
@@ -323,18 +282,28 @@ function A1Outer({ id }: Props) {
               &emsp;
             </>
           )}
-          <Button type="primary" disabled={selectedRowKeys.length <= 0}>
+          <Button
+            type="primary"
+            onClick={downSelectFu}
+            disabled={selectedRowKeys.length <= 0}
+          >
             批量下载
           </Button>
           &emsp;
-          <Button type="primary">批量上传</Button>&emsp;
+          <Button
+            type="primary"
+            onClick={() => setUpFileId(tab2.id ? tab2.id : tab1.id)}
+          >
+            批量上传
+          </Button>
+          &emsp;
         </div>
       </div>
       {/* 表格主体 */}
       <div className="A1OtableBox">
         <div className="A1OtableBox1">
           <div className="A1OtableBox1_1">目录</div>
-          {leftTabArr.map((v) => (
+          {A1OleftArr.map((v) => (
             <div
               onClick={() => cutTab1Fu(v.id, v.name)}
               className={classNames(
@@ -353,12 +322,11 @@ function A1Outer({ id }: Props) {
               type: "checkbox",
               selectedRowKeys,
               onChange: (selectedRowKeys: React.Key[]) => {
-                console.log("选中的ids", selectedRowKeys);
                 setSelectedRowKeys(selectedRowKeys);
               },
             }}
             scroll={{ y: 560 }}
-            dataSource={tableInfo.list}
+            dataSource={A1OtableInfo.list}
             columns={columns}
             rowKey="id"
             pagination={{
@@ -367,7 +335,7 @@ function A1Outer({ id }: Props) {
               showSizeChanger: true,
               current: fromData.pageNum,
               pageSize: fromData.pageSize,
-              total: tableInfo.total,
+              total: A1OtableInfo.total,
               onChange: paginationChange(),
             }}
           />
@@ -376,8 +344,13 @@ function A1Outer({ id }: Props) {
       {/* 点击 新建 文件夹 或者 重命名 */}
       {renFile.id ? (
         <A1ORenFile
-          closeFu={() => setRenFile({ id: 0, fileName: "", type: "" })}
+          addFu={() => setFromData({ ...fromData, searchKey: "", pageNum: 1 })}
+          editFu={() => getListFu()}
+          closeFu={() =>
+            setRenFile({ id: 0, name: "", type: 0 } as A1OFileType)
+          }
           fileInfo={renFile}
+          projectId={projectId}
         />
       ) : null}
 
@@ -390,6 +363,16 @@ function A1Outer({ id }: Props) {
           closeFu={() => setMoveId({ id: 0, name: "" })}
         />
       ) : null}
+
+      {/* 点击批量上传 */}
+      {upFileId ? (
+        <A1OupFile
+          myUrl={baseURL + "cms/item/upload"}
+          fromData={{ parentId: upFileId, projectId }}
+          nowLoc={nowLoc}
+          closeFu={() => setUpFileId(0)}
+        />
+      ) : null}
     </div>
   );
 }

+ 29 - 19
src/pages/A1Project/index.tsx

@@ -170,7 +170,7 @@ function A1Project() {
   );
 
   // 点击下载
-  const [downId, setDownId] = useState(0);
+  const [downId, setDownId] = useState({ id: 0, txt: "" });
 
   // 点击审批
   const lookTabType = useRef(false);
@@ -269,25 +269,33 @@ function A1Project() {
             查看
           </Button>
           {topType === "inner" ? (
-            <Button
-              size="small"
-              type="text"
-              onClick={() => {
-                lookTabType.current = true;
-                setPageType({
-                  txt: "look",
-                  id: item.id,
-                  tit: item.num + " - " + item.name,
-                });
-              }}
-            >
-              审批
-            </Button>
+            <>
+              <Button
+                size="small"
+                type="text"
+                onClick={() => {
+                  lookTabType.current = true;
+                  setPageType({
+                    txt: "look",
+                    id: item.id,
+                    tit: item.num + " - " + item.name,
+                  });
+                }}
+              >
+                审批
+              </Button>
+              <Button
+                size="small"
+                type="text"
+                onClick={() =>
+                  setDownId({ id: item.id, txt: item.num + " - " + item.name })
+                }
+              >
+                下载
+              </Button>
+            </>
           ) : null}
 
-          <Button size="small" type="text" onClick={() => setDownId(item.id)}>
-            下载
-          </Button>
           <Popconfirm
             title="删除后无法恢复,是否删除?"
             okText="删除"
@@ -499,7 +507,9 @@ function A1Project() {
       ) : null}
 
       {/* 下载 */}
-      {downId ? <A1Down id={downId} closeFu={() => setDownId(0)} /> : null}
+      {downId.id ? (
+        <A1Down downId={downId} closeFu={() => setDownId({ id: 0, txt: "" })} />
+      ) : null}
     </div>
   );
 }

+ 8 - 3
src/pages/Layout/index.tsx

@@ -27,12 +27,13 @@ import NotFound from "@/components/NotFound";
 import tabLeftArr from "./data";
 import { RootState } from "@/store";
 import { RouterType } from "@/types";
+import { A2_APIOgetHardCoded } from "@/store/action/A1Project";
 
 function Layout() {
   const dispatch = useDispatch();
 
   useEffect(() => {
-    // 获取权限信息(整个项目的关于权限的信息)
+    // 获取权限信息(整个项目的关于权限的信息--已过滤)
     dispatch(A4_APIgetRoleAll());
 
     // 进页面获取 部门 列表 信息(给 用户管理、字典管理 项目管理-内控文件下拉框 页面使用)
@@ -40,6 +41,10 @@ function Layout() {
 
     // 获取字典的 -内控文件属性 列表(角色管理 项目管理-内控文件下拉框 页面使用)
     dispatch(A2_APIgetListFile());
+
+    // 获取 项目管理-项目文件-左侧一级写死目录
+    dispatch(A2_APIOgetHardCoded())
+
   }, [dispatch]);
 
   // 左侧菜单 和 路由 信息
@@ -150,10 +155,10 @@ function Layout() {
           <div className="user">
             {userInfo.realName}
             <div className="userInco userInco1">
-              <CaretUpOutlined />
+              <CaretUpOutlined rev={undefined} />
             </div>
             <div className="userInco userInco2">
-              <CaretDownOutlined />
+              <CaretDownOutlined rev={undefined} />
             </div>
             <div className="userSet">
               <div>

+ 2 - 2
src/pages/Login/index.tsx

@@ -59,7 +59,7 @@ export default function Login() {
                 onKeyUp={(e) => keyUpEntFu(e)}
                 value={userName}
                 onChange={(e) => setUserName(e.target.value.trim())}
-                prefix={<UserOutlined />}
+                prefix={<UserOutlined rev={undefined} />}
                 placeholder="请输入账号"
                 maxLength={15}
               />
@@ -69,7 +69,7 @@ export default function Login() {
                 onKeyUp={(e) => keyUpEntFu(e)}
                 value={passWord}
                 onChange={(e) => setPassWord(e.target.value.trim())}
-                prefix={<LockOutlined />}
+                prefix={<LockOutlined rev={undefined} />}
                 placeholder="请输入密码"
                 maxLength={15}
               />

+ 57 - 0
src/store/action/A1Project.ts

@@ -36,3 +36,60 @@ export const A2_APIgetInfoById = (id: number) => {
 export const A2_APIdelProject = (id: number) => {
   return http.get(`cms/project/remove/${id}`);
 };
+
+/**
+ * 通过id删除项目
+ */
+export const A2_APIgetDownList = (id: number) => {
+  return http.get(`cms/inside/download/echoList/${id}`);
+};
+
+// --------------------------  项目文件
+/**
+ * 获取 左侧一级 写死目录
+ */
+export const A2_APIOgetHardCoded = () => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.get("cms/item/getHardCoded");
+    if (res.code === 0) {
+      dispatch({ type: "A1/outLeftArr", payload: res.data });
+    }
+  };
+};
+
+/**
+ * 新增、修改
+ */
+export const A2_APIOadd = (data: any) => {
+  return http.post("cms/item/save", data);
+};
+
+/**
+ * 获取列表
+ */
+export const A1_APIOgetList = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("cms/item/pageList", data);
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total,
+      };
+      dispatch({ type: "A1/outTableArr", payload: obj });
+    }
+  };
+};
+
+/**
+ * 批量下载
+ */
+export const A2_APIOdownload = (ids: string) => {
+  return http.get(`cms/item/download/${ids}`);
+};
+
+/**
+ * 批量下载
+ */
+export const A2_APIOdel = (id: number) => {
+  return http.get(`cms/item/remove/${id}`);
+};

+ 21 - 7
src/store/reducer/A1Project.ts

@@ -1,19 +1,28 @@
-import { A1TableType } from "@/types";
+import { A1OFileType, A1TableType } from "@/types";
 
 // 初始化状态
 const initState = {
   // 列表数据
   tableInfo: {
     list: [] as A1TableType[],
-    total: 2,
+    total: 0 as number,
+  },
+
+  // 项目 文件 -左侧写死列表
+  A1OleftArr: [] as A1OFileType[],
+
+  // 项目文件的表格数据
+  A1OtableInfo: {
+    list: [] as A1OFileType[],
+    total: 0 as number,
   },
 };
 
 // 定义 action 类型
-type Props = {
-  type: "A1/getList";
-  payload: { list: A1TableType[]; total: number };
-};
+type Props =
+  | { type: "A1/getList"; payload: { list: A1TableType[]; total: number } }
+  | { type: "A1/outLeftArr"; payload: A1OFileType[] }
+  | { type: "A1/outTableArr"; payload: { list: A1OFileType[]; total: number } };
 
 // 频道 reducer
 export default function A1Reducer(state = initState, action: Props) {
@@ -21,7 +30,12 @@ export default function A1Reducer(state = initState, action: Props) {
     // 获取列表数据
     case "A1/getList":
       return { ...state, tableInfo: action.payload };
-
+    // 项目 文件 -左侧写死列表
+    case "A1/outLeftArr":
+      return { ...state, A1OleftArr: action.payload };
+    // 项目 文件 -分页列表
+    case "A1/outTableArr":
+      return { ...state, A1OtableInfo: action.payload };
     default:
       return state;
   }

+ 15 - 0
src/types/api/A1Project.d.ts

@@ -18,3 +18,18 @@ export type A1TableType = {
   updateTime: string;
   amount:string
 };
+
+export type A1OFileType ={
+	ancestors: string;
+	createTime: string;
+	creatorId: number;
+	creatorName: string;
+	filePath: string;
+	hasHardCoded: number;
+	id: number;
+	name: string;
+	parentId: number;
+	projectId?: any;
+	type: 0|1;
+	updateTime: string;
+}

+ 6 - 1
src/utils/http.ts

@@ -84,7 +84,12 @@ http.interceptors.response.use(
           MessageFu.warning("取消上传!");
         else MessageFu.error("网络繁忙,请稍后重试!");
       } else {
-        if (err.response && err.response.data && err.response.data.msg)
+        if (
+          err.response &&
+          err.response.data &&
+          err.response.data.msg &&
+          err.response.data.msg.length < 30
+        )
           MessageFu.error(err.response.data.msg);
         else MessageFu.error("响应错误,请联系管理员!");
       }

+ 29 - 4
src/utils/storage.ts

@@ -4,14 +4,14 @@
 const TOKEN_KEY = "SWSDNBWJ_HT_USER_INFO";
 
 /**
- * 从本地缓存中获取 Token 信息
+ * 从本地缓存中获取 用户 信息
  */
 export const getTokenInfo = (): any => {
   return JSON.parse(localStorage.getItem(TOKEN_KEY) || "{}");
 };
 
 /**
- * 将 Token 信息存入缓存
+ * 将 用户 信息存入缓存
  * @param {Object} tokenInfo 从后端获取到的 Token 信息
  */
 export const setTokenInfo = (tokenInfo: any): void => {
@@ -19,7 +19,7 @@ export const setTokenInfo = (tokenInfo: any): void => {
 };
 
 /**
- * 删除本地缓存中的 Token 信息
+ * 删除本地缓存中的 用户 信息
  */
 export const removeTokenInfo = (): void => {
   localStorage.removeItem(TOKEN_KEY);
@@ -32,7 +32,14 @@ export const hasToken = (): boolean => {
   return Boolean(getTokenInfo().token);
 };
 
-// -------------------- 功能权限 的本地存储 --------------------
+/**
+ * 获取本地缓存中是否存在 Token 信息
+ */
+export const getTokenFu = (): string => {
+  return getTokenInfo().token;
+};
+
+// ---------------------------------------- 功能权限 的本地存储 --------------------
 const A4_KEY = "SWSDNBWJ_HT_A4_INFO";
 
 /**
@@ -48,3 +55,21 @@ export const A4getStorage = (): any => {
 export const A4setStorage = (info: any): void => {
   localStorage.setItem(A4_KEY, JSON.stringify(info));
 };
+
+// ---------------------------------------- 项目管理-内控文件视图-下载 的本地存储 --------------------
+
+const A1_DOWN = "SWSDNBWJ_HT_A1_DOWNIDS";
+
+/**
+ * 从本地缓存中获取 项目管理-内控文件-下载 信息
+ */
+export const A1getStorage = (): number[] => {
+  return JSON.parse(localStorage.getItem(A1_DOWN) || "[]");
+};
+
+/**
+ *  项目管理-内控文件-下载 信息 存入本地缓存
+ */
+export const A1setStorage = (info: any): void => {
+  localStorage.setItem(A1_DOWN, JSON.stringify(info));
+};