123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- import { IAppLoad, NsGraphCmd } from '@antv/xflow';
- import React, { useRef, useEffect, useImperativeHandle } from 'react';
- /** 交互组件 */
- import {
- /** XFlow核心组件 */
- XFlow,
- /** 流程图画布组件 */
- FlowchartCanvas,
- /** 流程图配置扩展 */
- FlowchartExtension,
- /** 流程图节点组件 */
- FlowchartNodePanel,
- /** 流程图表单组件 */
- FlowchartFormPanel,
- /** 通用组件:快捷键 */
- KeyBindings,
- /** 通用组件:画布缩放 */
- CanvasScaleToolbar,
- /** 通用组件:右键菜单 */
- CanvasContextMenu,
- /** 通用组件:工具栏 */
- CanvasToolbar,
- /** 通用组件:对齐线 */
- CanvasSnapline,
- /** 通用组件:节点连接桩 */
- CanvasNodePortTooltip,
- IApplication,
- XFlowNodeCommands,
- } from '@antv/xflow';
- import { Graph } from '@antv/x6';
- /** 配置Command*/
- import { useCmdConfig, initGraphCmds } from './config-cmd';
- /** 配置Menu */
- import { useMenuConfig } from './config-menu';
- /** 配置Toolbar */
- import { TOOLBAR_ITEMS, useToolbarConfig } from './config-toolbar';
- /** 配置快捷键 */
- import { useKeybindingConfig } from './config-keybinding';
- import { registerNode } from './node/registerNode';
- import CustomFlowchartFormPanel from './node/FlowFormPanel';
- /** 配置Dnd组件面板 */
- // import CustomCircle from './react-node/CustomCircle';
- // import CustomRect from './react-node/CustomRect';
- import '@antv/xflow/dist/index.css';
- import { Collapse } from 'antd';
- import './index.less';
- import { TYPE } from './node/auditNode/mapServe';
- const { Panel } = Collapse;
- export interface IProps {
- meta: {
- flowId: string;
- type: 'edit';
- editMode?: number; // 1. 管理员编辑 2. 普通编辑
- };
- flowDetail: any;
- onSelectNode?: Function;
- parentRef?: any;
- }
- export const Demo: React.FC<IProps> = props => {
- const { meta, flowDetail, parentRef } = props;
- const isEdit = meta.type == 'edit';
- const toolbarConfig = useToolbarConfig();
- const menuConfig = useMenuConfig();
- const keybindingConfig = useKeybindingConfig();
- const graphRef = useRef<Graph>();
- const appRef = useRef<IApplication>();
- const commandConfig: any = useCmdConfig(props);
- // 封装供外部主动调用的接口
- useImperativeHandle(parentRef, () => ({
- getGraphData: async cb => {
- appRef.current.commandService.executeCommand<NsGraphCmd.SaveGraphData.IArgs>(
- TOOLBAR_ITEMS.SAVE_GRAPH_DATA,
- {
- saveGraphDataService: (meta, graphData) => {
- let data = JSON.parse(JSON.stringify(graphData));
- let simpleNodes = data?.nodes?.map(curNode => {
- let childrenNodes = data.edges
- .map(edge => {
- if (edge.source?.cell == curNode.id) {
- return data.nodes.find(item => item.id == edge.target?.cell);
- }
- })
- .filter(item => item);
- //按优先级排序子节点
- const children = childrenNodes
- .sort((a, b) => a.priority - b.priority)
- .map(item => item.id);
- const node = {
- id: curNode.id,
- type: curNode.type,
- //条件节点
- formItems:
- curNode.type == TYPE.JUDGE && !curNode.formItems ? '[]' : curNode.formItems,
- priority: curNode.priority,
- //审批节点
- initiator: curNode.type == TYPE.INITIATOR ? curNode.initiator : null,
- audits: curNode.audits,
- children: children,
- };
- return node;
- });
- data.nodes = data.nodes.map(item => {
- let newItem = JSON.parse(JSON.stringify(item));
- delete newItem.incomingEdges;
- delete newItem.originData;
- delete newItem.outgoingEdges;
- delete newItem.ports.groups;
- // let ports = { ...item.ports };
- // delete ports.groups;
- // return {
- // id: item.id,
- // renderKey: item.renderKey,
- // name: item.name,
- // label: item.label,
- // width: item.width,
- // height: item.height,
- // ports: ports,
- // isCustom: item.isCustom,
- // parentKey: item.parentKey,
- // x: item.x,
- // y: item.y,
- // zIndex: item.zIndex,
- // count: item.count,
- // };
- return newItem;
- });
- // graphData.edges = []
- data.edges = data.edges.map(item => {
- // delete item.data;
- // delete item.attrs;
- // delete item.sourcePort;
- // delete item.sourcePortId;
- // delete item.targetPort;
- // delete item.targetPortId;
- // delete item.zIndex;
- return {
- id: item.id,
- source: item.source,
- target: item.target,
- // attr: JSON.stringify(item.attrs),
- };
- });
- console.log(simpleNodes);
- console.log(JSON.stringify(data));
- cb?.(JSON.stringify(data), JSON.stringify(simpleNodes));
- return data;
- },
- }
- );
- },
- }));
- /**
- * @param app 当前XFlow工作空间
- * @param extensionRegistry 当前XFlow配置项
- */
- const onLoad: IAppLoad = async app => {
- appRef.current = app;
- graphRef.current = await app.getGraphInstance();
- // graphRef.current.disableSnapline()
- renderGraph();
- };
- const renderGraph = () => {
- if (flowDetail.nodes.length == 0 || !appRef.current) return;
- initGraphCmds(appRef.current, flowDetail);
- // 设置选中状态
- const node = flowDetail.nodes.find(item => item.isCheck);
- if (node) {
- const args = {
- nodeIds: [node.id],
- resetSelection: true,
- };
- setTimeout(() => {
- appRef.current.commandService.executeCommand(XFlowNodeCommands.SELECT_NODE.id, args);
- }, 100);
- }
- };
- const getConfig = () => {
- const defaultOption = {
- grid: 1,
- mousewheel: {
- enabled: true,
- /** 将鼠标位置作为中心缩放 */
- zoomAtMousePosition: true,
- },
- resizing: {
- enabled: true,
- minWidth: 0,
- minHeight: 0,
- preserveAspectRatio: false,
- },
- snapline: false,
- };
- if (isEdit) {
- // 非管理员编辑
- if (meta.editMode == 2) {
- return {
- ...defaultOption,
- grid: false,
- selecting: {
- enabled: true,
- showNodeSelectionBox: true,
- },
- interacting: false,
- mousewheel: false,
- connecting: {
- highlight: false,
- allowBlank: false,
- allowPort: false,
- dangling: false,
- },
- };
- } else {
- // 管理员编辑
- return defaultOption;
- }
- } else {
- return {
- ...defaultOption,
- grid: false,
- resizing: false,
- panning: false,
- selecting: {
- enabled: true,
- showNodeSelectionBox: true,
- movable: false,
- },
- interacting: false,
- mousewheel: false,
- connecting: {
- highlight: false,
- allowBlank: false,
- allowPort: false,
- dangling: false,
- },
- };
- }
- };
- useEffect(() => {
- if (graphRef.current) {
- graphRef.current.on('node:click', (...arg) => {
- console.log(arg);
- });
- }
- }, [graphRef]);
- useEffect(() => {
- renderGraph();
- }, [flowDetail, appRef.current]);
- return (
- <XFlow
- className="flow-user-custom-clz"
- commandConfig={commandConfig}
- onLoad={onLoad}
- meta={meta}
- >
- <FlowchartNodePanel
- registerNode={{
- title: '节点',
- key: 'custom',
- nodes: registerNode,
- }}
- showOfficial={false}
- defaultActiveKey={['custom']}
- position={{ width: 162, top: 40, bottom: 0, left: isEdit && meta.editMode == 1 ? 0 : -999 }}
- />
- {isEdit && (
- <CanvasToolbar
- className="xflow-workspace-toolbar-top"
- layout="horizontal"
- config={toolbarConfig}
- position={{ top: 0, left: 0, right: 0, bottom: 0 }}
- />
- )}
- <FlowchartCanvas
- config={getConfig()}
- position={{ top: isEdit ? 40 : 0, left: 0, right: 0, bottom: 0 }}
- >
- {isEdit && (
- <>
- <CanvasScaleToolbar
- layout="horizontal"
- position={{ top: -40, right: 0 }}
- style={{
- width: 150,
- left: 'auto',
- height: 39,
- }}
- />
- <CanvasContextMenu config={menuConfig} />
- <CanvasSnapline color="#faad14" />
- <CanvasNodePortTooltip />
- </>
- )}
- </FlowchartCanvas>
- {isEdit && (
- <>
- <FlowchartExtension />
- {/* <FlowchartFormPanel show={true} position={{ width: 200, top: 40, bottom: 0, right: 0 }} /> */}
- <CustomFlowchartFormPanel />
- <KeyBindings config={keybindingConfig} />
- </>
- )}
- </XFlow>
- );
- };
- // 高阶组件
- const DemoHoc = Demo => {
- const forwardRef = (props, ref) => {
- return <Demo parentRef={ref} {...props}></Demo>;
- };
- return React.forwardRef(forwardRef);
- };
- export default DemoHoc(Demo);
|