refractor(web): 修复入参解析
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
import {type Edge, getIncomers, type Node} from '@xyflow/react'
|
import {type Edge, getIncomers, type Node} from '@xyflow/react'
|
||||||
import type {Option} from 'amis/lib/Schema'
|
import type {Option} from 'amis/lib/Schema'
|
||||||
import {find, has, isEmpty, isEqual, max, min, unique} from 'licia'
|
import {find, has, isEqual, max, min, unique} from 'licia'
|
||||||
import {type DependencyList, type MouseEvent as ReactMouseEvent, useCallback, useRef} from 'react'
|
import {type DependencyList, type MouseEvent as ReactMouseEvent, useCallback, useRef} from 'react'
|
||||||
import Queue from 'yocto-queue'
|
import Queue from 'yocto-queue'
|
||||||
import {useFlowStore} from './store/FlowStore.ts'
|
import {useFlowStore} from './store/FlowStore.ts'
|
||||||
import type {InputFormOptions, InputFormOptionsGroup} from './types.ts'
|
import type {OutputVariable} from './types.ts'
|
||||||
|
|
||||||
export const getAllIncomerNodeById: (id: string, nodes: Node[], edges: Edge[]) => string[] = (id, nodes, edges) => {
|
export const getAllIncomerNodeById: (id: string, nodes: Node[], edges: Edge[]) => string[] = (id, nodes, edges) => {
|
||||||
let queue = new Queue<Node>()
|
let queue = new Queue<Node>()
|
||||||
@@ -20,36 +20,16 @@ export const getAllIncomerNodeById: (id: string, nodes: Node[], edges: Edge[]) =
|
|||||||
return unique(result, (a, b) => isEqual(a, b))
|
return unique(result, (a, b) => isEqual(a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAllIncomerNodeOutputVariables: (id: string, nodes: Node[], edges: Edge[], data: any) => {
|
export const getAllIncomerNodeOutputVariables: (id: string, inputSchema: Record<string, Record<string, any>>, nodes: Node[], edges: Edge[], data: any) => OutputVariable[] = (id, inputSchema, nodes, edges, data) => {
|
||||||
id: string,
|
let inputSchemaVariables: OutputVariable[] = Object.keys(inputSchema).map(key => ({
|
||||||
variable: string
|
group: '流程入参',
|
||||||
}[] = (id, nodes, edges, data) => {
|
name: `${key}${inputSchema[key]?.label ? ` (${inputSchema[key].label})` : ''}`,
|
||||||
let incomerIds = getAllIncomerNodeById(id, nodes, edges)
|
variable: key,
|
||||||
let incomerVariables: { id: string, variable: string }[] = []
|
|
||||||
for (const incomerId of incomerIds) {
|
|
||||||
let nodeData = data[incomerId] ?? {}
|
|
||||||
if (has(nodeData, 'outputs')) {
|
|
||||||
let outputs = nodeData?.outputs ?? []
|
|
||||||
for (const output of Object.keys(outputs)) {
|
|
||||||
incomerVariables.push({
|
|
||||||
id: incomerId,
|
|
||||||
variable: output,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return incomerVariables
|
|
||||||
}
|
|
||||||
|
|
||||||
export const generateAllIncomerOutputVariablesFormOptions: (id: string, inputSchema: Record<string, Record<string, any>>, nodes: Node[], edges: Edge[], data: any) => Option[] = (id, inputSchema, nodes, edges, data) => {
|
|
||||||
let inputSchemaVariables: InputFormOptions[] = Object.keys(inputSchema).map(key => ({
|
|
||||||
label: `${key} (${inputSchema[key]?.label ?? ''})`,
|
|
||||||
value: key,
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let currentNode = find(nodes, n => isEqual(id, n.id))
|
let currentNode = find(nodes, n => isEqual(id, n.id))
|
||||||
if (!currentNode) {
|
if (!currentNode) {
|
||||||
return []
|
return inputSchemaVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
let incomerIds = getAllIncomerNodeById(id, nodes, edges)
|
let incomerIds = getAllIncomerNodeById(id, nodes, edges)
|
||||||
@@ -60,7 +40,7 @@ export const generateAllIncomerOutputVariablesFormOptions: (id: string, inputSch
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
let incomerVariables: InputFormOptionsGroup[] = []
|
let incomerVariables: OutputVariable[] = []
|
||||||
for (const incomerId of incomerIds) {
|
for (const incomerId of incomerIds) {
|
||||||
let nodeData = data[incomerId] ?? {}
|
let nodeData = data[incomerId] ?? {}
|
||||||
let group = incomerId
|
let group = incomerId
|
||||||
@@ -68,48 +48,51 @@ export const generateAllIncomerOutputVariablesFormOptions: (id: string, inputSch
|
|||||||
group = `${nodeData.node.name} ${incomerId}`
|
group = `${nodeData.node.name} ${incomerId}`
|
||||||
}
|
}
|
||||||
if (has(nodeData, 'outputs')) {
|
if (has(nodeData, 'outputs')) {
|
||||||
let outputs = nodeData?.outputs ?? []
|
let outputs = nodeData?.outputs ?? {}
|
||||||
incomerVariables.push({
|
for (const key of Object.keys(outputs)) {
|
||||||
group: group,
|
incomerVariables.push({
|
||||||
variables: Object.keys(outputs).map(key => ({
|
group: group,
|
||||||
value: `${incomerId}.${key}`,
|
name: key,
|
||||||
label: key,
|
variable: `${incomerId}.${key}`,
|
||||||
})),
|
})
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputVariables = [
|
return [
|
||||||
...(isEmpty(inputSchemaVariables) ? [] : [
|
...inputSchemaVariables,
|
||||||
{
|
|
||||||
group: '流程入参',
|
|
||||||
variables: inputSchemaVariables,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
...(currentNode.parentId ? [
|
...(currentNode.parentId ? [
|
||||||
{
|
{
|
||||||
group: '循环入参',
|
group: '循环入参',
|
||||||
variables: [
|
name: 'loopIndex (当前迭代索引)',
|
||||||
{
|
variable: 'loopIndex',
|
||||||
label: 'loopIndex (当前迭代索引)',
|
},
|
||||||
value: 'loopIndex',
|
{
|
||||||
},
|
group: '循环入参',
|
||||||
{
|
name: 'loopItem (当前迭代对象)',
|
||||||
label: 'loopItem (当前迭代对象)',
|
variable: 'loopItem',
|
||||||
value: 'loopItem',
|
},
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
] : []),
|
] : []),
|
||||||
...incomerVariables,
|
...incomerVariables,
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
export const generateAllIncomerOutputVariablesFormOptions: (id: string, inputSchema: Record<string, Record<string, any>>, nodes: Node[], edges: Edge[], data: any) => Option[] = (id, inputSchema, nodes, edges, data) => {
|
||||||
...inputVariables.map(item => ({
|
let optionMap: Record<string, Option[]> = {}
|
||||||
label: item.group,
|
for (const item of getAllIncomerNodeOutputVariables(id, inputSchema, nodes, edges, data)) {
|
||||||
children: item.variables,
|
if (!optionMap[item.group]) {
|
||||||
})),
|
optionMap[item.group] = []
|
||||||
]
|
}
|
||||||
|
optionMap[item.group].push({
|
||||||
|
label: item.name,
|
||||||
|
value: item.variable,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Object.keys(optionMap)
|
||||||
|
.map(key => ({
|
||||||
|
label: key,
|
||||||
|
children: optionMap[key],
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理循环节点的边界问题
|
// 处理循环节点的边界问题
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ const inputSingleVariableChecker: (field: string) => NodeChecker = field => {
|
|||||||
if (has(nodeData, field)) {
|
if (has(nodeData, field)) {
|
||||||
let expression = nodeData?.[field] ?? ''
|
let expression = nodeData?.[field] ?? ''
|
||||||
if (!isEmpty(expression)) {
|
if (!isEmpty(expression)) {
|
||||||
let outputVariables = new Set([
|
let outputVariables = new Set(getAllIncomerNodeOutputVariables(id, inputSchema, nodes, edges, data).map(i => i.variable))
|
||||||
...getAllIncomerNodeOutputVariables(id, nodes, edges, data).map(i => `${i.id}.${i.variable}`),
|
|
||||||
...Object.keys(inputSchema),
|
|
||||||
])
|
|
||||||
if (!outputVariables.has(expression)) {
|
if (!outputVariables.has(expression)) {
|
||||||
return {
|
return {
|
||||||
error: true,
|
error: true,
|
||||||
@@ -36,10 +33,7 @@ const inputMultiVariableChecker: NodeChecker = (id, inputSchema, nodes, edges, d
|
|||||||
if (has(nodeData, 'inputs')) {
|
if (has(nodeData, 'inputs')) {
|
||||||
let inputs = nodeData?.inputs ?? {}
|
let inputs = nodeData?.inputs ?? {}
|
||||||
if (!isEmpty(inputs)) {
|
if (!isEmpty(inputs)) {
|
||||||
let outputVariables = new Set([
|
let outputVariables = new Set(getAllIncomerNodeOutputVariables(id, inputSchema, nodes, edges, data).map(i => i.variable))
|
||||||
...getAllIncomerNodeOutputVariables(id, nodes, edges, data).map(i => `${i.id}.${i.variable}`),
|
|
||||||
...Object.keys(inputSchema),
|
|
||||||
])
|
|
||||||
for (const key of Object.keys(inputs)) {
|
for (const key of Object.keys(inputs)) {
|
||||||
let variable = inputs[key]?.variable ?? ''
|
let variable = inputs[key]?.variable ?? ''
|
||||||
if (!outputVariables.has(variable)) {
|
if (!outputVariables.has(variable)) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type {Edge, Node} from '@xyflow/react'
|
import type {Edge, Node} from '@xyflow/react'
|
||||||
import type {JSX} from 'react'
|
import type {JSX} from 'react'
|
||||||
|
|
||||||
export const flowBackgroundColor = "#fafafa"
|
export const flowBackgroundColor = '#fafafa'
|
||||||
export const flowDotColor = "#dedede"
|
export const flowDotColor = '#dedede'
|
||||||
|
|
||||||
export type InputFormOptions = {
|
export type InputFormOptions = {
|
||||||
label: string
|
label: string
|
||||||
@@ -38,3 +38,9 @@ export type NodeDefine = {
|
|||||||
component: any,
|
component: any,
|
||||||
checkers: NodeChecker[],
|
checkers: NodeChecker[],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type OutputVariable = {
|
||||||
|
group: string,
|
||||||
|
name: string | undefined,
|
||||||
|
variable: string,
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user