feat: 限制单个流向

This commit is contained in:
李如威 2025-09-18 17:00:00 +08:00
parent acba77a8da
commit cf972e6839
5 changed files with 47 additions and 8 deletions

View File

@ -5,6 +5,7 @@ import os
import uvicorn import uvicorn
import uuid import uuid
import time import time
from tool import format_content_uuid
import models.db as DB import models.db as DB
import nodes as F import nodes as F
from tortoise.transactions import in_transaction from tortoise.transactions import in_transaction
@ -298,11 +299,11 @@ def create_app():
if not work_content: if not work_content:
work_content = DB.WorkContent( work_content = DB.WorkContent(
user_id=work.creator_id, user_id=work.creator_id,
content=body.content, content=[],
is_deleted=0, is_deleted=0,
work_id=work.id, work_id=work.id,
) )
work_content.content = body.content work_content.content = format_content_uuid(body.content)
work_content.update_time = datetime.datetime.now() work_content.update_time = datetime.datetime.now()
await work_content.save() await work_content.save()
return BaseResponse() return BaseResponse()

View File

@ -0,0 +1,16 @@
from uuid import uuid4
def format_content_uuid(content:list[dict]):
"""替换所有由前端生成的 uuid 字段"""
uuid_mapping = {k.get('uuid', ''): uuid4().hex for k in list(filter(lambda x: "temp_" in x.get("uuid", "") , content))}
for x in content:
edge = x.get('edge')
x_uuid = x.get('uuid', '')
x["uuid"] = uuid_mapping.get(x_uuid) or x_uuid
if edge:
source_uuid = edge.get('source', '')
target_uuid = edge.get('target', '')
edge["source"] = uuid_mapping.get(source_uuid) or source_uuid
edge["target"] = uuid_mapping.get(target_uuid) or target_uuid
return content

View File

@ -90,6 +90,7 @@ const FlowDetail = () => {
sourcePosition: 'right', sourcePosition: 'right',
targetPosition: 'left', targetPosition: 'left',
type: type, type: type,
detail: { title: type}
}, },
]); ]);
} }
@ -142,11 +143,13 @@ const FlowDetail = () => {
onOk: async () => { onOk: async () => {
const content = []; const content = [];
nodes.forEach(e => { nodes.forEach(e => {
const edge = edges.find(obj => obj.target === e.id); const edge = edges.find(obj => obj.source === e.id);
content.push({ content.push({
...e.detail, ...e.detail,
position: e.position, position: e.position,
edge: edge ? { source: edge.source, target: edge.target } : undefined edge: edge ? { source: edge.source, target: edge.target } : undefined,
type: e.type,
uuid: e.id
}) })
}); });
const res = await flowUpdate(record.uuid, { const res = await flowUpdate(record.uuid, {
@ -154,7 +157,8 @@ const FlowDetail = () => {
...formRef.current.getFieldsValue() ...formRef.current.getFieldsValue()
}) })
if (res?.success) { if (res?.success) {
message.success("保持成功"); message.success("保存成功");
loadDetail();
} else { } else {
message.error(res.message); message.error(res.message);
} }

View File

@ -1,6 +1,7 @@
import React, { memo } from 'react'; import React, { memo } from 'react';
import { Handle, Position } from '@xyflow/react'; import { Position } from '@xyflow/react';
import './CustomNode.css'; import './CustomNode.css';
import OnlyOneHandle from './OnlyOneHandle';
const CustomNode = memo(({ data: { style, position, ...data}, isConnectable }) => { const CustomNode = memo(({ data: { style, position, ...data}, isConnectable }) => {
return ( return (
@ -8,8 +9,8 @@ const CustomNode = memo(({ data: { style, position, ...data}, isConnectable }) =
<div > <div >
{data.label} {data.label}
</div> </div>
{position?.includes('left') && <Handle type="target" position={Position.Left} isConnectable={isConnectable} />} {position?.includes('left') && <OnlyOneHandle connectionCount={1} type="target" position={Position.Left} isConnectable={isConnectable} />}
{position?.includes('right') && <Handle type="source" position={Position.Right} isConnectable={isConnectable} />} {position?.includes('right') && <OnlyOneHandle connectionCount={1} type="source" position={Position.Right} isConnectable={isConnectable} />}
</div> </div>
); );
}) })

View File

@ -0,0 +1,17 @@
import React from 'react';
import { Handle, useNodeConnections } from '@xyflow/react';
const OnlyOneHandle = (props) => {
const connections = useNodeConnections({
handleType: props.type,
});
return (
<Handle
{...props}
isConnectable={connections.length < props.connectionCount}
/>
);
};
export default OnlyOneHandle;