xujunjie 3 жил өмнө
parent
commit
ff319c8376

+ 7 - 7
src/components/Flow/config-cmd.ts

@@ -47,13 +47,13 @@ export const useCmdConfig = props => {
             }, 100);
           },
         }),
-        hooks.updateNode.registerHook({
-          name: 'updateNode',
-          handler: async args => {
-            const { nodeConfig } = args;
-            props.onUpdate?.(nodeConfig);
-          },
-        }),
+        // hooks.updateNode.registerHook({
+        //   name: 'updateNode',
+        //   handler: async args => {
+        //     const { nodeConfig } = args;
+        //     props.onUpdate?.(nodeConfig);
+        //   },
+        // }),
       ];
       const toDispose = new DisposableCollection();
       toDispose.pushAll(list);

+ 3 - 1
src/components/Flow/index.less

@@ -41,7 +41,9 @@
     left: 0;
     z-index: 1000;
   }
-
+  .xflow-json-schema-form-footer {
+    display: none;
+  }
   .flowchart-demo {
     .__dumi-default-previewer-actions {
       border: 0;

+ 1 - 1
src/components/Flow/node/FlowFormPanel.tsx

@@ -8,7 +8,7 @@ const CustomFlowchartFormPanel = () => {
   return (
     <FlowchartFormPanel
       show={true}
-      position={{ width: 200, top: 40, bottom: 0, right: 0 }}
+      position={{ width: 240, top: 40, bottom: 0, right: 0 }}
       controlMapService={controlMapService}
       formSchemaService={formSchemaService}
     ></FlowchartFormPanel>

+ 12 - 2
src/components/Flow/node/circle/index.tsx

@@ -1,17 +1,27 @@
 import React from 'react';
 import CircleServe from './mapServe';
 import { Badge } from 'antd';
+import { useXFlowApp, XFlowNodeCommands } from '@antv/xflow';
 export { CircleServe };
 
 export default function CustomRect(props) {
   const { size = { width: 90, height: 90 }, data } = props;
   const { width, height } = size;
   const { label, stroke, fill, fontFill, fontSize } = data;
-
+  const app = useXFlowApp();
+  const handleClick = () => {
+    // console.log(data);
+    app.executeCommand(XFlowNodeCommands.SELECT_NODE.id, {
+      nodeId: data.id,
+    });
+    // console.log('XFlowNodeCommands.SELECT_NODE.id', data);
+    // message.success(`${XFlowNodeCommands.SELECT_NODE.label}: 命令执行成功`);
+  };
   return (
-    <Badge count={data.count} offset={[-10, 10]}>
+    <Badge count={data.version?.length} offset={[-10, 10]}>
       <div
         className="container"
+        onClick={handleClick}
         style={{
           width,
           height,

+ 56 - 11
src/components/Flow/node/circle/mapServe.tsx

@@ -1,7 +1,10 @@
 import React, { useState, useEffect } from 'react';
 import { FlowchartFormWrapper } from '@antv/xflow';
-import { Position, Size, ColorPicker, InputNumberFiled, InputFiled } from '../fields';
+import { Position, Size, ColorPicker, InputNumberFiled, InputFiled, SelectField } from '../fields';
 import { PREFIX } from '../constants';
+import { connect } from 'dva';
+import { UnityAction } from '@/utils/utils';
+import { Button } from 'antd';
 
 export interface IConfig {
   label?: string;
@@ -14,24 +17,39 @@ export interface IConfig {
   fontFill?: string;
   fill?: string;
   stroke?: string;
+  flow_id?: string;
+  flow_node_id?: string;
 }
 
 const Component = (props: any) => {
-  const { config, plugin = {} } = props;
+  const { config, plugin = {}, auditList } = props;
   const { updateNode } = plugin;
   const [nodeConfig, setNodeConfig] = useState<IConfig>({
     ...config,
   });
-  const onNodeConfigChange = (key: string, value: number | string) => {
-    setNodeConfig({
-      ...nodeConfig,
-      [key]: value,
-    });
-    updateNode({
-      [key]: value,
-    });
+  const onNodeConfigChange = (key: string, value: number | string | object) => {
+    if (key) {
+      setNodeConfig({
+        ...nodeConfig,
+        [key]: value,
+      });
+      updateNode({
+        [key]: value,
+      });
+    } else if (value instanceof Object) {
+      setNodeConfig({
+        ...nodeConfig,
+        ...value,
+      });
+      updateNode({
+        ...value,
+      });
+    }
   };
 
+  const onSave = () => {
+    UnityAction.emit('NODE_SAVE', nodeConfig);
+  };
   useEffect(() => {
     setNodeConfig({
       ...config,
@@ -50,6 +68,28 @@ const Component = (props: any) => {
           }}
         />
       </div>
+      <div className={`${PREFIX}-panel-group`}>
+        <h5>数据</h5>
+        <SelectField
+          label="审核流程"
+          value={nodeConfig.flow_id}
+          onChange={value => {
+            let audit = auditList.find(item => item.list.id == value);
+
+            onNodeConfigChange(null, {
+              flow_node_id: audit.list.FlowNodes[0]?.id,
+              flow_id: value,
+            });
+          }}
+          options={auditList.map(item => {
+            const list = item.list;
+            return {
+              label: list.name || list.id,
+              value: list.id,
+            };
+          })}
+        />
+      </div>
       <div className={`${PREFIX}-panel-group`}>
         <h5>样式</h5>
         <Position
@@ -105,14 +145,19 @@ const Component = (props: any) => {
           }}
         />
       </div>
+      <Button style={{ marginTop: 20 }} type="primary" onClick={onSave}>
+        保存
+      </Button>
     </div>
   );
 };
 
-export default function RecthServe(props: any) {
+function RecthServe(props: any) {
   return (
     <FlowchartFormWrapper {...props}>
       {(config, plugin) => <Component {...props} plugin={plugin} config={config} />}
     </FlowchartFormWrapper>
   );
 }
+
+export default connect(({ xflow }) => ({ auditList: xflow.auditList }))(RecthServe);

+ 1 - 1
src/components/Flow/node/rect/index.tsx

@@ -21,7 +21,7 @@ export default function CustomRect(props) {
   };
 
   return (
-    <Badge count={data.verison?.length}>
+    <Badge count={data.version?.length}>
       <div
         style={{
           width,

+ 29 - 11
src/components/Flow/node/rect/mapServe.tsx

@@ -1,6 +1,6 @@
 import React, { useState, useEffect } from 'react';
 import { FlowchartFormWrapper } from '@antv/xflow';
-import { message } from 'antd';
+import { Button, message } from 'antd';
 import LuckyExcel from 'luckyexcel';
 import {
   Position,
@@ -10,9 +10,9 @@ import {
   InputFiled,
   UploadFiled,
   RadioField,
-  SelectField,
 } from '../fields';
 import { PREFIX } from '../constants';
+import { UnityAction } from '@/utils/utils';
 
 export interface IConfig {
   label?: string;
@@ -45,14 +45,28 @@ const Component = (props: any) => {
     ...defaultConfig,
     ...config,
   });
-  const onNodeConfigChange = (key: string, value: any) => {
-    setNodeConfig({
-      ...nodeConfig,
-      [key]: value,
-    });
-    updateNode({
-      [key]: value,
-    });
+  const onNodeConfigChange = (key: string, value: number | string | object) => {
+    if (key) {
+      setNodeConfig({
+        ...nodeConfig,
+        [key]: value,
+      });
+      updateNode({
+        [key]: value,
+      });
+    } else if (value instanceof Object) {
+      setNodeConfig({
+        ...nodeConfig,
+        ...value,
+      });
+      updateNode({
+        ...value,
+      });
+    }
+  };
+
+  const onSave = () => {
+    UnityAction.emit('NODE_SAVE', nodeConfig);
   };
 
   const beforeUpload = (file: any) => {
@@ -73,7 +87,7 @@ const Component = (props: any) => {
         }
         return { sheet_name: sheet.name, col_idx: item.r, col_axis: item.c, col_value: value };
       });
-      updateNode({
+      onNodeConfigChange(null, {
         data: [sheet],
         excel_info: {
           file_name: file.name,
@@ -89,6 +103,7 @@ const Component = (props: any) => {
       ...config,
     });
   }, [config]);
+  // console.log(nodeConfig, config)
 
   return (
     <div className={`${PREFIX}-panel-body`}>
@@ -198,6 +213,9 @@ const Component = (props: any) => {
           />
         </div>
       </div>
+      <Button type="primary" onClick={onSave}>
+        保存
+      </Button>
     </div>
   );
 };

+ 11 - 1
src/models/xflow.js

@@ -1,4 +1,4 @@
-import { queryOSSData,queryBoomFlowDetail } from '@/services/boom';
+import { queryOSSData, queryBoomFlowDetail, queryAuditList } from '@/services/boom';
 import { message } from 'antd';
 
 export default {
@@ -6,6 +6,7 @@ export default {
   state: {
     OSSData: {},
     flowDetail: { nodes: [], edges: [] },
+    auditList: [],
   },
 
   effects: {
@@ -26,6 +27,15 @@ export default {
         payload: { flowDetail: data },
       });
     },
+    *queryAuditList({ payload }, { call, put }) {
+      const response = yield call(queryAuditList, payload);
+      if (response) {
+        yield put({
+          type: 'save',
+          payload: { auditList: response.data },
+        });
+      }
+    },
   },
 
   reducers: {

+ 49 - 19
src/pages/PurchaseAdmin/PurchaseList/Detail/CommitAuditModal.js

@@ -5,22 +5,42 @@ import { Modal, Input, Select } from 'antd';
 import { connect } from 'dva';
 
 const { TextArea } = Input;
+const { Option } = Select;
 
 // 提交
 function CommitModal(props) {
-  const { visible, onClose, onOk, form, loading, version, flowDetail } = props;
-
+  const { visible, onClose, onOk, form, loading, version, flowDetail, auditList } = props;
+  const [auditId, setAuditId] = useState();
   const handleOk = () => {
     form.validateFields((err, fieldsValue) => {
       if (err) return;
-      onOk(fieldsValue);
+      let nextNode = flowDetail.nodes.find?.(item => item.Id == fieldsValue.node_id);
+      let { list: flow } = auditList.find(item => item.list.id == nextNode?.flow_id);
+      let params = {
+        desc: fieldsValue.desc,
+        // 审核流程id
+        flow_id: flow?.id || 0,
+        node_level_id: flow?.FlowNodes[0]?.seq || 0,
+
+        id: version.id,
+        project_id: version.project_id,
+        template_node_id: nextNode.Id, // 将要流转的节点
+        cur_template_node_id: version.template_node_id * 1, // 当前节点
+        next_template_node_id: fieldsValue.next_template_node_id * 1, // 审核完成后的业务节点
+
+        // 模板id.一致就行
+        template_id: version.template_id,
+        cur_template_id: version.template_id,
+        next_template_id: version.template_id,
+      };
+      console.log(params);
+      onOk(params);
     });
   };
   const currentNodeId = useMemo(() => {
-    let Id = version.template_node_id
-    return flowDetail.nodes.find?.(item => item.Id == Id)
-  },[flowDetail,version])
-
+    let Id = version.template_node_id;
+    return flowDetail.nodes.find?.(item => item.Id == Id)?.node_id;
+  }, [flowDetail, version]);
   /**
    *
    * @param {*} currentId 当前节点
@@ -29,7 +49,7 @@ function CommitModal(props) {
    */
   const getNextNodes = (currentId, type) => {
     const { edges, nodes } = flowDetail;
-    if (!currentId) return;
+    if (!currentId) return [];
     let targetIds = edges
       .filter(edge => edge.source.cell == currentId)
       .map(item => item.target.cell);
@@ -37,6 +57,11 @@ function CommitModal(props) {
     return auditNodes || [];
   };
 
+  const changeAudit = id => {
+    let node = flowDetail.nodes.find?.(item => item.Id == id);
+    setAuditId(node.node_id);
+  };
+
   return (
     <Modal
       confirmLoading={loading}
@@ -47,28 +72,33 @@ function CommitModal(props) {
       onOk={handleOk}
     >
       <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="审批节点">
-        {form.getFieldDecorator('version_name')(
-          <Select style={{ width: '100%' }}>
-            {/* <Option>节点1</Option> */}
-            {/* {getNextNodes(currentNodeId,"custom-circle").map(item => <Option key={item.Id}>{item.label}</Option>)} */}
+        {form.getFieldDecorator('node_id')(
+          <Select style={{ width: '100%' }} onChange={changeAudit}>
+            {getNextNodes(currentNodeId, 'custom-circle').map(item => (
+              <Option key={item.Id}>{item.label}</Option>
+            ))}
           </Select>
         )}
       </Form.Item>
       <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="业务节点">
-        {form.getFieldDecorator('description')(
+        {form.getFieldDecorator('next_template_node_id')(
           <Select style={{ width: '100%' }}>
-            {/* <Option>节点1</Option> */}
-            {/* {getNextNodes(auditId,"custom-rect").map(item => <Option key={item.Id}>{item.label}</Option>)} */}
+            {getNextNodes(auditId || currentNodeId, auditId ? 'custom-rect' : 'custom-circle').map(
+              item => (
+                <Option key={item.Id}>{item.label}</Option>
+              )
+            )}
           </Select>
         )}
       </Form.Item>
       <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="备注信息">
-        {form.getFieldDecorator('description')(<Input.TextArea />)}
+        {form.getFieldDecorator('desc')(<Input.TextArea />)}
       </Form.Item>
     </Modal>
   );
 }
 
-export default connect(({ xflow }) => ({ flowDetail: xflow.flowDetail }))(
-  Form.create()(CommitModal)
-);
+export default connect(({ xflow, detail }) => ({
+  auditList: detail.auditList,
+  flowDetail: xflow.flowDetail,
+}))(Form.create()(CommitModal));

+ 55 - 49
src/pages/PurchaseAdmin/PurchaseList/Detail/CompareModal.js

@@ -1,34 +1,14 @@
 import React, { useEffect, useState, useRef } from 'react';
 import { Form } from '@ant-design/compatible';
 import '@ant-design/compatible/assets/index.css';
-import {
-  Steps,
-  Button,
-  Drawer,
-  Comment,
-  Tooltip,
-  Avatar,
-  List,
-  Card,
-  Modal,
-  Checkbox,
-  Row,
-  Col,
-  message,
-  Input,
-  Table,
-  Alert,
-  Spin,
-  Tabs,
-} from 'antd';
+import { Modal, Checkbox, Row, Col, message, Tabs } from 'antd';
+import { connect } from 'dva';
 
-const { Step } = Steps;
-const { TextArea } = Input;
 const { TabPane } = Tabs;
 
 // 选择比对版本
 function CompareModal(props) {
-  const { visible, onClose, onOk, list } = props;
+  const { visible, versionList, onClose, onOk, historyList, dispatch, version } = props;
 
   const [checkValue, setCheckValue] = useState([]);
   const [tabList, setTabList] = useState([]);
@@ -42,17 +22,34 @@ function CompareModal(props) {
     }
   };
 
+  const changeAcitve = versionId => {
+    setActive(versionId);
+    if (!versionId || historyList[versionId]) return;
+    // 查询历史提交
+    dispatch({
+      type: 'detail/queryHistoryList',
+      payload: {
+        version_id: versionId,
+      },
+    });
+  };
+
   const handleOk = () => {
     if (checkValue.length != 2) {
       message.error('请选择要比对的两个文件');
     } else {
-      let checkSheet = checkValue.map(id => {
-        var item = list.find(sheet => sheet.id == id);
-        return {
-          ...item,
-          name: item.version_name,
-        };
+      let checkSheet = [];
+
+      Object.values(historyList).forEach(verList => {
+        if(checkSheet.length >= 2) return;
+        verList.forEach(item => {
+          if(checkValue.indexOf(item.id) != -1) {
+            checkSheet.push(item)
+          }
+        })
+        
       });
+      // console.log(checkSheet);
       onOk(checkSheet);
       onClose();
       setCheckValue([]);
@@ -60,21 +57,25 @@ function CompareModal(props) {
   };
 
   useEffect(() => {
-    let obj = {};
-    list.forEach(item => {
-      let nodeId = item.NodeInfo.id;
-      if (!obj[nodeId])
-        obj[nodeId] = {
-          list: [],
-          id: nodeId + '',
-          name: item.NodeInfo.node,
-        };
-      obj[nodeId].list.push(item);
-    });
-    let arr = Object.values(obj).map(item => item);
-    setTabList(arr);
-    setActive(arr[0]?.id);
-  }, [list]);
+    changeAcitve(version.id);
+  }, [version.id]);
+
+  // useEffect(() => {
+  //   let obj = {};
+  //   list.forEach(item => {
+  //     let nodeId = item.NodeInfo.id;
+  //     if (!obj[nodeId])
+  //       obj[nodeId] = {
+  //         list: [],
+  //         id: nodeId + '',
+  //         name: item.NodeInfo.node,
+  //       };
+  //     obj[nodeId].list.push(item);
+  //   });
+  //   let arr = Object.values(obj).map(item => item);
+  //   setTabList(arr);
+  //   setActive(arr[0]?.id);
+  // }, [list]);
 
   return (
     <Modal
@@ -85,11 +86,12 @@ function CompareModal(props) {
       bodyStyle={{ paddingTop: 0 }}
     >
       <Checkbox.Group value={checkValue} style={{ width: '100%' }} onChange={onChange}>
-        <Tabs activeKey={active} onChange={setActive}>
-          {tabList.map(tab => (
-            <TabPane tab={tab.name} key={tab.id}>
+        <Tabs activeKey={active} onChange={changeAcitve}>
+          {/* {tabList.map(tab => ( */}
+          {versionList.map(version => (
+            <TabPane tab={version.version_name} key={version.id}>
               <Row>
-                {tab.list.map(item => (
+                {(historyList[version.id] || []).map(item => (
                   <Col span={8} key={item.id}>
                     <Checkbox value={item.id}>{item.version_name}</Checkbox>
                   </Col>
@@ -102,4 +104,8 @@ function CompareModal(props) {
     </Modal>
   );
 }
-export default CompareModal
+
+export default connect(({ detail }) => ({
+  historyList: detail.historyList,
+  versionList: detail.versionList,
+}))(CompareModal);

+ 15 - 9
src/pages/PurchaseAdmin/PurchaseList/Detail/FlowModal.js

@@ -12,17 +12,11 @@ const localData = JSON.parse(localStorage.ggDetaiData || '{}');
 function FlowModal(props) {
   const { visible, onClose, onChangeVersion, form, loading, flowDetail, versionList } = props;
   const [data, setData] = useState([]);
-  const handleOk = () => {
-    form.validateFields((err, fieldsValue) => {
-      if (err) return;
-      onOk(fieldsValue);
-    });
-  };
 
   const graphData = useMemo(() => {
     let nodes = flowDetail.nodes.map(item => ({
       ...item,
-      verison: versionList.filter(version => version.template_node_id == item.Id) || [],
+      version: versionList.filter(version => version.template_node_id == item.Id) || [],
     }));
     return {
       nodes,
@@ -31,6 +25,7 @@ function FlowModal(props) {
   }, [flowDetail, versionList]);
 
   const handleSelectNode = node => {
+    console.log(node);
     setData(node.version);
   };
 
@@ -44,7 +39,7 @@ function FlowModal(props) {
       footer={false}
       width="80%"
     >
-      <Flow meta={{ type: 'view' }} flowDetail={flowDetail} onSelectNode={handleSelectNode} />
+      <Flow meta={{ type: 'view' }} flowDetail={graphData} onSelectNode={handleSelectNode} />
       <List
         size="small"
         header={<div>版本列表</div>}
@@ -52,7 +47,18 @@ function FlowModal(props) {
         dataSource={data}
         style={{ marginTop: 20 }}
         renderItem={item => (
-          <List.Item actions={[<a onClick={() => onChangeVersion(item)}>切换</a>]}>
+          <List.Item
+            actions={[
+              <a
+                onClick={() => {
+                  onChangeVersion(item);
+                  onClose();
+                }}
+              >
+                切换
+              </a>,
+            ]}
+          >
             {item.version_name}
           </List.Item>
         )}

+ 9 - 37
src/pages/PurchaseAdmin/PurchaseList/Detail/HistoryModal.js

@@ -1,33 +1,10 @@
 import React, { useEffect, useState, useRef } from 'react';
-import { Form } from '@ant-design/compatible';
-import '@ant-design/compatible/assets/index.css';
-import {
-  Steps,
-  Button,
-  Drawer,
-  Comment,
-  Tooltip,
-  Avatar,
-  List,
-  Card,
-  Modal,
-  Checkbox,
-  Row,
-  Col,
-  message,
-  Input,
-  Table,
-  Alert,
-  Spin,
-  Tabs,
-} from 'antd';
+import { Modal, Table } from 'antd';
+import { connect } from 'dva';
 
-const { Step } = Steps;
-const { TextArea } = Input;
-const { TabPane } = Tabs;
 // 历史版本
 function HistoryModal(props) {
-  const { visible, onClose, onSelect, onCompare, onChange, data } = props;
+  const { visible, onClose, version, onSelect, historyList } = props;
   const handleSelect = item => {
     onSelect(item);
     onClose();
@@ -41,11 +18,6 @@ function HistoryModal(props) {
       title: '描述',
       dataIndex: 'desc',
     },
-    {
-      title: '所属节点',
-      dataIndex: 'NodeInfo',
-      render: info => info.node,
-    },
     {
       title: '操作',
       render: record => (
@@ -55,14 +27,14 @@ function HistoryModal(props) {
       ),
     },
   ];
-  const onClick = item => {
-    onClose();
-    onSelect(item);
-  };
+  
+
   return (
     <Modal title="版本记录" width="60%" onCancel={onClose} visible={visible} footer={false}>
-      <Table rowKey="id" columns={columns} dataSource={data.list} />
+      <Table rowKey="id" columns={columns} dataSource={historyList[version.id]} />
     </Modal>
   );
 }
-export default HistoryModal
+export default connect(({ detail }) => ({
+  historyList: detail.historyList,
+}))(HistoryModal);

+ 109 - 49
src/pages/PurchaseAdmin/PurchaseList/Detail/Index.js

@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useRef } from 'react';
+import React, { useEffect, useState, useRef, useMemo } from 'react';
 import { DownOutlined } from '@ant-design/icons';
 import { Button, Modal, message, Alert, Spin, Select, Menu, Dropdown } from 'antd';
 import { connect } from 'dva';
@@ -26,7 +26,7 @@ let cell_position = {};
 
 function Detail(props) {
   const {
-    flow,
+    // flow,
     dispatch,
     comment,
     history,
@@ -36,10 +36,10 @@ function Detail(props) {
     roleList,
     template,
     versionList,
+    auditList,
     match: { params },
   } = props;
   // const audit_status = 0
-  const audit_status = history.list[0]?.audit_status;
   const [commentVisible, setCommentVisible] = useState(false);
   const [historyVisible, setHistoryVisible] = useState(false);
   const [compareVisible, setCompareVisible] = useState(false);
@@ -69,10 +69,32 @@ function Detail(props) {
     edit: false,
     compare: false,
   });
+  const audit_status = version.audit_status;
 
   const excelId = parseInt(params.excelId);
   const projectId = parseInt(params.projectId);
 
+  const flow = useMemo(() => {
+    let data = {
+      active: 0,
+      current: 0,
+      currentNode: {},
+      list: {
+        FlowNodes: [],
+      },
+    };
+    if (version?.flow_id && auditList?.length > 0) {
+      let item = auditList.find(item => item.list.id == version.flow_id);
+      if (!item) return data;
+      item.current = item.list.FlowNodes.findIndex(node => node.id == item.active);
+      item.current = item.current == -1 ? 0 : item.current;
+      item.currentNode = item.list.FlowNodes[item.current];
+      data = item;
+    }
+
+    return data;
+  }, [auditList, version]);
+
   const onSave = () => {
     setEdit(false);
     statusRef.current.edit = false;
@@ -137,7 +159,10 @@ function Detail(props) {
   const renderSheetDom = (item, index) => {
     return (
       <div key={item?.id || 'temp'} className={styles.sheetItem}>
-        <h3>{item?.name}</h3>
+        <h3>
+          {item?.name}
+          {item.version_name && `(${item.version_name})`}
+        </h3>
         <LuckySheet
           className={styles.sheet}
           ref={!index ? sheetRef : sheetRef2}
@@ -308,18 +333,6 @@ function Detail(props) {
             flow_id: flowNode.flow_id,
             node_id: flowNode.id,
           },
-          callback: (flow, sheets) => {
-            if (flag) {
-              // 更新excel id后 跳转新页面
-              router.push(`/home/detail/${sheets.id}/${projectId}`);
-              // 更新版本列表
-              sheets.excel_id = sheets.id;
-              sheets.name = sheets.version_name;
-              delete sheets.id;
-              queryHistory(sheets.excel_id);
-              setSheet(sheets);
-            }
-          },
         });
       },
     });
@@ -435,14 +448,14 @@ function Detail(props) {
         // 模板
         handleClickFile();
         break;
-      case 'auditSuccess':
-        // 审核通过
-        onApprove(true);
-        break;
-      case 'auditFailed':
-        // 审核拒绝
-        onApprove(false);
-        break;
+      // case 'auditSuccess':
+      //   // 审核通过
+      //   onApprove(true);
+      //   break;
+      // case 'auditFailed':
+      //   // 审核拒绝
+      //   onApprove(false);
+      //   break;
       case 'edit':
         // 编辑
         handleEdit(true);
@@ -509,10 +522,7 @@ function Detail(props) {
       menuList.push(<Menu.Item key="version">历史提交</Menu.Item>);
       // menuList.push(<Menu.Item key="template">模板</Menu.Item>);
     }
-    if (isAuditor) {
-      menuList.push(<Menu.Item key="auditSuccess">审批通过</Menu.Item>);
-      menuList.push(<Menu.Item key="auditFailed">审批拒绝</Menu.Item>);
-    } else if (canEdit()) {
+    if (!isAuditor && canEdit()) {
       menuList.push(<Menu.Item key="edit">编辑</Menu.Item>);
       menuList.push(<Menu.Item key="merge">合并</Menu.Item>);
       menuList.push(<Menu.Item key="commit">提交</Menu.Item>);
@@ -521,11 +531,23 @@ function Detail(props) {
       }
     }
     return (
-      <Dropdown overlay={<Menu onClick={handleMenuClick}>{menuList}</Menu>}>
-        <Button type="primary">
-          其他操作 <DownOutlined />
-        </Button>
-      </Dropdown>
+      <>
+        {isAuditor && (
+          <>
+            <Button type="primary" onClick={() => onApprove(true)}>
+              审批通过
+            </Button>
+            <Button onClick={() => onApprove(false)} danger>
+              审批拒绝
+            </Button>
+          </>
+        )}
+        <Dropdown overlay={<Menu onClick={handleMenuClick}>{menuList}</Menu>}>
+          <Button type="primary">
+            其他操作 <DownOutlined />
+          </Button>
+        </Dropdown>
+      </>
     );
   };
 
@@ -678,14 +700,12 @@ function Detail(props) {
     window.location.href = `${record.url}`;
   };
 
-  const onChangeVersion = version => {
-    // TODO 查询version对应内容,渲染到界面上
-  };
-
   const changeVersion = id => {
     let version = versionList.find(item => item.id == id);
+    if (!version) return message.error('版本不存在!');
     setVersion(version);
-    sheetRef.current.renderSheet([]);
+
+    // 查询excel内容
     dispatch({
       type: 'detail/queryRecord',
       payload: {
@@ -695,9 +715,38 @@ function Detail(props) {
         version_id: version.id,
       },
       callback: sheets => {
+        console.log(sheets);
+        setSheet(sheets);
         sheetRef.current.renderSheet(sheets.data);
       },
     });
+
+    // 查询历史修改
+    dispatch({
+      type: 'detail/queryHistoryList',
+      payload: {
+        version_id: version.id,
+      },
+    });
+    // 判断是否审批节点
+    // dispatch({
+    //   type: 'detail/queryAuditList',
+    //   payload: {
+    //     template_id: version.template_id ,
+    //     template_node_id: version.template_node_id ,
+    //      flow_id: version.flow_id
+    //   }
+    // })
+  };
+
+  const onSubmitNextNode = values => {
+    dispatch({
+      type: 'detail/submitNextNode',
+      payload: values,
+      callback: () => {
+        setCommitAuditVisible(false);
+      },
+    });
   };
 
   useEffect(() => {
@@ -713,7 +762,10 @@ function Detail(props) {
         id: 1,
       },
     });
-
+    // 审批流程
+    dispatch({
+      type: 'detail/queryAuditList',
+    });
     // 查询节点
     // dispatch({
     //   type: 'detail/queryFlowInfo',
@@ -767,10 +819,14 @@ function Detail(props) {
     }
   }, [compareList]);
 
-  // useEffect(() => {
-  //   // 根据excel id查询历史版本
-  //   queryHistory();
-  // }, [excelId]);
+  useEffect(() => {
+    if (versionList.length == 0) return;
+    if (!version.id) {
+      changeVersion(excelId);
+    } else {
+      changeVersion(version.id);
+    }
+  }, [versionList]);
 
   return (
     <Spin spinning={false}>
@@ -780,7 +836,10 @@ function Detail(props) {
       </Button>
       <div className={styles.top}>
         <div>
-          当前节点: {version.template_node_id}/当前状态:{version.audit_status}
+          {/* 当前节点: {version.template_node_id}
+          <br />
+          当前状态:{version.audit_status} */}
+          {flow.active !== 0 && <TimeNode flow={flow}></TimeNode>}
         </div>
         <div className={styles.btns}>
           {renderBtns()}
@@ -798,7 +857,7 @@ function Detail(props) {
             ))}
           </Select>
         </div>
-        {/* <TimeNode flow={flow}></TimeNode>
+        {/* 
        
         <div className={styles.btns}>{renderBtns()}</div>
          */}
@@ -832,14 +891,14 @@ function Detail(props) {
       />
       <HistoryModal
         visible={historyVisible}
-        data={history}
+        version={version}
         // onChange={queryHistory}
         onClose={() => setHistoryVisible(false)}
         onSelect={item => exportSheet(item)}
       />
       <CompareModal
         visible={compareVisible}
-        list={history.list}
+        version={version}
         onClose={() => setCompareVisible(false)}
         onOk={onCompare}
       />
@@ -860,7 +919,7 @@ function Detail(props) {
         visible={flowVisible}
         onClose={() => setFlowVisible(false)}
         // onOk={onCommit}
-        onChangeVersion={onChangeVersion}
+        onChangeVersion={version => changeVersion(version.id)}
       />
       <AuditModal
         loading={getLoading()}
@@ -888,7 +947,7 @@ function Detail(props) {
         visible={commitAuditVisible}
         version={version}
         onClose={() => setCommitAuditVisible(false)}
-        onOk={() => {}}
+        onOk={onSubmitNextNode}
       />
     </Spin>
   );
@@ -896,6 +955,7 @@ function Detail(props) {
 
 export default connect(({ detail, user, loading }) => ({
   flow: detail.flow,
+  auditList: detail.auditList,
   fileList: detail.fileList,
   history: detail.history,
   comment: detail.comment,

+ 109 - 40
src/pages/PurchaseAdmin/PurchaseList/Detail/models/detail.js

@@ -3,23 +3,28 @@ import {
   // commitSheet,
   querySheet,
   queryHistory,
-  queryHistoryDetail,
+  // queryHistoryDetail,
   queryComment,
   addComment,
   createExcel,
   queryExcel,
   updateFlowInfo,
   submitAudit,
-  approve,
+  // approve,
   queryFiles,
   deleteFiles,
 } from '@/services/PurchaseList';
 import {
+  queryAuditList,
   queryVersionsList,
   queryProjectRecord,
   queryRecord,
   commitSheet,
   queryDetail,
+  queryHistoryList,
+  queryHistoryDetail,
+  submitNextNode,
+  approve
 } from '@/services/boom';
 import { queryRole } from '@/services/SysAdmin';
 import { setCurrentUser } from '@/utils/authority';
@@ -34,6 +39,8 @@ export default {
     template: {},
     version: {},
     versionList: [],
+    historyList: [],
+    auditList: [],
 
     flow: {
       active: 0,
@@ -75,8 +82,8 @@ export default {
             type: 'queryVersionsList',
             payload: {
               ...payload,
-              template_id,
-              template_node_id,
+              // template_id,
+              // template_node_id,
             },
             callback,
           });
@@ -90,16 +97,23 @@ export default {
     *queryVersionsList({ payload, callback }, { call, put }) {
       const response = yield call(queryVersionsList, payload);
       if (response) {
-        let version = response.data[0];
-        if (version) {
-          yield put({
-            type: 'save',
-            payload: {
-              version,
-              versionList: response.data,
-            },
-          });
-        }
+        callback && callback();
+        yield put({
+          type: 'save',
+          payload: {
+            versionList: response.data,
+          },
+        });
+      }
+    },
+    *queryAuditList({ payload }, { call, put }) {
+      const response = yield call(queryAuditList, payload);
+      if (response) {
+        console.log(response);
+        yield put({
+          type: 'save',
+          payload: { auditList: response.data || [] },
+        });
       }
     },
     // 查询子版本详情
@@ -133,8 +147,22 @@ export default {
           type: 'queryVersionsList',
           payload: {
             project_id: payload.project_id,
-            template_id: payload.template_id,
-            template_node_id: payload.template_node_id,
+            // template_id: payload.template_id,
+            // template_node_id: payload.template_node_id,
+          },
+          callback,
+        });
+      }
+    },
+    // 提交流转
+    *submitNextNode({ payload, callback }, { call, put }) {
+      let response = yield call(submitNextNode, payload);
+      if (response) {
+        message.success('提交成功');
+        yield put({
+          type: 'queryVersionsList',
+          payload: {
+            project_id: payload.project_id,
           },
           callback,
         });
@@ -153,6 +181,38 @@ export default {
         callback?.(sheet);
       }
     },
+    *queryHistoryList({ payload, callback }, { call, put, select }) {
+      const response = yield call(queryHistoryList, {
+        ...payload,
+        pageSize: 9999,
+      });
+      if (response) {
+        console.log(response);
+        yield put({
+          type: 'saveHistory',
+          payload: {
+            [payload.version_id]: response.data.list,
+          },
+        });
+      }
+    },
+    // 审批
+    *approve({ payload, callback }, { call, put }) {
+      try {
+        const response = yield call(approve, payload);
+        if (response) {
+          message.success('操作成功');
+          yield put({
+            type: 'queryVersionsList',
+            payload: {
+              projectId: payload.projectId,
+            },
+          });
+        }
+      } catch (error) {
+        console.error(error);
+      }
+    },
 
     // =================================================================================================================================
     *queryFlowInfo({ payload, callback }, { call, put }) {
@@ -234,30 +294,30 @@ export default {
         });
       }
     },
-    *approve({ payload, callback }, { call, put }) {
-      try {
-        const response = yield call(approve, payload);
-        if (response) {
-          message.success('操作成功');
-          yield put({
-            type: 'queryHistory',
-            payload: {
-              projectId: payload.projectId,
-              excel_id: payload.id,
-            },
-          });
-          yield put({
-            type: 'queryFlowInfo',
-            payload: {
-              projectId: payload.project_id,
-            },
-            callback,
-          });
-        }
-      } catch (error) {
-        console.error(error);
-      }
-    },
+    // *approve({ payload, callback }, { call, put }) {
+    //   try {
+    //     const response = yield call(approve, payload);
+    //     if (response) {
+    //       message.success('操作成功');
+    //       yield put({
+    //         type: 'queryHistory',
+    //         payload: {
+    //           projectId: payload.projectId,
+    //           excel_id: payload.id,
+    //         },
+    //       });
+    //       yield put({
+    //         type: 'queryFlowInfo',
+    //         payload: {
+    //           projectId: payload.project_id,
+    //         },
+    //         callback,
+    //       });
+    //     }
+    //   } catch (error) {
+    //     console.error(error);
+    //   }
+    // },
 
     *queryHistoryDetail({ payload, callback }, { call, put }) {
       const response = yield call(queryHistoryDetail, payload);
@@ -387,6 +447,15 @@ export default {
   },
 
   reducers: {
+    saveHistory(state, action) {
+      return {
+        ...state,
+        historyList: {
+          ...state.historyList,
+          ...action.payload,
+        },
+      };
+    },
     save(state, action) {
       return {
         ...state,

+ 38 - 23
src/pages/PurchaseAdmin/PurchaseList/Flow/Flow.js

@@ -1,34 +1,35 @@
 import Flow, { FLOW_TYPE } from '@/components/Flow';
 import { connect } from 'dva';
 import React, { useEffect } from 'react';
-// import { Form } from 'antd';
+import { UnityAction } from '@/utils/utils';
+import { Button } from 'antd';
+import Link from 'umi/link';
 
 @connect(({ xflow }) => ({ flowDetail: xflow.flowDetail }))
 class FlowPage extends React.PureComponent {
   onUpdate(node) {
     const { dispatch, flowDetail } = this.props;
-    console.log(node);
-    if (node.is_start_node && node.bom_template) {
-      let params = {
-        ...node,
-        id: node.Id,
-        node_type: 0,
-        data: JSON.stringify(node.data),
-        project_id: flowDetail.ProjectId,
-        template_id: flowDetail.Id,
-        template_name: flowDetail.Name,
-      };
-      // delete params.label;
-      dispatch({
-        type: 'flow/updateNode',
-        payload: {
-          templateId: flowDetail.Id,
-          nodeId: node.Id,
-          body: params,
-        },
-      });
-    }
+    let params = {
+      ...node,
+      id: node.Id,
+      node_type: node.name == 'custom-circle' ? 1 : 0,
+
+      data: JSON.stringify(node.data),
+      project_id: flowDetail.ProjectId,
+      template_id: flowDetail.Id,
+      template_name: flowDetail.Name,
+    };
+    delete params.node_id;
+    dispatch({
+      type: 'flow/updateNode',
+      payload: {
+        templateId: flowDetail.Id,
+        nodeId: node.Id,
+        body: params,
+      },
+    });
   }
+
   componentDidMount() {
     const { dispatch } = this.props;
     dispatch({
@@ -40,16 +41,30 @@ class FlowPage extends React.PureComponent {
         id: 1,
       },
     });
+    dispatch({
+      type: 'xflow/queryAuditList',
+    });
+
+    UnityAction.on('NODE_SAVE', nodeConfig => {
+      this.onUpdate(nodeConfig);
+    });
+  }
+  componentWillUnmount() {
+    UnityAction.off('NODE_SAVE');
   }
   render() {
     const { flowDetail } = this.props;
     return (
       <div>
         {/* <Form></Form> */}
+        <Link to="/home/audit" style={{ marginBottom: 20 }}>
+          <Button style={{ marginBottom: 20 }}>流程管理</Button>
+        </Link>
+
         <Flow
           meta={{ type: 'edit', flowId: 1 }}
           flowDetail={flowDetail}
-          onUpdate={node => this.onUpdate(node)}
+          // onUpdate={node => this.onUpdate(node)}
         />
       </div>
     );

+ 1 - 0
src/pages/PurchaseAdmin/PurchaseList/Flow/models/flow.js

@@ -11,6 +11,7 @@ export default {
   namespace: 'flow',
   state: {
     flowDetail: { nodes: [], edges: [] },
+    auditList: [],
   },
 
   effects: {

+ 2 - 2
src/pages/PurchaseAdmin/PurchaseList/List/NewList.js

@@ -19,8 +19,8 @@ function List(props) {
     //   },
     // },
     {
-      title: '当前节点',
-      dataIndex: 'NodeInfo.node',
+      title: '版本名称',
+      dataIndex: 'version_name',
     },
     {
       title: '操作',

+ 29 - 8
src/services/boom.js

@@ -18,11 +18,39 @@ export async function commitSheet(params) {
     body: params
   });
 }
+export async function approve(params) {
+  return request(`/purchase/audit/status`, {
+    method: 'POST',
+    body: params
+  });
+}
+
+/**
+ * 提交流转
+  "id":3, 当前流转文档id,必填
+  "project_id":46, 所属项目id
+  "template_id":1, 所属模板id ,必填
+  "template_node_id":34,所属节点id,必填
+  "next_template_id":1,跳转的下级业务模板id,必填
+  "next_template_node_id":2,跳转的下级业务节点id,必填
+  "flow_id":1, 跳转的下级审核流程id , 如果不为空,则说明流转的是审核节点,下级业务节点为审核通过后进入的业务节点
+  "node_id":1,跳转的下级审核节点id
+  "desc":"流转描述"
+ */
+export async function submitNextNode(params) {
+  return request(`/purchase/next/node/submit`, {
+    method: 'POST',
+    body: params
+  });
+}
 
 export async function queryDetail(params) {
   return request(`/purchase/record?${stringify(params)}`);
 }
 export async function queryHistoryDetail(params) {
+  return request(`/purchase/record/history/detail?${stringify(params)}`);
+}
+export async function queryHistoryList(params) {
   return request(`/purchase/record/history?${stringify(params)}`);
 }
 
@@ -115,16 +143,9 @@ export async function queryBoomFlowDetail(params) {
   };
   let nodes = data.Nodes.map(item => {
     let node = {
-      Id: item.Id,
+      ...item,
       id: item.node_id,
-      name: item.name,
       renderKey: item.render_key,
-      color: item.color,
-      height: item.height,
-      label: item.label,
-      width: item.width,
-      x: item.x,
-      y: item.y,
       zIndex: item.z_index,
       isCustom: !!item.is_custom,
       ports: JSON.parse(item.ports || '{}'),