Commit 99153a3f authored by 邓超's avatar 邓超

fix: 流程中心

parent 3d7123dc
Pipeline #65819 passed with stages
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
import React, { useEffect, useState, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import classnames from 'classnames';
import { Tabs, Input, message, Modal } from 'antd';
import {
PlusOutlined,
EditOutlined,
DeleteOutlined,
ExclamationCircleOutlined,
} from '@ant-design/icons';
import FlowModal from './workFlowComponents/FlowModal';
import FlowGroupModal from './workFlowComponents/FlowGroupModal';
import styles from './WorkflowHomePage.less';
import { WFGetAllFlow, GetFlowNode, DeleteFlow } from '@/services/workflow/workflow';
const { Search } = Input;
const { confirm } = Modal;
const WorkflowHomePage = () => {
const history = useHistory();
const [flowList, setFlowList] = useState([]); // 流程列表
const [currentList, setCurrentList] = useState([]); // 当前tab显示列表
const [modalType, setModalType] = useState(''); // 弹窗类型是编辑还是新增
const [editMsg, setEditMsg] = useState({}); // 弹窗编辑回显
const [editIndex, setEditIndex] = useState(); // 编辑流程组得索引
const [flowNames, setFlowNames] = useState([]);
const [visible, setVisible] = useState({
FlowModal: false,
FlowGroupModal: false,
}); // 弹窗显示
const [flag, setFlag] = useState(0);
const activeKey = useRef(null);
useEffect(() => {
console.log(history.location.state, 'history.location.state');
if (history.location.state) {
activeKey.current = history.location.state.activeKey;
}
getFlowList();
}, []);
// 获取所有数据
const getFlowList = () => {
WFGetAllFlow().then(res => {
if (res.code === 0) {
let flowNameList = [];
let list = res.data.map(item => {
item.children.forEach(ele => {
flowNameList.push(ele.FlowName);
});
item.isOld = true;
return item;
});
setFlowList(list);
console.log(activeKey.current, 'activeKey');
if (activeKey.current) {
setCurrentList(list.filter(item => item.name === activeKey.current));
} else {
setCurrentList(list);
}
console.log(flowNameList, 'flowNameList');
setFlowNames(flowNameList);
}
});
};
// 弹窗显示控制
const showModal = (key, value) => {
setVisible({ ...visible, [key]: value });
};
// 查看所有
const chageAll = () => {
// setActiveKey(null);
activeKey.current = null;
setCurrentList(flowList);
};
// 搜索
const onSearch = val => {
let copyList = JSON.parse(JSON.stringify(flowList));
let list = activeKey.current
? copyList.filter(item => item.name === activeKey.current)
: copyList;
if (val) {
list.forEach(item => {
item.children = item.children.filter(ele => ele.FlowName.includes(val));
});
}
setCurrentList(list);
setFlag(flag + 1);
};
// 切换tab
const onChange = val => {
let copyList = JSON.parse(JSON.stringify(flowList));
let list = copyList.filter(item => item.name === val);
activeKey.current = val;
setCurrentList(list);
// setActiveKey(val);
};
// 编辑流程
const editFlow = (val, e) => {
e.stopPropagation();
showModal('FlowModal', true);
setModalType('edit');
setEditMsg(val);
};
// 新增流程
const addFlow = val => {
showModal('FlowModal', true);
setEditMsg(val);
setModalType('add');
};
// 添加流程组
const addFlowGroup = () => {
showModal('FlowGroupModal', true);
setModalType('add');
};
// 编辑流程组
const eiditFlowGroup = (val, index) => {
setEditIndex(index);
showModal('FlowGroupModal', true);
setModalType('edit');
setEditMsg(val);
};
// 编辑组回调
const groupCallBack = val => {
activeKey.current = val;
showModal('FlowGroupModal', false);
// 编辑老数据需要掉接口更新新数据手动修改数据,新增插入一条数据
if (modalType === 'edit' && editMsg.isOld) {
getFlowList();
} else if (modalType === 'edit') {
let newflowList = [...flowList];
newflowList[editIndex].name = val;
setFlowList(newflowList);
setCurrentList(newflowList.filter(item => item.name === activeKey.current));
} else {
setCurrentList([{ name: val, children: [] }]);
setFlowList([...flowList, { name: val }]);
}
};
const chooseNode = val => {
console.log(val, 'val');
GetFlowNode({ flowID: val.FlowID }).then(res => {
if (res.code === 0) {
res.data.Nodes.forEach(item => {
item.nodeDetail = JSON.stringify(item);
});
history.push({
pathname: '/biz/workflow/flowBoard',
state: {
flowData: { ...res.data, flowName: val.FlowName },
flowID: val.FlowID,
chartLoading: false,
activeKey: activeKey.current,
},
});
} else {
message.error(res.msg);
}
});
};
// 删除流程
const delFlow = (val, e) => {
e.stopPropagation();
confirm({
title: '确定要删除吗?',
icon: <ExclamationCircleOutlined />,
content: '',
okText: '是',
okType: 'danger',
cancelText: '否',
onOk() {
DeleteFlow({ FlowId: val.FlowID })
.then(res => {
if (res.code === 0) {
getFlowList();
message.success('删除成功');
} else {
message.error(res.msg);
}
})
.catch(() => {
message.error('网络异常请稍后再试');
});
},
onCancel() {},
});
};
// tab栏选项渲染
const tabRender = (val, index) => (
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-around' }}>
{val.name}({val.count})
{val.name === activeKey.current ? (
<EditOutlined onClick={() => eiditFlowGroup(val, index)} style={{ marginLeft: '5px' }} />
) : (
''
)}
</div>
);
return (
<div className={styles.pageContent}>
<div className={styles.headerBox}>
<div className={styles.left}>
<div
className={classnames(styles.allFlows, { [styles.allFlowsChoose]: !activeKey.current })}
onClick={chageAll}
/>
<div className={styles.flows}>
<Tabs activeKey={activeKey.current} type="card" onChange={onChange} animated={false}>
{flowList.map((item, index) => (
<Tabs.TabPane tab={tabRender(item, index)} key={item.name} />
))}
</Tabs>
</div>
</div>
<div className={styles.right} onClick={addFlowGroup}>
<div className={styles.icon} />
<div>新增分组</div>
</div>
</div>
<div className={styles.controlBox}>
<div className={styles.left}>
总计:
<span>{currentList.reduce((sum, p) => p.children.length + sum, 0)}</span>
</div>
<div className={styles.right}>
<div className={styles.btn} onClick={() => addFlow(currentList[0])}>
<PlusOutlined style={{ marginLeft: '5px' }} />
新增流程
</div>
<Search
placeholder="输入关键字搜索"
allowClear
onSearch={onSearch}
style={{
width: 490,
}}
/>
</div>
</div>
<div className={styles.flowTable}>
{currentList.map((item, index) => (
<div className={styles.flowGroup} key={item.name}>
<div
className={styles.header}
style={{ display: item.children.length > 0 ? 'flex' : 'none' }}
>
<div className={styles.line} />
<div className={styles.name}>{item.name}</div>
</div>
<div className={styles.groupBox}>
{item.children.map(ele => (
<div
className={styles.flowBox}
type={(index + 1) % 5}
key={ele.Code}
onClick={() => chooseNode(ele)}
>
<div className={styles.header}>
<div className={styles.title}>{ele.FlowName}</div>
<div className={styles.delete}>
<DeleteOutlined onClick={e => delFlow(ele, e)} />
</div>
<div className={styles.editBtn} onClick={e => editFlow(ele, e)}>
<EditOutlined />
编辑
</div>
</div>
<div className={styles.imgBox}>
<img
src={`http://192.168.12.178:8085/${
ele.PreviewImage
}?v=${new Date().getTime()}`}
alt=""
/>
</div>
<div className={styles.bottom}>
<div className={styles.left}>创建人:{ele.CreateUser || '--'}</div>
<div className={styles.right}>更新于{ele.UpdateTime || '--'}</div>
</div>
</div>
))}
</div>
</div>
))}
</div>
{/* 添加流程弹窗 */}
<FlowModal
visible={visible.FlowModal}
msg={editMsg}
modalType={modalType}
handleCancel={() => showModal('FlowModal', false)}
keep={flowNames}
treeData={flowList}
onSubumit={() => {
showModal('FlowModal', false);
getFlowList();
}}
/>
{/* 创建分组弹窗 */}
<FlowGroupModal
visible={visible.FlowGroupModal}
msg={editMsg}
modalType={modalType}
handleCancel={() => showModal('FlowGroupModal', false)}
treeData={flowList}
keep={flowNames}
onSubumit={val => groupCallBack(val)}
/>
</div>
);
};
export default WorkflowHomePage;
.pageContent {
margin-top: -12px;
margin-left: -12px;
width: calc(100% + 24px);
height: calc(100% + 24px);
background: url("../../../../assets/images/workFlow/index/bg.png") no-repeat;
background-size: 100% 100%;
display: flex;
flex-direction: column;
padding: 12px;
.headerBox {
height: 50px;
display: flex;
background-color: #e9f0ff;
justify-content: space-between;
.left {
display: flex;
flex: 1;
.allFlows {
width: 176px;
height: 50px;
background: url("../../../../assets/images/workFlow/index/all.png") no-repeat;
background-size: 100% 100%;
cursor: pointer;
}
.allFlowsChoose {
background: url("../../../../assets/images/workFlow/index/allChoose.png") no-repeat;
background-size: 100% 100%;
}
.flows {
flex: 1;
height: 50px;
.ant-tabs-tab {
height: 50px;
background-color: #e9f0ff;
border-bottom: none;
}
.ant-tabs-tab-active {
border-top: 2px solid #3D78FF;
border-bottom: none;
background: linear-gradient(0deg, #BED2F9 0%, #F2F7FF 100%);
color: #3D78FF;
}
}
}
.right {
height: 50px;
display: flex;
align-items: center;
color: #3D78FF;
cursor: pointer;
margin-right: 12px;
.icon {
width: 18px;
height: 15px;
background: url("../../../../assets/images/workFlow/index/add.png") no-repeat;
background-size: 100% 100%;
}
}
}
.controlBox {
height: 65px;
display: flex;
align-items: center;
font-size: 14px;
.left {
margin-right: 490px;
span {
font-size: 18px;
font-weight: 700;
color: #3D78FF;
}
}
.right {
display: flex;
.btn {
display: flex;
margin-right: 5px;
align-items: center;
background: #3D78FF;
box-shadow: 0px 2px 2px 0px rgba(0, 34, 97, 0.1);
border-radius: 15px;
color: #fff;
padding: 3px 16px;
cursor: pointer;
}
.ant-input-affix-wrapper {
background-color: #C2D6FA;
border-radius: 16px 0 0 16px;
.ant-input {
background-color: #C2D6FA;
color: #7E8BA3;
border: none;
}
.ant-input::placeholder {
color: #7E8BA3;
}
}
.ant-input-group-addon {
border-radius: 0 16px 16px 0;
.ant-input-search-button {
border-radius: 0 16px 16px 0;
background-color: #C2D6FA;
border: none;
}
}
}
}
.flowTable {
flex: 1;
overflow-y: scroll;
.flowGroup {
.header {
display: flex;
align-items: center;
height: 45px;
.line {
width: 3px;
height: 12px;
background-color: #3D78FF;
margin-right: 5px;
margin-left: 7px;
}
.name {
font-size: 14px;
color: #2A4260;
}
}
.groupBox {
display: flex;
flex-wrap: wrap;
.flowBox {
width: 350px;
height: 222px;
display: flex;
flex-direction: column;
justify-content: space-between;
cursor: pointer;
transition: transform 0.5s;
margin-bottom: 5px;
.header {
display: flex;
width: 100%;
.title {
width: 200px;
margin-left: 15px;
margin-top: 26px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding-left: 5px;
box-sizing: border-box;
}
.delete {
color: #FE5557;
cursor: pointer;
font-size: 16px;
margin-top: 22px;
}
.editBtn {
font-size: 14px;
display: flex;
margin-left: 31px;
width: 67px;
margin-top: 11px;
justify-content: center;
align-items: center;
color: #fff;
cursor: pointer;
}
}
.imgBox {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
margin-top: 1px;
img {
width: 230px;
// height: 125px;
// height: 350px;
}
}
.bottom {
display: flex;
width: 100%;
justify-content: space-between;
padding: 0 18px;
margin-bottom: 8px;
box-sizing: border-box;
}
&[type='1'] {
background: url("../../../../assets/images/workFlow/index/card1.png") no-repeat;
background-size: 100% 100%;
}
&[type='2'] {
background: url("../../../../assets/images/workFlow/index/card2.png") no-repeat;
background-size: 100% 100%;
}
&[type='3'] {
background: url("../../../../assets/images/workFlow/index/card3.png") no-repeat;
background-size: 100% 100%;
}
&[type='4'] {
background: url("../../../../assets/images/workFlow/index/card4.png") no-repeat;
background-size: 100% 100%;
}
&[type='0'] {
background: url("../../../../assets/images/workFlow/index/card5.png") no-repeat;
background-size: 100% 100%;
}
}
.flowBox:hover {
transform: translateY(-10px);
}
}
}
}
}
\ No newline at end of file
import React, { useState, useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import styles from './FlowBoard.less';
import FlowChart from './FlowChartRt';
const FlowBoard = () => {
const history = useHistory();
useEffect(() => {}, []);
const { flowData, flowID, chartLoading, activeKey } = history.location.state;
return (
<div className={styles.flowChartContainer}>
<FlowChart
flowData={flowData}
flowID={flowID}
chartLoading={chartLoading}
activeKey={activeKey}
/>
</div>
);
};
export default FlowBoard;
// 流程图
.flowChartContainer {
position: relative;
width: 100%;
height: calc(100%);
background-color: #fff;
.chartBox {
position: relative;
// display: flex;
height: calc(100% - 52px);
.flowName {
position: absolute;
width: calc(100% - 360px);
top: 10px;
text-align: center;
font-size: 24px;
font-weight: 700;
color: #1585FF;
background-color: transparent;
z-index: 9;
}
.myOverviewDiv {
position: absolute;
height: 150px;
width: 300px;
left: 0;
bottom: 0;
background-color: #ccc;
z-index: 9;
}
}
.control {
display: flex;
justify-content: space-between;
height: 52px;
align-items: center;
padding: 0 10px;
.nodeList {
display: flex;
align-items: center;
.myPaletteSubprocess {
height: 52px;
width: 130px;
canvas {
height: 100%;
width: 1000px;
}
}
.myPaletteDiv {
// margin-right: 20px;
height: 52px;
width: 380px;
canvas {
height: 100%;
width: 1000px;
}
}
.lineBox {
height: 52px;
width: 1px;
background-color: #ccc;
// margin-right: 10px;
}
.nodeBox {
display: flex;
align-items: center;
justify-content: center;
height: 52px;
padding: 0 10px;
border-radius: 10px;
background-color: #D9E0FF;
margin-right: 10px;
.nodeImg {
img {
height: 35px;
}
margin-right: 5px;
}
}
}
.buttonList {
display: flex;
justify-content: flex-start;
margin: 15px 0 15px 0;
.ant-btn {
display: flex;
align-items: center;
justify-content: center;
margin-left: 10px;
}
}
}
canvas {
border: 0px;
outline: none;
}
.myDiagramDiv {
width: calc(100% - 360px);
// flex: 1;
height: 100%;
}
}
\ No newline at end of file
/* eslint-disable global-require */
import React, { useState, useEffect, useRef } from 'react';
import { useHistory, Prompt } from 'react-router-dom';
import { Button, Modal, notification, Spin, Tooltip, message } from 'antd';
import lodash from 'lodash';
import {
SaveNodeChange,
GetFlowNode,
FlowNodeSave,
DeleteFlowNode,
DeleteFlowNodes,
SaveWorkFlowImage,
} from '@/services/workflow/workflow';
import { ExclamationCircleOutlined, TrophyOutlined } from '@ant-design/icons';
import * as go from 'gojs';
import styles from './FlowBoard.less';
// import styles from '../workflow.less';
import NodeModal from './flowChartComponents/NodeModal';
import LineModal from './flowChartComponents/LineModal';
// import imgUrl from '@/assets/images/icons/closeBlue.png';
import nodeEnd from '@/assets/images/workFlow/nodeEnd.svg';
import nodeGeneral from '@/assets/images/workFlow/nodeGeneral.svg';
import nodeStart from '@/assets/images/workFlow/nodeStart.svg';
// import cc from '@/assets/images/workFlow/cc.png';
import gatewayCondition from '@/assets/images/workFlow/gatewayCondition.svg';
import gatewayParallel from '@/assets/images/workFlow/gatewayParallel.svg';
import gatewayJoin from '@/assets/images/workFlow/gatewayJoin.svg';
const { confirm } = Modal;
let diagram = null;
let myPaletteNode = null;
let myPaletteGateway = null;
let myPaletteSubprocess = null;
let myOverview = null;
const FlowChart = props => {
const history = useHistory();
const { flowData, flowID, chartLoading, msg, treeVisible, activeKey } = props;
const [visible, setVisible] = useState(false);
const [lineVisible, setLineVisible] = useState(false);
const [editMsg, setEditMsg] = useState({}); // 编辑节点的信息
const [lineMsg, setLineMsg] = useState({});
const [modalType, setModalType] = useState(''); // 存入弹窗是编辑还是新增
const [LineKey, setLineKey] = useState(''); // 存入编辑线id
const [nodeKey, setNodeKey] = useState(''); // 存入编辑节点的key
const [DeleteNodes, setDeleteNodes] = useState([]); // 删除节点数组
const [DeleteLines, setDeleteLines] = useState([]); // 删除线数组
const [deleteLine, setDeleteLine] = useState(); // 删除的线id
const [deleteNode, setDeleteNode] = useState(); // 删除的节点id
const [AddNodes, setAddNodes] = useState([]); // 新增数组
const [initFlowData, setInitFlowData] = useState({}); // 初始数据,用来比对是否有修改流程图
const [currentFlowData, setCurrentFlowData] = useState({
Nodes: [],
Lines: [],
}); // 组件内得流程图数据
const [showLeaveTip, setShowLeaveTip] = useState(false); // 离开路由是否又提醒
const [buttonLoading, setButtonLoading] = useState(); // 发布按钮保存loading
const [flag, setFlag] = useState(0);
const currentNode = useRef();
const afterNodes = useRef(new Map([])); // 当前节点后所有节点
const limitFinshNodes = useRef([new Set([])]);
const objGo = go.GraphObject.make;
useEffect(() => {
if (treeVisible) {
setVisible(false);
}
}, [treeVisible]);
// 监听删除,给删除数组里添加删除id
useEffect(() => {
if (deleteLine) {
setDeleteLines([...DeleteLines, deleteLine]);
}
}, [deleteLine]);
useEffect(() => {
if (deleteNode) {
setDeleteNodes([...DeleteNodes, deleteNode]);
}
}, [deleteNode]);
// 初始化
useEffect(() => {
// 初始化流程图
init();
initPalette();
myOverview = objGo(go.Overview, 'myOverviewDiv', { observed: diagram });
// 监听节点或线的删除事件
diagram.addDiagramListener('SelectionDeleted', e => {
let delNodes = [];
let delLinks = [];
e.subject.each(n => {
if (n.data.LineId) {
delLinks.push(n.data.LineId);
}
if (n.data.ActivityId) {
delNodes.push(n.data.ActivityId);
}
// 如果删除得节点不是新增得就给id放入到删除节点数组中
if (n.data.NodeId && !AddNodes.some(item => item === n.data.NodeId)) {
setTimeout(() => {
setDeleteNode(n.data.NodeId);
}, 0);
}
if (n.data.LineKey) {
setTimeout(() => {
setDeleteLine(n.data.LineId);
}, 0);
}
});
if (delNodes.length === 0) {
return;
}
DeleteFlowNodes({ ActivityIds: delNodes, LineIds: delLinks }).then(res => {
if (res.code === 0) {
message.success('删除成功');
} else {
message.error(res.msg);
}
});
console.log(delNodes, delLinks, 'fffff');
});
// 监听节点或线的删除前事件
diagram.commandHandler.canDeleteSelection = () =>
// 用例获取选中的节点或线
diagram.selection.all(e => {
// 判断是否存在不允许删除的节点或线
showDeleteConfirm(e.data);
return false;
});
// 监听线,连接线的时候加上text属性
diagram.addDiagramListener('LinkDrawn', e => {
// e.subject.data.text = '';
e.subject.data.lineDetail = JSON.stringify(e.subject.data);
console.log(e, e.subject.data, 'fasdfasdgds');
diagram.model.updateTargetBindings(e.subject.data);
// leaveCallBack(true);
});
// 监听节点拖拽到画布事件
diagram.addDiagramListener('externalobjectsdropped', e => {
afterNodes.current = new Map([]);
const list = JSON.parse(diagram.model.toJson()).nodeDataArray;
console.log(list, 'list');
let newNum;
let newKey;
if (list.length > 0) {
// eslint-disable-next-line prefer-spread
newNum = Math.max.apply(Math, list.map(item => item.SerialNo)) + 1;
// eslint-disable-next-line prefer-spread
newKey = Math.max.apply(Math, list.map(item => item.key)) + 1;
} else {
newKey = 1;
newNum = 1;
}
console.log(e);
e.subject.each(n => {
// 得到从Palette拖过来的节点
console.log(n.data.key);
let nodeData = diagram.model.findNodeDataForKey(n.data.key);
nodeData.NodeName = `${n.data.NodeName}${newKey}`;
nodeData.NodeAliasName = nodeData.NodeName;
nodeData.SerialNo = newNum;
// nodeData.key = newKey;
nodeData.NodeId = newKey;
nodeData.nodeDetail = JSON.stringify(nodeData);
console.log(nodeData);
diagram.model.updateTargetBindings(nodeData);
diagram.model.setDataProperty(nodeData, 'key', newKey);
currentNode.current = nodeData;
setNodeKey(nodeData.key);
setEditMsg(nodeData);
setModalType('edit');
setVisible(true);
});
setAddNodes([...AddNodes, newKey]);
leaveTip();
});
// diagram.addDiagramListener('SelectionDeleted', e => {
// });
}, []);
useEffect(() => {
if (flowData) {
console.log(flowData, 'msgmsgmsg');
// 每次切换时清空删除得id数组跟新增得id数组
setDeleteNodes([]);
setDeleteLines([]);
setAddNodes([]);
setDeleteNode('');
setDeleteLine('');
setEditMsg({});
let dataList = lodash.cloneDeep(flowData);
console.log(dataList, 'dataList');
setCurrentFlowData(dataList);
setShowLeaveTip(false);
setVisible(false);
}
}, [flowData]);
// 存入在树形流程中选择得流程数据
useEffect(() => {
let nodeDataArray = [];
let linkDataArray = [];
// 处理老数据,让老数据可以正常展示
limitFinshNodes.current = new Set([]);
nodeDataArray = currentFlowData.Nodes.map((item, index) => {
if (item.FlowTimerList.length > 0) {
item.FlowTimerList.forEach(ele => {
limitFinshNodes.current.add(ele.EndNode);
});
}
let obj;
obj = item;
obj.key = item.NodeId;
if (!obj.NodeAliasName) {
obj.NodeAliasName = obj.NodeName;
}
obj.nodeDetail = JSON.stringify(obj);
obj.CarbonCopyPeopleList = obj.CarbonCopyPeopleList.map(ele => ({
label: ele.userName,
value: ele.userID,
}));
if (obj.points === '') {
if (obj.NodeType === '1') {
obj.points = `${(index * 200).toString()}" 100"`;
} else {
obj.points = `${(index * 200).toString()}" -22"`;
}
}
return obj;
});
linkDataArray = currentFlowData.Lines.map(item => {
let obj;
obj = item;
obj.LineKey = item.LineId;
obj.lineDetail = JSON.stringify(obj);
return obj;
});
// 保存初始数据
setInitFlowData(
JSON.parse(
JSON.stringify({
Nodes: nodeDataArray,
Lines: linkDataArray,
}),
),
);
diagram.model = go.Model.fromJson({
linkFromPortIdProperty: 'fromPort', // 所需信息:
linkToPortIdProperty: 'toPort', // 标识数据属性名称
nodeDataArray,
linkDataArray,
});
// 初次选中
if (nodeDataArray?.length > 0) {
currentNode.current = diagram.model.findNodeDataForKey(
nodeDataArray[nodeDataArray.length - 1].NodeId,
);
setNodeKey(currentNode.current.key);
setEditMsg(currentNode.current);
setModalType('edit');
setVisible(true);
}
// 修改复制后节点内容
diagram.model.copyNodeDataFunction = (obj, model) => {
let copyObj = lodash.cloneDeep(obj);
console.log(copyObj, 'copyObj');
copyObj.FlowTimerList.forEach(item => {
item.key = item.ID;
delete item.ID;
});
delete copyObj.ActivityId;
delete copyObj.FlowNodeExtendId;
return copyObj;
};
// 修改复制后线内容
diagram.model.copyLinkDataFunction = (obj, model) => {
let copyObj = lodash.cloneDeep(obj);
delete copyObj.LineId;
return copyObj;
};
diagram.model.linkKeyProperty = 'LineKey';
diagram.model.makeUniqueLinkKeyFunction = (model, data) => {
let i = model.linkDataArray.length * 2 + 2;
while (model.findLinkDataForKey(i) !== null) i += 2;
return i;
};
}, [currentFlowData]);
// 删除提醒
const showDeleteConfirm = val => {
confirm({
title: '确定要删除所选中的节点吗?',
icon: <ExclamationCircleOutlined />,
content: '',
okText: '是',
okType: 'danger',
cancelText: '否',
onOk() {
delNode(val);
},
onCancel() {},
});
};
// 删除节点
const delNode = val => {
setShowLeaveTip(true);
// leaveCallBack(true);
diagram.commandHandler.deleteSelection();
// if (val.LineId) {
// diagram.commandHandler.deleteSelection();
// return;
// }
// DeleteFlowNode({ activityId: val.ActivityId }).then(res => {
// if (res.code === 0) {
// message.success('删除成功');
// diagram.commandHandler.deleteSelection();
// } else {
// message.error(res.msg);
// }
// });
};
const animateFadeDown = e => {
let diagrams = e.diagram;
let animation = new go.Animation();
animation.isViewportUnconstrained = true; // 所以图表定位规则让动画在屏幕外开始
animation.easing = go.Animation.EaseOutExpo;
animation.duration = 900;
// 淡入“向下”,换句话说,从上方淡入
animation.add(diagrams, 'position', diagrams.position.copy().offset(0, 200), diagrams.position);
animation.add(diagrams, 'opacity', 0, 1);
animation.start();
};
// 初始化拖拽面板
const initPalette = () => {
const defaultField = {
aheadHandle: 1,
NodeHandling: 1,
RuleList: [],
roleList: [],
CarbonCopyPeopleList: [],
ExtendPageList: [],
FlowTimerList: [],
TurnOnCc: 0,
NodeAliasName: '',
Handover: '移交选择人',
TableName: '',
Fields: '',
WebPage: '',
FeedbackName: '',
Transferable: 0,
EventsInformation: 0,
IsSendMessage: 1,
IsSave: 0,
AutoClose: '否',
HalfwayClose: 0,
RollbackNode: '(上一节点)',
Rollbackable: false,
};
myPaletteNode = objGo(go.Palette, 'myPaletteNode', {
// 代替默认动画,使用自定义淡入淡出
'animationManager.initialAnimationStyle': go.AnimationManager.None,
InitialAnimationStarting: animateFadeDown, // 相反,使用此功能制作动画
// nodeTemplateMap: diagram.nodeTemplateMap, // 分享 myDiagram 使用的模板
scale: '1',
nodeSelectionAdornmentTemplate: objGo(
go.Adornment,
'Auto',
objGo(go.Shape, 'Rectangle', { fill: 'white', stroke: null }),
), // 去掉节点点击时的边框颜色
model: new go.GraphLinksModel([
// 指定调色板的内容
{
category: 'nodeStart',
NodeName: '开始节点',
NodeType: '1',
SerialNo: 0,
...defaultField,
},
{
category: 'nodeGeneral',
NodeName: '普通节点',
NodeType: '0',
SerialNo: 0,
...defaultField,
},
{
category: 'nodeEnd',
NodeName: '结束节点',
NodeType: '2',
SerialNo: 0,
...defaultField,
},
]),
});
myPaletteNode.nodeTemplate = objGo(
go.Node,
'Auto',
new go.Binding('location', 'points', go.Point.parse).makeTwoWay(go.Point.stringify),
// 节点样式配置
objGo(
go.Panel,
{ width: 108, height: 42 },
objGo(
go.Picture,
{ width: 108, height: 42 },
new go.Binding('source', 'NodeType', v => {
switch (v) {
case '1':
return require('../../../../../assets/images/workFlow/icon1.svg');
case '2':
return require('../../../../../assets/images/workFlow/icon3.svg');
case '0':
return require('../../../../../assets/images/workFlow/icon2.svg');
default:
return null;
}
}),
),
),
);
myPaletteGateway = objGo(go.Palette, 'myPaletteGateway', {
// 代替默认动画,使用自定义淡入淡出
'animationManager.initialAnimationStyle': go.AnimationManager.None,
InitialAnimationStarting: animateFadeDown, // 相反,使用此功能制作动画
// nodeTemplateMap: diagram.nodeTemplateMap, // 分享 myDiagram 使用的模板
scale: '1',
nodeSelectionAdornmentTemplate: objGo(
go.Adornment,
'Auto',
objGo(go.Shape, 'Rectangle', { fill: 'white', stroke: null }),
), // 去掉节点点击时的边框颜色
model: new go.GraphLinksModel([
// 指定调色板的内容
{
category: 'gatewayCondition',
NodeName: '条件网关',
NodeType: '20',
SerialNo: 0,
...defaultField,
},
{
category: 'gatewayParallel',
NodeName: '并行网关',
NodeType: '22',
SerialNo: 0,
...defaultField,
},
{
category: 'gatewayJoin',
NodeName: '汇合网关',
NodeType: '21',
SerialNo: 0,
...defaultField,
},
]),
});
myPaletteGateway.nodeTemplate = objGo(
go.Node,
'Auto',
new go.Binding('location', 'points', go.Point.parse).makeTwoWay(go.Point.stringify),
// 节点样式配置
objGo(
go.Panel,
{ width: 108, height: 42 },
objGo(
go.Picture,
{ width: 108, height: 42 },
new go.Binding('source', 'NodeType', v => {
switch (v) {
case '20':
return require('../../../../../assets/images/workFlow/gateWayicon1.svg');
case '21':
return require('../../../../../assets/images/workFlow/gateWayicon3.svg');
case '22':
return require('../../../../../assets/images/workFlow/gateWayicon2.svg');
default:
return null;
}
}),
),
),
);
myPaletteSubprocess = objGo(go.Palette, 'myPaletteSubprocess', {
// 代替默认动画,使用自定义淡入淡出
'animationManager.initialAnimationStyle': go.AnimationManager.None,
InitialAnimationStarting: animateFadeDown, // 相反,使用此功能制作动画
// nodeTemplateMap: diagram.nodeTemplateMap, // 分享 myDiagram 使用的模板
scale: '1',
nodeSelectionAdornmentTemplate: objGo(
go.Adornment,
'Auto',
objGo(go.Shape, 'Rectangle', { fill: 'white', stroke: null }),
), // 去掉节点点击时的边框颜色
model: new go.GraphLinksModel([
// 指定调色板的内容
{
category: 'gatewayCondition',
NodeName: '子流程',
NodeType: '30',
SerialNo: 0,
...defaultField,
},
]),
});
myPaletteSubprocess.nodeTemplate = objGo(
go.Node,
'Auto',
new go.Binding('location', 'points', go.Point.parse).makeTwoWay(go.Point.stringify),
// 节点样式配置
objGo(
go.Panel,
{ width: 108, height: 42 },
objGo(
go.Picture,
{ width: 108, height: 42 },
new go.Binding('source', 'NodeType', v => {
switch (v) {
case '30':
return require('../../../../../assets/images/workFlow/subprocessicon.svg');
default:
return null;
}
}),
),
),
);
};
// 流程图初始化
const init = () => {
diagram = objGo(go.Diagram, 'myDiagramDiv', {
'undoManager.isEnabled': true,
allowDragOut: false,
'dragSelectingTool.isEnabled': false, // 禁止多选
// 'grid.visible': true,
scrollMode: go.Diagram.InfiniteScroll, // 无限滚动
allowCopy: true, // 禁止复制
allowDrop: true,
// nodeSelectionAdornmentTemplate: objGo(
// go.Adornment,
// 'Auto',
// objGo(go.Shape, 'Rectangle', { fill: 'white', stroke: null }),
// ), // 去掉节点点击时的边框颜色
scale: '0.8',
});
diagram.grid.gridCellSize = new go.Size(10, 10);
diagram.toolManager.draggingTool.isGridSnapEnabled = true;
// 节点配置
diagram.nodeTemplate = objGo(
go.Node,
'Auto',
new go.Binding('location', 'points', go.Point.parse).makeTwoWay(go.Point.stringify),
// 节点样式配置
objGo(
go.Panel,
nodeBoxStyle('width'),
nodeBoxStyle('height'),
objGo(
go.Picture,
new go.Binding('source', 'NodeType', v => {
switch (v) {
case '1':
return nodeStart;
case '2':
return nodeEnd;
case '0':
return nodeGeneral;
// case '4':
// return cc;
case '20':
return gatewayCondition;
case '21':
return gatewayJoin;
case '22':
return gatewayParallel;
case '30':
return require('../../../../../assets/images/workFlow/nodesubprocess.svg');
default:
return null;
}
}),
nodeBoxStyle('width'),
nodeBoxStyle('height'),
),
objGo(
go.Panel,
'Horizontal',
nodeBoxStyle('height'),
{ alignment: go.Spot.Center },
objGo(
go.Panel,
'Vertical', // 节点文案
nodeBoxStyle('width'),
objGo(
go.TextBlock,
{
maxSize: new go.Size(120, NaN),
maxLines: 1,
alignment: go.Spot.Center,
margin: new go.Margin(0, 15, 0, 15),
overflow: go.TextBlock.OverflowEllipsis,
font: 'normal 12pt Microsoft YaHei',
},
new go.Binding('visible', 'NodeType', v => {
if (v.NodeType === '20' || v.NodeType === '21' || v.NodeType === '22') {
return false;
}
return true;
}),
new go.Binding('text', 'NodeAliasName'),
nodeBoxStyle('stroke', 'nodeStyle'),
),
objGo(
go.TextBlock,
{
alignment: go.Spot.Center,
maxLines: 2,
overflow: go.TextBlock.OverflowEllipsis,
font: 'normal 12pt Microsoft YaHei',
},
new go.Binding('spacingAbove', 'roleList', v => (v?.length > 0 ? 5 : 0)),
new go.Binding('height', 'roleList', v => (v?.length > 0 ? 30 : 0)),
new go.Binding('margin', 'roleList', v =>
v?.length > 0 ? new go.Margin(10, 10, 0, 10) : 0,
),
new go.Binding('text', 'nodeDetail', v => {
const obj = JSON.parse(v);
if (obj.NodeType === '20' || obj.NodeType === '21' || obj.NodeType === '22') {
return '';
}
if (obj.roleList?.length === 0) {
return '';
}
return obj.roleList.map(item => item.roleName).join(',');
}),
nodeBoxStyle('stroke', 'roleStyle'),
),
),
),
),
// 我们的小命名端口,每侧一个:
makePort('T', go.Spot.Top),
makePort('L', go.Spot.Left),
makePort('R', go.Spot.Right),
makePort('B', go.Spot.Bottom),
{
// 节点之间线得连接
linkValidation(fromnode, fromport, tonode, toport, thisLink) {
// 并行网关不让连接汇合网关
if (fromnode.data.NodeType === '22' && tonode.data.NodeType === '21') {
return false;
}
// 条件网关不让连接条件网关
if (fromnode.data.NodeType === '20' && tonode.data.NodeType === '20') {
return false;
}
// 汇合网关不让连条件网关
if (fromnode.data.NodeType === '21' && tonode.data.NodeType === '20') {
return false;
}
return true;
},
// 处理鼠标进入/离开事件以显示/隐藏端口
mouseEnter(e, node) {
showSmallPorts(node, true);
},
mouseLeave(e, node) {
showSmallPorts(node, false);
},
click(e, node) {
handlerDC(e, node);
},
// 处理双击
doubleClick(e, node) {
// 双击事件
// handlerDC(e, node); // 双击执行的方法
},
selectionChanged: node => {
// console.log(node.data, 'nodenodenode');
},
toolTip: objGo(
'ToolTip',
objGo(
go.TextBlock,
{ margin: 4 },
new go.Binding('text', 'nodeDetail', v => {
const obj = JSON.parse(v);
return `节点名称:${obj.NodeName}\n${
obj.roleList.length > 0 ? '承办:' : ''
}${obj.roleList.map(item => item.roleName).join(',')}`;
}),
),
),
},
);
// 链接设置
diagram.linkTemplate = objGo(
go.Link,
{
routing: go.Link.Orthogonal,
curve: go.Link.JumpOver,
corner: 5,
toShortLength: 4,
selectionAdornmentTemplate: objGo(
go.Adornment,
objGo(go.Shape, { isPanelMain: true, stroke: '#faad14', strokeWidth: 2 }), // 修改线颜色和大小
objGo(go.Shape, { toArrow: 'Standard', fill: '#faad14', stroke: '#faad14' }), // 修改线箭头的颜色和大小
),
},
new go.Binding('points').makeTwoWay(),
objGo(
go.Shape, // 链接路径形状
{
isPanelMain: true,
strokeWidth: 2,
},
new go.Binding('stroke', 'from', v => lineStyle(v, 'stroke')),
new go.Binding('strokeDashArray', 'from', v => lineStyle(v, 'strokeDashArray')),
),
objGo(
go.Shape, // 箭头
{ toArrow: 'Standard' },
new go.Binding('stroke', 'from', v => lineStyle(v, 'stroke')),
new go.Binding('fill', 'from', v => lineStyle(v, 'stroke')),
),
objGo(
go.Panel,
'Auto',
objGo(
go.Shape, // 标签背景,在边缘变得透明
// { fill: 'transparent' },
new go.Binding('fill', 'lineDetail', v => lineTextStyle(v)),
new go.Binding('stroke', 'lineDetail', v => lineTextStyle(v)),
),
objGo(
go.TextBlock,
{
textAlign: 'center',
font: '10pt helvetica, arial, Microsoft YaHei',
stroke: '#555555',
margin: 4,
},
new go.Binding('text', 'lineDetail', v => lineText(v)),
),
),
// {
// // 处理双击
// doubleClick(e, node) {
// addLineMsg(e, node);
// },
// },
);
// 初始化流程的节点数组
diagram.model = objGo(go.GraphLinksModel, {
linkFromPortIdProperty: 'fromPort', // 所需信息:
linkToPortIdProperty: 'toPort', // 标识数据属性名称
nodeDataArray: currentFlowData.Nodes,
linkDataArray: currentFlowData.Lines,
});
};
// 线的样式
const lineStyle = (v, styleName) => {
const linemsg = diagram.model.findNodeDataForKey(v);
switch (styleName) {
case 'strokeDashArray':
if (linemsg.NodeType === '20') {
return [6, 3];
}
return null;
case 'stroke':
return '#1685FF';
default:
return null;
}
};
// 线上文案样式
const lineTextStyle = v => {
let obj = JSON.parse(v);
let nodeData = diagram.model.findNodeDataForKey(obj.from);
if (nodeData.NodeType === '20' || nodeData.NodeType === '21') {
// if(nodeData.)
if (nodeData.RuleList.some(ele => ele.NextNodeId === obj.to)) {
return '#EFF8FA';
}
return 'transparent';
}
return 'transparent';
};
// 线上的文案
const lineText = v => {
let obj = JSON.parse(v);
let nodeData = diagram.model.findNodeDataForKey(obj.from);
if (nodeData.NodeType === '20' || nodeData.NodeType === '21') {
return nodeData.RuleList.find(ele => ele.NextNodeId === obj.to).RuleName;
}
return '';
};
// 是否显示端口
const showSmallPorts = (node, show) => {
node.ports.each(port => {
if (port.portId !== '') {
// 不要更改默认端口,这是大形状
port.fill = show ? 'rgba(5,135,224,.3)' : null;
}
});
};
// 创建节点端口
const makePort = (name, spot) =>
// 端口基本上只是一个小的透明 方块
objGo(
go.Shape,
'Circle',
{
fill: null, // 默认情况下不可见; 由 showSmallPorts 设置为半透明灰色,定义如下
stroke: null,
desiredSize: new go.Size(8, 8),
alignment: spot, // 对齐主要形状上的端口
alignmentFocus: spot, // 就在形状里面
portId: name, // 将此对象声明为“端口”
fromSpot: spot,
toSpot: spot, // 声明链接可以在此端口连接的位置
cursor: 'pointer', // 显示不同的光标以指示潜在的链接点
},
new go.Binding('fromLinkable', 'NodeType', v => v !== '2'), // 是否允许用户绘制的链接到这里
new go.Binding('toLinkable', 'NodeType', v => v !== '1'), // 声明用户是否可以从这里绘制链接
);
// 节点盒子样式
const nodeBoxStyle = (atr, classname) => {
switch (atr) {
case 'width':
return new go.Binding('width', 'NodeType', v => {
switch (v) {
case '1':
return 140;
case '2':
return 140;
case '0':
return 220;
case '4':
return 220;
case '20':
return 60;
case '21':
return 60;
case '22':
return 60;
case '30':
return 220;
default:
return null;
}
});
case 'height':
return new go.Binding('height', 'NodeType', v => {
switch (v) {
case '1':
return 140;
case '2':
return 140;
case '0':
return 120;
case '4':
return 120;
case '20':
return 60;
case '21':
return 60;
case '22':
return 60;
case '30':
return 120;
default:
return null;
}
});
case 'stroke':
return new go.Binding('stroke', 'NodeType', v => {
switch (v) {
case '1':
return classname === 'roleStyle' ? '#BCBCBC' : '#1685FF';
case '2':
return classname === 'roleStyle' ? '#BCBCBC' : '#51C21A';
case '0':
return classname === 'roleStyle' ? '#BCBCBC' : '#1685FF';
case '30':
return classname === 'roleStyle' ? '#BCBCBC' : '#9850F6';
default:
return null;
}
});
default:
return null;
}
};
const findAfterNode = startNode => {
// let nodeList = new Map([]);
startNode.findNodesOutOf().each(node => {
if (!afterNodes.current.has(node.data.NodeName)) {
if (['1', '0', '2'].includes(node.data.NodeType)) {
afterNodes.current.set(node.data.NodeName, node.data.TableName);
}
findAfterNode(node);
}
});
};
// 双击节点
const handlerDC = (e, node) => {
currentNode.current = node.data;
// 找到节点后得除去网关跟子流程的所有节点
afterNodes.current = new Map([]);
findAfterNode(node);
console.log(Object.fromEntries(afterNodes.current));
setModalType('edit');
setVisible(true);
setNodeKey(node.part.data.key);
setEditMsg(node.part.data);
};
// 双击线
const addLineMsg = (e, node) => {
setLineKey(node.part.data.LineKey);
setLineMsg(node.part.data);
setLineVisible(true);
};
const copyNode = e => {
// diagram.commandHandler.canSelectAll();
console.log(
diagram.makeImageData({
background: 'rgb(239, 248, 250)',
maxSize: new go.Size(1260, 500),
}),
'fasdfsad',
);
};
// 节点配置回调
// const nodeCallBack = obj => {
// let nameIsRepeat;
// let { nodes } = diagram;
// let keyArr = [];
// // 遍历输出节点对象
// nodes.each(node => {
// keyArr = [...keyArr, Number(node.data.key)];
// if (obj.NodeName === node.data.NodeName) {
// nameIsRepeat = true;
// if (modalType === 'edit' && obj.NodeName === editMsg.NodeName) {
// nameIsRepeat = false;
// }
// }
// });
// if (nameIsRepeat) {
// notification.error({
// message: '提示',
// duration: 3,
// description: '节点名称不能重复',
// });
// return;
// }
// // 编辑节点
// let nodeData = diagram.model.findNodeDataForKey(nodeKey);
// const {
// NodeName,
// NodeType,
// roleList,
// SerialNo,
// aheadHandle,
// NodeHandling,
// nodeDetail,
// RuleList,
// CarbonCopyPeopleList,
// SubFlowInfo,
// } = obj;
// nodeData.NodeName = NodeName;
// nodeData.NodeType = NodeType;
// nodeData.NodeId = nodeKey;
// nodeData.roleList = roleList;
// nodeData.SerialNo = SerialNo;
// nodeData.aheadHandle = aheadHandle;
// nodeData.NodeHandling = NodeHandling;
// nodeData.nodeDetail = nodeDetail;
// nodeData.RuleList = RuleList;
// nodeData.CarbonCopyPeopleList = CarbonCopyPeopleList;
// nodeData.SubFlowInfo = SubFlowInfo;
// diagram.model.updateTargetBindings(nodeData);
// // 给线上添加文字
// let diagramObj = JSON.parse(diagram.model.toJson());
// console.log(diagramObj.linkDataArray, 'diagramObj.linkDataArray');
// diagramObj.linkDataArray.forEach(item => {
// let node = diagram.model.findLinkDataForKey(item.LineKey);
// node.text = item.RuleName;
// diagram.model.updateTargetBindings(node);
// });
// // 关闭时进行数据比对看数据是否改变
// leaveTip();
// // setVisible(false);
// };
const nodeCallBack = () => {
SaveWorkFlowImage({
flowName: flowData.flowName,
base64Data: diagram.makeImageData({
background: 'rgb(239, 248, 250)',
maxSize: new go.Size(1260, 500),
}),
}).then(response => {
if (response.code === 0) {
FlowNodeSave({
PreviewImage: response.data,
flowID,
...currentNode.current,
CarbonCopyPeopleList: currentNode.current.CarbonCopyPeopleList.map(item =>
Number(item.value),
),
}).then(res => {
if (res.code === 0) {
diagram.model.setDataProperty(
currentNode.current,
'FlowTimerList',
res.data.FlowTimerList,
);
diagram.model.setDataProperty(currentNode.current, 'ActivityId', res.data.ActivityId);
diagram.model.setDataProperty(
currentNode.current,
'FlowNodeExtendId',
res.data.FlowNodeExtendId,
);
message.success('保存成功');
} else {
message.error(res.msg);
}
});
}
});
};
// 关闭时进行数据比对看数据是否改变
const leaveTip = () => {
let diagramObj = JSON.parse(diagram.model.toJson());
let stageJson = {
Nodes: diagramObj.nodeDataArray,
Lines: diagramObj.linkDataArray,
};
if (JSON.stringify(stageJson.Nodes) === JSON.stringify(initFlowData.Nodes)) {
setShowLeaveTip(false);
// leaveCallBack(false);
} else {
// leaveCallBack(true);
setShowLeaveTip(true);
}
};
// 线配置回调函数
const lineCallBack = obj => {
let node = diagram.model.findLinkDataForKey(LineKey);
node.text = obj.text;
diagram.model.updateTargetBindings(node);
// 关闭时进行数据比对看数据是否改变
leaveTip();
setLineVisible(false);
};
// 获取保存后的流程数据
const getFlowData = () => {
GetFlowNode({ flowID }).then(res => {
if (res.code === 0) {
// 保存后离开不用提醒要修改数据了
setShowLeaveTip(false);
// leaveCallBack(false);
setCurrentFlowData(JSON.parse(JSON.stringify(res.data)));
} else {
notification.error({
title: '提示',
duration: 3,
description: res.msg,
});
}
});
};
const isRepeat = (arr, key) => {
let obj = {};
for (let i = 0; i < arr.length; i++) {
if (obj[arr[i][key]]) {
return false;
}
obj[arr[i][key]] = arr[i];
}
return obj;
};
// 节点数据改边
const nodeChage = (key, value) => {
console.log(key, value);
setShowLeaveTip(true);
let obj = JSON.parse(JSON.stringify(currentNode.current));
obj[key] = value;
const nodeDetail = JSON.stringify(obj);
diagram.model.setDataProperty(currentNode.current, key, value);
if (key === 'roleList') {
diagram.model.setDataProperty(currentNode.current, 'nodeDetail', nodeDetail);
}
if (key === 'FlowTimerList') {
const list = value.map(item => item.EndNode);
limitFinshNodes.current = new Set(list);
setFlag(flag + 1);
// limitFinshNodes;
}
if (key === 'TableName') {
setFlag(flag + 1);
}
diagram.rebuildParts();
// leaveCallBack(true);
};
// 保存流程
const saveFlow = () => {
let diagramObj = JSON.parse(diagram.model.toJson());
// let list = isRepeat(diagramObj.nodeDataArray, 'SerialNo');
// if (!list) {
// notification.error({
// message: '提示',
// duration: 3,
// description: '请检查序号是否重复',
// });
// return;
// }
let list = new Set([]);
console.log(list, '11111');
diagramObj.nodeDataArray.forEach(item => {
if ((item.NodeType === '20' || item.NodeType === '21') && item.RuleList) {
item.RuleList.forEach(ele => {
if (!ele.RuleName) {
list.add(item.NodeName);
return;
}
if (!ele.NextNodeId && ele.NextNodeId !== 0) {
list.add(item.NodeName);
return;
}
if (!ele.RuleContent) {
list.add(item.NodeName);
}
});
}
const newListLength = new Set(item.RuleList.map(ele => ele.NextNodeId)).size;
if (item.RuleList.length > newListLength) {
list.add(item.NodeName);
return;
}
item.CarbonCopyPeopleList = item.CarbonCopyPeopleList.map(ele => Number(ele.value));
});
console.log(list, '222');
if ([...list].length > 0) {
list.forEach(item => {
message.error(`请检查${item}规则配置`);
});
return;
}
setButtonLoading(true);
SaveWorkFlowImage({
flowName: flowData.flowName,
base64Data: diagram.makeImageData({
background: 'rgb(239, 248, 250)',
maxSize: new go.Size(1260, 500),
}),
}).then(val => {
if (val.code === 0) {
SaveNodeChange({
FlowId: flowID,
// DeleteNodes,
PreviewImage: val.data,
DeleteLines,
Lines: diagramObj.linkDataArray,
Nodes: diagramObj.nodeDataArray,
})
.then(res => {
setButtonLoading(false);
if (res.code === 0) {
setDeleteNodes([]);
setDeleteLines([]);
setAddNodes([]);
setDeleteNode('');
setDeleteLine('');
getFlowData();
notification.success({
message: '提示',
duration: 3,
description: '保存成功',
});
} else {
notification.error({
message: '提示',
duration: 8,
description: res.msg,
});
}
})
.catch(() => {
setButtonLoading(false);
notification.error({
message: '提示',
duration: 3,
description: '网络异常请稍后重试',
});
});
}
});
};
return (
<>
<Prompt message="编辑的内容还未保存,确定要离开该页面吗?" when={showLeaveTip} />
<div className={styles.control}>
<div className={styles.nodeList}>
<div id="myPaletteNode" className={styles.myPaletteDiv} />
{/* <div className={styles.lineBox} /> */}
<div id="myPaletteGateway" className={styles.myPaletteDiv} />
<div id="myPaletteSubprocess" className={styles.myPaletteSubprocess} />
</div>
<div className={styles.buttonList}>
{/* <Button
type="link"
onClick={() => {
window.open(
'https://www.yuque.com/docs/share/da224db9-b8d1-49d2-838f-a23fcd15f0da?#%20%E3%80%8A%E6%B5%81%E7%A8%8B%E8%AE%BE%E8%AE%A1%E3%80%8B',
);
}}
>
说明文档
</Button> */}
{/* <Button type="link" onClick={() => copyNode()}>
复制
</Button> */}
<Button
onClick={() =>
history.push({
pathname: '/biz/workflow/center',
state: {
activeKey,
},
})
}
>
返回
</Button>
<Button type="primary" onClick={() => saveFlow()} loading={buttonLoading}>
发布
</Button>
</div>
</div>
<div className={styles.chartBox}>
<div id="myOverviewDiv" className={styles.myOverviewDiv} />
<div className={styles.flowName}>{flowData.flowName}</div>
<Spin spinning={chartLoading}>
<div
id="myDiagramDiv"
className={styles.myDiagramDiv}
style={{ backgroundColor: '#EFF8FA' }}
/>
</Spin>
<NodeModal
flowID={flowID}
visible={visible}
editMsg={editMsg}
modalType={modalType}
nodeChage={nodeChage}
currentNode={currentNode.current}
limitFinshNodes={[...limitFinshNodes.current]}
afterNodes={Object.fromEntries(afterNodes.current)}
handleCancel={() => setVisible(false)}
onSubumit={obj => nodeCallBack(obj)}
flowData={diagram ? JSON.parse(diagram.model.toJson()) : {}}
/>
</div>
<LineModal
visible={lineVisible}
lineMsg={lineMsg}
handleCancel={() => setLineVisible(false)}
onSubumit={obj => lineCallBack(obj)}
/>
</>
);
};
export default FlowChart;
......@@ -34,7 +34,7 @@ const FlowGroupModal = props => {
return;
}
if (validate.name === msg.name) {
onSubumit();
onSubumit(validate.name);
return;
}
if (!msg.isOld) {
......@@ -46,7 +46,7 @@ const FlowGroupModal = props => {
newName: validate.name,
}).then(res => {
if (res.code === 0) {
onSubumit();
onSubumit(validate.name);
notification.success({
message: '提示',
duration: 3,
......
......@@ -31,7 +31,7 @@ const FlowModal = props => {
if (validate) {
let obj = {};
if (modalType === 'add') {
obj = validate;
obj = { ...validate, CreateUser: sessionStorage.getItem('userType') };
} else {
obj = { ...validate, flowID: msg.FlowID };
}
......
......@@ -93,6 +93,12 @@ const DatabaseConnectConfig = asyncComponent(() =>
// 用户中心
const UserManage = asyncComponent(() => import('@/pages/userCenter/userManage/UserManage'));
const Workflow = asyncComponent(() => import('@/pages/bsmanager/workOrder/workflowEdit/Workflow'));
const WorkflowHomePage = asyncComponent(() =>
import('@/pages/bsmanager/workOrder/workflowEdit/WorkflowHomePage'),
);
const FlowBoard = asyncComponent(() =>
import('@/pages/bsmanager/workOrder/workflowEdit/workFlowComponents/FlowBoard'),
);
const RoleManage = asyncComponent(() => import('@/pages/userCenter/roleManage/RoleManage'));
const SiteManage = asyncComponent(() => import('@/pages/userCenter/siteManage/SiteManage'));
// 数据中心
......@@ -108,6 +114,9 @@ const PanoramaConfig = asyncComponent(() =>
import('@/pages/platformCenter/gis/panoramaConfig/index'),
);
const MessageManager = asyncComponent(() => import('@/pages/platformCenter/messageManage'));
// const SchemeDetail = asyncComponent(() =>
// import('@/pages/platformCenter/messageManage/schemeDetails/schemeDetails'),
// );
const SchemeDetail = asyncComponent(() =>
import('@/pages/platformCenter/messageManage/schemeDetail/schemeDetail'),
);
......@@ -329,6 +338,17 @@ export default {
name: '工作流编辑',
component: Workflow,
},
{
path: '/biz/workflow/center',
name: '流程中心',
component: WorkflowHomePage,
},
{
path: '/biz/workflow/flowBoard',
name: '流程画板',
component: FlowBoard,
hideMenu: true,
},
{
path: '/biz/workflow/holidays',
name: '节假日管理',
......
......@@ -35,3 +35,6 @@ export const FlowNodeSave = param =>
export const DeleteFlowNode = param => get(`${PUBLISH_SERVICE}/WorkFlow/DeleteFlowNode`, param);
// 批量删除
export const DeleteFlowNodes = param => post(`${PUBLISH_SERVICE}/WorkFlow/DeleteFlowNodes`, param);
// 保存basde65
export const SaveWorkFlowImage = param =>
post(`${PUBLISH_SERVICE}/FileCenter/SaveWorkFlowImage`, param);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment