@@ -4,7 +4,9 @@ import classNames from "classnames";
44
55import style from "../../../../styles/flow/nodes.module.less" ;
66import type { PipelineNodeDataType } from "../../../../stores/flow" ;
7+ import { useFlowStore } from "../../../../stores/flow" ;
78import { useConfigStore } from "../../../../stores/configStore" ;
9+ import { SourceHandleTypeEnum , TargetHandleTypeEnum , NodeTypeEnum } from "../constants" ;
810import IconFont from "../../../iconfonts" ;
911import { KVElem } from "../components/KVElem" ;
1012import { PipelineNodeHandles } from "../components/NodeHandles" ;
@@ -32,14 +34,18 @@ const focusDisplayNameMap: Record<string, string> = (() => {
3234
3335/**现代风格Pipeline节点内容 */
3436export const ModernContent = memo (
35- ( { data } : { data : PipelineNodeDataType ; props : NodeProps } ) => {
37+ ( { data, props } : { data : PipelineNodeDataType ; props : NodeProps } ) => {
38+ const nodeId = props . id ;
3639 const headerRef = useRef < HTMLDivElement > ( null ) ;
3740 const [ headerHeight , setHeaderHeight ] = useState ( 0 ) ;
3841
3942 // 是否显示节点模板图片
4043 const showNodeTemplateImages = useConfigStore (
4144 ( state ) => state . configs . showNodeTemplateImages ,
4245 ) ;
46+ const showNodeFlowSection = useConfigStore (
47+ ( state ) => state . configs . showNodeFlowSection ,
48+ ) ;
4349 // 是否渲染节点详细字段
4450 const showNodeDetailFields = useConfigStore (
4551 ( state ) => state . configs . showNodeDetailFields ,
@@ -52,6 +58,27 @@ export const ModernContent = memo(
5258 [ fieldSortConfig ] ,
5359 ) ;
5460
61+ // 读取出边,按 sourceHandle 分为 next/on_error 两组,保留顺序
62+ const edges = useFlowStore ( ( state ) => state . edges ) ;
63+ const nodes = useFlowStore ( ( state ) => state . nodes ) ;
64+ const { nextItems, errorItems } = useMemo ( ( ) => {
65+ const nodeMap = new Map ( nodes . map ( ( n ) => [ n . id , n ] ) ) ;
66+ const outEdges = edges . filter ( ( e ) => e . source === nodeId ) ;
67+ const nextItems : { label : string ; variant : "normal" | "jumpback" | "anchor" } [ ] = [ ] ;
68+ const errorItems : { label : string ; variant : "normal" | "jumpback" | "anchor" } [ ] = [ ] ;
69+ const sorted = [ ...outEdges ] . sort ( ( a , b ) => a . label - b . label ) ;
70+ for ( const e of sorted ) {
71+ const targetNode = nodeMap . get ( e . target ) ;
72+ const label = ( targetNode ?. data as any ) ?. label ?? e . target ;
73+ const isJumpBack = e . targetHandle === TargetHandleTypeEnum . JumpBack ;
74+ const isAnchor = targetNode ?. type === NodeTypeEnum . Anchor || ! ! e . attributes ?. anchor ;
75+ const variant = isJumpBack ? "jumpback" : isAnchor ? "anchor" : "normal" ;
76+ if ( e . sourceHandle === SourceHandleTypeEnum . Next ) nextItems . push ( { label, variant } ) ;
77+ else if ( e . sourceHandle === SourceHandleTypeEnum . Error ) errorItems . push ( { label, variant } ) ;
78+ }
79+ return { nextItems, errorItems } ;
80+ } , [ edges , nodes , nodeId ] ) ;
81+
5582 useEffect ( ( ) => {
5683 if ( headerRef . current ) {
5784 const height = headerRef . current . offsetHeight ;
@@ -267,6 +294,30 @@ export const ModernContent = memo(
267294 ) }
268295 </ div >
269296
297+ { /* 流程连接区域 */ }
298+ { showNodeFlowSection && ( nextItems . length > 0 || errorItems . length > 0 ) && (
299+ < div className = { style . flowSection } >
300+ { nextItems . length > 0 && (
301+ < div className = { style . flowRow } >
302+ < span className = { `${ style . flowTag } ${ style . flowTagNext } ` } > next</ span >
303+ < span className = { style . flowArrow } > →</ span >
304+ { nextItems . map ( ( item , i ) => (
305+ < span key = { i } className = { `${ style . flowTag } ${ style . flowTagTarget } ${ style [ `flowTarget-${ item . variant } ` ] } ` } > { item . label } </ span >
306+ ) ) }
307+ </ div >
308+ ) }
309+ { errorItems . length > 0 && (
310+ < div className = { style . flowRow } >
311+ < span className = { `${ style . flowTag } ${ style . flowTagError } ` } > on_error</ span >
312+ < span className = { style . flowArrow } > →</ span >
313+ { errorItems . map ( ( item , i ) => (
314+ < span key = { i } className = { `${ style . flowTag } ${ style . flowTagTarget } ${ style [ `flowTarget-${ item . variant } ` ] } ` } > { item . label } </ span >
315+ ) ) }
316+ </ div >
317+ ) }
318+ </ div >
319+ ) }
320+
270321 { /* 模板图片区域 */ }
271322 { showNodeTemplateImages && templatePaths . length > 0 && (
272323 < NodeTemplateImages templatePaths = { templatePaths } />
0 commit comments