<template>
|
<div class="h-full" :class="prefixCls">
|
<FlowChartToolbar
|
:prefixCls="prefixCls"
|
v-if="toolbar"
|
@view-data="handlePreview"
|
@save-data="handleSave"
|
@add-data="handleAdd"
|
@addlf="handleAddlf"
|
/>
|
<div ref="lfElRef" class="h-full"></div>
|
<BasicModal @register="register" title="流程数据" width="50%">
|
<JsonPreview :data="graphData" />
|
</BasicModal>
|
</div>
|
</template>
|
<script lang="ts">
|
import type { Ref } from 'vue';
|
import type { Definition } from '@logicflow/core';
|
import { defineComponent, 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/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';
|
|
const { notification } = useMessage();
|
const { t } = useI18n();
|
|
export default defineComponent({
|
name: 'FlowChart',
|
components: { BasicModal, FlowChartToolbar, JsonPreview },
|
props: {
|
flowOptions: {
|
type: Object as PropType<Definition>,
|
default: () => ({}),
|
},
|
|
data: {
|
type: Object as PropType<any>,
|
default: () => ({}),
|
},
|
|
toolbar: {
|
type: Boolean,
|
default: true,
|
},
|
patternItems: {
|
type: Array,
|
},
|
},
|
emits: ['view-data', 'save-data', 'add-lf'],
|
setup(props, { emit }) {
|
const globSetting = useGlobSetting();
|
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: 'bezier',
|
...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('line');
|
onRender();
|
lf?.setPatternItems(props.patternItems || configDefaultDndPanel(lf));
|
}
|
|
async function onRender() {
|
await nextTick();
|
const lf = unref(lfInstance);
|
if (!lf) {
|
return;
|
}
|
lf.register(customEdge);
|
// const lFData = toLogicFlowData(props.data);
|
lf.render(props.data);
|
|
if (globSetting.apiUrl == 'http://localhost:9528/api') {
|
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');
|
}
|
});
|
}
|
});
|
}
|
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,
|
});
|
} else {
|
console.log(data.data.type);
|
}
|
});
|
}
|
|
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);
|
}
|
|
onMounted(init);
|
|
return {
|
register,
|
prefixCls,
|
lfElRef,
|
handlePreview,
|
graphData,
|
handleSave,
|
handleAdd,
|
handleAddlf,
|
};
|
},
|
});
|
</script>
|