Bläddra i källkod

审批附加表单功能

Renxy 2 år sedan
förälder
incheckning
9fe91310ef

+ 6 - 5
src/components/FileViewer/index.js

@@ -1,10 +1,10 @@
 import FileViewer from 'react-file-viewer';
-import { Modal } from 'antd';
+import { Modal, Spin } from 'antd';
 import { memo } from 'react';
 
-const FileViewerModal = ({ url = '', visible, onCancel }) => {
-  const type = url?.split('.')[url?.split('.').length - 1];
-  console.log(url, type);
+const FileViewerModal = ({ data, visible, onCancel }) => {
+  const type = data?.url?.split('.')[data?.url?.split('.').length - 1];
+  console.log(data?.url, type);
   return (
     <Modal
       title="预览"
@@ -15,8 +15,9 @@ const FileViewerModal = ({ url = '', visible, onCancel }) => {
       bodyStyle={{ height: '680px', overflowY: 'hidden' }}
     >
       <FileViewer
+        key={data?.name}
         fileType={type}
-        filePath={url}
+        filePath={data?.url}
         onError={() => console.log('Failed to load')}
         errorComponent={console.log('出现错误')}
         unsupportedComponent={console.log('不支持')}

+ 43 - 18
src/pages/Detail/CommitAuditModal.js

@@ -37,6 +37,7 @@ import DDCode from '@/components/DDComponents/DDCode';
 import { uploadFile, queryUserListByRoleID } from '@/services/boom';
 import ApprovalProcess from './ApprovalProcess';
 import { uuidv4 } from '@antv/xflow';
+import AliyunOSSUpload from '@/components/OssUpload/AliyunOssUploader';
 
 const { TextArea } = Input;
 const { Option } = Select;
@@ -57,8 +58,10 @@ function CommitAuditModal(props) {
     currentUser,
     luckysheet,
     userList,
-    uploadProps,
+    // uploadProps,
+    OSSData,
   } = props;
+  console.log(loading);
   const [auditId, setAuditId] = useState();
   const [data, setData] = useState([]);
   const [length, setLength] = useState(1);
@@ -71,6 +74,7 @@ function CommitAuditModal(props) {
   const [curNodeIdx, setCurNodeIdx] = useState(-1);
 
   const [dataSource, setDataSource] = useState([]);
+  const uploadList = useRef([]);
 
   useEffect(() => {
     if (!visible) return;
@@ -79,6 +83,7 @@ function CommitAuditModal(props) {
     let Id = version.template_node_id;
     const currentId = flowDetail.nodes.find?.(item => item.Id == Id)?.node_id;
     const data = treeData(currentId);
+    console.log('===============审批节点======', data);
     if (data.length <= 0) {
       setAuditId(currentId);
     } else {
@@ -103,11 +108,38 @@ function CommitAuditModal(props) {
     // });
   }, [version.template_node_id, visible]);
 
+  useEffect(() => {
+    if (!visible) return;
+    dispatch({
+      type: 'detail/getChartOSSData',
+      payload: {
+        projectId: version.project_id,
+      },
+    });
+  }, [visible]);
+
   useEffect(() => {
     form.resetFields();
     setAuditList([]);
   }, [visible]);
 
+  const OnModelFileDone = file => {
+    var path = OSSData.host + '/' + file.url;
+    uploadList.current = [...uploadList.current, path];
+    // const files = form.getFieldsValue('files');
+    // form.setFieldValue('files', files.concat(path));
+    console.log(uploadList.current);
+    // setThumbnail(path);
+  };
+  const OnUploading = file => {};
+  const uploadProps = {
+    OSSData: OSSData,
+    onDone: OnModelFileDone,
+    onUploading: OnUploading,
+    noStyle: false,
+    // showUploadList: false,
+  };
+
   const initFormList = async () => {
     const res = await queryGetBomForm({
       project_id: version.project_id,
@@ -338,6 +370,7 @@ function CommitAuditModal(props) {
     // let attachment = await upload();
     firstList.forEach(id => {
       let approvalNode = flowDetail.nodes.find?.(item => item.Id == id);
+      if (!approvalNode) return;
       let values = data[approvalNode.Id] || [];
       const audit_list = approvalProcess[approvalNode.Id]?.map(item => {
         if (item[0].type == 'role') return item[0].nowValue;
@@ -382,9 +415,7 @@ function CommitAuditModal(props) {
   };
 
   const onFinish = async () => {
-    console.log(approvalProcess);
     const isOk = Object.values(approvalProcess).every(item => {
-      console.log(item);
       return item.every(cur => {
         if (cur[0].type == 'role') return cur[0].nowValue;
         return true;
@@ -483,6 +514,8 @@ function CommitAuditModal(props) {
       json: JSON.stringify({ approvalProcess }),
     });
     params.audit_series = uuidv4();
+    params.files = uploadList.current.join(',');
+    console.log(params);
     onOk(params);
   };
   const CascaderNode = index => {
@@ -535,7 +568,7 @@ function CommitAuditModal(props) {
 
   return (
     <Modal
-      confirmLoading={loading}
+      confirmLoading={loading.global}
       destroyOnClose
       title="提交流转目标"
       width={1000}
@@ -564,10 +597,9 @@ function CommitAuditModal(props) {
         <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="备注信息" name="desc">
           <Input.TextArea />
         </Form.Item>
-        {/* <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="授权码" name="ddCode">
-          <DDCode />
-          <Button onClick={upload}>上传文件</Button>
-        </Form.Item> */}
+        <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="附件">
+          <AliyunOSSUpload {...uploadProps} directory={false} label="上传文件" />
+        </Form.Item>
       </Form>
       <Tabs defaultActiveKey="1">
         {auditList.map((item, idx) => (
@@ -589,15 +621,6 @@ function CommitAuditModal(props) {
           </TabPane>
         ))}
       </Tabs>
-      {/* <Divider />
-      <div style={{ marginTop: '20px' }}>
-        <Upload {...uploadProps}>
-          <Button type="primary" loading={loading}>
-            <UploadOutlined /> 上传文件
-          </Button>
-        </Upload>
-        <Table style={{ marginTop: '20px' }} dataSource={dataSource} columns={columns} />
-      </div> */}
     </Modal>
   );
 }
@@ -612,9 +635,11 @@ function getDataValue(item) {
   return arr;
 }
 
-export default connect(({ xflow, detail, user }) => ({
+export default connect(({ xflow, detail, user, loading }) => ({
   flowDetail: xflow.flowDetail,
   versionList: detail.versionList,
   currentUser: user.currentUser,
   userList: user.list,
+  OSSData: detail.OSSData,
+  loading,
 }))(CommitAuditModal);

+ 17 - 17
src/pages/Detail/FlowModal.js

@@ -76,7 +76,6 @@ function FlowModal(props) {
   const [sealLoading, setSealLoading] = useState(false);
   // const [currentTempNodeId, setCurrentTempNodeId] = useState();
   const currentTempNodeId = useRef();
-  console.log('=======', currentTempNodeId);
 
   const graphData = useMemo(() => {
     if (!flowDetail) return;
@@ -89,6 +88,7 @@ function FlowModal(props) {
       edges: flowDetail.edges,
     };
   }, [flowDetail, version.template_node_id]);
+  console.log('version========', version);
 
   useEffect(() => {
     if (!visible) updateSteps([]);
@@ -446,22 +446,22 @@ function FlowModal(props) {
                 // }}
               />
             </div>
-            <Spin spinning={loading.global}>
-              {stepsData.map((item, idx) => (
-                <div key={`${item.name}_${idx}`} style={{ marginBottom: '20px' }}>
-                  <div style={{ marginBottom: '4px' }}>{item.name}</div>
-                  <Steps size="small" current={item.current} status={item.status}>
-                    {item.list.map(node => (
-                      <Step
-                        key={`${node.id}_${node.node}`}
-                        title={node.node}
-                        description={`审批人:${node.AuditorUser?.CName || '-'}`}
-                      />
-                    ))}
-                  </Steps>
-                </div>
-              ))}
-            </Spin>
+            {/* <Spin spinning={loading.global}> */}
+            {stepsData.map((item, idx) => (
+              <div key={`${item.name}_${idx}`} style={{ marginBottom: '20px' }}>
+                <div style={{ marginBottom: '4px' }}>{item.name}</div>
+                <Steps size="small" current={item.current} status={item.status}>
+                  {item.list.map(node => (
+                    <Step
+                      key={`${node.id}_${node.node}`}
+                      title={node.node}
+                      description={`审批人:${node.AuditorUser?.CName || '-'}`}
+                    />
+                  ))}
+                </Steps>
+              </div>
+            ))}
+            {/* </Spin> */}
           </Col>
         </Row>
       </Modal>

+ 102 - 0
src/pages/Detail/FormAndFilesNode.js

@@ -0,0 +1,102 @@
+import { Card, Col, Input, Row, Table } from 'antd';
+import { Form } from '@ant-design/compatible';
+import { useForm } from 'antd/lib/form/Form';
+import PreviewFile from '@/components/PreviewFile';
+import FileViewerModal from '@/components/FileViewer';
+import { useState } from 'react';
+
+const renderFrom = data => {
+  if (!data) return;
+  try {
+    const ding_schema = JSON.parse(data)[0];
+    const formData = JSON.parse(ding_schema)?.formComponentValues;
+    return (
+      <>
+        {formData.map((item, idx) => {
+          const value = item.value[0];
+          return (
+            <Form.Item
+              key={`FormAndFilesNode_${idx}`}
+              labelCol={{ span: 6 }}
+              wrapperCol={{ span: 18 }}
+              label={item.name}
+            >
+              <div
+                style={{
+                  width: '100%',
+                  paddingLeft: '20px',
+                  backgroundColor: '#ececef',
+                  border: '1px solid #bcb9b9',
+                  borderRadius: '4px',
+                }}
+              >
+                {value}
+              </div>
+            </Form.Item>
+          );
+        })}
+      </>
+    );
+  } catch {
+    return;
+  }
+};
+
+const FormAndFilesNode = ({
+  title,
+  formData,
+  excelFileData,
+  loading,
+  // setExportData,
+  // setExcelFileVisible,
+}) => {
+  const [exportData, setExportData] = useState({});
+  const [excelFileVisible, setExcelFileVisible] = useState(false);
+  const columns = [
+    {
+      title: '附件',
+      dataIndex: 'name',
+      render: (text, item) => {
+        return <PreviewFile name={item.name} src={item.url} />;
+      },
+    },
+    {
+      title: '预览',
+      render: record => (
+        <a
+          style={{ marginLeft: 10 }}
+          onClick={() => {
+            setExportData(record);
+            setExcelFileVisible(true);
+          }}
+        >
+          预览
+        </a>
+      ),
+    },
+  ];
+  return (
+    <>
+      {excelFileData && formData && (
+        <Card title={title} type="inner" style={{ marginTop: 20 }} loading={loading}>
+          <Row style={{ marginTop: '20px' }}>
+            <Col span={12}>{renderFrom(formData)}</Col>
+            <Col span={11} offset={1}>
+              <Table rowKey="id" columns={columns} dataSource={excelFileData} />
+            </Col>
+          </Row>
+        </Card>
+      )}
+
+      <FileViewerModal
+        data={exportData}
+        visible={excelFileVisible}
+        onCancel={() => {
+          setExcelFileVisible(false);
+        }}
+      />
+    </>
+  );
+};
+
+export default FormAndFilesNode;

+ 40 - 11
src/pages/Detail/Index.js

@@ -12,6 +12,8 @@ import {
   Dropdown,
   Row,
   Col,
+  Table,
+  Card,
 } from 'antd';
 import { connect } from 'dva';
 import styles from './Index.less';
@@ -42,6 +44,9 @@ import HistoryDrawer from './HistoryDrawer';
 import AuditFlow from './AuditFlow';
 import { getCurrentUser } from '@/utils/authority';
 import { async } from '@antv/x6/es/registry/marker/async';
+import FileViewerModal from '@/components/FileViewer';
+import PreviewFile from '@/components/PreviewFile';
+import FormAndFilesNode from './FormAndFilesNode';
 const LocalData = localStorage.luckysheet;
 
 const { Option } = Select;
@@ -64,6 +69,8 @@ function Detail(props) {
     instanceDetail,
     typeOptions,
     classifyList,
+    OSSData,
+    excelFileList,
   } = props;
   const [versionTreeVisible, setVersionTreeVisible] = useState(false);
   const [commentVisible, setCommentVisible] = useState(false);
@@ -98,6 +105,17 @@ function Detail(props) {
   });
   const cellPosition = useRef({});
 
+  useEffect(() => {
+    if (!version.id) return;
+    dispatch({
+      type: 'detail/QueryExcelFiles',
+      payload: {
+        file_type: 1,
+        excel_id: version.id,
+      },
+    });
+  }, [version.id]);
+
   const projectId = parseInt(params.projectId);
   const templateId = parseInt(params.templateId);
   const auditDetail = useMemo(() => {
@@ -826,21 +844,22 @@ function Detail(props) {
     const token = getToken() || GetTokenFromUrl();
     const uploadProps = {
       name: 'file',
-      showUploadList: false,
-      action: `/api/v1/purchase/attachment/${version.id}`,
+      // showUploadList: false,
+      action: `/api/v1/purchase/attachment/${projectId}`,
       headers: {
         'JWT-TOKEN': token,
       },
       data: {
         type: 'file',
+        file_type: 1, // '0 全局文件  1节点合同文件',
       },
       onChange(info) {
         if (info.file.status !== 'uploading') {
-          // console.log(info.file, info.fileList);
+          console.log(info.file, info.fileList);
         }
         if (info.file.status === 'done') {
           message.success(`${info.file.name} 文件上传成功`);
-          queryFiles();
+          // queryFiles();
         } else if (info.file.status === 'error') {
           message.error(`${info.file.name} 文件上传失败`);
         }
@@ -907,8 +926,6 @@ function Detail(props) {
         excel_id: version.id || localStorage.excelId,
       },
     });
-
-    console.log('-------------------------', version);
     // 判断是否审批节点
     if (version.flow_id) {
       dispatch({
@@ -1071,6 +1088,14 @@ function Detail(props) {
     }
   }, [versionList]);
 
+  const excelFileData = useMemo(() => {
+    return excelFileList?.map(item => {
+      const list = item.url.split('/');
+      const name = list[list.length - 1];
+      return { name, url: item.url };
+    });
+  }, [excelFileList]);
+
   return (
     <Spin spinning={false}>
       <div className={styles.top}>
@@ -1161,10 +1186,12 @@ function Detail(props) {
         onSubmit={handleSubmitCell}
         loading={loading.effects['detail/queryComment'] || loading.effects['detail/addComment']}
       />
-      {/* <Row style={{ marginTop: '20px' }}>
-        <Col span={12}>hahahh</Col>
-        <Col span={12}>hahahahh</Col>
-      </Row> */}
+      <FormAndFilesNode
+        title="表单信息及附件"
+        formData={version?.ding_schema}
+        excelFileData={excelFileData}
+        loading={loading.effects['detail/QueryExcelFiles']}
+      />
 
       <RightDrawer
         version={version}
@@ -1207,7 +1234,7 @@ function Detail(props) {
       <FilesModal
         projectId={projectId}
         typeOptions={typeOptions}
-        loading={getFilesLoading()}
+        // loading={getFilesLoading()}
         visible={fileVisible}
         onClose={() => setFileVisible(false)}
         queryFiles={queryFiles}
@@ -1249,5 +1276,7 @@ export default connect(({ detail, user, xflow, loading }) => ({
   versionTree: detail.versionTree,
   typeOptions: detail.typeOptions,
   classifyList: detail.classifyList,
+  OSSData: detail.OSSData,
+  excelFileList: detail.excelFileList,
   loading,
 }))(Detail);

+ 22 - 0
src/pages/Detail/models/detail.js

@@ -37,6 +37,7 @@ import {
   queryListParentByUser,
   queryClassify,
   queryBindClassify,
+  ChartTempOSSData,
 } from '@/services/boom';
 import { queryRole } from '@/services/SysAdmin';
 import { setCurrentUser } from '@/utils/authority';
@@ -82,6 +83,8 @@ export default {
     dingInstanceD: [],
     typeOptions: [],
     classifyList: [],
+    OSSData: {},
+    excelFileList: [],
   },
 
   effects: {
@@ -591,6 +594,25 @@ export default {
         });
       }
     },
+    *getChartOSSData({ callback, payload }, { call, put }) {
+      const res = yield call(ChartTempOSSData, payload);
+      if (res) {
+        yield put({
+          type: 'save',
+          payload: { OSSData: res.data },
+        });
+        callback && callback();
+      }
+    },
+    *QueryExcelFiles({ callback, payload }, { call, put }) {
+      const response = yield call(queryFiles, payload);
+      if (response) {
+        yield put({
+          type: 'save',
+          payload: { excelFileList: response.data.list },
+        });
+      }
+    },
   },
 
   reducers: {

+ 4 - 0
src/services/boom.js

@@ -462,3 +462,7 @@ export async function queryTrySeal(params) {
   });
   return res;
 }
+
+export async function ChartTempOSSData(params) {
+  return request(`/purchase/bom/contract-file/${params.projectId}`);
+}

+ 2 - 2
webpack.config.js

@@ -7,6 +7,6 @@ module.exports = {
       libs: path.resolve(__dirname, 'src/components/react-timeline-gantt-master/src/lib/'),
     },
   },
-  // test: /\.(pdf|svg|docx|doc)$/,
-  // use: 'file-loader', //如果不可以试试这个file-loader?name=[path][name].[ext]
+  test: /\.(pdf|svg|docx|doc)$/,
+  use: 'file-loader', //如果不可以试试这个file-loader?name=[path][name].[ext]
 };