import React, { PureComponent } from 'react' import { Row, Col, Button,} from 'antd'; import { openToast } from '../Notification' import GGEditor, { Flow } from 'gg-editor'; import EditorMinimap from './components/EditorMinimap'; import { FlowContextMenu } from './components/EditorContextMenu'; import { FlowToolbar } from './components/EditorToolbar'; import { FlowItemPanel } from './components/EditorItemPanel'; import { FlowDetailPanel } from './components/EditorDetailPanel'; import styles from './Flow/index.less'; import { NewItem, BPMN, StartNoneEvent, EndNoneEvent, BoundaryTimerEvent, ExclusiveGateway, MyEdge } from './components/NewItem' import { connect } from 'dva'; import GetServerData from './components/GetServerData' var updata = {} @connect() class FlowPage extends PureComponent { constructor(props) { super(props) this.state = { serverData: {}, perfectData: {}, lowerRightX: 0, lowerRightY: 0, upload: {}, maxX: 0, minY: 0, getEvent: '', getDrag: '', getDragEnd: '', getMouseUp: '', isDelete: false,//是否点击了删除按钮 nodeId: '',//点击的节点id isNode: '',//判断删除的是否为节点 canvasImg: '',//canvas转换的图片 isShow: true,//是否展示 } } //把canvas转化为图片 convertCanvasToImage(canvas) { // console.log(canvas) var image = new Image(); image.src = canvas.toDataURL("image/png"); // console.log(image) this.setState({ canvasImg: canvas.toDataURL("image/png") }, () => { if (this?.props?.getCanvasImg) { this.props.getCanvasImg(this.state.canvasImg) this.setState({ isShow: this.props.isShow }) } }) return image; } //获取服务器的数据 getServerData = (serverData, perfectData) => { this.setState({ serverData: serverData, perfectData: perfectData }, () => { let myCavas = document.querySelector('.graph-container canvas')//获取canvas的外层 // console.log(myCavas) setTimeout(() => { this.convertCanvasToImage(myCavas) }, 100); }) } //子传父的方法data数据 getprocess = (data, newData, type) => {//获取上传json updata = data //修改perfectData会报错 let myCavas = document.querySelector('.graph-container canvas')//获取canvas的外层 // console.log(myCavas) setTimeout(() => { this.convertCanvasToImage(myCavas) }, 100); this.type = type if (type == 'masg') {//修改属性 this.setState({ perfectData: data }) } else if (type == 'node') {//修改节点 this.setState({ perfectData: data }) } else if (type == 'stencilNode') {//修改带有定时器的节点 this.setState({ perfectData: data, serverData: newData }) } else if (type == 'newEdge') {//新增线条 this.setState({ perfectData: data, serverData: newData }) } } //子传父的方法是否删除 isDelete = (isDelete) => { this.setState({ isDelete: isDelete }, () => { this.deleteNode() }) } //删除节点和线 deleteNode = () => { // console.log(this.state.nodeId) const { nodeId, isNode } = this.state let data = this.state.perfectData if (isNode == 'node') { data.model.childShapes = data.model.childShapes.filter(item => { if ((item.resourceId !== nodeId && !item?.target?.resourceId) || (item.stencil.id == 'SequenceFlow' && item?.target?.resourceId !== nodeId) ) { return item } }) } else if (isNode == 'edge') { data.model.childShapes = data.model.childShapes.filter(item => { if (item.resourceId !== nodeId) { return item } }) } } //上传方法 upData = (updata) => { const { dispatch } = this.props; let timestamp = new Date().getTime(); const user = JSON.parse(localStorage.getItem('user')) updata.lastUpdated = timestamp//修改上传时间 updata.lastUpdatedBy = !!user.currentAuthority ? user.currentAuthority : 'admin'//确定上传者 console.log(updata) if (updata.model === undefined) { console.log('没有修改') openToast('info', '保存流程图', '没有修改,不用上传', 'topRight') } else { this.addPrefix(updata) dispatch({ type: 'DataGgEditor/upData', payload: updata, callback: (data) => { openToast('success', '保存流程图', '上传成功', 'topRight') dispatch({ type: 'DataGgEditor/fetch', payload: this.props.flowModelId, callback: (data) => { console.log(data) this.clearPrefix(data) } }); } }); } } //清除前缀 clearPrefix = (data) => { data.model.childShapes = data.model.childShapes.map(item => { if (item.resourceId.substring(0, 7) !== 'zysoft_') { return item } item.resourceId = item.resourceId.substring(7) if (item.outgoing.length > 0) { item.outgoing.map(goItem => { goItem.resourceId = goItem.resourceId.substring(7) return goItem }) } if (item?.target) { item.target.resourceId = item?.target?.resourceId ? item?.target?.resourceId.substring(7) : '' } return item }) this.deformation(data) } deformation = (data) => {//把服务器的数据转换为能展示的数据 // console.log(data) const arr = { nodes: [], edges: [] } data.model.childShapes.map(item => { if (item.stencil.id == "StartNoneEvent") { const obj = { type: 'node', size: '55*55', shape: 'StartNoneEvent', // color: '#FA8C16', label: item?.properties?.name ? item.properties.name : '', x: item.bounds.upperLeft.x, y: item.bounds.upperLeft.y, id: item.resourceId, } // console.log(obj) arr.nodes.push(obj) } else if (item.stencil.id == "UserTask") { const obj = { type: 'node', size: '60*48', shape: 'UserTask', // color: "#ffeae6", label: item.properties.name, x: item.bounds.upperLeft.x, y: item.bounds.upperLeft.y, id: item.resourceId, } // console.log(obj) arr.nodes.push(obj) } else if (item.stencil.id == "SequenceFlow") { data.model.childShapes.map(edge => { edge.outgoing.map(dome => { if (dome.resourceId == item.resourceId) { // console.log(item.target.resourceId) let staticValue = item?.properties?.conditionsequenceflow?.expression?.staticValue const obj = { source: edge.resourceId, target: item.target.resourceId, label: item.properties.name, index: 1, id: item.resourceId, shape: "flow-polyline", overrideid: item.properties.overrideid, conditions: staticValue ? staticValue : '', style: { lineWidth: 4,//连线的宽度 }, static: undefined, controlPoints: [], targetAnchor: item.properties.targetAnchor !== undefined ? item.properties.targetAnchor : '', sourceAnchor: item.properties.sourceAnchor !== undefined ? item.properties.sourceAnchor : '' } arr.edges.push(obj) } }) }) } else if (item.stencil.id == "EndNoneEvent") { const obj = { type: 'node', size: '55*55', shape: 'EndNoneEvent', // color: '#FA8C16', label: item.properties.name, x: item.bounds.upperLeft.x, y: item.bounds.upperLeft.y, id: item.resourceId, } // console.log(obj) arr.nodes.push(obj) } else if (item.stencil.id == "ExclusiveGateway") { const obj = { type: 'node', size: '55*55', shape: 'ExclusiveGateway', // color: 'blue', label: item.properties.name, x: item.bounds.upperLeft.x, y: item.bounds.upperLeft.y, id: item.resourceId, } // console.log(obj) arr.nodes.push(obj) } else if (item.stencil.id == "BoundaryTimerEvent") { const obj = { type: 'node', size: '55*55', shape: 'BoundaryTimerEvent', // color: '#FA8C16', label: item.properties.name, x: item.bounds.upperLeft.x, y: item.bounds.upperLeft.y, id: item.resourceId, } // console.log(obj) arr.nodes.push(obj) } }) this.setState({ serverData: arr, perfectData: data }) } //上传添加前缀 addPrefix = (data) => { data.model.childShapes = data.model.childShapes.map(item => { if (item.resourceId.substring(0, 7) === 'zysoft_') { return item } item.resourceId = 'zysoft_' + item.resourceId if (item.outgoing.length > 0) { item.outgoing.map(goItem => { goItem.resourceId = 'zysoft_' + goItem.resourceId return goItem }) } if (item?.target) { item.target.resourceId = item?.target?.resourceId ? 'zysoft_' + item?.target?.resourceId : '' } return item }) } getlowerRight = (e) => {//获取canvas的大小 // console.log(e, '点击') this.setState({ getEvent: e, getDrag: '', isDelete: false }) this.selectedId = '' if (e.item == null) { this.setState({ lowerRightX: e?.domEvent?.toElement?.width, lowerRightY: e?.domEvent?.toElement?.height, maxX: 0, minY: 0 }, () => { if (Object.keys(updata).length > 0 && updata.model?.bounds) { updata.model.bounds.lowerRight.x = this.state.lowerRightX updata.model.bounds.lowerRight.y = this.state.lowerRightY } }) } else if (e.item.bbox !== undefined) { //获取点击的位子在节点的中的坐标 const width = e.item.bbox.maxX - e.x const height = e.item.bbox.minY - e.y if (e.item.model.shape == 'EndNoneEvent') { this.setState({ maxX: 0, minY: 0 }) return } this.setState({ maxX: e.domX + width, minY: e.domY + height }) } else if (e.item.type == 'edge') { this.setState({ maxX: 0, minY: 0 }) } } //更新跟过选择框 more = (e) => { // console.log('拖动结束', e) this.setState({ maxX: 0, minY: 0, getDragEnd: e }) } //清除点击事件,拖动事件 clearClick = (e) => { // console.log('拖动', e) this.setState({ getEvent: '', getDrag: e, getDragEnd: '', maxX: 0, minY: 0, isDelete: false, }) } //鼠标抬起事件函数 mouseUp = (e) => { // console.log('抬起', e) this.setState({ getMouseUp: e }) } //鼠标移入事件 mouseEnter = (e) => { // console.log(e, '移入') if (e.item && e.item.type == 'node') { // console.log(12121455) e.item.keyShape._cfg.attrs.lineWidth = 5 } } //鼠标移出事件 mouseLeave = (e) => { // console.log(e, '移出') if (e.item && e.item.type == 'node' && this.selectedId !== e.item.id && e.item?.keyShape?._cfg.attrs?.fillStyle) { // e.item.keyShape._cfg.attrs.fillStyle = '#ffffff' // e.item.keyShape._cfg.attrs.strokeStyle = '#CED4D9' e.item.keyShape._cfg.attrs.lineWidth = 2 } } //选中节点后 afterItemSelected = (e) => { // console.log(e, '选中') if (e.item && e.item.type == 'node') { this.selectedId = e.item.id // console.log(32566555) e.item.keyShape._cfg.attrs.fillStyle = '#cccccc' e.item.keyShape._cfg.attrs.strokeStyle = '#1890ff' // e.item.keyShape._cfg.attrs.lineWidth = 5 } if (e.item && e.item.type == 'edge') { //线 this.selectedId = e.item.id e.item.keyShape._cfg.attrs.strokeStyle = '#A3B1BF' e.item.endArrow._cfg.attrs.fillStyle = '#A3B1BF' e.item.endArrow._cfg.attrs.fill = '#A3B1BF' } } //取消选中后 afterItemUnselected = (e) => { if (e.item && e.item.type == 'node') { this.selectedId = '' e.item.keyShape._cfg.attrs.fillStyle = '#ffffff' e.item.keyShape._cfg.attrs.strokeStyle = '#CED4D9' // e.item.keyShape._cfg.attrs.lineWidth = 2 } } //鼠标右键事件 mouseRight = (e) => { // console.log(e) this.setState({ maxX: 0, minY: 0, nodeId: e?.item?.id, isNode: e?.item?.type }) } //激活节点 AfterItemInactivated = (e) => { // console.log(e, '激活后') if (e.item && e.item.type == 'edge' && this.selectedId == e.item.id) { //线 e.item.keyShape._cfg.attrs.strokeStyle = '#A3B1BF' e.item.endArrow._cfg.attrs.fillStyle = '#A3B1BF' e.item.endArrow._cfg.attrs.fill = '#A3B1BF' e.item.keyShape._attrs.lineWidth = 2 } } //数据变化后 AfterChange = (e) => { console.log(e, '数据变化后') if (e.item && e.item.type == 'node' && this.selectedId == e.item.id) { // console.log(32566555) e.item.keyShape._cfg.attrs.fillStyle = '#cccccc' e.item.keyShape._cfg.attrs.strokeStyle = '#1890ff' // e.item.keyShape._cfg.attrs.lineWidth = 5 } if (e.item && e.item.type == 'edge' && this.selectedId == e.item.id && e.item?.keyShape?._cfg?.attrs?.stroke) { //线 e.item.keyShape._cfg.attrs.stroke = '#A3B1BF' e.item.keyShape._cfg.attrs.strokeStyle = '#A3B1BF' e.item.endArrow._cfg.attrs.fillStyle = '#A3B1BF' e.item.endArrow._cfg.attrs.fill = '#A3B1BF' } } render() { let { isDelete, maxX, minY } = this.state // console.log(this.props.flowModelId) return (<> <GGEditor id='editor' className={styles.editor} > <Row type="flex" className={styles.editorHd}> <Col span={24}> <FlowToolbar /> </Col> </Row> <Row type="flex" className={styles.editorBd}> <Col span={4} className={styles.editorSidebar}> {/* 选择需要的框的类型*/} <FlowItemPanel minY={minY} maxX={maxX} /> <NewItem></NewItem> <BPMN></BPMN> <StartNoneEvent></StartNoneEvent> <EndNoneEvent></EndNoneEvent> <BoundaryTimerEvent></BoundaryTimerEvent> <ExclusiveGateway></ExclusiveGateway> <MyEdge></MyEdge> </Col> <Col span={16} className={styles.editorContent}> <Flow className={styles.flow} data={this.state.serverData}//渲染data数据 onDragEnd={(e) => { this.more(e) }}//拖动结束事件 onClick={(e) => { this.getlowerRight(e) }}//点击事件 onDrag={(e) => { this.clearClick(e) }}//拖动事件 onMouseUp={(e) => { this.mouseUp(e) }}//鼠标抬起事件 // onMouseEnter={(e) => { this.mouseEnter(e) }}//鼠标移入事件 // onMouseLeave={(e) => { this.mouseLeave(e) }}//鼠标移出事件 onAfterItemSelected={(e) => { this.afterItemSelected(e) }}//选中节点事件 // onAfterItemUnselected={(e) => { this.afterItemUnselected(e) }}//取消选中后 onContextMenu={(e) => { this.mouseRight(e) }}//鼠标右键事件 // onAfterItemInactivated={(e) => { this.AfterItemInactivated(e) }}//激活节点和线 // onAfterChange={(e) => { this.AfterChange(e) }}//数据变化后 /> </Col> <Col span={4} className={styles.editorSidebar} > <FlowDetailPanel getEvent={this.state.getEvent}//传送e事件 data={this.state.perfectData}//数据 getprocess={this.getprocess}//字串传父的函数 getDrag={this.state.getDrag}//拖动事件数据 getDragEnd={this.state.getDragEnd}//拖动结束事件 isDelete={isDelete}//是否删除 /> <EditorMinimap /> </Col> </Row> <FlowContextMenu isDelete={this.isDelete} /> <Button className={styles.saveDate} onClick={() => { this.upData(updata) }}>保存 </Button> <GetServerData value={this.props.flowModelId} getServerData={this.getServerData} taskKeys={this.props?.taskKeys ? this.props?.taskKeys : ''} ></GetServerData> </GGEditor> {/* <img src={this.state.canvasImg}></img> */} </> ) } } export default FlowPage;