|
|
@@ -55,7 +55,9 @@ let isUnmounted = false;
|
|
|
const hasInstance = () => !isUnmounted && !!instance && !!instance.lf;
|
|
|
// end
|
|
|
let oldValue: FlowRequestData;
|
|
|
+const maxPanelHeight = ref(0);
|
|
|
const init = (lf: LogicFlowInstance): void => {
|
|
|
+ maxPanelHeight.value = lf.container.getBoundingClientRect().height - 80;
|
|
|
instance = VLogicFlowInit(lf, {
|
|
|
register: [{ category: 'node', type: 'FlowNode', view: FlowNodeView, model: FlowNodeViewModel }],
|
|
|
});
|
|
|
@@ -141,6 +143,27 @@ const init = (lf: LogicFlowInstance): void => {
|
|
|
getContainer: () => (el.value as HTMLElement) ?? document.body,
|
|
|
});
|
|
|
});
|
|
|
+ // @ts-ignore
|
|
|
+ instance.listener('connection:quick', (event: any) => {
|
|
|
+ const add = (id: string) => {
|
|
|
+ for (const group of nodeGroup.value) {
|
|
|
+ const node = group.find((node) => node.id === id);
|
|
|
+ if (node) return instance.lf.addNode(node);
|
|
|
+ }
|
|
|
+ return void 0;
|
|
|
+ };
|
|
|
+ const { sourceNodeId, targetNodeId } = event;
|
|
|
+ const source = instance.lf.getNodeModelById(sourceNodeId) ?? add(sourceNodeId);
|
|
|
+ const target = instance.lf.getNodeModelById(targetNodeId) ?? add(targetNodeId);
|
|
|
+ if (source && target) {
|
|
|
+ const sourceEdge = instance.lf.getNodeOutgoingEdge(sourceNodeId);
|
|
|
+ const targetEdge = instance.lf.getNodeIncomingEdge(targetNodeId);
|
|
|
+ for (const edge of sourceEdge) instance.lf.deleteEdge(edge.id);
|
|
|
+ for (const edge of targetEdge) instance.lf.deleteEdge(edge.id);
|
|
|
+ instance.lf.addEdge({ sourceNodeId, targetNodeId });
|
|
|
+ updateLayout();
|
|
|
+ }
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
const updateLayout = (dir?: 'LR' | 'TB' | 'center') => {
|
|
|
@@ -243,7 +266,7 @@ const update = (data?: FlowRequestData) => {
|
|
|
|
|
|
instance.lf.renderRawData(graph);
|
|
|
updateLayout('TB');
|
|
|
- if (graph.nodes && graph.nodes.length > 2) setTimeout(() => updateLayout('center'), 100)
|
|
|
+ if (graph.nodes && graph.nodes.length > 2) setTimeout(() => updateLayout('center'), 100);
|
|
|
};
|
|
|
const validate = (tips = true) => {
|
|
|
if (!hasInstance()) return Promise.reject(new Error('LogicFlow 已销毁'));
|
|
|
@@ -282,10 +305,10 @@ const validate = (tips = true) => {
|
|
|
|
|
|
const start = instance.lf.getNodeModelById(Node.ID_Start);
|
|
|
|
|
|
- let gather;
|
|
|
+ let gather: Gather;
|
|
|
const { promise, resolve, reject } = withResolvers<{ gather: Gather; data?: FlowRequestData; message?: string }>();
|
|
|
try {
|
|
|
- gather = map(start);
|
|
|
+ gather = map(start).sort((g1, g2) => g1.level - g2.level || +(g1.targetNodeId === Node.ID_Back) - +(g2.targetNodeId === Node.ID_Back));
|
|
|
|
|
|
const data: Record<string, any> = {
|
|
|
[Node.ID_Start]: instance.lf.getNodeModelById(Node.ID_Start)?.getProperties().requestData,
|
|
|
@@ -294,7 +317,7 @@ const validate = (tips = true) => {
|
|
|
oldValue = toFlowRequestData(gather, data);
|
|
|
requestData.value = oldValue;
|
|
|
resolve({ gather, data: oldValue });
|
|
|
- console.log('[AioFlowConfig] 更新 request-data 数据: ', );
|
|
|
+ console.log('[AioFlowConfig] 更新 request-data 数据: ', oldValue);
|
|
|
} catch (error: any) {
|
|
|
if (tips) {
|
|
|
notification.error({
|
|
|
@@ -310,9 +333,12 @@ const validate = (tips = true) => {
|
|
|
}
|
|
|
|
|
|
if (Array.isArray(gather) && gather.length) {
|
|
|
+ const last = gather.at(-1);
|
|
|
+ const notOpenEdgeId = last.targetNodeId === Node.ID_Back ? last.edgeId : void 0;
|
|
|
for (const { edgeId } of gather) {
|
|
|
instance.lf.setProperties(edgeId, { isAnimation: true });
|
|
|
- instance.lf.openEdgeAnimation(edgeId);
|
|
|
+ if (notOpenEdgeId === edgeId) instance.lf.closeEdgeAnimation(notOpenEdgeId);
|
|
|
+ else instance.lf.openEdgeAnimation(edgeId);
|
|
|
}
|
|
|
} else {
|
|
|
for (const edge of instance.lf.getGraphRawData().edges) {
|
|
|
@@ -350,7 +376,7 @@ defineExpose({
|
|
|
</template>
|
|
|
</a-button>
|
|
|
<template #overlay>
|
|
|
- <a-card size="small" style="width: 370px">
|
|
|
+ <a-card size="small" style="width: 370px; overflow-y: auto;" :style="{ maxHeight: maxPanelHeight + 'px' }">
|
|
|
<div class="flex justify-between m-y-2" v-for="(group, g) in nodeGroup" :key="g">
|
|
|
<FlowNodeComponent
|
|
|
:class="{ selected: dragPanelNodeId === node.id, disabled: getPanelNodeDisabled(node) }"
|
|
|
@@ -362,6 +388,12 @@ defineExpose({
|
|
|
@mousedown="startDragPanelNode(node, $event)"
|
|
|
/>
|
|
|
</div>
|
|
|
+ <a-space direction="vertical" class="tips-wrapper">
|
|
|
+ <div>添加流程:从左侧拖入</div>
|
|
|
+ <div>编辑流程:单击</div>
|
|
|
+ <div>删除流程和连线:双击</div>
|
|
|
+ <div>连接流程:从上流节点中拖拽锚点到下流节点以连接</div>
|
|
|
+ </a-space>
|
|
|
</a-card>
|
|
|
</template>
|
|
|
</a-dropdown>
|
|
|
@@ -403,6 +435,12 @@ defineExpose({
|
|
|
left: 24px;
|
|
|
z-index: 1;
|
|
|
}
|
|
|
+.tips-wrapper {
|
|
|
+ width: 100%;
|
|
|
+ padding: 4px;
|
|
|
+ color: rgba(0, 0, 0, 0.8);
|
|
|
+ border: 1px #bbbbbb dashed;
|
|
|
+}
|
|
|
.ant-float-btn-group {
|
|
|
position: absolute !important;
|
|
|
bottom: 24px;
|