fix: 完善工作流图片参数流转
- 图片参数使用 Object 类型并过滤上游图片引用 - 试运行支持上传、URL 和素材库图片输入 - 将模型图片能力映射到运行配置
This commit is contained in:
@@ -1,6 +1,53 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { filterRefOptionsByDataType } from './refOptionFilter';
|
||||
import {
|
||||
filterRefOptionsByContentType,
|
||||
filterRefOptionsByDataType,
|
||||
} from './refOptionFilter';
|
||||
|
||||
describe('filterRefOptionsByContentType', () => {
|
||||
const options = [
|
||||
{
|
||||
label: '开始节点',
|
||||
selectable: false,
|
||||
value: 'start',
|
||||
children: [
|
||||
{
|
||||
label: '图片',
|
||||
selectable: true,
|
||||
value: 'start.image',
|
||||
contentType: 'image',
|
||||
},
|
||||
{
|
||||
label: '问题',
|
||||
selectable: true,
|
||||
value: 'start.user_input',
|
||||
contentType: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
it('图片输入仅展示图片类型引用', () => {
|
||||
const filtered = filterRefOptionsByContentType(options, ['image']);
|
||||
|
||||
expect(filtered[0]?.children).toHaveLength(1);
|
||||
expect(filtered[0]?.children[0]?.value).toBe('start.image');
|
||||
});
|
||||
|
||||
it('保留当前已选择的旧版非图片引用', () => {
|
||||
const filtered = filterRefOptionsByContentType(
|
||||
options,
|
||||
['image'],
|
||||
'start.user_input',
|
||||
);
|
||||
|
||||
expect(filtered[0]?.children.map((item: any) => item.value)).toEqual([
|
||||
'start.image',
|
||||
'start.user_input',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterRefOptionsByDataType', () => {
|
||||
const options = [
|
||||
|
||||
@@ -1,3 +1,40 @@
|
||||
/**
|
||||
* 按内容类型过滤引用选项,并保留当前已选择的旧引用。
|
||||
*/
|
||||
export function filterRefOptionsByContentType(
|
||||
options: any[],
|
||||
acceptedContentTypes: string[],
|
||||
currentRef = '',
|
||||
): any[] {
|
||||
if (!acceptedContentTypes.length) {
|
||||
return options;
|
||||
}
|
||||
const accepted = new Set(acceptedContentTypes);
|
||||
return options
|
||||
.map((option) => {
|
||||
const children = Array.isArray(option.children)
|
||||
? filterRefOptionsByContentType(
|
||||
option.children,
|
||||
acceptedContentTypes,
|
||||
currentRef,
|
||||
)
|
||||
: [];
|
||||
const selectable =
|
||||
option.selectable === true &&
|
||||
(accepted.has(String(option.contentType || '')) ||
|
||||
String(option.value || '') === currentRef);
|
||||
if (!selectable && children.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
...option,
|
||||
selectable,
|
||||
children,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function isAcceptedDataType(dataType: string, acceptedDataTypes: string[]) {
|
||||
const normalized = dataType.trim().toLowerCase();
|
||||
return acceptedDataTypes.some((acceptedDataType) => {
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
isArrayDataType,
|
||||
projectParameterDataType,
|
||||
} from '../../utils/loopScope';
|
||||
import { filterRefOptionsByContentType } from './refOptionFilter';
|
||||
|
||||
const fillRefNodeIds = (
|
||||
refNodeIds: string[],
|
||||
@@ -53,6 +54,7 @@ const getChildren = (
|
||||
return {
|
||||
label: pathLabel,
|
||||
dataType,
|
||||
contentType: param.contentType,
|
||||
value: parentId + '.' + param.name,
|
||||
selectable: true,
|
||||
nodeType: nodeType,
|
||||
@@ -102,6 +104,7 @@ const nodeToOptions = (
|
||||
children.push({
|
||||
label,
|
||||
dataType: projectParameterDataType(parameter),
|
||||
contentType: parameter.contentType,
|
||||
value: node.id + '.' + parameter.name,
|
||||
selectable: true,
|
||||
nodeType: nodeType,
|
||||
@@ -153,6 +156,7 @@ const nodeToOptions = (
|
||||
|
||||
export const useRefOptions: any = (
|
||||
useChildrenOnly: boolean | (() => boolean) = false,
|
||||
acceptedContentTypes: string[] | (() => string[]) = [],
|
||||
currentRef: string | (() => string) = '',
|
||||
) => {
|
||||
const currentNodeId = getCurrentNodeId();
|
||||
@@ -162,6 +166,10 @@ export const useRefOptions: any = (
|
||||
typeof useChildrenOnly === 'function'
|
||||
? useChildrenOnly()
|
||||
: useChildrenOnly;
|
||||
const getAcceptedContentTypes = () =>
|
||||
typeof acceptedContentTypes === 'function'
|
||||
? acceptedContentTypes()
|
||||
: acceptedContentTypes;
|
||||
const getCurrentRef = () =>
|
||||
typeof currentRef === 'function' ? currentRef() : currentRef;
|
||||
|
||||
@@ -207,7 +215,11 @@ export const useRefOptions: any = (
|
||||
}
|
||||
}
|
||||
|
||||
const items = resultOptions;
|
||||
const items = filterRefOptionsByContentType(
|
||||
resultOptions,
|
||||
getAcceptedContentTypes(),
|
||||
getCurrentRef(),
|
||||
);
|
||||
const stack = [...items];
|
||||
let selected;
|
||||
const currentValue = getCurrentRef();
|
||||
|
||||
Reference in New Issue
Block a user