CommitAuditModal.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. import React, { useEffect, useState, useRef, useMemo, useCallback } from 'react';
  2. import '@ant-design/compatible/assets/index.css';
  3. import {
  4. Modal,
  5. Input,
  6. Select,
  7. message,
  8. Cascader,
  9. Form,
  10. Tabs,
  11. Row,
  12. Col,
  13. Empty,
  14. Button,
  15. Steps,
  16. Popover,
  17. Upload,
  18. Table,
  19. Divider,
  20. Collapse,
  21. } from 'antd';
  22. import { PlusOutlined, UploadOutlined } from '@ant-design/icons';
  23. import { connect } from 'dva';
  24. import { isArray, result, set } from 'lodash';
  25. import { useForm } from 'rc-field-form';
  26. import { async } from '@antv/x6/lib/registry/marker/async';
  27. import AuditDetailed from './AuditDetailed';
  28. import AuditFlow from './AuditFlow';
  29. import {
  30. queryDingSchema,
  31. queryGetBomForm,
  32. queryProcessFlows,
  33. querySaveBomForm,
  34. } from '@/services/boom';
  35. import { Form as Form3x } from '@ant-design/compatible';
  36. import { getCurrentUser } from '@/utils/authority';
  37. import DDCode from '@/components/DDComponents/DDCode';
  38. import { uploadFile, queryUserListByRoleID } from '@/services/boom';
  39. import ApprovalProcess from './ApprovalProcess';
  40. import { uuidv4 } from '@antv/xflow';
  41. import AliyunOSSUpload from '@/components/OssUpload/AliyunOssUploader';
  42. import AttachmentTable from '@/components/AttachmentTable';
  43. import { getToken } from '@/utils/utils';
  44. import LuckyExcel from 'luckyexcel';
  45. const { TextArea } = Input;
  46. const { Option } = Select;
  47. const { TabPane } = Tabs;
  48. const { Step } = Steps;
  49. // 提交
  50. function CommitAuditModal(props) {
  51. const {
  52. dispatch,
  53. visible,
  54. onClose,
  55. // loading,
  56. version,
  57. versionList,
  58. flowDetail,
  59. currentUser,
  60. luckysheet,
  61. userList,
  62. templateId,
  63. OSSData,
  64. } = props;
  65. // console.log(loading);
  66. const [auditId, setAuditId] = useState();
  67. const [data, setData] = useState([]);
  68. const [length, setLength] = useState(1);
  69. const [formData, setFromData] = useState({});
  70. const [auditList, setAuditList] = useState([]); //用于创建Tabs表单
  71. const [formComponentValues, setFormComponentValues] = useState({}); //用于创建Tabs表单
  72. const [form] = Form.useForm();
  73. const [approvalProcess, setApprovalProcess] = useState({});
  74. const [selectUserList, setSelectUserList] = useState([]);
  75. const [curNodeIdx, setCurNodeIdx] = useState(-1);
  76. const [dataSource, setDataSource] = useState([]);
  77. const [loading, setLoading] = useState(false);
  78. const uploadList = useRef([]);
  79. useEffect(() => {
  80. if (!visible) return;
  81. const { edges, nodes } = flowDetail;
  82. // initFormList().then(approvalProcess => {
  83. let Id = version.template_node_id;
  84. const currentId = flowDetail.nodes.find?.(item => item.Id == Id)?.node_id;
  85. const data = treeData(currentId);
  86. console.log('===============审批节点======', data);
  87. const nextNodes = getNextNodes(currentId, 'custom-rect');
  88. if (data.length <= 0 || nextNodes.length > 0) {
  89. setAuditId(currentId);
  90. } else {
  91. let defaultValues = {};
  92. if (data.length == 1) {
  93. let value = getDataValue(data[0]);
  94. defaultValues[`circle`] = value;
  95. } else {
  96. data.forEach((item, index) => {
  97. let value = getDataValue(item);
  98. defaultValues[`circle${index}`] = value;
  99. });
  100. }
  101. // 设置延迟,等待组件渲染
  102. setTimeout(async () => {
  103. form.setFieldsValue(defaultValues);
  104. const approvalProcess = await initFormList();
  105. Object.values(defaultValues).forEach(value => onChange(value, approvalProcess || {}));
  106. }, 200);
  107. }
  108. setData(data);
  109. // });
  110. }, [version.template_node_id, visible]);
  111. useEffect(() => {
  112. if (!visible) return;
  113. dispatch({
  114. type: 'detail/getChartOSSData',
  115. payload: {
  116. projectId: version.project_id,
  117. },
  118. });
  119. }, [visible]);
  120. useEffect(() => {
  121. form.resetFields();
  122. setAuditList([]);
  123. }, [visible]);
  124. // const OnModelFileDone = file => {
  125. // var path = OSSData.host + '/' + file.url;
  126. // uploadList.current = [...uploadList.current, path];
  127. // console.log(uploadList.current);
  128. // };
  129. const setUploadList = files => {
  130. uploadList.current = files.map(file => OSSData.host + '/' + file.url);
  131. console.log(uploadList.current);
  132. };
  133. const OnUploading = file => {};
  134. const uploadProps = {
  135. OSSData: OSSData,
  136. // onDone: OnModelFileDone,
  137. onUploading: OnUploading,
  138. noStyle: false,
  139. onChange: setUploadList,
  140. // showUploadList: false,
  141. };
  142. const initFormList = async () => {
  143. const res = await queryGetBomForm({
  144. project_id: version.project_id,
  145. node_id: version.template_node_id,
  146. });
  147. if (res.data) {
  148. const formList = JSON.parse(res.data.json);
  149. setApprovalProcess(formList.approvalProcess || {});
  150. return formList.approvalProcess;
  151. // setFormComponentValues(defaultFormData);
  152. }
  153. };
  154. const treeData = currentId => {
  155. const list = getNextNodes(currentId, 'custom-circle');
  156. const fun = nodes => {
  157. const re = nodes?.forEach((item, idx) => {
  158. const data = getNextNodes(item.Id, 'custom-circle');
  159. if (data || data.length > 0) list.push(...data);
  160. fun(data);
  161. });
  162. };
  163. fun(list);
  164. const fun2 = list => {
  165. const parents = list.filter(item => list.findIndex(node => node.Id == item.parentId) == -1);
  166. let translator = (parents, children) => {
  167. setLength(length + 1);
  168. parents.forEach(parent => {
  169. children.forEach((current, index) => {
  170. if (current.parentId === parent.Id) {
  171. let temp = JSON.parse(JSON.stringify(children));
  172. temp.splice(index, 1);
  173. translator([current], temp);
  174. if (!parent.children.find(item => item.Id == current.Id))
  175. parent.children.push(current);
  176. }
  177. });
  178. });
  179. };
  180. translator(parents, list);
  181. return parents;
  182. };
  183. return fun2(list);
  184. };
  185. const currentNodeId = useMemo(() => {
  186. let Id = version.template_node_id;
  187. setAuditId(currentNodeId);
  188. return flowDetail.nodes.find?.(item => item.Id == Id)?.node_id;
  189. }, [flowDetail, version]);
  190. /**
  191. *
  192. * @param {*} currentId 当前节点
  193. * @param {*} type 下一个节点的类型 custom-circle: 审批节点 custom-rect: 业务节点
  194. * @returns
  195. */
  196. const getNextNodes = (currentId, type) => {
  197. const { edges, nodes } = flowDetail;
  198. if (!currentId) return [];
  199. //删除虚线通向的节点
  200. // let targetIds = edges
  201. // .filter(edge => {
  202. // let line = edge.attrs?.line?.strokeDasharray?.split(' ');
  203. // return edge.source.cell == currentId && line && line[0] == '0';
  204. // })
  205. // .map(item => item.target.cell);
  206. console.log(
  207. '---------',
  208. edges.filter(edge => edge.source.cell == currentId)
  209. );
  210. let targetIds = edges
  211. .filter(edge => edge.source.cell == currentId)
  212. .map(item => item.target.cell);
  213. edges.filter(edge => edge.source.cell == currentId);
  214. let auditNodes = nodes.filter(node => {
  215. if (type && node.name != type) {
  216. return false;
  217. }
  218. return targetIds.indexOf(node.id) != -1;
  219. });
  220. const result = auditNodes.map(item => {
  221. return {
  222. label: item.label,
  223. value: item.Id,
  224. Id: item.node_id,
  225. parentId: currentId,
  226. children: [],
  227. };
  228. });
  229. return result || [];
  230. };
  231. const nextNodesList = useMemo(() => {
  232. if (!auditId && !currentNodeId) return [];
  233. return getNextNodes(auditId || currentNodeId, 'custom-rect');
  234. }, [auditId, currentNodeId, flowDetail]);
  235. const changeAudit = id => {
  236. let node = flowDetail.nodes.find?.(item => item.Id == id);
  237. setAuditId(node?.node_id);
  238. };
  239. const onChange = (value) => {
  240. if (value) {
  241. changeAudit(value[value.length - 1]);
  242. setAuditListFun(approvalProcess);
  243. } else {
  244. changeAudit('');
  245. setAuditList([]);
  246. setApprovalProcess({});
  247. }
  248. form.setFieldValue('next_template_node_id', '');
  249. };
  250. const getReComputeAudit = (items, changedValues) => {
  251. const id = Object.keys(changedValues)[0];
  252. const formItem = items?.find(item => item.props.id == id);
  253. if (formItem && formItem.props?.required) return true;
  254. return false;
  255. };
  256. //填写表单实时计算审批流程
  257. const advanceSubmit = async () => {
  258. console.log('重重新计算审批流程');
  259. var fieldsValue = await form.validateFields();
  260. let hasFlowId = true; //是否都绑定审批节点
  261. let result = Object.values(fieldsValue)
  262. .map(item => {
  263. if (item && Array.isArray(item)) return item;
  264. })
  265. .filter(item => item);
  266. const formList = await getFromData(result);
  267. let params = {
  268. desc: fieldsValue.desc,
  269. // 审核流程id
  270. flow_id: 0,
  271. node_level_id: 0,
  272. id: version.id,
  273. project_id: version.project_id,
  274. cur_template_node_id: version.template_node_id * 1, // 当前节点
  275. next_template_node_id: 0, // 审核完成后的业务节点
  276. template_node_id: null, // 将要流转的节点审批节点
  277. flow_path: null, //审批节点数组
  278. // 模板id.一致就行
  279. template_id: version.template_id,
  280. cur_template_id: version.template_id,
  281. next_template_id: version.template_id,
  282. form_list: formList,
  283. };
  284. dispatch({
  285. type: 'detail/advanceSubmitNextNode',
  286. payload: params, //values,
  287. callback: data => {
  288. if (data) {
  289. setApprovalProcess(data);
  290. }
  291. },
  292. });
  293. };
  294. //处理tabs页
  295. const setAuditListFun = async (approvalProcess = {}) => {
  296. var fieldsValue = await form.validateFields();
  297. let addAuditList = [];
  298. let result = Object.values(fieldsValue)
  299. .map(item => {
  300. if (item && Array.isArray(item)) return item;
  301. })
  302. .filter(item => item)
  303. .flat(Infinity);
  304. let nodeList = [...new Set(result)]
  305. .map(Id => {
  306. return flowDetail.nodes.find?.(item => item.Id == Id);
  307. })
  308. .filter(item => item);
  309. let flowIds = [...new Set(nodeList.map(item => item.flow_id))].join(',');
  310. let data = await queryProcessFlows({ ids: flowIds });
  311. if (data && data?.length > 0) {
  312. let newlist = nodeList.map(node => {
  313. let curData = data.find(item => item.id == node.flow_id);
  314. let newItem = {
  315. name: curData?.name,
  316. nodeId: node.Id,
  317. items: JSON.parse(curData.form_json || '[]'),
  318. };
  319. return newItem;
  320. });
  321. addAuditList = [...addAuditList, ...newlist];
  322. }
  323. addAuditList.forEach((item, index) => {
  324. let Components = Form3x.create({
  325. onValuesChange: (props, changedValues, allValues) => {
  326. const { items } = props;
  327. formComponentValues[item.nodeId] = items
  328. .map(item => {
  329. const itemProps = item.props;
  330. let val = allValues[itemProps.id];
  331. if (!itemProps.label || val === '') return;
  332. if (val instanceof Object) {
  333. return {
  334. name: itemProps.label,
  335. id: itemProps.id,
  336. value: [...val],
  337. };
  338. } else if (allValues[itemProps.id]) {
  339. return {
  340. name: itemProps.label,
  341. id: itemProps.id,
  342. value: [allValues[itemProps.id]] || undefined,
  343. };
  344. }
  345. })
  346. .filter(item => item);
  347. if (getReComputeAudit(items, changedValues)) advanceSubmit();
  348. setFormComponentValues({ ...formComponentValues });
  349. },
  350. })(AuditDetailed);
  351. item.FormComponents = <Components items={item.items} />;
  352. });
  353. setAuditList(addAuditList);
  354. if (Object.keys(approvalProcess).length == 0) advanceSubmit();
  355. };
  356. const getFromData = async idList => {
  357. const data = formComponentValues;
  358. const result = [];
  359. //获取流转节点的层级关系
  360. let len = 0;
  361. let list = [];
  362. idList.forEach(item => {
  363. if (len < item.length) len = item.length;
  364. });
  365. for (let i = 0; i < len; i++) {
  366. idList.forEach(item => {
  367. if (item && item[i]) list.push(item[i]);
  368. });
  369. }
  370. let firstList = [...new Set(list)];
  371. // let attachment = await upload();
  372. firstList.forEach(id => {
  373. let approvalNode = flowDetail.nodes.find?.(item => item.Id == id);
  374. if (!approvalNode) return;
  375. let values = data[approvalNode.Id] || [];
  376. let audit_list = [],
  377. cc_list = [];
  378. approvalProcess[approvalNode.Id]?.forEach(item => {
  379. let arr = item[0].is_cc == 1 ? cc_list : audit_list;
  380. if (item[0].type == 'role') return arr.push(item[0].nowValue);
  381. return arr.push(item[0].value);
  382. });
  383. const formItem = {
  384. flow_id: approvalNode.flow_id,
  385. template_node_id: approvalNode.Id,
  386. formComponentValues: [...values], //{ name: '附件', value: JSON.stringify(attachment) }
  387. audit_list,
  388. cc_list,
  389. };
  390. result.push(JSON.stringify(formItem));
  391. });
  392. return result;
  393. };
  394. const getFlowPath = node => {
  395. //[134, 135]
  396. let itemData = {};
  397. const Function = (curId, index) => {
  398. if (!curId) return;
  399. let data = {};
  400. let approvalNode = flowDetail.nodes.find?.(item => item.Id == curId);
  401. data.template_id = version.template_id;
  402. data.flow_id = approvalNode?.flow_id || 0;
  403. data.node_level_id = approvalNode?.flow_id ? 1 : 0;
  404. data.template_node_id = approvalNode?.Id;
  405. index++;
  406. if (approvalNode?.Id) {
  407. if (!approvalNode?.flow_id) {
  408. hasFlowId = false;
  409. }
  410. }
  411. const res = Function(node[index], index);
  412. if (res) {
  413. data.flow_path = [res];
  414. }
  415. return data;
  416. };
  417. itemData = Function(node[0], 0);
  418. return itemData;
  419. };
  420. const onFinish = async () => {
  421. const isOk = Object.values(approvalProcess).every(item => {
  422. return item.every(cur => {
  423. if (cur[0].type == 'role') return cur[0].nowValue;
  424. return true;
  425. });
  426. });
  427. if (!isOk) {
  428. message.error('请选择审批人。');
  429. return;
  430. }
  431. var fieldsValue = await form.validateFields();
  432. let hasFlowId = true; //是否都绑定审批节点
  433. const getFlowPath = node => {
  434. //[134, 135]
  435. let itemData = {};
  436. const Function = (curId, index) => {
  437. if (!curId) return;
  438. let data = {};
  439. let approvalNode = flowDetail.nodes.find?.(item => item.Id == curId);
  440. data.template_id = version.template_id;
  441. data.flow_id = approvalNode?.flow_id || 0;
  442. data.node_level_id = approvalNode?.flow_id ? 1 : 0;
  443. data.template_node_id = approvalNode?.Id;
  444. index++;
  445. if (approvalNode?.Id) {
  446. if (!approvalNode?.flow_id) {
  447. hasFlowId = false;
  448. }
  449. }
  450. const res = Function(node[index], index);
  451. if (res) {
  452. data.flow_path = [res];
  453. }
  454. return data;
  455. };
  456. itemData = Function(node[0], 0);
  457. return itemData;
  458. };
  459. let result = Object.values(fieldsValue)
  460. .map(item => {
  461. if (item && Array.isArray(item)) return item;
  462. })
  463. .filter(item => item);
  464. let serviceNode = flowDetail.nodes.find?.(item => item.Id == fieldsValue.next_template_node_id);
  465. if (!serviceNode) {
  466. message.error('请选择需要流转的业务节点。');
  467. return;
  468. }
  469. const flowPath = result.map(item => getFlowPath(item));
  470. setLoading(true);
  471. try {
  472. const formList = await getFromData(result);
  473. let params = {
  474. desc: fieldsValue.desc,
  475. // 审核流程id
  476. // flow_id: approvalNode?.flow_id || 0,
  477. // node_level_id: approvalNode?.flow_id ? 1 : 0,
  478. id: version.id,
  479. project_id: version.project_id,
  480. cur_template_node_id: version.template_node_id * 1, // 当前节点
  481. next_template_node_id: serviceNode.Id * 1, // 审核完成后的业务节点
  482. // template_node_id: result[0][0], // 将要流转的节点审批节点
  483. // flow_path:flow_path, //审批节点数组
  484. // 模板id.一致就行
  485. template_id: version.template_id,
  486. cur_template_id: version.template_id,
  487. next_template_id: version.template_id,
  488. };
  489. if (serviceNode.node_type_psr == 3 || serviceNode.node_type_psr == 4) {
  490. params.data = await uploadExcelByUrl(serviceNode.node_type_psr, version.id);
  491. }
  492. // params.data = await uploadExcelByUrl(3, version.id);
  493. console.log(params);
  494. if (result.length <= 0) {
  495. //直接走业务节点
  496. } else if (result.length <= 1 && result[0]?.length <= 1) {
  497. //单个审批节点
  498. let approvalNode = flowDetail.nodes.find?.(item => item.Id == result[0][0]);
  499. params.flow_id = approvalNode?.flow_id || 0;
  500. params.node_level_id = approvalNode?.flow_id ? 1 : 0;
  501. params.template_node_id = result[0][0]; // 将要流转的节点审批节点
  502. params.form_list = formList; //创建钉钉表单所需数据
  503. if (approvalNode?.Id) {
  504. if (!approvalNode?.flow_id) {
  505. hasFlowId = false;
  506. }
  507. }
  508. } else {
  509. //多节点审批
  510. params.template_node_id = result[0][0]; // 将要流转的节点审批节点
  511. params.flow_path = flowPath;
  512. params.form_list = formList; //创建钉钉表单所需数据
  513. }
  514. if (!hasFlowId) {
  515. message.error('当前存在审批节点未绑定审批流程!请联系管理员。');
  516. return;
  517. }
  518. await querySaveBomForm({
  519. project_id: version.project_id,
  520. node_id: version.template_node_id,
  521. json: JSON.stringify({ approvalProcess }),
  522. });
  523. params.audit_series = uuidv4();
  524. params.files = uploadList.current.join(',');
  525. onSubmitNextNode(params);
  526. } catch (error) {
  527. console.error(error);
  528. }
  529. };
  530. const onSubmitNextNode = values => {
  531. dispatch({
  532. type: 'detail/submitNextNode',
  533. payload: values,
  534. callback: newVersion => {
  535. setLoading(false);
  536. onClose();
  537. // 更新flow流程图
  538. dispatch({
  539. type: 'xflow/queryBoomFlowDetail',
  540. payload: {
  541. id: templateId,
  542. },
  543. });
  544. },
  545. });
  546. };
  547. const CascaderNode = index => {
  548. return (
  549. <Form.Item
  550. labelCol={{ span: 7 }}
  551. wrapperCol={{ span: 15 }}
  552. label={`审批节点${index + 1}`}
  553. name={`circle${index}`}
  554. key={`circle${index}`}
  555. >
  556. <Cascader style={{ width: '100%' }} options={data} onChange={onChange} />
  557. </Form.Item>
  558. );
  559. };
  560. const upload = async () => {
  561. let blob = await luckysheet.current.getExcelBolb();
  562. let formData = new FormData();
  563. formData.append('userid', currentUser.DingUserId);
  564. formData.append('file', new File([blob], `${version.version_name}_${version.version_no}.xlsx`));
  565. try {
  566. let res = await uploadFile(formData);
  567. let data = JSON.parse(res.dentry);
  568. return [
  569. {
  570. spaceId: String(data.spaceId),
  571. fileName: data.name,
  572. fileSize: String(data.spaceId),
  573. fileType: data.extension,
  574. fileId: data.id,
  575. },
  576. ];
  577. } catch (error) {
  578. message.error('附件上传失败');
  579. }
  580. };
  581. const columns = [
  582. {
  583. title: '文件名称',
  584. dataIndex: 'name',
  585. key: 'name',
  586. },
  587. {
  588. title: '操作',
  589. render: record => <a>删除</a>,
  590. },
  591. ];
  592. useEffect(() => {
  593. if (!visible) {
  594. // 清空数据
  595. uploadList.current = [];
  596. }
  597. }, [visible]);
  598. return (
  599. <Modal
  600. confirmLoading={loading}
  601. destroyOnClose
  602. title="提交流转目标"
  603. width={1000}
  604. visible={visible}
  605. onCancel={() => {
  606. setAuditId();
  607. onClose();
  608. }}
  609. onOk={onFinish}
  610. >
  611. <Form form={form}>
  612. {data.map((item, idx) => (data.length == 1 ? CascaderNode('') : CascaderNode(idx)))}
  613. <Form.Item
  614. labelCol={{ span: 7 }}
  615. wrapperCol={{ span: 15 }}
  616. label="业务节点"
  617. name="next_template_node_id"
  618. // rules={[{ required: true, message: '请选择业务节点' }]}
  619. >
  620. <Select style={{ width: '100%' }}>
  621. {nextNodesList.map(item => (
  622. <Option key={item.value}>{item.label}</Option>
  623. ))}
  624. </Select>
  625. </Form.Item>
  626. <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="备注信息" name="desc">
  627. <Input.TextArea />
  628. </Form.Item>
  629. <Form.Item labelCol={{ span: 7 }} wrapperCol={{ span: 15 }} label="附件">
  630. {OSSData.host && <AliyunOSSUpload {...uploadProps} directory={false} label="上传文件" />}
  631. </Form.Item>
  632. </Form>
  633. <Collapse style={{ marginTop: 20 }}>
  634. <Collapse.Panel header="已上传附件" key="1">
  635. <AttachmentTable version={version} canDelete={version.last_version == 0} />
  636. </Collapse.Panel>
  637. </Collapse>
  638. <Tabs defaultActiveKey="1">
  639. {auditList.map((item, idx) => (
  640. <TabPane tab={item.name} key={`${idx}_${item.title}`}>
  641. <Row>
  642. <Col span={17}>{item.FormComponents}</Col>
  643. <Col offset={1} span={6}>
  644. {!approvalProcess[item.nodeId] ? ( //!formComponentValues[item.nodeId] ||
  645. <Empty description="请先填写表单" />
  646. ) : (
  647. <ApprovalProcess
  648. id={item.nodeId}
  649. approvalProcess={approvalProcess}
  650. onChange={setApprovalProcess}
  651. />
  652. )}
  653. </Col>
  654. </Row>
  655. </TabPane>
  656. ))}
  657. </Tabs>
  658. </Modal>
  659. );
  660. }
  661. function getDataValue(item) {
  662. let arr = [];
  663. arr.push(item.value);
  664. if (item.children?.length > 0) {
  665. let res = getDataValue(item.children[0]);
  666. arr = arr.concat(res);
  667. }
  668. return arr;
  669. }
  670. const uploadExcelByUrl = (nodeType, versionId) => {
  671. const TEMPLATE_URL =
  672. 'https://water-service-test.oss-cn-hangzhou.aliyuncs.com/doc/contract/2023-06-29/ed0d5dcd-6ce0-40df-9d17-a1f69245dbb9.xlsx';
  673. const TEMPLATE_URL2 =
  674. 'https://water-service-test.oss-cn-hangzhou.aliyuncs.com/doc/contract/2023-06-29/431733cd-0abc-4a68-a439-d24c466e9845.xlsx';
  675. return new Promise((reslove, reject) => {
  676. LuckyExcel.transformExcelToLuckyByUrl(
  677. nodeType == 3 ? TEMPLATE_URL : TEMPLATE_URL2,
  678. '模板.xlsx',
  679. async (exportJson, luckysheetfile) => {
  680. let [record] = await getExcel(versionId);
  681. let len = exportJson.sheets.length;
  682. const excelData = exportJson.sheets?.map(item => {
  683. return { ...item, order: Number(item.order) };
  684. });
  685. delete record.id;
  686. record.order = len;
  687. record.index = String(len);
  688. record.status = '0';
  689. record.name = '投标成本';
  690. var res = [...excelData, record];
  691. console.log(res);
  692. reslove(JSON.stringify(res));
  693. }
  694. );
  695. });
  696. };
  697. async function getExcel(gridKey) {
  698. var formData = new FormData();
  699. formData.append('gridKey', gridKey);
  700. let res = await fetch(
  701. `/api/v1/purchase/record/sheet?gridKey=${gridKey}&JWT-TOKEN=${getToken()}`,
  702. {
  703. method: 'POST',
  704. body: formData,
  705. }
  706. ).then(response => response.text());
  707. return JSON.parse(JSON.parse(res));
  708. }
  709. export default connect(({ xflow, detail, user }) => ({
  710. flowDetail: xflow.flowDetail,
  711. versionList: detail.versionList,
  712. currentUser: user.currentUser,
  713. userList: user.list,
  714. OSSData: detail.OSSData,
  715. }))(CommitAuditModal);