123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- import React, { useEffect, useState, useRef, useMemo } from 'react';
- import '@ant-design/compatible/assets/index.css';
- import { Modal, Input, Select, message, Cascader, Form, Tabs, Row, Col, Empty, Button } from 'antd';
- import { connect } from 'dva';
- import { isArray, result } from 'lodash';
- import { useForm } from 'rc-field-form';
- import { async } from '@antv/x6/lib/registry/marker/async';
- import AuditDetailed from './AuditDetailed';
- import AuditFlow from './AuditFlow';
- import { queryDingSchema, queryProcessFlows } from '@/services/boom';
- import { Form as Form3x } from '@ant-design/compatible';
- import { getCurrentUser } from '@/utils/authority';
- import DDCode from '@/components/DDComponents/DDCode';
- import { uploadFile } from '@/services/boom';
- const { TextArea } = Input;
- const { Option } = Select;
- const { TabPane } = Tabs;
- // 提交
- function CommitAuditModal(props) {
- const {
- visible,
- onClose,
- onOk,
- loading,
- version,
- versionList,
- flowDetail,
- currentUser,
- luckysheet,
- } = props;
- const [auditId, setAuditId] = useState();
- const [data, setData] = useState([]);
- const [length, setLength] = useState(1);
- const [formData, setFromData] = useState({});
- const [auditList, setAuditList] = useState([]); //用于创建Tabs表单
- const [formComponentValues, setFormComponentValues] = useState({}); //用于创建Tabs表单
- const [form] = Form.useForm();
- useEffect(() => {
- if (!visible) return;
- const { edges, nodes } = flowDetail;
- let Id = version.template_node_id;
- const currentId = flowDetail.nodes.find?.(item => item.Id == Id)?.node_id;
- const data = treeData(currentId);
- if (data.length <= 0) setAuditId(currentId);
- setData(data);
- }, [auditId, version.template_node_id, visible]);
- useEffect(() => {
- form.resetFields();
- setAuditList([]);
- }, [visible]);
- const treeData = currentId => {
- const list = getNextNodes(currentId, 'custom-circle');
- const fun = nodes => {
- const re = nodes?.forEach((item, idx) => {
- const data = getNextNodes(item.Id, 'custom-circle');
- if (data || data.length > 0) list.push(...data);
- fun(data);
- });
- };
- fun(list);
- const fun2 = list => {
- const parents = list.filter(item => list.findIndex(node => node.Id == item.parentId) == -1);
- let translator = (parents, children) => {
- setLength(length + 1);
- parents.forEach(parent => {
- children.forEach((current, index) => {
- if (current.parentId === parent.Id) {
- let temp = JSON.parse(JSON.stringify(children));
- temp.splice(index, 1);
- translator([current], temp);
- if (!parent.children.find(item => item.Id == current.Id))
- parent.children.push(current);
- }
- });
- });
- };
- translator(parents, list);
- return parents;
- };
- return fun2(list);
- };
- const currentNodeId = useMemo(() => {
- let Id = version.template_node_id;
- setAuditId(currentNodeId);
- return flowDetail.nodes.find?.(item => item.Id == Id)?.node_id;
- }, [flowDetail, version]);
- /**
- *
- * @param {*} currentId 当前节点
- * @param {*} type 下一个节点的类型 custom-circle: 审批节点 custom-rect: 业务节点
- * @returns
- */
- const getNextNodes = (currentId, type) => {
- const { edges, nodes } = flowDetail;
- if (!currentId) return [];
- //删除虚线通向的节点
- // let targetIds = edges
- // .filter(edge => {
- // let line = edge.attrs?.line?.strokeDasharray?.split(' ');
- // return edge.source.cell == currentId && line && line[0] == '0';
- // })
- // .map(item => item.target.cell);
- let targetIds = edges
- .filter(edge => edge.source.cell == currentId)
- .map(item => item.target.cell);
- edges.filter(edge => edge.source.cell == currentId);
- let auditNodes = nodes.filter(node => {
- if (type && node.name != type) {
- return false;
- }
- return targetIds.indexOf(node.id) != -1;
- });
- const result = auditNodes.map(item => {
- return {
- label: item.label,
- value: item.Id,
- Id: item.node_id,
- parentId: currentId,
- children: [],
- };
- });
- return result || [];
- };
- const changeAudit = id => {
- let node = flowDetail.nodes.find?.(item => item.Id == id);
- setAuditId(node.node_id);
- };
- const onChange = value => {
- changeAudit(value[value.length - 1]);
- setAuditListFun();
- };
- //处理tabs页
- const setAuditListFun = async () => {
- var fieldsValue = await form.validateFields();
- let addAuditList = [];
- let result = Object.values(fieldsValue)
- .map(item => {
- if (item && Array.isArray(item)) return item;
- })
- .filter(item => item)
- .flat(Infinity);
- let codeList = [...new Set(result)]
- .map(Id => {
- return flowDetail.nodes.find?.(item => item.Id == Id);
- })
- .filter(item => item);
- console.log('============', codeList);
- let flowIds = [...new Set(codeList.map(item => item.flow_id))].join(',');
- let data = await queryProcessFlows({ ids: flowIds });
- if (data && data?.length > 0) {
- let newlist = codeList.map(node => {
- let curData = data.find(item => item.id == node.flow_id);
- let newItem = {
- name: curData?.name,
- nodeId: node.Id,
- items: JSON.parse(curData.form_json),
- };
- return newItem;
- });
- addAuditList = [...addAuditList, ...newlist];
- }
- console.log(addAuditList);
- addAuditList.forEach((item, index) => {
- let Components = Form3x.create({
- onValuesChange: (props, changedValues, allValues) => {
- const { items } = props;
- formComponentValues[item.nodeId] = items
- .map(item => {
- const itemProps = item.props;
- let val = allValues[itemProps.id];
- if (!itemProps.label || val === '') return;
- if (val instanceof Object) {
- return {
- name: itemProps.label,
- id: itemProps.id,
- ...val,
- };
- } else if (allValues[itemProps.id]) {
- return {
- name: itemProps.label,
- id: itemProps.id,
- value: allValues[itemProps.id] || undefined,
- };
- }
- })
- .filter(item => item);
- setFormComponentValues({ ...formComponentValues });
- },
- })(AuditDetailed);
- item.FormComponents = <Components items={item.items} />;
- });
- setAuditList(addAuditList);
- };
- const getFromData = async idList => {
- const data = formComponentValues;
- const result = [];
- //获取流转节点的层级关系
- let len = 0;
- let list = [];
- idList.forEach(item => {
- if (len < item.length) len = item.length;
- });
- for (let i = 0; i < len; i++) {
- idList.forEach(item => {
- if (item && item[i]) list.push(item[i]);
- });
- }
- let firstList = [...new Set(list)];
- let attachment = await upload();
- firstList.forEach(id => {
- let approvalNode = flowDetail.nodes.find?.(item => item.Id == id);
- let values = data[approvalNode.Id] || [];
- const formItem = {
- flow_id: `${approvalNode.flow_id}`,
- template_node_id: `${approvalNode.Id}`,
- formComponentValues: [...values, { name: '附件', value: JSON.stringify(attachment) }],
- };
- result.push(JSON.stringify(formItem));
- });
- return result;
- };
- const onFinish = async () => {
- var fieldsValue = await form.validateFields();
- console.log();
- let hasFlowId = true; //是否都绑定审批节点
- const getFlowPath = node => {
- //[134, 135]
- let itemData = {};
- const Function = (curId, index) => {
- if (!curId) return;
- let data = {};
- let approvalNode = flowDetail.nodes.find?.(item => item.Id == curId);
- data.template_id = version.template_id;
- data.flow_id = approvalNode?.flow_id || 0;
- data.node_level_id = approvalNode?.flow_id ? 1 : 0;
- data.template_node_id = approvalNode?.Id;
- index++;
- if (approvalNode?.Id) {
- if (!approvalNode?.flow_id) {
- hasFlowId = false;
- }
- }
- const res = Function(node[index], index);
- if (res) {
- data.flow_path = [res];
- }
- return data;
- };
- itemData = Function(node[0], 0);
- return itemData;
- };
- let result = Object.values(fieldsValue)
- .map(item => {
- if (item && Array.isArray(item)) return item;
- })
- .filter(item => item);
- let serviceNode = flowDetail.nodes.find?.(item => item.Id == fieldsValue.next_template_node_id);
- if (!serviceNode) {
- message.error('请选择需要流转的业务节点。');
- return;
- }
- const flowPath = result.map(item => getFlowPath(item));
- const formList = await getFromData(result);
- let params = {
- desc: fieldsValue.desc,
- // 审核流程id
- // flow_id: approvalNode?.flow_id || 0,
- // node_level_id: approvalNode?.flow_id ? 1 : 0,
- id: version.id,
- project_id: version.project_id,
- cur_template_node_id: version.template_node_id * 1, // 当前节点
- next_template_node_id: serviceNode.Id * 1, // 审核完成后的业务节点
- // template_node_id: result[0][0], // 将要流转的节点审批节点
- // flow_path:flow_path, //审批节点数组
- // 模板id.一致就行
- template_id: version.template_id,
- cur_template_id: version.template_id,
- next_template_id: version.template_id,
- };
- if (result.length <= 0) {
- //直接走业务节点
- } else if (result.length <= 1 && result[0]?.length <= 1) {
- //单个审批节点
- let approvalNode = flowDetail.nodes.find?.(item => item.Id == result[0][0]);
- params.flow_id = approvalNode?.flow_id || 0;
- params.node_level_id = approvalNode?.flow_id ? 1 : 0;
- params.template_node_id = result[0][0]; // 将要流转的节点审批节点
- params.form_list = formList; //创建钉钉表单所需数据
- if (approvalNode?.Id) {
- if (!approvalNode?.flow_id) {
- hasFlowId = false;
- }
- }
- } else {
- //多节点审批
- params.template_node_id = result[0][0]; // 将要流转的节点审批节点
- params.flow_path = flowPath;
- params.form_list = formList; //创建钉钉表单所需数据
- }
- if (!hasFlowId) {
- message.error('当前存在审批节点未绑定审批流程!请联系管理员。');
- return;
- }
- onOk(params);
- };
- const CascaderNode = index => {
- return (
- <Form.Item
- labelCol={{ span: 7 }}
- wrapperCol={{ span: 15 }}
- label={`审批节点${index + 1}`}
- name={`circle${index}`}
- key={`circle${index}`}
- >
- <Cascader style={{ width: '100%' }} options={data} onChange={onChange} />
- </Form.Item>
- );
- };
- const upload = async () => {
- let blob = await luckysheet.current.getExcelBolb();
- let formData = new FormData();
- formData.append('userid', currentUser.DingUserId);
- formData.append('file', new File([blob], `${version.version_name}_${version.version_no}.xlsx`));
- try {
- let res = await uploadFile(formData);
- let data = JSON.parse(res.dentry);
- return [
- {
- spaceId: String(data.spaceId),
- fileName: data.name,
- fileSize: String(data.spaceId),
- fileType: data.extension,
- fileId: data.id,
- },
- ];
- } catch (error) {
- message.error('附件上传失败');
- }
- };
- return (
- <Modal
- confirmLoading={loading}
- destroyOnClose
- title="提交流转目标"
- width={1000}
- visible={visible}
- onCancel={() => {
- setAuditId();
- onClose();
- }}
- onOk={onFinish}
- >
- <Form form={form}>
- {data.map((item, idx) => (data.length == 1 ? CascaderNode('') : CascaderNode(idx)))}
- <Form.Item
- labelCol={{ span: 7 }}
- wrapperCol={{ span: 15 }}
- label="业务节点"
- name="next_template_node_id"
- >
- <Select style={{ width: '100%' }}>
- {getNextNodes(data.length < 0 ? currentNodeId : auditId, 'custom-rect').map(item => (
- <Option key={item.value}>{item.label}</Option>
- ))}
- </Select>
- </Form.Item>
- <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>
- <Tabs defaultActiveKey="1">
- {auditList.map((item, idx) => (
- <TabPane tab={item.name} key={`${idx}_${item.title}`}>
- <Row>
- <Col span={17}>{item.FormComponents}</Col>
- <Col offset={1} span={4}>
- {!formComponentValues[item.nodeId] ? (
- <Empty description="请先填写表单" />
- ) : (
- <AuditFlow
- processCode={item.formCode}
- formComponentValues={formComponentValues[item.nodeId]}
- direction={'vertical'}
- deptId={'14237557'}
- userId={currentUser.DingUserId || getCurrentUser()?.DingUserId}
- />
- )}
- </Col>
- </Row>
- </TabPane>
- ))}
- </Tabs>
- </Modal>
- );
- }
- export default connect(({ xflow, detail, user }) => ({
- flowDetail: xflow.flowDetail,
- versionList: detail.versionList,
- currentUser: user.currentUser,
- }))(CommitAuditModal);
|