feat: loop start add index (#3101)
* feat: loop start add index * update doc
This commit is contained in:
@@ -9,14 +9,15 @@ weight: 811
|
||||
|
||||
## 更新说明
|
||||
|
||||
1.
|
||||
1. 新增 - 数组变量选择支持多选,可以选多个数组或对应的单一数据类型,会自动按选择顺序进行合并。
|
||||
2. 新增 - 文件上传方案调整,节点直接支持接收文件链接,插件自定义变量支持文件上传。
|
||||
3. 新增 - 对话记录增加时间显示。
|
||||
4. 新增 - 工作流校验错误时,跳转至错误节点。
|
||||
5. 优化 - 知识库上传文件,优化报错提示。
|
||||
6. 优化 - 全文检索语句,减少一轮查询。
|
||||
7. 优化 - 修改 findLast 为 [...array].reverse().find,适配旧版浏览器。
|
||||
8. 优化 - Markdown 组件自动空格,避免分割 url 中的中文。
|
||||
9. 优化 - 工作流上下文拆分,性能优化。
|
||||
10. 修复 - Dockerfile pnpm install 支持代理。
|
||||
11. 修复 - BI 图表生成无法写入文件。
|
||||
5. 新增 - 循环节点增加下标值。
|
||||
6. 优化 - 知识库上传文件,优化报错提示。
|
||||
7. 优化 - 全文检索语句,减少一轮查询。
|
||||
8. 优化 - 修改 findLast 为 [...array].reverse().find,适配旧版浏览器。
|
||||
9. 优化 - Markdown 组件自动空格,避免分割 url 中的中文。
|
||||
10. 优化 - 工作流上下文拆分,性能优化。
|
||||
11. 修复 - Dockerfile pnpm install 支持代理。
|
||||
12. 修复 - BI 图表生成无法写入文件。
|
||||
|
||||
@@ -256,9 +256,9 @@ export enum NodeOutputKeyEnum {
|
||||
|
||||
// loop
|
||||
loopArray = 'loopArray',
|
||||
|
||||
// loop start
|
||||
loopStartInput = 'loopStartInput',
|
||||
loopArrayIndex = 'loopArrayIndex',
|
||||
|
||||
// form input
|
||||
formInputResult = 'formInputResult'
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../../node/constant';
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../../node/constant';
|
||||
import { FlowNodeTemplateType } from '../../../type/node.d';
|
||||
import {
|
||||
FlowNodeTemplateTypeEnum,
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
WorkflowIOValueTypeEnum
|
||||
} from '../../../constants';
|
||||
import { getHandleConfig } from '../../utils';
|
||||
@@ -30,5 +35,13 @@ export const LoopStartNode: FlowNodeTemplateType = {
|
||||
value: ''
|
||||
}
|
||||
],
|
||||
outputs: []
|
||||
outputs: [
|
||||
{
|
||||
id: NodeOutputKeyEnum.loopArrayIndex,
|
||||
key: NodeOutputKeyEnum.loopArrayIndex,
|
||||
label: i18nT('workflow:Array_element_index'),
|
||||
type: FlowNodeOutputTypeEnum.static,
|
||||
valueType: WorkflowIOValueTypeEnum.number
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -43,6 +43,7 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
|
||||
let totalPoints = 0;
|
||||
let newVariables: Record<string, any> = props.variables;
|
||||
|
||||
let index = 0;
|
||||
for await (const item of loopInputArray.filter(Boolean)) {
|
||||
runtimeNodes.forEach((node) => {
|
||||
if (
|
||||
@@ -50,14 +51,21 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
|
||||
node.flowNodeType === FlowNodeTypeEnum.loopStart
|
||||
) {
|
||||
node.isEntry = true;
|
||||
node.inputs = node.inputs.map((input) =>
|
||||
input.key === NodeInputKeyEnum.loopStartInput
|
||||
? {
|
||||
...input,
|
||||
value: item
|
||||
}
|
||||
: input
|
||||
);
|
||||
node.inputs = node.inputs.map((input) => {
|
||||
if (input.key === NodeInputKeyEnum.loopStartInput) {
|
||||
return {
|
||||
...input,
|
||||
value: item
|
||||
};
|
||||
} else if (input.key === NodeInputKeyEnum.loopStartInput) {
|
||||
return {
|
||||
...input,
|
||||
value: index++
|
||||
};
|
||||
} else {
|
||||
return input;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
const response = await dispatchWorkFlow({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"Array_element": "Array element",
|
||||
"Array_element_index": "Index",
|
||||
"Code": "Code",
|
||||
"Confirm_sync_node": "It will be updated to the latest node configuration and fields that do not exist in the template will be deleted (including all custom fields).\n\nIf the fields are complex, it is recommended that you copy a node first and then update the original node to facilitate parameter copying.",
|
||||
"Node.Open_Node_Course": "Open node course",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"Array_element": "数组元素",
|
||||
"Array_element_index": "下标",
|
||||
"Code": "代码",
|
||||
"Confirm_sync_node": "将会更新至最新的节点配置,不存在模板中的字段将会被删除(包括所有自定义字段)。\n如果字段较为复杂,建议您先复制一份节点,再更新原来的节点,便于参数复制。",
|
||||
"Node.Open_Node_Course": "查看节点教程",
|
||||
|
||||
@@ -43,15 +43,11 @@ const NodeLoop = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
|
||||
const { resetParentNodeSizeAndPosition } = useWorkflow();
|
||||
|
||||
const loopInputArray = useMemo(
|
||||
() => inputs.find((input) => input.key === NodeInputKeyEnum.loopInputArray),
|
||||
[inputs]
|
||||
);
|
||||
|
||||
const { nodeWidth, nodeHeight } = useMemo(() => {
|
||||
const { nodeWidth, nodeHeight, loopInputArray } = useMemo(() => {
|
||||
return {
|
||||
nodeWidth: inputs.find((input) => input.key === NodeInputKeyEnum.nodeWidth)?.value,
|
||||
nodeHeight: inputs.find((input) => input.key === NodeInputKeyEnum.nodeHeight)?.value
|
||||
nodeHeight: inputs.find((input) => input.key === NodeInputKeyEnum.nodeHeight)?.value,
|
||||
loopInputArray: inputs.find((input) => input.key === NodeInputKeyEnum.loopInputArray)
|
||||
};
|
||||
}, [inputs]);
|
||||
|
||||
|
||||
@@ -8,11 +8,15 @@ import { WorkflowContext } from '../../../context';
|
||||
import {
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
toolValueTypeList,
|
||||
WorkflowIOValueTypeEnum
|
||||
} from '@fastgpt/global/core/workflow/constants';
|
||||
import { Box, Flex, Table, TableContainer, Tbody, Td, Th, Thead, Tr } from '@chakra-ui/react';
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { FlowNodeOutputTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import {
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowValueTypeMap
|
||||
} from '@fastgpt/global/core/workflow/node/constant';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
|
||||
const typeMap = {
|
||||
@@ -24,7 +28,7 @@ const typeMap = {
|
||||
|
||||
const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
const { t } = useTranslation();
|
||||
const { nodeId } = data;
|
||||
const { nodeId, outputs } = data;
|
||||
const { nodeList, onChangeNode } = useContextSelector(WorkflowContext, (v) => v);
|
||||
|
||||
const loopStartNode = useMemo(
|
||||
@@ -94,23 +98,21 @@ const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
debug: true
|
||||
}}
|
||||
>
|
||||
<Box px={4} pt={2} w={'420px'} h={'116px'}>
|
||||
{!loopItemInputType ? (
|
||||
<EmptyTip text={t('workflow:loop_start_tip')} py={0} mt={4} iconSize={'32px'} />
|
||||
) : (
|
||||
<Box bg={'white'} borderRadius={'md'} overflow={'hidden'} border={'base'}>
|
||||
<TableContainer>
|
||||
<Table bg={'white'}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th borderBottomLeftRadius={'none !important'}>
|
||||
{t('workflow:Variable_name')}
|
||||
</Th>
|
||||
<Th>{t('common:core.workflow.Value type')}</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
<Tr>
|
||||
<Box px={4} pt={2} w={'420px'}>
|
||||
<Box bg={'white'} borderRadius={'md'} overflow={'hidden'} border={'base'}>
|
||||
<TableContainer>
|
||||
<Table bg={'white'}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th borderBottomLeftRadius={'none !important'}>
|
||||
{t('workflow:Variable_name')}
|
||||
</Th>
|
||||
<Th>{t('common:core.workflow.Value type')}</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{outputs.map((output) => (
|
||||
<Tr key={output.id}>
|
||||
<Td>
|
||||
<Flex alignItems={'center'}>
|
||||
<MyIcon
|
||||
@@ -119,20 +121,20 @@ const NodeLoopStart = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
|
||||
mr={1}
|
||||
color={'primary.600'}
|
||||
/>
|
||||
{t('workflow:Array_element')}
|
||||
{t(output.label)}
|
||||
</Flex>
|
||||
</Td>
|
||||
<Td>{loopItemInputType}</Td>
|
||||
{output.valueType && <Td>{FlowValueTypeMap[output.valueType]?.label}</Td>}
|
||||
</Tr>
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
)}
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
</Box>
|
||||
</NodeCard>
|
||||
);
|
||||
}, [data, loopItemInputType, selected, t]);
|
||||
}, [data, outputs, selected, t]);
|
||||
|
||||
return Render;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user