CommitAuditModal.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import React, { useEffect, useState, useRef, useMemo } from 'react';
  2. import '@ant-design/compatible/assets/index.css';
  3. import { Modal, Input, Select, message, Cascader, Form } from 'antd';
  4. import { connect } from 'dva';
  5. import { isArray, result } from 'lodash';
  6. import { useForm } from 'rc-field-form';
  7. import { async } from '@antv/x6/lib/registry/marker/async';
  8. const { TextArea } = Input;
  9. const { Option } = Select;
  10. // 提交
  11. function CommitAuditModal(props) {
  12. const { visible, onClose, onOk, loading, version, versionList, flowDetail } = props;
  13. const [auditId, setAuditId] = useState();
  14. const [data, setData] = useState([])
  15. const [length, setLength] = useState(1)
  16. const [formData, setFromData] = useState({})
  17. const [form] = Form.useForm();
  18. useEffect(() => {
  19. const { edges, nodes } = flowDetail;
  20. let Id = version.template_node_id;
  21. const currentId = flowDetail.nodes.find?.(item => item.Id == Id)?.node_id
  22. const data = treeData(currentId)
  23. if(data.length <= 0) setAuditId(currentId)
  24. setData(data)
  25. }, [auditId, version.template_node_id])
  26. useEffect(()=>{
  27. form.resetFields()
  28. },[visible])
  29. const treeData = (currentId) => {
  30. const list = getNextNodes(currentId,'custom-circle');
  31. const fun = (nodes) => {
  32. const re = nodes?.forEach((item, idx)=>{
  33. const data = getNextNodes(item.Id,'custom-circle');
  34. if(data || data.length > 0) list.push(...data);
  35. fun(data)
  36. })
  37. }
  38. fun(list)
  39. console.log(list)
  40. const fun2 = (list) => {
  41. const parents = list.filter(item=>list.findIndex(node=>node.Id == item.parentId) == -1)
  42. let translator = (parents, children) => {
  43. setLength(length+1)
  44. parents.forEach((parent) => {
  45. children.forEach((current, index) => {
  46. if (current.parentId === parent.Id) {
  47. let temp = JSON.parse(JSON.stringify(children))
  48. temp.splice(index, 1)
  49. translator([current], temp)
  50. if(!parent.children.find(item=>item.Id == current.Id))parent.children.push(current)
  51. }
  52. })
  53. })
  54. }
  55. translator(parents, list)
  56. return parents
  57. }
  58. return fun2(list)
  59. }
  60. const currentNodeId = useMemo(() => {
  61. let Id = version.template_node_id;
  62. setAuditId(currentNodeId)
  63. return flowDetail.nodes.find?.(item => item.Id == Id)?.node_id;
  64. }, [flowDetail, version]);
  65. /**
  66. *
  67. * @param {*} currentId 当前节点
  68. * @param {*} type 下一个节点的类型 custom-circle: 审批节点 custom-rect: 业务节点
  69. * @returns
  70. */
  71. const getNextNodes = (currentId, type) => {
  72. const { edges, nodes } = flowDetail;
  73. if (!currentId) return [];
  74. let targetIds = edges
  75. .filter(edge => edge.source.cell == currentId)
  76. .map(item => item.target.cell);
  77. edges.filter(edge => edge.source.cell == currentId)
  78. let auditNodes = nodes.filter(node => {
  79. if (type && node.name != type) {
  80. return false;
  81. }
  82. return targetIds.indexOf(node.id) != -1;
  83. });
  84. const result = auditNodes.map(item=>{return { label:item.label, value:item.Id, Id:item.node_id,parentId:currentId, children:[]}})
  85. return result || [];
  86. };
  87. const changeAudit = id => {
  88. let node = flowDetail.nodes.find?.(item => item.Id == id);
  89. setAuditId(node.node_id);
  90. };
  91. const onChange = (value) => {
  92. changeAudit(value[value.length-1])
  93. };
  94. const onFinish = async() => {
  95. var fieldsValue = await form.validateFields();
  96. const getFlowPath = (node) => { //[134, 135]
  97. let itemData = {}
  98. const Function = (curId,index) => {
  99. if(!curId) return;
  100. let data = {}
  101. let approvalNode = flowDetail.nodes.find?.(item => item.Id == curId);
  102. data.template_id = version.template_id;
  103. data.flow_id = approvalNode?.flow_id || 0;
  104. data.node_level_id = approvalNode?.flow_id ? 1 : 0;
  105. data.template_node_id = approvalNode?.Id;
  106. index++;
  107. const res = Function(node[index], index);
  108. if(res) {
  109. data.flow_path = [res]
  110. }
  111. return data
  112. }
  113. itemData = Function(node[0], 0)
  114. return itemData
  115. }
  116. let result = Object.values(fieldsValue).map(item=> {if(item && Array.isArray(item)) return item}).filter(item=>item)
  117. let serviceNode = flowDetail.nodes.find?.(
  118. item => item.Id == fieldsValue.next_template_node_id
  119. );
  120. let params = {
  121. desc: fieldsValue.desc,
  122. // 审核流程id
  123. // flow_id: approvalNode?.flow_id || 0,
  124. // node_level_id: approvalNode?.flow_id ? 1 : 0,
  125. id: version.id,
  126. project_id: version.project_id,
  127. cur_template_node_id: version.template_node_id * 1, // 当前节点
  128. next_template_node_id: serviceNode.Id * 1, // 审核完成后的业务节点
  129. // template_node_id: result[0][0], // 将要流转的节点审批节点
  130. // flow_path:flow_path, //审批节点数组
  131. // 模板id.一致就行
  132. template_id: version.template_id,
  133. cur_template_id: version.template_id,
  134. next_template_id: version.template_id,
  135. };
  136. if(result.length <= 0){
  137. //直接走业务节点
  138. }else if(result.length <= 1 && result[0]?.length <= 1){
  139. //单个审批节点
  140. let approvalNode = flowDetail.nodes.find?.(item => item.Id == result[0][0]);
  141. params.flow_id = approvalNode?.flow_id || 0;
  142. params.node_level_id = approvalNode?.flow_id ? 1 : 0;
  143. params.template_node_id = result[0][0]; // 将要流转的节点审批节点
  144. }else{
  145. //多节点审批
  146. params.template_node_id = result[0][0]; // 将要流转的节点审批节点
  147. params.flow_path = result.map(item=>getFlowPath(item));
  148. }
  149. // if (approvalNode?.Id) {
  150. // if (!approvalNode?.flow_id) {
  151. // message.error('审批节点未绑定审批流程!请联系管理员。');
  152. // return;
  153. // }
  154. // }
  155. // setAuditId();
  156. onOk(params);
  157. }
  158. const CascaderNode = (index) => {
  159. return(
  160. <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label={`审批节点${index+1}`} name={`circle${index}`} key={`circle${index}`}>
  161. <Cascader style={{ width: '100%' }} options={data} onChange={onChange} />
  162. </Form.Item>
  163. )
  164. }
  165. return (
  166. <Modal
  167. confirmLoading={loading}
  168. destroyOnClose
  169. title="提交流转目标"
  170. visible={visible}
  171. onCancel={() => {
  172. setAuditId();
  173. onClose();
  174. }}
  175. onOk={onFinish}
  176. >
  177. <Form form={form}>
  178. {data.map((item, idx)=> data.length == 1? CascaderNode(''): CascaderNode(idx) )}
  179. <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="业务节点" name='next_template_node_id' >
  180. <Select style={{ width: '100%' }}>
  181. {getNextNodes(data.length < 0 ?currentNodeId : auditId, 'custom-rect' ).map(item => (
  182. <Option key={item.value}>{item.label}</Option>
  183. ))}
  184. </Select>
  185. </Form.Item>
  186. <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="备注信息" name="desc">
  187. <Input.TextArea />
  188. </Form.Item>
  189. </Form>
  190. </Modal>
  191. );
  192. }
  193. export default connect(({ xflow, detail }) => ({
  194. flowDetail: xflow.flowDetail,
  195. versionList: detail.versionList,
  196. }))(CommitAuditModal);