From 2e468fc8cab0d10109d7fd5000b10185e5aa12e9 Mon Sep 17 00:00:00 2001 From: heheer <71265218+newfish-cmyk@users.noreply.github.com> Date: Wed, 8 May 2024 14:39:02 +0800 Subject: [PATCH] 4.8 test fix (#1386) * fix: boolean of if else input * fix laf node * fix laf bind * fix laf input type * fix if else check * fix * fix --- .../core/workflow/dispatch/tools/runIfElse.ts | 47 +++++- .../Flow/nodes/NodeIfElse/ListItem.tsx | 12 +- .../core/workflow/Flow/nodes/NodeLaf.tsx | 155 +++++++++--------- .../support/laf/LafAccountModal.tsx | 10 +- 4 files changed, 140 insertions(+), 84 deletions(-) diff --git a/packages/service/core/workflow/dispatch/tools/runIfElse.ts b/packages/service/core/workflow/dispatch/tools/runIfElse.ts index c9fda7201..21ba9f114 100644 --- a/packages/service/core/workflow/dispatch/tools/runIfElse.ts +++ b/packages/service/core/workflow/dispatch/tools/runIfElse.ts @@ -22,20 +22,55 @@ type Response = DispatchNodeResultType<{ [NodeOutputKeyEnum.ifElseResult]: string; }>; +function isEmpty(value: any) { + return ( + // 检查未定义或null值 + value === undefined || + value === null || + // 检查空字符串 + (typeof value === 'string' && value.trim() === '') || + // 检查NaN + (typeof value === 'number' && isNaN(value)) || + // 检查空数组 + (Array.isArray(value) && value.length === 0) || + // 检查空对象 + (typeof value === 'object' && Object.keys(value).length === 0) + ); +} + +function isInclude(value: any, target: any) { + if (Array.isArray(value)) { + return value.map((item: any) => String(item)).includes(target); + } else if (typeof value === 'string') { + return value.includes(target); + } else { + return false; + } +} + function checkCondition(condition: VariableConditionEnum, variableValue: any, value: string) { const operations = { - [VariableConditionEnum.isEmpty]: () => !variableValue, - [VariableConditionEnum.isNotEmpty]: () => !!variableValue, - [VariableConditionEnum.equalTo]: () => variableValue === value, - [VariableConditionEnum.notEqual]: () => variableValue !== value, + [VariableConditionEnum.isEmpty]: () => isEmpty(variableValue), + [VariableConditionEnum.isNotEmpty]: () => !isEmpty(variableValue), + + [VariableConditionEnum.equalTo]: () => String(variableValue) === value, + [VariableConditionEnum.notEqual]: () => String(variableValue) !== value, + + // number [VariableConditionEnum.greaterThan]: () => Number(variableValue) > Number(value), [VariableConditionEnum.lessThan]: () => Number(variableValue) < Number(value), [VariableConditionEnum.greaterThanOrEqualTo]: () => Number(variableValue) >= Number(value), [VariableConditionEnum.lessThanOrEqualTo]: () => Number(variableValue) <= Number(value), - [VariableConditionEnum.include]: () => variableValue?.includes(value), - [VariableConditionEnum.notInclude]: () => !variableValue?.includes(value), + + // array or string + [VariableConditionEnum.include]: () => isInclude(variableValue, value), + [VariableConditionEnum.notInclude]: () => !isInclude(variableValue, value), + + // string [VariableConditionEnum.startWith]: () => variableValue?.startsWith(value), [VariableConditionEnum.endWith]: () => variableValue?.endsWith(value), + + // array [VariableConditionEnum.lengthEqualTo]: () => variableValue?.length === Number(value), [VariableConditionEnum.lengthNotEqualTo]: () => variableValue?.length !== Number(value), [VariableConditionEnum.lengthGreaterThan]: () => variableValue?.length > Number(value), diff --git a/projects/app/src/components/core/workflow/Flow/nodes/NodeIfElse/ListItem.tsx b/projects/app/src/components/core/workflow/Flow/nodes/NodeIfElse/ListItem.tsx index 7a5b19e83..5f23a34f7 100644 --- a/projects/app/src/components/core/workflow/Flow/nodes/NodeIfElse/ListItem.tsx +++ b/projects/app/src/components/core/workflow/Flow/nodes/NodeIfElse/ListItem.tsx @@ -17,6 +17,7 @@ import { arrayConditionList, booleanConditionList, numberConditionList, + objectConditionList, stringConditionList } from '@fastgpt/global/core/workflow/template/system/ifElse/constant'; import { useContextSelector } from 'use-context-selector'; @@ -133,7 +134,8 @@ const ListItem = ({ if (index === i) { return { ...item, - variable: e + variable: e, + condition: undefined }; } return item; @@ -334,10 +336,10 @@ const ConditionSelect = ({ valueType === WorkflowIOValueTypeEnum.arrayBoolean || valueType === WorkflowIOValueTypeEnum.arrayNumber || valueType === WorkflowIOValueTypeEnum.arrayObject || - valueType === WorkflowIOValueTypeEnum.arrayString || - valueType === WorkflowIOValueTypeEnum.object + valueType === WorkflowIOValueTypeEnum.arrayString ) return arrayConditionList; + if (valueType === WorkflowIOValueTypeEnum.object) return objectConditionList; if (valueType === WorkflowIOValueTypeEnum.any) return allConditionList; @@ -395,6 +397,10 @@ const ConditionValueInput = ({ onchange={onChange} value={value} placeholder={'选择值'} + isDisabled={ + condition === VariableConditionEnum.isEmpty || + condition === VariableConditionEnum.isNotEmpty + } /> ); } else { diff --git a/projects/app/src/components/core/workflow/Flow/nodes/NodeLaf.tsx b/projects/app/src/components/core/workflow/Flow/nodes/NodeLaf.tsx index 5acc27da1..81d1c8d40 100644 --- a/projects/app/src/components/core/workflow/Flow/nodes/NodeLaf.tsx +++ b/projects/app/src/components/core/workflow/Flow/nodes/NodeLaf.tsx @@ -33,6 +33,7 @@ import { getNanoid } from '@fastgpt/global/common/string/tools'; import IOTitle from '../components/IOTitle'; import { useContextSelector } from 'use-context-selector'; import { WorkflowContext } from '../../context'; +import { putUpdateTeam } from '@/web/support/user/team/api'; const LafAccountModal = dynamic(() => import('@/components/support/laf/LafAccountModal')); @@ -47,20 +48,11 @@ const NodeLaf = (props: NodeProps) => { const requestUrl = inputs.find((item) => item.key === NodeInputKeyEnum.httpReqUrl); - const { userInfo } = useUserStore(); + const { userInfo, initUserInfo } = useUserStore(); const token = userInfo?.team.lafAccount?.token; const appid = userInfo?.team.lafAccount?.appid; - // not config laf - if (!token || !appid) { - return ( - - - - ); - } - const { data: lafData, isLoading: isLoadingFunctions, @@ -69,24 +61,32 @@ const NodeLaf = (props: NodeProps) => { ['getLafFunctionList'], async () => { // load laf app detail - const appDetail = await getLafAppDetail(appid); + try { + const appDetail = await getLafAppDetail(appid || ''); + // load laf app functions + const schemaUrl = `https://${appDetail?.domain.domain}/_/api-docs?token=${appDetail?.openapi_token}`; - // load laf app functions - const schemaUrl = `https://${appDetail?.domain.domain}/_/api-docs?token=${appDetail?.openapi_token}`; + const schema = await getApiSchemaByUrl(schemaUrl); + const openApiSchema = await str2OpenApiSchema(JSON.stringify(schema)); + const filterPostSchema = openApiSchema.pathData.filter((item) => item.method === 'post'); - const schema = await getApiSchemaByUrl(schemaUrl); - const openApiSchema = await str2OpenApiSchema(JSON.stringify(schema)); - const filterPostSchema = openApiSchema.pathData.filter((item) => item.method === 'post'); - - return { - lafApp: appDetail, - lafFunctions: filterPostSchema.map((item) => ({ - ...item, - requestUrl: `https://${appDetail?.domain.domain}${item.path}` - })) - }; + return { + lafApp: appDetail, + lafFunctions: filterPostSchema.map((item) => ({ + ...item, + requestUrl: `https://${appDetail?.domain.domain}${item.path}` + })) + }; + } catch (err) { + await putUpdateTeam({ + teamId: userInfo?.team.teamId || '', + lafAccount: { token: '', appid: '', pat: '' } + }); + initUserInfo(); + } }, { + enabled: !!token && !!appid, onError(err) { toast({ status: 'error', @@ -155,14 +155,14 @@ const NodeLaf = (props: NodeProps) => { desc: bodyParams[key].description, required: requiredParams?.includes(key) || false, value: `{{${key}}}`, - type: 'string' + type: bodyParams[key].type })) ].filter((item) => !inputs.find((input) => input.key === item.name)); allParams.forEach((param) => { const newInput: FlowNodeInputItemType = { key: param.name, - valueType: WorkflowIOValueTypeEnum.string, + valueType: param.type, label: param.name, renderTypeList: [FlowNodeInputTypeEnum.reference], required: param.required, @@ -215,54 +215,63 @@ const NodeLaf = (props: NodeProps) => { successToast: t('common.Sync success') }); - return ( - - - {/* select function */} - { - onChangeNode({ - nodeId, - type: 'updateInput', - key: NodeInputKeyEnum.httpReqUrl, - value: { - ...requestUrl, - value: e - } - }); - }} - value={selectedFunction} - /> - {/* auto set params and go to edit */} - {!!selectedFunction && ( - - - + - - )} - - {!!selectedFunction && } - - ); + if (!lafFunction) return; + const url = `${feConfigs.lafEnv}/app/${lafData?.lafApp?.appid}/function${lafFunction?.path}?templateid=FastGPT_Laf`; + window.open(url, '_blank'); + }} + > + {t('plugin.go to laf')} + + + )} + + {!!selectedFunction && } + + ); + } }; export default React.memo(NodeLaf); diff --git a/projects/app/src/components/support/laf/LafAccountModal.tsx b/projects/app/src/components/support/laf/LafAccountModal.tsx index d765d106a..b0140446c 100644 --- a/projects/app/src/components/support/laf/LafAccountModal.tsx +++ b/projects/app/src/components/support/laf/LafAccountModal.tsx @@ -67,7 +67,7 @@ const LafAccountModal = ({ enabled: !!lafToken, onSuccess: (data) => { if (!getValues('appid') && data.length > 0) { - setValue('appid', data[0].appid); + setValue('appid', data.filter((app) => app.state === 'Running')[0]?.appid); } }, onError: (err) => { @@ -175,7 +175,13 @@ const LafAccountModal = ({ )} - {appid && (