<template>
|
<div class="h-full" :class="prefixCls">
|
<FlowChartToolbar
|
:prefixCls="prefixCls"
|
v-if="toolbar"
|
@view-data="handlePreview"
|
@save-data="handleSave"
|
@add-data="handleAdd"
|
@addlf="handleAddlf"
|
@undo="handleUndo"
|
@redo="handleRedo"
|
/>
|
<div ref="lfElRef" class="h-full"></div>
|
<BasicModal @register="register" title="流程数据" width="50%">
|
<JsonPreview :data="graphData" />
|
</BasicModal>
|
</div>
|
</template>
|
<script lang="ts" setup>
|
import type { Ref } from 'vue';
|
import type { Definition } from '@logicflow/core';
|
import { ref, onMounted, unref, nextTick, computed, watch } from 'vue';
|
import FlowChartToolbar from './FlowChartToolbar.vue';
|
import LogicFlow from '@logicflow/core';
|
import { Snapshot, BpmnElement, Menu, DndPanel, SelectionSelect } from '@logicflow/extension';
|
import { useDesign } from '@/hooks/web/useDesign';
|
import { useAppStore } from '@/store/modules/app';
|
import { createFlowChartContext } from './useFlowContext';
|
import { toLogicFlowData } from './adpterForTurbo';
|
import { useModal, BasicModal } from '@/components/Modal';
|
import { JsonPreview } from '@/components/CodeEditor';
|
import { configDefaultDndPanel } from './config';
|
import '@logicflow/core/lib/style/index.css';
|
// import '@logicflow/core/dist/style/index.css';
|
import '@logicflow/extension/lib/style/index.css';
|
import { useGlobSetting } from '/@/hooks/setting';
|
import customEdge from './customEdge';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
import actionRect from './actionRect';
|
import TestNode from './TestNode';
|
import CollectNode from './CollectNode';
|
import AssemblyNode from './AssemblyNode';
|
import PackingNode from './PackingNode';
|
import RepairNode from './RepairNode';
|
import SpecPackingNode from './SpecPackingNode';
|
|
defineOptions({ name: 'FlowChart' });
|
|
const props = defineProps({
|
flowOptions: {
|
type: Object as PropType<Definition>,
|
default: () => ({}),
|
},
|
|
data: {
|
type: Object as PropType<any>,
|
default: () => ({}),
|
},
|
|
toolbar: {
|
type: Boolean,
|
default: true,
|
},
|
patternItems: {
|
type: Array,
|
},
|
});
|
|
const emit = defineEmits([
|
'view-data',
|
'save-data',
|
'add-lf',
|
'select-node',
|
'click-blank',
|
'init',
|
'undo',
|
'redo',
|
'anchor-drop',
|
'anchor-dragend',
|
]);
|
const lfElRef = ref(null);
|
const graphData = ref({});
|
|
const lfInstance = ref(null) as Ref<LogicFlow | null>;
|
|
const { prefixCls } = useDesign('flow-chart');
|
const appStore = useAppStore();
|
const [register, { openModal }] = useModal();
|
createFlowChartContext({
|
logicFlow: lfInstance as unknown as LogicFlow,
|
});
|
|
const getFlowOptions = computed(() => {
|
const { flowOptions } = props;
|
|
const defaultOptions: Partial<Definition> = {
|
grid: true,
|
background: {
|
color: appStore.getDarkMode === 'light' ? '#f7f9ff' : '#151515',
|
},
|
keyboard: {
|
enabled: true,
|
},
|
edgeType: 'polyline',
|
...flowOptions,
|
};
|
return defaultOptions as Definition;
|
});
|
|
watch(
|
() => props.data,
|
() => {
|
onRender();
|
},
|
);
|
|
// TODO
|
// watch(
|
// () => appStore.getDarkMode,
|
// () => {
|
// init();
|
// }
|
// );
|
|
watch(
|
() => unref(getFlowOptions),
|
(options) => {
|
unref(lfInstance)?.updateEditConfig(options);
|
},
|
);
|
|
// init logicFlow
|
async function init() {
|
await nextTick();
|
|
const lfEl = unref(lfElRef);
|
if (!lfEl) {
|
return;
|
}
|
LogicFlow.use(DndPanel);
|
|
// Canvas configuration
|
LogicFlow.use(Snapshot);
|
// Use the bpmn plug-in to introduce bpmn elements, which can be used after conversion in turbo
|
LogicFlow.use(BpmnElement);
|
// Start the right-click menu
|
LogicFlow.use(Menu);
|
LogicFlow.use(SelectionSelect);
|
|
lfInstance.value = new LogicFlow({
|
...unref(getFlowOptions),
|
container: lfEl,
|
edgeGenerator: (sourceNode) => {
|
// console.log('a');
|
// 起始节点类型 rect 时使用 自定义的边 custom-edge
|
if (sourceNode.properties.isReturn) return 'custom-edge';
|
// if (sourceNode.type === 'rect') return 'custom-edge';
|
// return 'custom-edge';
|
},
|
});
|
const lf = unref(lfInstance)!;
|
lf?.setDefaultEdgeType('polyline');
|
lf.register(actionRect);
|
lf.register(TestNode);
|
lf.register(CollectNode);
|
lf.register(AssemblyNode);
|
lf.register(PackingNode);
|
lf.register(RepairNode);
|
lf.register(customEdge);
|
lf.register(SpecPackingNode);
|
onRender();
|
lf?.setPatternItems(props.patternItems || configDefaultDndPanel(lf));
|
}
|
|
async function onRender() {
|
await nextTick();
|
const lf = unref(lfInstance);
|
if (!lf) {
|
return;
|
}
|
const lFData = toLogicFlowData(props.data);
|
lf.render(lFData);
|
|
lf.on('anchor:drop', (data) => {
|
const nodeData = data.nodeModel.getData();
|
if (nodeData.properties.isReturn === true) {
|
console.log(11, nodeData.properties.isReturn);
|
data.nodeModel.graphModel.edges.forEach((element) => {
|
if (element.sourceNodeId === data.nodeModel.id) {
|
lf.changeEdgeType(element.id, 'custom-edge');
|
}
|
});
|
}
|
emit('anchor-drop', data, lf);
|
});
|
|
/**
|
* @description: 锚点连线结束,不管是否创建连线都会触发。
|
* @return {*}
|
*/
|
lf.on('anchor:dragend', (data, e, nodeModel) => {
|
emit('anchor-dragend',data, e, nodeModel, lf);
|
});
|
|
lf.on('node:click,edge:click', (data) => {
|
if (data.isSelected) {
|
console.log(data.data.text.value, data.isSelected);
|
// notification.success({
|
// message: t('点击了节点'),
|
// description: `${data.data.text.value}: ${data.isSelected}`,
|
// duration: 3,
|
// });
|
emit('select-node', data, lf);
|
} else {
|
console.log(data.data.type);
|
}
|
});
|
|
lf.on('blank:mousedown', (e) => {
|
emit('click-blank');
|
});
|
|
lf.on('node:dnd-add', (data, e) => {
|
console.log('node:dnd-add', data);
|
emit('select-node', data, lf);
|
});
|
|
emit('init', lf);
|
}
|
|
function handlePreview() {
|
const lf = unref(lfInstance);
|
if (!lf) {
|
return;
|
}
|
graphData.value = unref(lf).getGraphData();
|
openModal();
|
}
|
|
function handleSave() {
|
// console.log('handleSave');
|
const lf = unref(lfInstance);
|
if (!lf) {
|
return;
|
}
|
emit('save-data', lf);
|
}
|
|
function handleAdd() {
|
const lf = unref(lfInstance);
|
console.log('handleAdd');
|
if (!lf) {
|
return;
|
}
|
// lf.clearData();
|
lf.render({});
|
}
|
|
function handleAddlf() {
|
const lf = unref(lfInstance);
|
if (!lf) {
|
return;
|
}
|
emit('add-lf', lf);
|
}
|
|
function handleUndo() {
|
const lf = unref(lfInstance);
|
if (!lf) {
|
return;
|
}
|
emit('undo', lf);
|
}
|
|
function handleRedo() {
|
const lf = unref(lfInstance);
|
if (!lf) {
|
return;
|
}
|
emit('redo', lf);
|
}
|
|
onMounted(init);
|
</script>
|