| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import { Spin, Tooltip, message, Modal, notification } from 'antd' |
| | | import { UndoOutlined, RedoOutlined, VerticalAlignTopOutlined, VerticalAlignBottomOutlined, SaveOutlined, ZoomInOutlined, ZoomOutOutlined, OneToOneOutlined } from '@ant-design/icons' |
| | | import { Spin, Tooltip, message, Modal, notification, Switch, Button } from 'antd' |
| | | import { UndoOutlined, RedoOutlined, VerticalAlignTopOutlined, VerticalAlignBottomOutlined, ZoomInOutlined, ZoomOutOutlined, OneToOneOutlined, QuestionCircleOutlined, ClearOutlined } from '@ant-design/icons' |
| | | import { Graph, Shape } from '@antv/x6' |
| | | import { Stencil } from '@antv/x6-plugin-stencil' |
| | | import { Transform } from '@antv/x6-plugin-transform' |
| | |
| | | import MKEmitter from '@/utils/events.js' |
| | | import asyncComponent from '@/utils/asyncComponent' |
| | | import NormalHeader from '@/tabviews/custom/components/share/normalheader' |
| | | import lanes from '@/menu/components/chart/antv-X6/lane.json' |
| | | import xflows from '@/menu/components/chart/antv-X6/xflow.json' |
| | | // import lanes from '@/menu/components/chart/antv-X6/lane.json' |
| | | // import xflows from '@/menu/components/chart/antv-X6/xflow.json' |
| | | import './index.scss' |
| | | |
| | | const { confirm } = Modal |
| | | const NodeUpdate = asyncComponent(() => import('./nodeupdate')) |
| | | |
| | | const groups = { |
| | |
| | | 'mk-rect', |
| | | { |
| | | inherit: 'rect', |
| | | width: 66, |
| | | height: 36, |
| | | width: 100, |
| | | height: 32, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | |
| | | 'mk-polygon', |
| | | { |
| | | inherit: 'polygon', |
| | | width: 66, |
| | | height: 36, |
| | | width: 100, |
| | | height: 32, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | |
| | | 'mk-paral', |
| | | { |
| | | inherit: 'polygon', |
| | | width: 66, |
| | | height: 36, |
| | | width: 100, |
| | | height: 32, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | |
| | | 'mk-circle', |
| | | { |
| | | inherit: 'circle', |
| | | width: 36, |
| | | height: 36, |
| | | width: 40, |
| | | height: 40, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | |
| | | 'mk-ellipse', |
| | | { |
| | | inherit: 'ellipse', |
| | | width: 66, |
| | | height: 36, |
| | | width: 100, |
| | | height: 32, |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 1, |
| | |
| | | 'mk-star', |
| | | { |
| | | inherit: 'polygon', |
| | | width: 36, |
| | | height: 36, |
| | | width: 40, |
| | | height: 40, |
| | | points: '100,10 40,198 190,78 10,78 160,198', |
| | | attrs: { |
| | | body: { |
| | |
| | | Graph.registerNode( |
| | | 'mk-text', |
| | | { |
| | | inherit: 'rect', |
| | | width: 66, |
| | | height: 36, |
| | | inherit: 'text-block', |
| | | width: 100, |
| | | height: 50, |
| | | text: '文本域', |
| | | attrs: { |
| | | body: { |
| | | strokeWidth: 0, |
| | | fill: 'transparent' |
| | | }, |
| | | text: { |
| | | fontSize: 12, |
| | | fill: '#262626' |
| | | fill: '#ffffff', |
| | | stroke: '#000000', |
| | | strokeWidth: 1, |
| | | rx: 0, |
| | | ry: 0 |
| | | } |
| | | } |
| | | }, |
| | | true |
| | | ) |
| | | |
| | | const styles = { |
| | | blue: '#1890ff', |
| | | red: '#f5222d', |
| | | orange_red: '#fa541c', |
| | | orange: '#fa8c16', |
| | | orange_yellow: '#faad14', |
| | | yellow: '#fadb14', |
| | | yellow_green: '#a0d911', |
| | | green: '#52c41a', |
| | | cyan: '#13c2c2', |
| | | blue_purple: '#3860f4', |
| | | purple: '#722ed1', |
| | | magenta: '#eb2f96', |
| | | grass_green: '#aeb303', |
| | | deep_red: '#c32539', |
| | | deep_blue: '#1d3661', |
| | | blue1: '#e6f7ff', |
| | | red1: '#fff1f0', |
| | | orange_red1: '#fff2e8', |
| | | orange1: '#fff7e6', |
| | | orange_yellow1: '#fffbe6', |
| | | yellow1: '#feffe6', |
| | | yellow_green1: '#fcffe6', |
| | | green1: '#f6ffed', |
| | | cyan1: '#e6fffb', |
| | | blue_purple1: '#f0f5ff', |
| | | purple1: '#f9f0ff', |
| | | magenta1: '#fff0f6', |
| | | grass_green1: '#f2efda', |
| | | deep_red1: '#fff0f0', |
| | | deep_blue1: '#eff1f4' |
| | | } |
| | | |
| | | let sysColor = '#1890ff' |
| | | let lightColor = '#e6f7ff' |
| | | if (window.GLOB.style) { |
| | | let type = window.GLOB.style.replace(/bg_black_style_|bg_white_style_/, '') |
| | | sysColor = styles[type] || '#1890ff' |
| | | lightColor = styles[type + '1'] || '#e6f7ff' |
| | | } |
| | | |
| | | class antvX6Chart extends Component { |
| | | static propTpyes = { |
| | |
| | | config: null, |
| | | editing: false, |
| | | node: null, |
| | | loading: false |
| | | loading: false, |
| | | status: 0, |
| | | flowname: '', |
| | | flowcode: '', |
| | | orgs: [], |
| | | empty: true |
| | | } |
| | | |
| | | selectNode = null |
| | |
| | | if (BData) { |
| | | BID = BData.$BID || '' |
| | | } |
| | | |
| | | |
| | | this.setState({ |
| | | config: _config, |
| | | BID: BID || '', |
| | |
| | | plot: _config.plot |
| | | }, () => { |
| | | this.loadData() |
| | | |
| | | if (_config.plot.function === 'edit') { |
| | | this.getorganizations() |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | async loadData () { |
| | | const { config, BID } = this.state |
| | | getorganizations = () => { |
| | | Api.genericInterface({func: 's_get_organizations_v1'}).then(res => { |
| | | if (!res.status) { |
| | | notification.error({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | return |
| | | } |
| | | |
| | | if (config.setting.supModule && !BID) { // BID 不存在时,不做查询 |
| | | let orgs = [] |
| | | res.organizations && res.organizations.forEach(com => { |
| | | let _com = { |
| | | key: com.OrgCode, |
| | | title: com.OrgName, |
| | | shortName: com.ShortName, |
| | | checkable: false, |
| | | selectable: false, |
| | | children: [] |
| | | } |
| | | let _works = [] |
| | | |
| | | com.departments.forEach(dep => { |
| | | let _dep = { |
| | | key: dep.co_pro_code, |
| | | title: dep.co_pro_name, |
| | | checkable: false, |
| | | selectable: false, |
| | | children: [] |
| | | } |
| | | |
| | | dep.jobs.forEach(job => { |
| | | let _job = { |
| | | key: job.jobcode, |
| | | title: job.jobname, |
| | | checkable: false, |
| | | selectable: false, |
| | | children: [] |
| | | } |
| | | |
| | | job.work_group.forEach(group => { |
| | | if (group.work_group === 'normal') { |
| | | group.workers.forEach(work => { |
| | | let _work = { |
| | | key: work.worker_id, |
| | | title: work.workername, |
| | | email: work.email || '', |
| | | images: work.images || '', |
| | | mob: work.mob || '', |
| | | sex: work.sex || '', |
| | | work_grade: work.work_grade || '', |
| | | worker_id: work.worker_id || '', |
| | | workercode: work.workercode || '', |
| | | workername: work.workername || '', |
| | | job_type: job.job_type || '', |
| | | parentIds: [com.OrgCode, dep.co_pro_code, job.jobcode], |
| | | parentNames: [com.OrgName, dep.co_pro_name, job.jobname] |
| | | } |
| | | |
| | | _job.children.push(_work) |
| | | }) |
| | | } else { |
| | | let _group = { |
| | | key: group.work_group, |
| | | title: group.work_group, |
| | | checkable: false, |
| | | selectable: false, |
| | | children: [] |
| | | } |
| | | |
| | | group.workers.forEach(work => { |
| | | let _work = { |
| | | key: work.worker_id, |
| | | title: work.workername, |
| | | email: work.email || '', |
| | | images: work.images || '', |
| | | mob: work.mob || '', |
| | | sex: work.sex || '', |
| | | work_grade: work.work_grade || '', |
| | | worker_id: work.worker_id || '', |
| | | workercode: work.workercode || '', |
| | | workername: work.workername || '', |
| | | job_type: job.job_type || '', |
| | | parentIds: [com.OrgCode, dep.co_pro_code, job.jobcode, group.work_group], |
| | | parentNames: [com.OrgName, dep.co_pro_name, job.jobname, group.work_group] |
| | | } |
| | | |
| | | _group.children.push(_work) |
| | | }) |
| | | |
| | | if (_group.children.length > 0) { |
| | | _job.children.push(_group) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (_job.children.length > 0) { |
| | | _dep.children.push(_job) |
| | | } |
| | | }) |
| | | |
| | | if (_dep.children.length > 0) { |
| | | _com.children.push(_dep) |
| | | } |
| | | }) |
| | | |
| | | if (_com.children.length > 0) { |
| | | _com.works = _works |
| | | orgs.push(_com) |
| | | } |
| | | }) |
| | | |
| | | this.setState({orgs: orgs}) |
| | | }) |
| | | } |
| | | |
| | | async loadData () { |
| | | const { BID } = this.state |
| | | |
| | | if (!BID) { |
| | | this.cells = [] |
| | | if (!is(fromJS(this.data), fromJS([]))) { |
| | | this.cells = [] |
| | | this.handleData() |
| | | } |
| | | this.setState({empty: true}) |
| | | return |
| | | } |
| | | |
| | |
| | | loading: true |
| | | }) |
| | | |
| | | if (config) { |
| | | if (config.plot.subtype === 'xflow') { |
| | | this.cells = xflows |
| | | } else { |
| | | this.cells = lanes |
| | | } |
| | | this.handleData() |
| | | |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | }, 2000) |
| | | return |
| | | } |
| | | |
| | | let param = { |
| | | func: '', |
| | | BID: BID |
| | | func: 's_get_works_flow_local_param_v6', |
| | | ID: BID |
| | | } |
| | | |
| | | let result = await Api.genericInterface(param) |
| | | if (result.status) { |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | let item = result.data && result.data[0] ? result.data[0] : null |
| | | let cells = [] |
| | | |
| | | this.cells = result.data || [] |
| | | if (item && item.long_param) { |
| | | let long_param = JSON.parse(window.decodeURIComponent(window.atob(item.long_param))) |
| | | cells = long_param.cells || [] |
| | | } |
| | | |
| | | this.cells = cells |
| | | this.handleData() |
| | | |
| | | this.setState({ |
| | | status: item.status || 0, |
| | | flowname: item.works_flow_name || '', |
| | | flowcode: item.works_flow_code || '', |
| | | loading: false, |
| | | empty: cells.length === 0 |
| | | }) |
| | | |
| | | if (result.message) { |
| | | if (result.ErrCode === 'Y') { |
| | |
| | | max: 2 |
| | | }, |
| | | autoResize: true, |
| | | interacting: false, |
| | | panning: true, |
| | | background: { |
| | | color: config.plot.backgroundColor || 'transparent' |
| | |
| | | allowBlank: false, |
| | | snap: { |
| | | radius: 20 |
| | | }, |
| | | createEdge() { |
| | | return new Shape.Edge({ |
| | | attrs: { |
| | | line: { |
| | | stroke: '#000000', |
| | | strokeWidth: 1, |
| | | targetMarker: { |
| | | name: 'block', |
| | | width: 12, |
| | | height: 8 |
| | | } |
| | | } |
| | | }, |
| | | zIndex: 0 |
| | | }) |
| | | }, |
| | | validateConnection({ targetMagnet }) { |
| | | return !!targetMagnet |
| | | } |
| | | }, |
| | | highlighting: { |
| | | magnetAdsorbed: { |
| | | name: 'stroke', |
| | | args: { |
| | | attrs: { |
| | | fill: '#5F95FF', |
| | | stroke: '#5F95FF' |
| | | } |
| | | } |
| | | } |
| | | } |
| | | }) |
| | |
| | | graph.resetCells(cells) |
| | | graph.positionContent('center') |
| | | } |
| | | |
| | | if (config.plot.click) { |
| | | graph.on('cell:click', ({ node }) => { |
| | | this.checkNode(graph, node) |
| | | }) |
| | | |
| | | graph.on('blank:click', () => { |
| | | this.checkNode(graph) |
| | | }) |
| | | } |
| | | } |
| | | |
| | | laneSrender = () => { |
| | |
| | | min: 0.5, |
| | | max: 2 |
| | | }, |
| | | interacting: false, |
| | | autoResize: true, |
| | | panning: true, |
| | | background: { color: '#ffffff' }, |
| | |
| | | allowBlank: false, |
| | | snap: { |
| | | radius: 20 |
| | | }, |
| | | createEdge() { |
| | | return new Shape.Edge({ |
| | | attrs: { |
| | | line: { |
| | | stroke: '#000000', |
| | | strokeWidth: 1, |
| | | targetMarker: { |
| | | name: 'block', |
| | | width: 12, |
| | | height: 8 |
| | | } |
| | | } |
| | | }, |
| | | zIndex: 2 |
| | | }) |
| | | }, |
| | | validateConnection({ targetMagnet }) { |
| | | return !!targetMagnet |
| | | } |
| | | }, |
| | | highlighting: { |
| | | magnetAdsorbed: { |
| | | name: 'stroke', |
| | | args: { |
| | | attrs: { |
| | | fill: '#5F95FF', |
| | | stroke: '#5F95FF' |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | translating: { |
| | | restrict(cellView) { |
| | | const cell = cellView.cell |
| | | const parentId = cell.prop('parent') |
| | | |
| | | if (parentId) { |
| | | const parentNode = graph.getCellById(parentId) |
| | | if (parentNode) { |
| | | return parentNode.getBBox().moveAndExpand({ |
| | | x: 0, |
| | | y: 36, |
| | | width: 0, |
| | | height: -36, |
| | | }) |
| | | } |
| | | } |
| | | return cell.getBBox() |
| | | } |
| | | } |
| | | }) |
| | |
| | | }) |
| | | graph.resetCells(cells) |
| | | graph.positionContent('top') |
| | | } |
| | | |
| | | if (config.plot.click) { |
| | | graph.on('cell:click', ({ node }) => { |
| | | this.checkNode(graph, node) |
| | | }) |
| | | |
| | | graph.on('blank:click', () => { |
| | | this.checkNode(graph) |
| | | }) |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | }) |
| | | |
| | | // #region 使用插件 |
| | | graph |
| | | .use(new Transform({ |
| | | resizing: true, |
| | |
| | | .use(new History()) |
| | | .use(new Export()) |
| | | |
| | | // #region 初始化 stencil |
| | | const stencil = new Stencil({ |
| | | title: '流程图', |
| | | target: graph, |
| | | stencilGraphWidth: 180, |
| | | stencilGraphWidth: 230, |
| | | stencilGraphHeight: 180, |
| | | groups: [ |
| | | { |
| | | title: '通用节点', |
| | | name: 'group1' |
| | | name: 'group1', |
| | | graphHeight: 150 |
| | | }, |
| | | { |
| | | title: '自定义', |
| | | name: 'group2', |
| | | graphHeight: 150, |
| | | graphHeight: 300, |
| | | layoutOptions: { |
| | | rowHeight: 70 |
| | | } |
| | |
| | | ], |
| | | layoutOptions: { |
| | | columns: 2, |
| | | columnWidth: 80, |
| | | columnWidth: 110, |
| | | rowHeight: 55 |
| | | } |
| | | }) |
| | | |
| | | document.getElementById(config.uuid + 'stencil').appendChild(stencil.container) |
| | | |
| | | // #region 快捷键与事件 |
| | | graph.bindKey(['meta+c', 'ctrl+c'], () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | |
| | | return false |
| | | }) |
| | | |
| | | // undo redo |
| | | graph.bindKey(['meta+z', 'ctrl+z'], () => { |
| | | if (graph.canUndo()) { |
| | | graph.undo() |
| | |
| | | return false |
| | | }) |
| | | |
| | | // 删除元素 |
| | | graph.bindKey(['backspace', 'delete'], () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | |
| | | showPorts(ports, false) |
| | | }) |
| | | |
| | | graph.on('node:click', ({ e, x, y, node, view }) => { |
| | | graph.on('node:click', ({ node }) => { |
| | | this.selectNode = node |
| | | |
| | | this.setState({node: node.store.data}) |
| | | }) |
| | | graph.on('edge:click', ({ e, x, y, edge, view }) => { |
| | | graph.on('edge:click', ({ edge }) => { |
| | | this.selectNode = edge |
| | | |
| | | |
| | | this.setState({node: edge.store.data}) |
| | | |
| | | graph.clearTransformWidgets() |
| | | }) |
| | | graph.on('blank:click', ({ e, x, y }) => { |
| | | |
| | | graph.on('node:dblclick', () => { |
| | | setTimeout(() => { |
| | | MKEmitter.emit('mk-x6-dbclick') |
| | | }, 100) |
| | | }) |
| | | graph.on('edge:dblclick', () => { |
| | | setTimeout(() => { |
| | | MKEmitter.emit('mk-x6-dbclick') |
| | | }, 100) |
| | | }) |
| | | |
| | | graph.on('blank:click', () => { |
| | | this.selectNode = null |
| | | |
| | | this.setState({node: null}) |
| | | }) |
| | | graph.on('edge:connected', ({ isNew, edge }) => { |
| | | if (!isNew) return |
| | | |
| | | let target = edge.getTargetCell() |
| | | let source = edge.getSourceCell() |
| | | |
| | | if (!target || !source) return |
| | | |
| | | if (source.prop('mknode') === 'end') { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '结束节点不可添加分支!', |
| | | duration: 2 |
| | | }) |
| | | graph.removeCells([edge]) |
| | | return |
| | | } |
| | | |
| | | let mkdata = target.prop('mkdata') |
| | | |
| | | if (source.prop('mknode') === 'start' && target.prop('mknode') === 'end') { |
| | | edge.prop('mknode', 'throughEdge') |
| | | } else if (target.prop('mknode') === 'end') { |
| | | edge.prop('mknode', 'endEdge') |
| | | } else if (target.prop('mknode') === 'start') { |
| | | edge.prop('mknode', 'startEdge') |
| | | } else if (source.prop('mknode') === 'start') { |
| | | edge.prop('mknode', 'firstEdge') |
| | | } |
| | | if (mkdata) { |
| | | edge.prop('mkdata', {status: mkdata.status, statusName: mkdata.statusName}) |
| | | } |
| | | }) |
| | | |
| | | const r1 = graph.createNode({ |
| | | shape: 'mk-rect', |
| | | label: '开始', |
| | | mknode: 'start', |
| | | mkdata: {status: 0, statusName: '未提交'}, |
| | | attrs: { |
| | | body: { |
| | | rx: 20, |
| | | ry: 26 |
| | | rx: 0, |
| | | ry: 0, |
| | | fill: '#000000', |
| | | stroke: '#000000' |
| | | }, |
| | | text: { |
| | | fill: '#ffffff', |
| | | text: '开始' |
| | | } |
| | | } |
| | | }) |
| | | |
| | | const r4 = graph.createNode({ |
| | | shape: 'mk-rect', |
| | | attrs: { |
| | | body: { |
| | | rx: 0, |
| | | ry: 0, |
| | | fill: '#ffffff', |
| | | stroke: '#757575' |
| | | }, |
| | | text: { |
| | | fill: '#000000', |
| | | text: '节点' |
| | | } |
| | | } |
| | | }) |
| | | |
| | | const r5 = graph.createNode({ |
| | | shape: 'mk-polygon', |
| | | attrs: { |
| | | body: { |
| | | refPoints: '0,10 10,0 20,10 10,20', |
| | | fill: '#ffffff', |
| | | stroke: '#757575' |
| | | }, |
| | | text: { |
| | | fill: '#000000', |
| | | text: '决策' |
| | | } |
| | | } |
| | | }) |
| | | |
| | | const r8 = graph.createNode({ |
| | | shape: 'mk-rect', |
| | | mknode: 'end', |
| | | mkdata: {status: 888, statusName: '已完成'}, |
| | | attrs: { |
| | | body: { |
| | | rx: 0, |
| | | ry: 0, |
| | | fill: '#000000', |
| | | stroke: '#000000' |
| | | }, |
| | | text: { |
| | | fill: '#ffffff', |
| | | text: '结束' |
| | | } |
| | | } |
| | | }) |
| | | |
| | | stencil.load([r1, r4, r5, r8], 'group1') |
| | | |
| | | const r2 = graph.createNode({ |
| | | shape: 'mk-rect', |
| | | label: '过程' |
| | | attrs: { |
| | | body: { |
| | | rx: 20, |
| | | ry: 26, |
| | | fill: '#ffffff', |
| | | stroke: '#757575' |
| | | }, |
| | | text: { |
| | | fill: '#000000', |
| | | text: '过程' |
| | | } |
| | | } |
| | | }) |
| | | const r3 = graph.createNode({ |
| | | shape: 'mk-rect', |
| | | attrs: { |
| | | body: { |
| | | rx: 6, |
| | | ry: 6 |
| | | ry: 6, |
| | | fill: '#ffffff', |
| | | stroke: '#757575' |
| | | }, |
| | | text: { |
| | | fill: '#000000', |
| | | text: '可选过程' |
| | | } |
| | | }, |
| | | label: '可选过程' |
| | | } |
| | | }) |
| | | const r4 = graph.createNode({ |
| | | shape: 'mk-polygon', |
| | | attrs: { |
| | | body: { |
| | | refPoints: '0,10 10,0 20,10 10,20' |
| | | } |
| | | }, |
| | | label: '决策' |
| | | }) |
| | | const r5 = graph.createNode({ |
| | | const r6 = graph.createNode({ |
| | | shape: 'mk-paral', |
| | | attrs: { |
| | | body: { |
| | | refPoints: '10,0 40,0 30,20 0,20' |
| | | refPoints: '10,0 40,0 30,20 0,20', |
| | | fill: '#ffffff', |
| | | stroke: '#757575' |
| | | }, |
| | | text: { |
| | | fill: '#000000', |
| | | text: '数据' |
| | | } |
| | | }, |
| | | label: '数据' |
| | | } |
| | | }) |
| | | const r6 = graph.createNode({ |
| | | const r7 = graph.createNode({ |
| | | shape: 'mk-circle', |
| | | label: '连接' |
| | | attrs: { |
| | | body: { |
| | | fill: '#ffffff', |
| | | stroke: '#757575' |
| | | }, |
| | | text: { |
| | | fill: '#000000', |
| | | text: '连接' |
| | | } |
| | | } |
| | | }) |
| | | |
| | | stencil.load([r1, r2, r3, r4, r5, r6], 'group1') |
| | | |
| | | const p1 = graph.createNode({ |
| | | shape: 'mk-ellipse', |
| | |
| | | }) |
| | | |
| | | const p3 = graph.createNode({ |
| | | shape: 'mk-text', |
| | | label: '文本' |
| | | shape: 'mk-text' |
| | | }) |
| | | |
| | | stencil.load([p1, p2, p3], 'group2') |
| | | stencil.load([r2, r3, r6, r7, p1, p2, p3], 'group2') |
| | | |
| | | if (this.cells.length > 0) { |
| | | let cells = [] |
| | |
| | | }) |
| | | |
| | | graph |
| | | .use(new Transform({ |
| | | resizing: true, |
| | | rotating: true |
| | | })) |
| | | .use(new Selection()) |
| | | .use(new Snapline()) |
| | | .use(new Snapline({ |
| | | enabled: true, |
| | | filter: (Graph) => Graph.prop('shape') !== 'lane' |
| | | })) |
| | | .use(new Keyboard()) |
| | | .use(new Clipboard()) |
| | | .use(new History()) |
| | | .use(new Export()) |
| | | |
| | | // #region 初始化 stencil |
| | | const stencil = new Stencil({ |
| | | title: '流程图', |
| | | target: graph, |
| | | stencilGraphWidth: 180, |
| | | stencilGraphWidth: 230, |
| | | stencilGraphHeight: 180, |
| | | groups: [ |
| | | { |
| | |
| | | ], |
| | | layoutOptions: { |
| | | columns: 2, |
| | | columnWidth: 80, |
| | | columnWidth: 110, |
| | | rowHeight: 55 |
| | | } |
| | | }) |
| | | |
| | | document.getElementById(config.uuid + 'stencil').appendChild(stencil.container) |
| | | |
| | | // #region 快捷键与事件 |
| | | graph.bindKey(['meta+c', 'ctrl+c'], () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | | graph.copy(cells) |
| | | if (cells[0].prop('shape') !== 'lane' && cells[0].prop('shape') !== 'edge') { |
| | | graph.copy(cells) |
| | | } |
| | | } |
| | | return false |
| | | }) |
| | | graph.bindKey(['meta+x', 'ctrl+x'], () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | | graph.cut(cells) |
| | | if (cells[0].prop('shape') !== 'lane' && cells[0].prop('shape') !== 'edge') { |
| | | graph.cut(cells) |
| | | } |
| | | } |
| | | return false |
| | | }) |
| | |
| | | return false |
| | | }) |
| | | |
| | | // 删除元素 |
| | | graph.bindKey(['backspace', 'delete'], () => { |
| | | const cells = graph.getSelectedCells() |
| | | if (cells.length) { |
| | | graph.removeCells(cells) |
| | | this.selectNode = null |
| | | this.setState({node: null}) |
| | | |
| | | if (cells[0].prop('shape') === 'lane') { |
| | | graph.startBatch('delete-lane') |
| | | |
| | | graph.removeCells(cells) |
| | | this.deleteLane(cells[0], graph) |
| | | |
| | | graph.stopBatch('delete-lane') |
| | | } else { |
| | | graph.removeCells(cells) |
| | | } |
| | | } |
| | | }) |
| | | |
| | | // 控制连接桩显示/隐藏 |
| | | const showPorts = (ports, show) => { |
| | | for (let i = 0, len = ports.length; i < len; i += 1) { |
| | | ports[i].style.visibility = show ? 'visible' : 'hidden' |
| | |
| | | showPorts(ports, false) |
| | | }) |
| | | |
| | | graph.on('node:added', ({ cell, index, options }) => { |
| | | graph.on('node:added', ({ cell }) => { |
| | | if (cell.prop('shape') === 'lane') { |
| | | if (cell.prop('zIndex') === 0) return |
| | | |
| | | graph.startBatch('add-lane') |
| | | |
| | | this.addLane(cell, graph) |
| | |
| | | if (num <= 1) { |
| | | message.warning('请添加泳道!') |
| | | graph.removeCells([cell]) |
| | | } else { |
| | | } else if (!cell.prop('parent')) { |
| | | this.addNode(cell, graph) |
| | | } |
| | | } |
| | | }) |
| | | graph.on('node:click', ({ e, x, y, node, view }) => { |
| | | graph.on('node:click', ({ node }) => { |
| | | this.selectNode = node |
| | | this.setState({node: node.store.data}) |
| | | |
| | | if (node.prop('shape') === 'lane') { |
| | | graph.clearTransformWidgets() |
| | | } |
| | | }) |
| | | graph.on('edge:click', ({ e, x, y, edge, view }) => { |
| | | graph.on('edge:click', ({ edge }) => { |
| | | this.selectNode = edge |
| | | this.setState({node: edge.store.data}) |
| | | |
| | | graph.clearTransformWidgets() |
| | | }) |
| | | graph.on('blank:click', ({ e, x, y }) => { |
| | | graph.on('blank:click', () => { |
| | | this.selectNode = null |
| | | |
| | | this.setState({node: null}) |
| | |
| | | }) |
| | | |
| | | const p3 = graph.createNode({ |
| | | shape: 'mk-text', |
| | | label: '文本' |
| | | shape: 'mk-text' |
| | | }) |
| | | |
| | | stencil.load([p1, p2, p3], 'group2') |
| | |
| | | return |
| | | } |
| | | |
| | | // let cells = this.mkGraph.getCells() |
| | | this.selectNode.toBack() |
| | | } |
| | | |
| | | // zoom() 可获取或者设置缩放比例 |
| | | setback = () => { |
| | | if (this.mkGraph.canUndo()) { |
| | | this.mkGraph.undo() |
| | | } else { |
| | | message.warning('无可撤销记录!') |
| | | } |
| | | } |
| | | |
| | | setprev = () => { |
| | | if (this.mkGraph.canRedo()) { |
| | | this.mkGraph.redo() |
| | | } else { |
| | | message.warning('无可前进记录!') |
| | | } |
| | | } |
| | | |
| | |
| | | this.mkGraph.zoomTo(1) |
| | | } |
| | | |
| | | close = () => { |
| | | const { config } = this.state |
| | | |
| | | let nodes = this.mkGraph.toJSON() |
| | | |
| | | if (!is(fromJS(nodes.cells), fromJS(this.cells))) { |
| | | confirm({ |
| | | title: '流程图已修改,确定关闭吗?', |
| | | okText: '确定', |
| | | cancelText: '取消', |
| | | onOk() { |
| | | MKEmitter.emit('closeTabView', config.$pageId) |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } else { |
| | | MKEmitter.emit('closeTabView', config.$pageId) |
| | | } |
| | | } |
| | | |
| | | save = () => { |
| | | // let nodes = this.mkGraph.toJSON() |
| | | // this.mkGraph.toPNG((dataUri) => { |
| | | // Api.fileuploadbase64({ |
| | | // Base64Img: dataUri |
| | | // }).then(res => { |
| | | // }) |
| | | // }, {padding: 20}) |
| | | const { BID, plot, status, flowname, flowcode } = this.state |
| | | |
| | | if (!BID) { |
| | | Modal.error({ |
| | | title: '未获取到流程ID,不可保存!', |
| | | }) |
| | | return |
| | | } |
| | | |
| | | let nodes = this.mkGraph.toJSON() |
| | | let _status = status |
| | | |
| | | if (plot.subtype === 'xflow' && status === 10) { |
| | | let start_num = 0 |
| | | let end_num = 0 |
| | | let unvalid = false |
| | | let map = new Map() |
| | | let appMap = new Map() |
| | | |
| | | nodes.cells.forEach(item => { |
| | | if (item.shape === 'mk-text' || item.shape === 'lane') return |
| | | |
| | | if (!item.mkdata) { |
| | | unvalid = true |
| | | } else if (item.mknode === 'start') { |
| | | start_num++ |
| | | } else if (item.mknode === 'end') { |
| | | end_num++ |
| | | } else if (item.shape === 'edge') { |
| | | if (item.mknode === 'throughEdge') { |
| | | if (!item.mkdata.seniorbers || item.mkdata.seniorbers.length === 0) { |
| | | unvalid = true |
| | | } |
| | | } else if (item.mkdata.seniorCondition === 'open') { |
| | | |
| | | } else if (item.mknode !== 'endEdge' && item.mknode !== 'startEdge' && (!item.mkdata.members || item.mkdata.members.length === 0)) { |
| | | unvalid = true |
| | | } else if (item.mknode === 'startEdge' || item.mkdata.flowType === 'reject') { |
| | | if (map.has(item.source.cell)) { |
| | | unvalid = true |
| | | } else { |
| | | map.set(item.source.cell, true) |
| | | } |
| | | } else if (item.mkdata.flowType === 'approval' || item.mknode === 'endEdge') { |
| | | let val = '' |
| | | if (item.mkdata.execCondition === 'open') { |
| | | val = item.mkdata.match + item.mkdata.matchVal |
| | | } |
| | | if (appMap.has(item.source.cell + val)) { |
| | | unvalid = true |
| | | } else { |
| | | appMap.set(item.source.cell + val, true) |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (start_num !== 1 || end_num === 0 || unvalid) { |
| | | _status = 0 |
| | | } |
| | | } |
| | | |
| | | this.setState({ |
| | | loading: true |
| | | }) |
| | | |
| | | this.mkGraph.toPNG((dataUri) => { |
| | | let param = { |
| | | func: 's_works_flow_param_upt_v6', |
| | | long_param: window.btoa(window.encodeURIComponent(JSON.stringify(nodes))), |
| | | flow_image: dataUri, |
| | | status: status, |
| | | ID: BID, |
| | | BID: '' |
| | | } |
| | | |
| | | let ssoParam = { |
| | | func: 's_works_flow_param_sso_upt_v6', |
| | | status: status, |
| | | ID: BID, |
| | | works_flow_code: flowcode, |
| | | works_flow_name: flowname, |
| | | long_param: window.btoa(window.encodeURIComponent(JSON.stringify(nodes))) |
| | | } |
| | | |
| | | Api.genericInterface(param).then(res => { |
| | | if (res.status) { |
| | | if (plot.subtype === 'xflow') { |
| | | Api.getSystemConfig(ssoParam).then(result => { |
| | | if (result.status) { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功!', |
| | | duration: 2 |
| | | }) |
| | | this.setState({ |
| | | loading: false, |
| | | status: _status |
| | | }) |
| | | this.cells = nodes.cells |
| | | } else { |
| | | notification.error({ |
| | | top: 92, |
| | | message: result.message, |
| | | duration: 10 |
| | | }) |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | notification.success({ |
| | | top: 92, |
| | | message: '保存成功!', |
| | | duration: 2 |
| | | }) |
| | | this.setState({ |
| | | loading: false, |
| | | status: _status |
| | | }) |
| | | this.cells = nodes.cells |
| | | } |
| | | } else { |
| | | notification.error({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 10 |
| | | }) |
| | | this.setState({ |
| | | loading: false |
| | | }) |
| | | } |
| | | }) |
| | | }, {padding: 20}) |
| | | } |
| | | |
| | | clearNode = () => { |
| | | let cells = this.mkGraph.getCells() |
| | | const that = this |
| | | |
| | | if (cells.length === 0) { |
| | | message.warning('尚未添加元素!') |
| | | return |
| | | } |
| | | |
| | | confirm({ |
| | | title: '确定清空元素吗?', |
| | | content: '清空后不可恢复。', |
| | | okText: '确定', |
| | | cancelText: '取消', |
| | | onOk() { |
| | | that.mkGraph.removeCells(cells) |
| | | that.mkGraph.cleanHistory() |
| | | }, |
| | | onCancel() {} |
| | | }) |
| | | } |
| | | |
| | | deleteLane = (cell, graph) => { |
| | | let id = cell.id |
| | | |
| | | let nodes = graph.getNodes() |
| | | let cells = [] |
| | | |
| | | nodes.forEach(item => { |
| | | if (item.prop('shape') === 'lane') return |
| | | |
| | | if (item.prop('parent') === id) { |
| | | cells.push(item) |
| | | } |
| | | }) |
| | | |
| | | graph.removeCells(cells) |
| | | |
| | | this.resetlane(cell.id, cell.prop('position/x'), -cell.prop('size/width')) |
| | | } |
| | | |
| | | addLane = (cell, graph) => { |
| | |
| | | } |
| | | |
| | | let height = 400 |
| | | |
| | | if (typeof(config.plot.height) === 'number' || /px/.test(config.plot.height)) { |
| | | height = parseInt(config.plot.height) |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | delCell = () => { |
| | | const { node } = this.state |
| | | |
| | | let cell = this.mkGraph.getCellById(node.id) |
| | | |
| | | this.mkGraph.removeCells([cell]) |
| | | |
| | | this.setState({node: null}) |
| | | } |
| | | |
| | | changeProps = (value, key) => { |
| | | const { node } = this.state |
| | | |
| | | if (node.shape === 'edge') { |
| | | let labels = this.selectNode.prop('labels') |
| | | if (!labels || labels.length === 0) { |
| | | labels = [{ |
| | | attrs: {label: { text: '' }} |
| | | }] |
| | | } |
| | | |
| | | if (key === 'title') { |
| | | this.selectNode.setLabels(value) |
| | | labels = JSON.parse(JSON.stringify(labels)) |
| | | labels[0].attrs.label.text = value |
| | | this.selectNode.setLabels(labels) |
| | | } else if (key === 'stroke') { |
| | | this.selectNode.attr('line/stroke', value) |
| | | } else if (key === 'strokeWidth') { |
| | | this.selectNode.attr('line/strokeWidth', value) |
| | | } else if (key === 'fontSize') { |
| | | labels = JSON.parse(JSON.stringify(labels)) |
| | | labels[0].attrs.label.fontSize = value |
| | | this.selectNode.setLabels(labels) |
| | | } else if (key === 'fontFill') { |
| | | labels = JSON.parse(JSON.stringify(labels)) |
| | | labels[0].attrs.label.fill = value |
| | | this.selectNode.setLabels(labels) |
| | | } else if (key === 'lineType') { |
| | | if (value === 'dash') { |
| | | this.selectNode.attr('line/strokeDasharray', 5) |
| | | } else { |
| | | this.selectNode.attr('line/strokeDasharray', 0) |
| | | } |
| | | } else if (key === 'mkdata') { |
| | | if (!node.mkdata) { |
| | | if (node.target && node.target.cell) { |
| | | let cell = this.mkGraph.getCellById(node.target.cell) |
| | | |
| | | if (cell) { |
| | | cell.prop('mkdata', {status: value.status, statusName: value.statusName || ''}) |
| | | } |
| | | } |
| | | } |
| | | |
| | | this.selectNode.prop('mkdata', value) |
| | | } |
| | | } else if (node.shape === 'lane') { |
| | | if (key === 'title') { |
| | |
| | | |
| | | this.mkGraph.stopBatch('width-change') |
| | | } |
| | | } else if (node.shape === 'mk-text') { |
| | | if (key === 'title') { |
| | | this.selectNode.attr('label/text', value) |
| | | } else if (key === 'fill') { |
| | | this.selectNode.attr('body/fill', value) |
| | | } else if (key === 'stroke') { |
| | | this.selectNode.attr('body/stroke', value) |
| | | } else if (key === 'fontSize') { |
| | | this.selectNode.attr('label/style/fontSize', value) |
| | | } else if (key === 'fontFill') { |
| | | this.selectNode.attr('label/style/color', value) |
| | | } |
| | | } else { |
| | | if (key === 'title') { |
| | | this.selectNode.attr('text/text', value) |
| | |
| | | this.selectNode.attr('text/fontSize', value) |
| | | } else if (key === 'fontFill') { |
| | | this.selectNode.attr('text/fill', value) |
| | | } else if (key === 'mksign') { |
| | | this.selectNode.prop('mksign', value) |
| | | } else if (key === 'mkdata') { |
| | | this.selectNode.prop('mkdata', value) |
| | | } |
| | | } |
| | | } |
| | | |
| | | checkNode = (graph, node) => { |
| | | const { plot, config } = this.state |
| | | |
| | | let nodes = graph.getNodes() |
| | | |
| | | nodes.forEach(item => { |
| | | if (item.prop('shape') === 'lane') return |
| | | |
| | | if (item.prop('oristyle')) { |
| | | let style = item.prop('oristyle') |
| | | |
| | | item.prop('attrs/body/fill', style.fill) |
| | | item.prop('attrs/body/stroke', style.stroke) |
| | | item.prop('attrs/text/fill', style.text) |
| | | } |
| | | }) |
| | | |
| | | if (!node || ['lane', 'mk-text', 'edge'].includes(node.prop('shape'))) { |
| | | MKEmitter.emit('resetSelectLine', config.uuid, '', '') |
| | | return |
| | | } |
| | | |
| | | if (!node.prop('oristyle')) { |
| | | node.prop('oristyle', { |
| | | fill: node.prop('attrs/body/fill'), |
| | | stroke: node.prop('attrs/body/stroke'), |
| | | text: node.prop('attrs/text/fill') |
| | | }) |
| | | } |
| | | |
| | | node.prop('attrs/body/fill', lightColor) |
| | | node.prop('attrs/body/stroke', sysColor) |
| | | node.prop('attrs/text/fill', sysColor) |
| | | |
| | | let sign = node.prop('mksign') || '' |
| | | |
| | | if (plot.click === 'menus') { |
| | | let menu = null |
| | | |
| | | if (plot.menus && plot.menus.length > 0) { |
| | | plot.menus.forEach(m => { |
| | | if (sign !== m.sign) return |
| | | menu = m |
| | | }) |
| | | } |
| | | if (!menu || !menu.MenuID) return |
| | | |
| | | let newtab = { |
| | | MenuID: menu.MenuID, |
| | | MenuName: menu.MenuName, |
| | | MenuNo: menu.MenuNo || '', |
| | | type: menu.tabType, |
| | | param: {$BID: sign} |
| | | } |
| | | |
| | | MKEmitter.emit('modifyTabs', newtab, true) |
| | | } else if (plot.click === 'menu') { |
| | | let menuId = plot.menu.slice(-1)[0] |
| | | let menu = null |
| | | |
| | | if (window.GLOB.mkThdMenus.has(menuId)) { |
| | | menu = {...window.GLOB.mkThdMenus.get(menuId)} |
| | | } else if (plot.MenuID) { |
| | | menu = { |
| | | MenuID: plot.MenuID, |
| | | MenuName: plot.MenuName, |
| | | type: plot.tabType |
| | | } |
| | | } |
| | | |
| | | if (!menu) return |
| | | |
| | | menu.param = {$BID: sign} |
| | | |
| | | MKEmitter.emit('modifyTabs', menu, true) |
| | | } else { |
| | | MKEmitter.emit('resetSelectLine', config.uuid, sign, {}) |
| | | } |
| | | } |
| | | |
| | | changeStatus = () => { |
| | | const { plot, status } = this.state |
| | | |
| | | let _status = status === 10 ? 0 : 10 |
| | | |
| | | if (plot.subtype === 'xflow' && _status === 10) { |
| | | let nodes = this.mkGraph.toJSON() |
| | | |
| | | let start_num = 0 |
| | | let end_num = 0 |
| | | let unvalidId = '' |
| | | let emptyNode = null |
| | | let emptyEdge = null |
| | | let map = new Map() |
| | | let appMap = new Map() |
| | | let rejectId = '' |
| | | let approvalId = '' |
| | | |
| | | nodes.cells.forEach(item => { |
| | | if (item.shape === 'mk-text' || item.shape === 'lane') return |
| | | |
| | | if (!item.mkdata) { |
| | | if (item.shape !== 'edge') { |
| | | if (!emptyNode) { |
| | | emptyNode = item |
| | | } |
| | | } else { |
| | | if (!emptyEdge) { |
| | | emptyEdge = item |
| | | } |
| | | } |
| | | } else if (item.mknode === 'start') { |
| | | start_num++ |
| | | } else if (item.mknode === 'end') { |
| | | end_num++ |
| | | } else if (item.shape === 'edge' && !unvalidId && !rejectId && !approvalId) { |
| | | if (item.mknode === 'throughEdge') { |
| | | if (!item.mkdata.seniorbers || item.mkdata.seniorbers.length === 0) { |
| | | unvalidId = item.id |
| | | } |
| | | } else if (item.mkdata.seniorCondition === 'open') { |
| | | |
| | | } else if (item.mknode !== 'endEdge' && item.mknode !== 'startEdge' && (!item.mkdata.members || item.mkdata.members.length === 0)) { |
| | | unvalidId = item.id |
| | | } else if (item.mknode === 'startEdge' || item.mkdata.flowType === 'reject') { |
| | | if (map.has(item.source.cell)) { |
| | | rejectId = item.source.cell |
| | | } else { |
| | | map.set(item.source.cell, true) |
| | | } |
| | | } else if (item.mkdata.flowType === 'approval' || item.mknode === 'endEdge') { |
| | | let val = '' |
| | | if (item.mkdata.execCondition === 'open') { |
| | | val = item.mkdata.match + item.mkdata.matchVal |
| | | } |
| | | if (appMap.has(item.source.cell + val)) { |
| | | approvalId = item.source.cell |
| | | } else { |
| | | appMap.set(item.source.cell + val, item) |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | |
| | | if (start_num === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请添加开始节点!', |
| | | duration: 2 |
| | | }) |
| | | } else if (start_num > 1) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '开始节点不可添加多个!', |
| | | duration: 2 |
| | | }) |
| | | } else if (end_num === 0) { |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '请添加结束节点!', |
| | | duration: 2 |
| | | }) |
| | | // } else if (end_num > 1) { |
| | | // notification.warning({ |
| | | // top: 92, |
| | | // message: '结束节点不可添加多个!', |
| | | // duration: 2 |
| | | // }) |
| | | } else if (emptyNode) { |
| | | let errmsg = '部分节点未设置基本信息。' |
| | | if (emptyNode.attrs && emptyNode.attrs.text && emptyNode.attrs.text.text) { |
| | | errmsg = '节点《' + emptyNode.attrs.text.text + '》未设置基本信息。' |
| | | } |
| | | notification.warning({ |
| | | top: 92, |
| | | message: errmsg, |
| | | duration: 2 |
| | | }) |
| | | } else if (emptyEdge) { |
| | | let errmsg = '部分连线未设置基本信息。' |
| | | |
| | | let edge = this.mkGraph.getCellById(emptyEdge.id) |
| | | let target = edge.getTargetCell() |
| | | |
| | | let t_label = '' |
| | | if (target.attrs && target.attrs.text && target.attrs.text.text) { |
| | | t_label = target.attrs.text.text |
| | | } |
| | | |
| | | let source = edge.getSourceCell() |
| | | |
| | | let s_label = '' |
| | | if (source.attrs && source.attrs.text && source.attrs.text.text) { |
| | | s_label = source.attrs.text.text |
| | | } |
| | | |
| | | if (t_label && s_label) { |
| | | errmsg = '节点《' + s_label + '》与节点《' + t_label + '》间连线未设置基本信息。' |
| | | } |
| | | |
| | | notification.warning({ |
| | | top: 92, |
| | | message: errmsg, |
| | | duration: 2 |
| | | }) |
| | | } else if (rejectId) { |
| | | let node = this.mkGraph.getCellById(rejectId) |
| | | |
| | | let title = '' |
| | | if (node.attrs && node.attrs.text && node.attrs.text.text) { |
| | | title = '节点《' + node.attrs.text.text + '》' |
| | | } else if (node.mkdata) { |
| | | title = '状态:' + node.mkdata.status + ' - ' + node.mkdata.statusName |
| | | } |
| | | |
| | | notification.warning({ |
| | | top: 92, |
| | | message: title + ' 不可设置两条驳回连线!', |
| | | duration: 2 |
| | | }) |
| | | } else if (approvalId) { |
| | | let node = this.mkGraph.getCellById(approvalId) |
| | | |
| | | let title = '' |
| | | if (node.attrs && node.attrs.text && node.attrs.text.text) { |
| | | title = '节点《' + node.attrs.text.text + '》' |
| | | } else if (node.mkdata) { |
| | | title = '状态:' + node.mkdata.status + ' - ' + node.mkdata.statusName |
| | | } |
| | | |
| | | notification.warning({ |
| | | top: 92, |
| | | message: title + ' 后的审批分支执行条件重复!', |
| | | duration: 2 |
| | | }) |
| | | } else if (unvalidId) { |
| | | let edge = this.mkGraph.getCellById(unvalidId) |
| | | |
| | | let node = edge.getTargetCell() |
| | | |
| | | let title = '' |
| | | if (node.attrs && node.attrs.text && node.attrs.text.text) { |
| | | title = node.attrs.text.text |
| | | } else if (node.mkdata) { |
| | | title = '状态:' + node.mkdata.status + ' - ' + node.mkdata.statusName |
| | | } |
| | | |
| | | let source = edge.getSourceCell() |
| | | |
| | | let s_label = '' |
| | | if (source.attrs && source.attrs.text && source.attrs.text.text) { |
| | | s_label = source.attrs.text.text |
| | | } else if (source.mkdata) { |
| | | s_label = '状态:' + source.mkdata.status + ' - ' + source.mkdata.statusName |
| | | } |
| | | |
| | | notification.warning({ |
| | | top: 92, |
| | | message: '节点《' + s_label + '》与《' + title + '》间连线未设置审批人!', |
| | | duration: 2 |
| | | }) |
| | | } else { |
| | | this.setState({status: _status}) |
| | | } |
| | | } else { |
| | | this.setState({status: _status}) |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | render() { |
| | | const { loading, config, node } = this.state |
| | | const { loading, config, node, orgs, status, flowname, empty } = this.state |
| | | |
| | | let style = {...config.style} |
| | | |
| | | if (config.plot.function === 'show') { |
| | | if (config.plot.empty === 'hidden' && this.cells.length === 0) { |
| | | style.display = 'none' |
| | | if (config.plot.empty === 'hidden' && empty) { |
| | | style.position = 'absolute' |
| | | style.width = '100%' |
| | | style.zIndex = -1 |
| | | } |
| | | |
| | | return ( |
| | | <div className="custom-x6-plot-box" id={'anchor' + config.uuid} style={config.style}> |
| | | <div className="custom-x6-plot-box" id={'anchor' + config.uuid} style={style}> |
| | | {loading ? |
| | | <div className="loading-mask"> |
| | | <div className="ant-spin-blur"></div> |
| | |
| | | </div> : null |
| | | } |
| | | <NormalHeader config={config} /> |
| | | <div className="canvas" style={{width: '100%', minHeight: config.plot.height, height: config.plot.height}} id={config.uuid + 'canvas'}> |
| | | <div className={'canvas only-show' + (config.plot.click ? ' switchable' : '')} style={{width: '100%', minHeight: config.plot.height, height: config.plot.height}} id={config.uuid + 'canvas'}> |
| | | <div id={config.uuid + 'container'} className="mk-container"></div> |
| | | </div> |
| | | </div> |
| | |
| | | <Tooltip title="前进"> |
| | | <RedoOutlined onClick={this.setprev}/> |
| | | </Tooltip> |
| | | </div> |
| | | <div className="right-tool"> |
| | | <Tooltip title="保存"> |
| | | <SaveOutlined onClick={this.save}/> |
| | | <Tooltip title="清空"> |
| | | <ClearOutlined onClick={this.clearNode}/> |
| | | </Tooltip> |
| | | <Tooltip overlayStyle={{maxWidth: 310}} title="快捷键:复制(ctrl+c)、剪切(ctrl+x)、粘贴(ctrl+v)、后退(ctrl+z)、前进(ctrl+shift+z)、删除(backspace 或 delete);双击节点或连线可编辑自定义信息。"> |
| | | <QuestionCircleOutlined /> |
| | | </Tooltip> |
| | | </div> |
| | | <div className="flow-name">{flowname}</div> |
| | | <div className="right-tool"> |
| | | <Switch size="large" checked={status === 10} checkedChildren="启" unCheckedChildren="停" onChange={this.changeStatus} /> |
| | | <Button className="save" onClick={this.save}>保存</Button> |
| | | <Button className="close" onClick={this.close}>关闭</Button> |
| | | </div> |
| | | </div> |
| | | <div className="canvas" style={{width: '100%', minHeight: config.plot.height, height: config.plot.height}} id={config.uuid + 'canvas'}> |
| | |
| | | <div id={config.uuid + 'container'} className="mk-container"></div> |
| | | <div className="mk-node-edit"> |
| | | <div className="header">设置</div> |
| | | {!node ? <div className="empty">未选中</div> : <NodeUpdate node={node} onChange={this.changeProps}/>} |
| | | {!node ? <div className="empty">未选中</div> : <NodeUpdate node={node} orgs={orgs} onChange={this.changeProps} onDel={this.delCell}/>} |
| | | </div> |
| | | </div> |
| | | </div> |