Browse Source

精简flow结构

Renxy 2 năm trước cách đây
mục cha
commit
98c72e94f4

+ 28 - 14
src/components/DDComponents/DepartmentField/index.js

@@ -1,9 +1,10 @@
 import { TreeSelect } from 'antd';
 import React, { useState, useEffect } from 'react';
 import { queryDDdepList } from '@/services/boom';
+import { connect } from 'dva';
 
 function DepartmentField(props) {
-  const { value, onChange } = props;
+  const { value, onChange, depUserTree } = props;
 
   // const [value, setValue] = useState();
   const [treeData, setTreeData] = useState([]);
@@ -30,31 +31,44 @@ function DepartmentField(props) {
 
   const onChangeValue = newValue => {
     console.log(newValue);
-    let dep = treeData.find(dep => dep.id == newValue);
-    onChange({ value: dep?.title, extValue: JSON.stringify([{ name: dep?.title }]) });
+    let dep = depUserTree.find(dep => dep.id == newValue);
+    onChange({ value: dep?.title, id: dep?.ID });
   };
 
-  useEffect(() => {
-    onLoadData({});
-  }, []);
+  // useEffect(() => {
+  //   onLoadData({});
+  // }, []);
 
   return (
+    // <TreeSelect
+    //   treeDataSimpleMode
+    //   style={{
+    //     width: '100%',
+    //   }}
+    //   // value={value}
+    //   dropdownStyle={{
+    //     maxHeight: 400,
+    //     overflow: 'auto',
+    //   }}
+    //   placeholder="请选择部门"
+    //   onChange={onChangeValue}
+    //   loadData={onLoadData}
+    //   treeData={treeData}
+    // />
     <TreeSelect
-      treeDataSimpleMode
-      style={{
-        width: '100%',
-      }}
-      // value={value}
+      showSearch
+      multiple
+      allowClear
       dropdownStyle={{
         maxHeight: 400,
         overflow: 'auto',
       }}
+      style={{ width: '100%' }}
       placeholder="请选择部门"
+      treeData={depUserTree}
       onChange={onChangeValue}
-      loadData={onLoadData}
-      treeData={treeData}
     />
   );
 }
 
-export default DepartmentField;
+export default connect(({ user }) => ({ depUserTree: user.depUserTree }))(DepartmentField);

+ 3 - 5
src/components/Flow/components/judgeComponent/index.tsx

@@ -38,7 +38,6 @@ const RenderJudge = (props: any) => {
   const { formItems = '', onChange, depUserTree } = props;
   let formData: FormItem[] = formItems ? JSON.parse(formItems) : [];
 
-  const [isBetween, setIsBetween] = useState(false);
   const handleChange = (values: any[], item: FormItem, condition?: Condition) => {
     const itemCur = formData.find(cur => cur.props.id == item.props.id);
     let judge: JudgeType = {
@@ -145,7 +144,6 @@ const RenderJudge = (props: any) => {
               defaultValue={judge?.values[0]}
               onChange={(value: number) => {
                 let newCondition: Condition = null;
-                value == 6 ? setIsBetween(true) : setIsBetween(false);
                 if (judge && judge.values && judge.values.length > 0) {
                   if (judge?.values[0] == 6 && value != 6) newCondition = {};
                   else if (judge.values[0] != 6 && value == 6) newCondition = {};
@@ -153,7 +151,7 @@ const RenderJudge = (props: any) => {
                 handleChange([value], item, newCondition);
               }}
             />
-            {isBetween ? (
+            {judge?.values[0] == 6 ? (
               <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                 <InputNumberFiled
                   value={judge?.condition?.smallValue}
@@ -164,7 +162,7 @@ const RenderJudge = (props: any) => {
                 <Select
                   defaultValue={judge?.condition?.smallSign}
                   onChange={(value: number) => {
-                    handleChange([], item, { ...judge?.condition, smallSign: value });
+                    handleChange([], item, { ...judge?.condition, smallSign: Number(value) });
                   }}
                 >
                   {SiginOptions.map(item => (
@@ -175,7 +173,7 @@ const RenderJudge = (props: any) => {
                 <Select
                   defaultValue={judge?.condition?.bigSign}
                   onChange={(value: number) => {
-                    handleChange([], item, { ...judge?.condition, bigSign: value });
+                    handleChange([], item, { ...judge?.condition, bigSign: Number(value) });
                   }}
                 >
                   {SiginOptions.map(item => (

+ 42 - 0
src/components/Flow/index.tsx

@@ -95,6 +95,48 @@ export const Demo: React.FC<IProps> = props => {
               };
               return node;
             });
+            data.nodes = data.nodes.map(item => {
+              let newItem = JSON.parse(JSON.stringify(item));
+              delete newItem.incomingEdges;
+              delete newItem.originData;
+              delete newItem.outgoingEdges;
+              delete newItem.ports.groups;
+              // let ports = { ...item.ports };
+              // delete ports.groups;
+              // return {
+              //   id: item.id,
+              //   renderKey: item.renderKey,
+              //   name: item.name,
+              //   label: item.label,
+              //   width: item.width,
+              //   height: item.height,
+              //   ports: ports,
+              //   isCustom: item.isCustom,
+              //   parentKey: item.parentKey,
+              //   x: item.x,
+              //   y: item.y,
+              //   zIndex: item.zIndex,
+              //   count: item.count,
+              // };
+              return newItem;
+            });
+            // graphData.edges = []
+            data.edges = data.edges.map(item => {
+              // delete item.data;
+              // delete item.attrs;
+              // delete item.sourcePort;
+              // delete item.sourcePortId;
+              // delete item.targetPort;
+              // delete item.targetPortId;
+              // delete item.zIndex;
+              return {
+                id: item.id,
+                source: item.source,
+                target: item.target,
+                // attr: JSON.stringify(item.attrs),
+              };
+            });
+
             console.log(data);
             console.log(JSON.stringify(data));
             cb?.(JSON.stringify(data), JSON.stringify(simpleNodes));

+ 106 - 10
src/pages/PurchaseAdmin/PurchaseList/Detail/Index.js

@@ -351,7 +351,100 @@ function Detail(props) {
     });
   };
 
-  const onApprove = (flag, taskId) => {
+  const onApprove = flag => {
+    if (!flag) {
+      setAuditVisible(true);
+      return;
+    }
+
+    let isSingle = false;
+    let serviceNode;
+    const flowNode = flow.currentNode;
+    const getLastTemplateNodeId = data => {
+      let result;
+      const getFun = item => {
+        if (item.flow_path?.length > 0) {
+          getFun(item.flow_path[0]);
+        } else {
+          result = item.template_node_id;
+        }
+      };
+      if (!data) return version.template_node_id;
+      getFun(data[0]);
+      return result;
+    };
+    let lastTemplateNodeId = version.template_node_id;
+    if (version.flow_path) {
+      //如果多节点审批  获取当前是否审批流程的最后一个审批节点
+      let flowPathList = JSON.parse(version.flow_path);
+      lastTemplateNodeId = getLastTemplateNodeId(flowPathList);
+    }
+
+    // 判断是否为最后一个审批节点
+    if (
+      lastTemplateNodeId == version.template_node_id &&
+      flow.current == flow.list.FlowNodes.length - 1
+    ) {
+      serviceNode = flowDetail.nodes.find?.(item => item.Id == version.next_template_node_id);
+      if (!serviceNode.muti_version) {
+        //audit_status=4 表示为清单推进后留存的副本.不计入多清单计算
+        isSingle = versionList.find(
+          item => item.audit_status != 4 && item.template_node_id == serviceNode.Id
+        );
+      }
+    }
+    Modal.confirm({
+      title: '提示',
+      content: isSingle
+        ? `节点【${serviceNode.label}】只能拥有一个清单,是否覆盖?`
+        : `是否通过审批。`,
+      okText: '确定',
+      cancelText: '取消',
+      onOk: () => {
+        dispatch({
+          type: 'detail/approve',
+          payload: {
+            id: flow.active_id,
+            project_id: projectId,
+            audit_status: 3,
+            flow_id: flowNode.flow_id,
+            node_id: flowNode.seq,
+          },
+          callback: newVersion => {
+            // 更新flow流程图
+            dispatch({
+              type: 'xflow/queryBoomFlowDetail',
+              payload: {
+                id: templateId,
+              },
+            });
+
+            // 更新审批流
+            dispatch({
+              type: 'detail/queryAuditList',
+              payload: {
+                template_id: version.template_id,
+                template_node_id: version.template_node_id,
+                flow_id: version.flow_id,
+                version_id: version.version_id,
+              },
+            });
+            if (flow.current == flow.list.FlowNodes.length - 1) {
+              // 最后一个审核节点通过后  需要更新version id 不更不更,留在原地
+              // localStorage.excelId = newVersion.id;
+              // setVersion({
+              //   ...version,
+              //   flow_id: newVersion.flow_id,
+              //   id: newVersion.id,
+              // });
+            }
+          },
+        });
+      },
+    });
+  };
+
+  const onApprove1 = (flag, taskId) => {
     const callback = () => {
       // 更新flow流程图
       dispatch({
@@ -796,12 +889,12 @@ function Detail(props) {
           version_id: version.version_id,
         },
       });
-      dispatch({
-        type: 'detail/queryDingInstanceDetail',
-        payload: {
-          process_instance_id: version.ding_instance_id, //创建表单成功返回的id
-        },
-      });
+      // dispatch({
+      //   type: 'detail/queryDingInstanceDetail',
+      //   payload: {
+      //     process_instance_id: version.ding_instance_id, //创建表单成功返回的id
+      //   },
+      // });
     }
   };
 
@@ -879,6 +972,9 @@ function Detail(props) {
     dispatch({
       type: 'user/fetch',
     });
+    dispatch({
+      type: 'user/fetchDepV2',
+    });
     dispatch({
       type: 'detail/queryListParentByUser',
       payload: {
@@ -958,10 +1054,10 @@ function Detail(props) {
           onChange={e => exportExcl(e.target.files)}
         />
       </div>
-      {/* <TimeNode flow={flow} isAuditor={isAuditor} onApprove={onApprove}></TimeNode> */}
-      {version.flow_id ? (
+      <TimeNode flow={flow} isAuditor={isAuditor} onApprove={onApprove}></TimeNode>
+      {/* {version.flow_id ? (
         <AuditFlow {...auditDetail} canShowAudit={true} onApprove={onApprove} />
-      ) : null}
+      ) : null} */}
 
       {/* {renderAlert()} */}
       {/* 判断是否为比对模式 */}

+ 24 - 2
src/pages/PurchaseAdmin/PurchaseList/Flow/Audit.js

@@ -14,13 +14,22 @@ const { TabPane } = Tabs;
 const FLOWID = 2;
 
 function Audit(props) {
-  const { roleList, currentItem, dispatch, formItems, formData, flowDetail } = props;
+  const {
+    roleList,
+    currentItem,
+    dispatch,
+    formItems,
+    formData,
+    flowDetail,
+    simpleFlowDteail,
+  } = props;
   const ref = useRef();
 
   const curItem = useMemo(() => {
     let item = localStorage.getItem('currentAudit');
     return JSON.stringify(currentItem) == '{}' ? JSON.parse(item) : currentItem;
   }, [currentItem, localStorage.getItem('currentAudit')]);
+  console.log('=====================', formData, flowDetail);
 
   useEffect(() => {
     dispatch({
@@ -45,7 +54,19 @@ function Audit(props) {
   };
 
   const handleSaveClick = async () => {
-    const data = await ref.current.getGraphData((data, simpleNodes) => {
+    //只修改表单不渲染xflow getGraphData方法找不到,保存接口返回的flowDetail数据
+    if (!ref.current?.getGraphData) {
+      let param = {
+        // name: curItem.name,
+        id: Number(curItem.id),
+        form_json: JSON.stringify(formItems),
+        process_json: JSON.stringify(flowDetail),
+        process_simple_json: simpleFlowDteail,
+      };
+      dispatch({ type: 'flow/saveAuditFlowInfo', payload: param });
+      return;
+    }
+    await ref.current?.getGraphData?.((data, simpleNodes) => {
       let param = {
         // name: curItem.name,
         id: Number(curItem.id),
@@ -84,4 +105,5 @@ export default connect(({ flow, loading, xflow }) => ({
   formItems: xflow.formData,
   flowDetail: flow.flowDetail,
   formData: flow.formData,
+  simpleFlowDteail: flow.simpleFlowDteail,
 }))(Audit);

+ 1 - 6
src/pages/PurchaseAdmin/PurchaseList/Flow/List.js

@@ -50,12 +50,7 @@ function List(props) {
     // dispatch({
     //   type: 'flow/getRoleList',
     // });
-    dispatch({
-      type: 'user/getRoleList',
-    });
-    dispatch({
-      type: 'user/fetchDepV2',
-    });
+
     // dispatch({
     //   type: 'flow/queryDingTemplateList',
     // });

+ 97 - 2
src/pages/PurchaseAdmin/PurchaseList/Flow/models/flow.js

@@ -41,6 +41,96 @@ function getDepUserTree(data) {
   return data;
 }
 
+const getFlowDetail = data => {
+  const groups = {
+    top: {
+      position: { name: 'top' },
+      attrs: {
+        circle: {
+          r: 4,
+          magnet: true,
+          stroke: '#31d0c6',
+          strokeWidth: 2,
+          fill: '#fff',
+          style: { visibility: 'hidden' },
+        },
+      },
+      zIndex: 10,
+    },
+    right: {
+      position: { name: 'right' },
+      attrs: {
+        circle: {
+          r: 4,
+          magnet: true,
+          stroke: '#31d0c6',
+          strokeWidth: 2,
+          fill: '#fff',
+          style: { visibility: 'hidden' },
+        },
+      },
+      zIndex: 10,
+    },
+    bottom: {
+      position: { name: 'bottom' },
+      attrs: {
+        circle: {
+          r: 4,
+          magnet: true,
+          stroke: '#31d0c6',
+          strokeWidth: 2,
+          fill: '#fff',
+          style: { visibility: 'hidden' },
+        },
+      },
+      zIndex: 10,
+    },
+    left: {
+      position: { name: 'left' },
+      attrs: {
+        circle: {
+          r: 4,
+          magnet: true,
+          stroke: '#31d0c6',
+          strokeWidth: 2,
+          fill: '#fff',
+          style: { visibility: 'hidden' },
+        },
+      },
+      zIndex: 10,
+    },
+  };
+  const attrs = {
+    line: {
+      stroke: '#A2B1C3',
+      targetMarker: { name: 'block', width: 12, height: 8 },
+      strokeDasharray: '5 5',
+      strokeWidth: 1,
+    },
+  };
+  let nodes = data.nodes.map(item => {
+    let node = { ...item };
+    node.ports.groups = groups;
+    node.parentKey = '1';
+
+    return node;
+  });
+  let edges = data.edges.map(item => {
+    let edge = { ...item };
+    try {
+      edge.attrs = item.attr ? JSON.parse(item.attr) : attrs;
+    } catch (error) {
+      edge.attrs = attrs;
+    }
+    return edge;
+  });
+  return {
+    ...data,
+    nodes,
+    edges,
+  };
+};
+
 export default {
   namespace: 'flow',
   state: {
@@ -53,6 +143,7 @@ export default {
     roleList: [],
     templateList: [],
     depUserTree: [],
+    simpleFlowDteail: '',
   },
 
   effects: {
@@ -165,11 +256,15 @@ export default {
     *queryProcessFlows({ payload }, { call, put }) {
       const data = yield call(queryProcessFlows, payload);
       if (data && data.length > 0) {
+        console.log(data);
         yield put({
           type: 'save',
           payload: {
-            flowDetail: JSON.parse(data[0].process_json),
-            formData: JSON.parse(data[0].form_json),
+            flowDetail: data[0].process_json
+              ? getFlowDetail(JSON.parse(data[0].process_json))
+              : { nodes: [], edges: [] },
+            formData: data[0].form_json ? JSON.parse(data[0].form_json) : [],
+            simpleFlowDteail: data[0].process_simple_json,
           },
         });
       }