Selaa lähdekoodia

修改文档管理

Renxy 2 vuotta sitten
vanhempi
commit
becbee44ee

+ 19 - 13
.umirc.ts

@@ -11,8 +11,14 @@ export default defineConfig({
     title: '金科环境数字化管理平台',
     locale: false,
   },
-  title: "金科环境数字化管理平台",
+  title: '金科环境数字化管理平台',
   proxy: {
+    '/api/v1/oa': {
+      // target: 'http://47.96.12.136:8788/',
+      target: 'http://47.96.12.136:8896/',
+      // target: 'http://120.55.44.4:8900/',
+      changeOrigin: true,
+    },
     '/api': {
       // target: 'http://47.96.12.136:8788/',
       target: 'http://47.96.12.136:8888/',
@@ -127,23 +133,23 @@ export default defineConfig({
     {
       name: '个人中心',
       path: '/profile',
-      routes:[
+      routes: [
         {
-          name:'我的申请',
-          path:'/profile/apply',
-          component:'./Profile/apply'
+          name: '我的申请',
+          path: '/profile/apply',
+          component: './Profile/apply',
         },
         {
-          name:'我的审批',
-          path:'/profile/approve',
-          component:'./Profile/approve'
+          name: '我的审批',
+          path: '/profile/approve',
+          component: './Profile/approve',
         },
         {
-          name:'已审核',
-          path:'/profile/approved',
-          component:'./Profile/approved'
-        }
-      ]
+          name: '已审核',
+          path: '/profile/approved',
+          component: './Profile/approved',
+        },
+      ],
       // component: './Profile/index',
       // hideInMenu: true,
     },

+ 3 - 3
package.json

@@ -2,11 +2,11 @@
   "private": true,
   "author": "xjj <645007605@qq.com>",
   "scripts": {
-    "dev": "max dev",
     "build": "max build",
+    "dev": "max dev",
     "format": "prettier --cache --write .",
-    "prepare": "husky install",
     "postinstall": "max setup",
+    "prepare": "husky install",
     "setup": "max setup",
     "start": "npm run dev"
   },
@@ -20,7 +20,7 @@
     "moment": "^2.29.4",
     "qs": "^6.11.1",
     "react-file-viewer": "^1.2.1",
-    "react-zmage": "^0.8.5-beta.37",
+    "react-zmage": "^0.8.5-beta.36",
     "umi-request": "^1.4.0"
   },
   "devDependencies": {

+ 81 - 0
src/components/FileViewerNew/index.js

@@ -0,0 +1,81 @@
+import React, { useState, useEffect } from 'react';
+import FileViewer from 'react-file-viewer';
+import { Modal, Table } from 'antd';
+
+const FileViewerModal = ({ data, visible, onCancel, downloadFile }) => {
+  const [img, setImg] = useState();
+  useEffect(() => {
+    if (!visible) setImg(null);
+  }, [visible]);
+  const renderContent = (data) => {
+    if (data?.type == 'xlsx') {
+      return (
+        <div>
+          不支持的文件格式点击<a onClick={() => downloadFile(data)}>下载</a>
+        </div>
+      );
+    } else if (data?.url) {
+      return (
+        <FileViewer
+          key={data?.name}
+          fileType={data?.type}
+          filePath={data?.url}
+          onError={() => downloadFile(data)}
+          errorComponent={() => (
+            <div>
+              文件加载错误点击<a onClick={() => downloadFile(data)}>下载</a>
+            </div>
+          )}
+          unsupportedComponent={() => (
+            <div>
+              不支持的文件格式点击<a onClick={() => downloadFile(data)}>下载</a>
+            </div>
+          )}
+        />
+      );
+    }
+  };
+
+  const renderListContent = () => {
+    const columns = [
+      { title: '文档名称', dataIndex: 'name' },
+      {
+        title: '操作',
+        render: (_, record) => (
+          <a
+            onClick={() => {
+              const arr = record.name.split('.');
+              const type = arr[arr.length - 1];
+              const dataItem = { url: record.url, name: record.name, type };
+              setImg(dataItem);
+            }}
+          >
+            查看
+          </a>
+        ),
+      },
+    ];
+    return (
+      <>
+        <Table columns={columns} dataSource={data} />
+        {img && renderContent(img)}
+      </>
+    );
+  };
+
+  return (
+    <Modal
+      destroyOnClose
+      title="预览"
+      open={visible}
+      width={1000}
+      footer={null}
+      onCancel={onCancel}
+      bodyStyle={{ height: '680px', overflowY: 'hidden' }}
+    >
+      {Array.isArray(data) ? renderListContent() : renderContent(data)}
+    </Modal>
+  );
+};
+
+export default FileViewerModal;

+ 30 - 7
src/pages/ContractManager/index.jsx

@@ -9,10 +9,13 @@ import {
   queryApproval,
   queryContract,
   queryContractCancel,
+  queryContractDownload,
   queryGetContractList,
 } from '../../services/contract';
 import dayjs from 'dayjs';
 import useModal from 'antd/es/modal/useModal';
+import FileViewerModal from '@/components/FileViewerNew';
+import { getToken } from '@/utils/utils';
 
 const ConteactManager = (props) => {
   const { dispatch } = props;
@@ -31,6 +34,8 @@ const ConteactManager = (props) => {
   const [pagination, setPagination] = useState({ current: 0 });
   const typeRef = useRef();
   const parentIdRef = useRef(0);
+  const [fileViewerVisible, setFileViewerVisible] = useState(false);
+  const [fileViewerData, setFileViewerData] = useState();
 
   const showBtn = (record, type) => {
     let bool = false;
@@ -149,8 +154,10 @@ const ConteactManager = (props) => {
             >
               详情
             </a>
-            <a onClick={handlePreView}>预览</a>
-            {showBtn(record, 'download') && <a onClick={handleUpload}>下载</a>}
+            <a onClick={() => handlePreView(record)}>预览</a>
+            {showBtn(record, 'download') && (
+              <a onClick={() => handleUpload(record)}>下载</a>
+            )}
             {showBtn(record, 'addOrCal') && !record.parent_id && (
               <a
                 onClick={() => {
@@ -229,13 +236,21 @@ const ConteactManager = (props) => {
     defaultParams: [{ pageSize: 99999 }],
   });
 
-  const handlePreView = () => {
-    // originFileObj 是读取的文件对象,如上传组件读取到的
-    // const fileURL = URL.createObjectURL(originFileObj);
-    // window.open(fileURL);
+  const handlePreView = (record) => {
+    if (!record.attach) return;
+    const attach = JSON.parse(record.attach);
+    setFileViewerData(attach);
+    setFileViewerVisible(true);
   };
 
-  const handleUpload = () => {};
+  const handleUpload = (record) => {
+    const token = getToken();
+    window.downloadFile(
+      `/api/archive/v1/file/download?id=${record.id}&JWT-TOKEN=${token}`,
+      record.name,
+      false,
+    );
+  };
   const handleSearch = () => {
     run(searchData);
   };
@@ -377,6 +392,14 @@ const ConteactManager = (props) => {
         handleOk={handleOk}
         handleCancel={() => setVisible(false)}
       />
+      <FileViewerModal
+        data={fileViewerData}
+        visible={fileViewerVisible}
+        downloadFile={() => {}}
+        onCancel={() => {
+          setFileViewerVisible(false);
+        }}
+      />
     </PageContainer>
   );
 };

+ 61 - 34
src/pages/FileManagement/components/PreModal.js

@@ -1,46 +1,68 @@
-import { Checkbox, Modal, Radio } from "antd";
-import { useRef, useEffect, useMemo } from "react";
-import style from './index.less'
+import { Checkbox, Modal, Radio } from 'antd';
+import { useRef, useEffect, useMemo } from 'react';
+import style from './index.less';
 import { useRequest } from '@umijs/max';
 
-const PerModal = ({ node,fileNode,auditList, visible, handleCancel, handleOk }) => {
-  console.log(node)
-  const checkedValuesRef = useRef([])
-  const auditItem= useRef()
+const PerModal = ({
+  node,
+  fileNode,
+  auditList,
+  visible,
+  handleCancel,
+  handleOk,
+}) => {
+  // console.log(node, fileNode);
+  const checkedValuesRef = useRef([]);
+  const auditItem = useRef();
   const data = [
-    { name: "文件权限", id: "DDMultiSelectField_2e553cd3-094e-4a34-8a2a-40271d6b107e", value: ["删除", "下载"] },
-    { name: "文件名称", id: "TextField_663c9a4e - 26c7- 408e-ac90 - fac20e796edf", value: ["文件夹1"] },
-    { name: "文件id", id: "TextField_1d1334ed - 1944 - 4e59 - 97db - 2d8615acf7c6", value: ["2"] },
-    { name: "文件类型", id: "TextField_1d1334ed - 1944 - 4e59 - 97db - 2d8615acf7c7", value: ["2"] }
-  ]
-  const options = useMemo(() => {
-   return node?.dir_type ? [
-    { label: '下载', value: 1},
-    { label: '删除', value:2 }
-  ] : [
-    { label: '下载', value: 1}
+    {
+      name: '文件权限',
+      id: 'DDMultiSelectField_2e553cd3-094e-4a34-8a2a-40271d6b107e',
+      value: ['删除', '下载'],
+    },
+    {
+      name: '文件名称',
+      id: 'TextField_663c9a4e - 26c7- 408e-ac90 - fac20e796edf',
+      value: ['文件夹1'],
+    },
+    {
+      name: '文件id',
+      id: 'TextField_1d1334ed - 1944 - 4e59 - 97db - 2d8615acf7c6',
+      value: ['2'],
+    },
+    {
+      name: '文件类型',
+      id: 'TextField_1d1334ed - 1944 - 4e59 - 97db - 2d8615acf7c7',
+      value: ['2'],
+    },
   ];
-  }, [node]) 
+  const options = useMemo(() => {
+    return node?.dir_type
+      ? [{ label: '下载', value: '下载' }]
+      : [
+          { label: '下载', value: '下载' },
+          { label: '删除', value: '删除' },
+        ];
+  }, [node]);
 
   const onChange = (checkedValues) => {
     checkedValuesRef.current = checkedValues;
-    console.log('checked = ', checkedValues);
   };
   const handleOkClick = () => {
     data[0].value = checkedValuesRef.current;
-    data[1].value = [node?.dir_name];
-    data[2].value = [node?.id.toString()];
+    data[1].value = [fileNode?.dir_name];
+    data[2].value = [fileNode?.id.toString()];
     data[3].value = [node?.dir_type.toString()];
 
     const result = {
       flow_id: auditItem.current,
       form: JSON.stringify(data),
-      audit_list:[448],
+      audit_list: [7],
       files: '',
-      file_type:fileNode?.file_type,
-    }
-    handleOk?.(result)
-  }
+      file_type: node.dir_type, //fileNode?.file_type,
+    };
+    handleOk?.(result);
+  };
   return (
     <Modal
       title="权限申请"
@@ -51,18 +73,23 @@ const PerModal = ({ node,fileNode,auditList, visible, handleCancel, handleOk })
       width={800}
     >
       <div className={style.title}>申请权限对象:</div>
-      <div className={style.content}>{fileNode?.file_name}</div>
+      <div className={style.content}>{fileNode?.dir_name}</div>
       <div className={style.title}>选择权限:</div>
       <div className={style.content}>
         <Checkbox.Group options={options} onChange={onChange} />
       </div>
       <div className={style.title}>可选流程:</div>
-      <Radio.Group onChange={onChange}>
-       {auditList?.map(item=><Radio value={item?.id} onChange={(e)=>{auditItem.current = e.target.value}}>{item?.name}</Radio>)}
+      <Radio.Group
+        onChange={(e) => {
+          auditItem.current = e.target.value;
+        }}
+      >
+        {auditList?.map((item) => (
+          <Radio value={item?.id}>{item?.name}</Radio>
+        ))}
       </Radio.Group>
-
     </Modal>
   );
-}
-  
-export default PerModal
+};
+
+export default PerModal;

+ 302 - 172
src/pages/FileManagement/index.js

@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect } from 'react';
 import {
   Input,
   Tree,
@@ -13,27 +13,32 @@ import {
   Upload,
   Space,
   message,
+  Spin,
 } from 'antd';
 import dayjs from 'dayjs';
 import { PageContainer, ProCard } from '@ant-design/pro-components';
 import { useRequest, useModel } from '@umijs/max';
-import axios from 'axios';
 import {
   queryDirCreate,
   queryDirList,
+  queryFileDelete,
   queryFileList,
   queryFileUpload,
   queryOAFile,
+  queryPermitList,
   querySetPermit,
-  queryFileDownload,
 } from '../../services/file';
 import { queryGetContractList } from '../../services/contract';
 import { downloadFile, getToken } from '@/utils/utils';
-import { PlusCircleOutlined } from '@ant-design/icons';
+import {
+  ExclamationCircleOutlined,
+  PlusCircleOutlined,
+} from '@ant-design/icons';
 import AddFileModal from './components/model';
 import PerModal from './components/PreModal';
 import { queryAuditList, createAduit } from '@/services/boom';
-import {stringify} from 'qs'
+import { stringify } from 'qs';
+import FileViewerModal from '@/components/FileViewerNew';
 
 const tempData = [
   { name: '文件1', upload_user: '管理员', upload_time: '2023-04-08 11:00:00' },
@@ -46,69 +51,94 @@ const { RangePicker } = DatePicker;
 
 function FileManagement(props) {
   const [form] = Form.useForm();
+  const [modal, contextHolder] = Modal.useModal();
   const { user } = useModel('userInfo');
-  const [tableData , setTableData] = useState([])
+  const [tableData, setTableData] = useState([]);
   const [visible, setVisible] = useState(false);
   const [node, setNode] = useState();
-  const [selectedRowKeys, setSelectedRowKeys] = useState([])
+  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
+  const [fileViewerVisible, setFileViewerVisible] = useState(false);
+  const [fileViewerData, setFileViewerData] = useState();
 
-  const { data:treeData, run: runFileDir } = useRequest((data) => queryDirList(data), {
+  const {
+    data: treeData,
+    loading: treeLoading,
+    run: runFileDir,
+  } = useRequest((data) => queryDirList(data), {
     formatResult: (res) => {
       const result = [];
       result[0] = res?.data.limit_list[0];
       result[1] = res?.data.list[0];
-      return result
+      return result;
     },
   });
 
   const { loading, run } = useRequest((data) => queryFileList(data), {
     manual: true,
     onSuccess: (data) => {
-      let result = data?.list?.map((item, idx) => {
-        return {...item, dir_name:item.file_name, create_time: item.created_on, key:idx }
-      }) || []
-      setTableData(result)
-      setSelectedRowKeys([])
-    }
+      let result =
+        data?.list?.map((item, idx) => {
+          return {
+            ...item,
+            dir_name: item.file_name,
+            create_time: item.created_on,
+            key: idx,
+          };
+        }) || [];
+      setTableData(result);
+      setSelectedRowKeys([]);
+    },
   });
 
-  const {
-    loading: OAloading,
-    run: runOA,
-  } = useRequest((data) => queryOAFile(data), {
-    manual: true,
-    onSuccess: (data) => {
-      let result = data?.list.map((item, idx) => {
-        let name
-        if (item?.name) {
-          name = item.name
-        } else if (item?.path) {
-          const list = item.path.split('/');
-          name = list?.length > 0 ? list[list.length - 1] : "-";
-        } else if (item?.url) {
-          const list = item?.url?.split('/');
-          name = list?.length > 0 ? list[list.length - 1] : "-";
-        }
-        return {...item, dir_name:name, create_time: dayjs(item.c_time).format('YYYY-MM-DD'), key:idx}
-      }) || []
-      setTableData(result)
-      setSelectedRowKeys([])
-    }
-  });
+  const { loading: OAloading, run: runOA } = useRequest(
+    (data) => queryOAFile(data),
+    {
+      manual: true,
+      onSuccess: (data) => {
+        let result =
+          data?.list.map((item, idx) => {
+            let name;
+            if (item?.name) {
+              name = item.name;
+            } else if (item?.path) {
+              const list = item.path.split('/');
+              name = list?.length > 0 ? list[list.length - 1] : '-';
+            } else if (item?.url) {
+              const list = item?.url?.split('/');
+              name = list?.length > 0 ? list[list.length - 1] : '-';
+            }
+            return {
+              ...item,
+              dir_name: name,
+              create_time: dayjs(item.c_time).format('YYYY-MM-DD'),
+              key: idx,
+            };
+          }) || [];
+        setTableData(result);
+        setSelectedRowKeys([]);
+      },
+    },
+  );
 
-  const {
-    loading: contractLoading,
-    run: runContract,
-  } = useRequest((data) => queryGetContractList({ ...data, status: 3 }), {
-    manual: true,
-    onSuccess: (data) => {
-      let result = data?.list.map((item, idx) => {
-        return {...item, dir_name:item.name, create_time: item.created_on, key:idx }
-      }) || []
-      setTableData(result)
-      setSelectedRowKeys([])
-    }
-  });
+  const { loading: contractLoading, run: runContract } = useRequest(
+    (data) => queryGetContractList({ ...data, status: 3 }),
+    {
+      manual: true,
+      onSuccess: (data) => {
+        let result =
+          data?.list.map((item, idx) => {
+            return {
+              ...item,
+              dir_name: item.name,
+              create_time: item.created_on,
+              key: idx,
+            };
+          }) || [];
+        setTableData(result);
+        setSelectedRowKeys([]);
+      },
+    },
+  );
 
   const { loading: createLoading, run: RunCreate } = useRequest(
     (data) => queryDirCreate(data),
@@ -116,7 +146,7 @@ function FileManagement(props) {
       manual: true,
       onSuccess: () => {
         setVisible(false);
-        runFileDir()
+        runFileDir();
         message.success('创建成功');
       },
       onError: () => {
@@ -125,61 +155,103 @@ function FileManagement(props) {
     },
   );
   //申请权限
-  const { loading:perLoading, run:runPer } = useRequest((data) => querySetPermit(data), {
-    manual: true,
-    onSuccess: (data) => {
-      message.success('申请成功')
+  const { loading: perLoading, run: runPer } = useRequest(
+    (data) => querySetPermit(data),
+    {
+      manual: true,
+      onSuccess: (data) => {
+        message.success('申请成功');
+      },
+      onError: () => {
+        message.error('申请失败');
+      },
     },
-    onError: () => {
-      message.error('申请失败')
-    }
-  });
+  );
 
   //上传文件
-  const { run:runUploadFiles} = useRequest((data) => queryFileUpload(data), {
+  const { run: runUploadFiles } = useRequest((data) => queryFileUpload(data), {
     manual: true,
     onSuccess: (data) => {
-      updateTableFile(node)
-      message.success('文件上传成功')
+      updateTableFile(node);
+      message.success('文件上传成功');
     },
     onError: () => {
-      message.error('文件上传失败')
-    }
-  })
+      message.error('文件上传失败');
+    },
+  });
 
   //文件审批列表
-  const { data: auditList} = useRequest(() => queryAuditList({ flow_type: 1 }));
+  const { data: auditList } = useRequest(() =>
+    queryAuditList({ flow_type: 1 }),
+  );
   //发起申请权限的文件审批
-  const { loading: createLoadin, run:runAuditCreate  } = useRequest(createAduit, {
-    manual: true,
-    onSuccess() {
-      message.success('申请审批成功');
-      setPerOpen(false);
+  const { loading: createLoadin, run: runAuditCreate } = useRequest(
+    createAduit,
+    {
+      manual: true,
+      onSuccess() {
+        message.success('申请审批成功');
+        setPerOpen(false);
+      },
     },
+  );
+
+  //文档权限列表
+  const {
+    data: preListData,
+    loading: preListLoading,
+    run: runPreList,
+  } = useRequest((data) => queryPermitList(data), {
+    manual: true,
   });
 
-  //下载文件
-  // const { data: fileData, run:runDownload } = useRequest((data) => queryFileDownload(data), {
-  //   manual: true,
-  //   onSuccess: (data) => {
-  //     message.success('文件下载成功')
-  //   },
-  //   onError: (data) => {
-  //     message.error('文件下载失败')
-  //   }
-  // })
+  //删除文件
+  const { loading: delFileLoading, run: runDelFile } = useRequest(
+    (data) => queryFileDelete(data),
+    {
+      manual: true,
+      onSuccess: () => {
+        updateTableFile(node);
+        message.success('删除成功');
+      },
+      onError: () => {
+        message.success('删除失败');
+      },
+    },
+  );
 
   const [expandedKeys, setExpandedKeys] = useState([]);
   const [searchValue, setSearchValue] = useState('');
   const [permissionOpen, setPerOpen] = useState(false);
   const [addOpen, setAddOpen] = useState(false);
-  const [editPer, setEditPer] = useState(false);
+
+  const delConfirm = (record) => {
+    modal.confirm({
+      title: '删除',
+      icon: <ExclamationCircleOutlined />,
+      content: `确定删除文件${record.dir_name}, 删除后不能恢复`,
+      okText: '确认',
+      cancelText: '取消',
+      onOk: () => runDelFile({ file_id: record.id }),
+    });
+  };
+
+  const isShow = (id, num) => {
+    //num  下载 1   删除 2
+    let bool = false;
+    const idx = preListData?.list?.findIndex(
+      (item) => item.file_id == id && item.permit == num,
+    );
+    if (idx > -1) bool = true;
+    return bool;
+  };
 
   const columns = [
     { title: '文档名称', dataIndex: 'dir_name' },
-    { title: '上传人员', dataIndex: 'user_name' },
+    { title: '上传人员', align: 'center', dataIndex: 'user_name' },
     {
       title: '上传时间',
+      align: 'center',
       dataIndex: 'create_time',
       render: (text) => dayjs(text).format('YYYY-MM-DD'),
     },
@@ -187,14 +259,28 @@ function FileManagement(props) {
       title: '操作',
       render: (_, record) => (
         <Space>
-          <a onClick={()=>handleSeeClick(record)}>查看</a>
-          <a onClick={() => onDownload(record)}>下载</a>
-          {node?.dir_type == 0 && <a>删除</a>}
+          <a onClick={() => handleSeeClick(record)}>查看</a>
+          {isShow(record.id, 1) && (
+            <a onClick={() => onDownload(record)}>下载</a>
+          )}
+          {isShow(record.id, 2) && node?.dir_type == 0 && (
+            <a onClick={() => delConfirm(record)}>删除</a>
+          )}
         </Space>
       ),
     },
   ];
 
+  useEffect(() => {
+    //获取列表的权限
+    if (!tableData || tableData.length <= 0) return;
+    const ids = tableData.map((item) => item.id);
+    const data = {
+      file_type: node.dir_type,
+      file_ids: ids?.join(','),
+    };
+    runPreList(data);
+  }, [tableData]);
 
   // 搜索文件夹树
   const onSearchDirectory = (value, nodes = treeData) => {
@@ -242,118 +328,140 @@ function FileManagement(props) {
   };
 
   const findListById = (id) => {
-    if(!id )return 
+    if (!id) return;
     const fun = (data) => {
-      for (let i = 0; i < data.length; i++){
+      for (let i = 0; i < data.length; i++) {
         let item = data[i];
         if (item.id == id) {
           return item.children;
-        }else if(item.children){
+        } else if (item.children) {
           let res = fun(item.children);
           if (res) return res;
         }
       }
-    }
-    const list = fun(treeData)
+    };
+    const list = fun(treeData);
 
-    return list?.map((item, idx) => { return { ...item, key :idx} })
-  }
+    return list?.map((item, idx) => {
+      return { ...item, key: idx };
+    });
+  };
 
   const updateTableFile = (node) => {
     if (node.id == 1) {
       //点击受控文件直接把文件夹下的文件夹列表显示出来
-      setTableData(findListById(1))
-      setSelectedRowKeys([])
+      setTableData(findListById(1));
+      setSelectedRowKeys([]);
     } else if (node.id == 3) {
       //点击合同文件直接把文件夹下的文件夹列表显示出来
-      setTableData(findListById(3))
-      setSelectedRowKeys([])
+      setTableData(findListById(3));
+      setSelectedRowKeys([]);
     } else if (node.id == 7) {
       //合同归档走合同接口
       runContract({});
-    } else if(node.is_limit){
+    } else if (node.is_limit) {
       //其他受控文件走classify_id
       runOA({ classify_id: node.classify_id });
     } else {
       //部门文件
-      run({ dir_id:node.id })
+      run({ dir_id: node.id });
     }
-  }
- cons
+  };
+
   const handleSelect = (SelectKeys, e) => {
-    console.log(e, SelectKeys)
+    // console.log(e, SelectKeys);
     const node = e.node;
-    setNode(node)
-    updateTableFile(e.node)
+    setNode(node);
+    updateTableFile(e.node);
   };
 
-
   const onDownload = (record) => {
-    // runDownload({file_id:record.id, path:record.path, file_type:node.dir_type })
-    // const token = getToken();
-    const data = {file_id:record.id, path:record.path, file_type:node.dir_type }
-    window.downloadFile(`/api/archive/v1/file/download?${stringify(data)}`, record.dir_name, false);
+    const data = {
+      file_id: record.id,
+      path: record.path,
+      file_type: node.dir_type,
+    };
+    window.downloadFile(
+      `/api/archive/v1/file/download?${stringify(data)}`,
+      record.dir_name,
+      false,
+    );
   };
 
   const handleSeeClick = (record) => {
-    const token = getToken();
-    const data = {file_id:record.id, path:record.path, file_type:node.dir_type,'JWT-TOKEN':token }
-    axios.get(`/api/archive/v1/file/download?${stringify(data)}`)
-      .then(function (response) {
-        console.log(response);
-      })
-      .catch(function (error) {
-        console.log(error);
-      });
-  }
+    if (node?.dir_type == 2) {
+      // 合同归档
+      if (!record.attach) return;
+      const attach = JSON.parse(record.attach);
+      setFileViewerData(attach);
+      setFileViewerVisible(true);
+    } else {
+      const token = getToken();
+      const params = {
+        file_id: record.id,
+        path: record.path,
+        file_type: node.dir_type,
+        'JWT-TOKEN': token,
+      };
+      const url = `${location.origin}/api/archive/v1/file/download?${stringify(
+        params,
+      )}`;
+      const arr = record.dir_name.split('.');
+      const type = arr[arr.length - 1];
+      const data = { url, name: record.dir_name, type };
+      setFileViewerData(data);
+      setFileViewerVisible(true);
+    }
+  };
 
   const handleFilesChange = () => {
     const inputDom = document.getElementById('files');
-    let formData = new FormData()
+    let formData = new FormData();
     formData.append('dir_id', node.id);
     formData.append('user_name', user.CName);
     if (inputDom.files?.length > 0) {
-      for (let i = 0; i < inputDom.files.length; i++){
+      for (let i = 0; i < inputDom.files.length; i++) {
         formData.append('files', inputDom.files[i]);
       }
-      runUploadFiles(formData)
+      runUploadFiles(formData);
     }
-  }
+  };
 
   return (
     <PageContainer>
       <div style={{ display: 'flex', justifyContent: 'space-between' }}>
         <ProCard style={{ height: '100%', width: '30%' }}>
-          <Search onSearch={(value, _) => onSearchDirectory(value)} />
-          <DirectoryTree
-            expandedKeys={expandedKeys}
-            onExpand={onExpand}
-            treeData={treeData}
-            onSelect={handleSelect}
-            fieldNames={{ key: 'id', title: 'dir_name', children: 'children' }}
-            filterTreeNode={filterTreeNode}
-            titleRender={(item) => {
-              return item.dir_name == '部门文件' ? (
-                <Space>
+          <Search onChange={(e) => onSearchDirectory(e.target.value)} />
+          <Spin spinning={treeLoading}>
+            <DirectoryTree
+              expandedKeys={expandedKeys}
+              onExpand={onExpand}
+              treeData={treeData}
+              onSelect={handleSelect}
+              fieldNames={{
+                key: 'id',
+                title: 'dir_name',
+                children: 'children',
+              }}
+              filterTreeNode={filterTreeNode}
+              titleRender={(item) => {
+                return item.dir_name == '部门文件' ? (
+                  <Space>
+                    <span>{item.dir_name}</span>
+                    <PlusCircleOutlined
+                      style={{ fontSize: '16px' }}
+                      onClick={() => {
+                        setNode(item);
+                        setVisible(true);
+                      }}
+                    />
+                  </Space>
+                ) : (
                   <span>{item.dir_name}</span>
-                  <PlusCircleOutlined style={{fontSize:'16px'}} onClick={() => {
-                      setNode(item);
-                      setVisible(true);
-                    }}/>
-                  {/* <Button
-                    shape="circle"
-                    icon={<PlusOutlined style={{fontSize:'16px'}} />}
-                    onClick={() => {
-                      setNode(item);
-                      setVisible(true);
-                    }}
-                  /> */}
-                </Space>
-              ) : (
-                <span>{item.dir_name}</span>
-              );
-            }}
-          />
+                );
+              }}
+            />
+          </Spin>
         </ProCard>
         <ProCard style={{ height: '100%', width: 'calc(70% - 20px)' }}>
           <Form layout="inline" form={form}>
@@ -369,10 +477,20 @@ function FileManagement(props) {
               </Button>
             </Form.Item>
             <Form.Item>
-              <Button type="primary" onClick={ ()=>document.getElementById('files')?.click()} disabled={node ? false : true}>上传</Button>
+              <Button
+                type="primary"
+                onClick={() => document.getElementById('files')?.click()}
+                disabled={node ? false : true}
+              >
+                上传
+              </Button>
             </Form.Item>
             <Form.Item>
-              <Button type="primary" onClick={() => setPerOpen(true)} disabled={selectedRowKeys ? false : true}>
+              <Button
+                type="primary"
+                onClick={() => setPerOpen(true)}
+                disabled={selectedRowKeys?.length > 0 ? false : true}
+              >
                 申请权限
               </Button>
             </Form.Item>
@@ -382,16 +500,17 @@ function FileManagement(props) {
               columns={columns}
               dataSource={tableData}
               rowSelection={{
-                selectedRowKeys ,
-                type:'radio',
-                onChange: (e,fileNode) => {
-                  console.log(e)
-                  setSelectedRowKeys(e)
-                    // (fileNode[0])
-              }}}
+                selectedRowKeys,
+                type: 'radio',
+                onChange: (e, fileNode) => {
+                  console.log(e);
+                  setSelectedRowKeys(e);
+                  // (fileNode[0])
+                },
+              }}
               loading={OAloading || contractLoading || loading}
               style={{ overflowY: 'auto' }}
-              childrenColumnName='none'
+              childrenColumnName="none"
               pagination={false}
             />
             {/* 
@@ -425,13 +544,14 @@ function FileManagement(props) {
             */}
           </div>
         </ProCard>
-         <Input
-            id="files"
-            type="file"
-            style={{ display: 'none' }}
-            onChange={handleFilesChange}
-            multiple
-          />
+        <Input
+          id="files"
+          type="file"
+          style={{ display: 'none' }}
+          onChange={handleFilesChange}
+          multiple
+        />
+        {contextHolder}
       </div>
       {/* <PerModal /> */}
       <AddModal />
@@ -446,11 +566,21 @@ function FileManagement(props) {
       />
       <PerModal
         node={node}
-        fileNode={tableData?.find(item => item.key == selectedRowKeys[0])}
+        fileNode={tableData?.find((item) => item.key == selectedRowKeys[0])}
         auditList={auditList}
         visible={permissionOpen}
         handleCancel={() => setPerOpen(false)}
-        handleOk={(data)=>{runAuditCreate(data)}}
+        handleOk={(data) => {
+          runAuditCreate(data);
+        }}
+      />
+      <FileViewerModal
+        data={fileViewerData}
+        visible={fileViewerVisible}
+        downloadFile={() => {}}
+        onCancel={() => {
+          setFileViewerVisible(false);
+        }}
       />
     </PageContainer>
   );

+ 12 - 6
src/services/file.js

@@ -35,14 +35,20 @@ export const queryFileUpload = async (data) => {
   return await request('/api/archive/v1/file/upload', {
     method: 'POST',
     data,
-    headers: {'content-type':'mutipart/form-data'}
+    headers: { 'content-type': 'mutipart/form-data' },
   });
 };
 
-export const queryFileDownload = async (data) => {
-  return await request('/api/archive/v1/file/download', {
-    method: 'GET',
-    params: data,
-    responseType: 'blob',
+export const queryPermitList = async (data) => {
+  return await request('/api/archive/v1/permit/list', {
+    method: 'POST',
+    data,
+  });
+};
+
+export const queryFileDelete = async (data) => {
+  return await request('/api/archive/v1/file/delete', {
+    method: 'POST',
+    data,
   });
 };

+ 1 - 1
yarn.lock

@@ -8602,7 +8602,7 @@ react-visibility-sensor@^5.0.2:
   dependencies:
     prop-types "^15.7.2"
 
-react-zmage@^0.8.5-beta.37:
+react-zmage@^0.8.5-beta.36:
   version "0.8.5-beta.37"
   resolved "https://registry.npmmirror.com/react-zmage/-/react-zmage-0.8.5-beta.37.tgz#a310a2ea273685021e098edd10505011b3f3b778"
   integrity sha512-6US4DVozc2IdqxHCrMAejDy3H08B95Rc/LeFMnHBblE0wagKbqbQlHfwgLRUcdPBBKCtm1KuWNKiN3MXurrcOg==