-
+
@@ -789,6 +794,7 @@ import '@logicflow/core/dist/index.css';
import '@logicflow/extension/lib/style/index.css';
import SkillSelector from '/@/components/skill/NodeSkillSelector.vue';
import ModelSelector from '/@/components/model/ModelSelector.vue';
+import SaveWorkflowDialog from './component/SaveWorkflowDialog.vue';
import type { SkillItem } from '/@/api/settings/skill';
import {
downloadToFile,
@@ -3236,14 +3242,14 @@ watch(
currentHttpBodyField.value = '';
showHttpBodyDialog.value = false;
- // 重置 dynamicFormValues(不删除固定字段键,动态 expand 键按节点切换清理)
- for (const key in dynamicFormValues) {
- if (key.includes('_responseType_expand_')) {
- delete dynamicFormValues[key];
- continue;
- }
- dynamicFormValues[key] = '';
+ // 重置 dynamicFormValues(不删除固定字段键,动态 expand 键按节点切换清理)
+ for (const key in dynamicFormValues) {
+ if (key.includes('_responseType_expand_')) {
+ delete dynamicFormValues[key];
+ continue;
}
+ dynamicFormValues[key] = '';
+ }
const currentNodeCode = formState.nodeCode;
const baseFormFields = nodeSchemaMap.value[currentNodeCode] || [];
const baseFieldNames = new Set(baseFormFields.map((f) => f.field));
@@ -3779,7 +3785,100 @@ const resetFlow = () => {
selectedElement.value = null;
syncDsl();
};
-// 从后端 DSL 恢复工作流
+const cleanupReferencesToNode = (deletedNodeId: string) => {
+ const lf = logicFlowInstance.value;
+ if (!lf) return 0;
+
+ const graphData = lf.getGraphData() as { nodes?: Item[] };
+ const nodes = graphData.nodes || [];
+ let affectedCount = 0;
+
+ nodes.forEach((node: any) => {
+ if (node.id === deletedNodeId) return;
+ const props = node.properties || {};
+ const inputSource = Array.isArray(props.inputSource) ? props.inputSource : [];
+ const nextInputSource = inputSource.filter((item: any) => item?.nodeId !== deletedNodeId);
+
+ if (nextInputSource.length === inputSource.length) return;
+
+ affectedCount += 1;
+ const normalizedInputSource = nextInputSource.length > 0 ? nextInputSource : null;
+ lf.setProperties(node.id, {
+ ...props,
+ inputSource: normalizedInputSource,
+ });
+
+ if (selectedElement.value?.id === node.id) {
+ selectedElement.value.properties = {
+ ...props,
+ inputSource: normalizedInputSource,
+ };
+ }
+ });
+
+ return affectedCount;
+};
+const getAffectedDownstreamNodeNames = (deletedNodeId: string) => {
+ const lf = logicFlowInstance.value;
+ if (!lf) return [] as string[];
+
+ const graphData = lf.getGraphData() as { nodes?: Item[] };
+ const nodes = graphData.nodes || [];
+ const names: string[] = [];
+
+ nodes.forEach((node: any) => {
+ if (node.id === deletedNodeId) return;
+ const props = node.properties || {};
+ const inputSource = Array.isArray(props.inputSource) ? props.inputSource : [];
+ const referenced = inputSource.some((item: any) => item?.nodeId === deletedNodeId);
+ if (!referenced) return;
+
+ const nodeName = typeof node.text === 'string' ? node.text : node.text?.value || node.id;
+ names.push(String(nodeName));
+ });
+
+ return names;
+};
+const deleteSelectedElement = async () => {
+ const lf = logicFlowInstance.value;
+ const cur = selectedElement.value;
+ if (!lf || !cur) return;
+
+ if (cur.kind === 'node' && (cur.properties?.nodeCode === START_NODE_CODE || cur.text === START_NODE_TEXT)) {
+ ElMessage.warning('开始节点不能删除');
+ return;
+ }
+
+ try {
+ let affectedCount = 0;
+ if (cur.kind === 'node') {
+ const affectedNodeNames = getAffectedDownstreamNodeNames(cur.id);
+ if (affectedNodeNames.length > 0) {
+ const previewNames = affectedNodeNames.slice(0, 8);
+ const overflowText = affectedNodeNames.length > 8 ? `\n...等 ${affectedNodeNames.length} 个节点` : '';
+ await ElMessageBox.confirm(
+ `删除该节点将清理以下下级节点中的引用:\n${previewNames.join('、')}${overflowText}`,
+ '删除确认',
+ {
+ confirmButtonText: '继续删除',
+ cancelButtonText: '取消',
+ type: 'warning',
+ }
+ );
+ }
+
+ affectedCount = cleanupReferencesToNode(cur.id);
+ lf.deleteNode(cur.id);
+ } else {
+ lf.deleteEdge(cur.id);
+ }
+ selectedElement.value = null;
+ ElMessage.success(affectedCount > 0 ? `删除成功,已清理 ${affectedCount} 个下级节点引用` : '删除成功');
+ } catch (error) {
+ if (error === 'cancel') return;
+ ElMessage.error('删除失败');
+ }
+};// 从后端 DSL 恢复工作流
const loadWorkflowFromDsl = (dsl: any) => {
const lf = logicFlowInstance.value;
if (!lf || !dsl) return;
@@ -5527,3 +5626,7 @@ onBeforeUnmount(() => {
justify-content: center;
}
+
+
+
+