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
This commit is contained in:
heheer
2024-05-08 14:39:02 +08:00
committed by GitHub
parent caa0755d9a
commit 2e468fc8ca
4 changed files with 140 additions and 84 deletions

View File

@@ -22,20 +22,55 @@ type Response = DispatchNodeResultType<{
[NodeOutputKeyEnum.ifElseResult]: string; [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) { function checkCondition(condition: VariableConditionEnum, variableValue: any, value: string) {
const operations = { const operations = {
[VariableConditionEnum.isEmpty]: () => !variableValue, [VariableConditionEnum.isEmpty]: () => isEmpty(variableValue),
[VariableConditionEnum.isNotEmpty]: () => !!variableValue, [VariableConditionEnum.isNotEmpty]: () => !isEmpty(variableValue),
[VariableConditionEnum.equalTo]: () => variableValue === value,
[VariableConditionEnum.notEqual]: () => variableValue !== value, [VariableConditionEnum.equalTo]: () => String(variableValue) === value,
[VariableConditionEnum.notEqual]: () => String(variableValue) !== value,
// number
[VariableConditionEnum.greaterThan]: () => Number(variableValue) > Number(value), [VariableConditionEnum.greaterThan]: () => Number(variableValue) > Number(value),
[VariableConditionEnum.lessThan]: () => Number(variableValue) < Number(value), [VariableConditionEnum.lessThan]: () => Number(variableValue) < Number(value),
[VariableConditionEnum.greaterThanOrEqualTo]: () => Number(variableValue) >= Number(value), [VariableConditionEnum.greaterThanOrEqualTo]: () => Number(variableValue) >= Number(value),
[VariableConditionEnum.lessThanOrEqualTo]: () => 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.startWith]: () => variableValue?.startsWith(value),
[VariableConditionEnum.endWith]: () => variableValue?.endsWith(value), [VariableConditionEnum.endWith]: () => variableValue?.endsWith(value),
// array
[VariableConditionEnum.lengthEqualTo]: () => variableValue?.length === Number(value), [VariableConditionEnum.lengthEqualTo]: () => variableValue?.length === Number(value),
[VariableConditionEnum.lengthNotEqualTo]: () => variableValue?.length !== Number(value), [VariableConditionEnum.lengthNotEqualTo]: () => variableValue?.length !== Number(value),
[VariableConditionEnum.lengthGreaterThan]: () => variableValue?.length > Number(value), [VariableConditionEnum.lengthGreaterThan]: () => variableValue?.length > Number(value),

View File

@@ -17,6 +17,7 @@ import {
arrayConditionList, arrayConditionList,
booleanConditionList, booleanConditionList,
numberConditionList, numberConditionList,
objectConditionList,
stringConditionList stringConditionList
} from '@fastgpt/global/core/workflow/template/system/ifElse/constant'; } from '@fastgpt/global/core/workflow/template/system/ifElse/constant';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
@@ -133,7 +134,8 @@ const ListItem = ({
if (index === i) { if (index === i) {
return { return {
...item, ...item,
variable: e variable: e,
condition: undefined
}; };
} }
return item; return item;
@@ -334,10 +336,10 @@ const ConditionSelect = ({
valueType === WorkflowIOValueTypeEnum.arrayBoolean || valueType === WorkflowIOValueTypeEnum.arrayBoolean ||
valueType === WorkflowIOValueTypeEnum.arrayNumber || valueType === WorkflowIOValueTypeEnum.arrayNumber ||
valueType === WorkflowIOValueTypeEnum.arrayObject || valueType === WorkflowIOValueTypeEnum.arrayObject ||
valueType === WorkflowIOValueTypeEnum.arrayString || valueType === WorkflowIOValueTypeEnum.arrayString
valueType === WorkflowIOValueTypeEnum.object
) )
return arrayConditionList; return arrayConditionList;
if (valueType === WorkflowIOValueTypeEnum.object) return objectConditionList;
if (valueType === WorkflowIOValueTypeEnum.any) return allConditionList; if (valueType === WorkflowIOValueTypeEnum.any) return allConditionList;
@@ -395,6 +397,10 @@ const ConditionValueInput = ({
onchange={onChange} onchange={onChange}
value={value} value={value}
placeholder={'选择值'} placeholder={'选择值'}
isDisabled={
condition === VariableConditionEnum.isEmpty ||
condition === VariableConditionEnum.isNotEmpty
}
/> />
); );
} else { } else {

View File

@@ -33,6 +33,7 @@ import { getNanoid } from '@fastgpt/global/common/string/tools';
import IOTitle from '../components/IOTitle'; import IOTitle from '../components/IOTitle';
import { useContextSelector } from 'use-context-selector'; import { useContextSelector } from 'use-context-selector';
import { WorkflowContext } from '../../context'; import { WorkflowContext } from '../../context';
import { putUpdateTeam } from '@/web/support/user/team/api';
const LafAccountModal = dynamic(() => import('@/components/support/laf/LafAccountModal')); const LafAccountModal = dynamic(() => import('@/components/support/laf/LafAccountModal'));
@@ -47,20 +48,11 @@ const NodeLaf = (props: NodeProps<FlowNodeItemType>) => {
const requestUrl = inputs.find((item) => item.key === NodeInputKeyEnum.httpReqUrl); const requestUrl = inputs.find((item) => item.key === NodeInputKeyEnum.httpReqUrl);
const { userInfo } = useUserStore(); const { userInfo, initUserInfo } = useUserStore();
const token = userInfo?.team.lafAccount?.token; const token = userInfo?.team.lafAccount?.token;
const appid = userInfo?.team.lafAccount?.appid; const appid = userInfo?.team.lafAccount?.appid;
// not config laf
if (!token || !appid) {
return (
<NodeCard minW={'350px'} selected={selected} {...data}>
<ConfigLaf />
</NodeCard>
);
}
const { const {
data: lafData, data: lafData,
isLoading: isLoadingFunctions, isLoading: isLoadingFunctions,
@@ -69,24 +61,32 @@ const NodeLaf = (props: NodeProps<FlowNodeItemType>) => {
['getLafFunctionList'], ['getLafFunctionList'],
async () => { async () => {
// load laf app detail // 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 schema = await getApiSchemaByUrl(schemaUrl);
const schemaUrl = `https://${appDetail?.domain.domain}/_/api-docs?token=${appDetail?.openapi_token}`; const openApiSchema = await str2OpenApiSchema(JSON.stringify(schema));
const filterPostSchema = openApiSchema.pathData.filter((item) => item.method === 'post');
const schema = await getApiSchemaByUrl(schemaUrl); return {
const openApiSchema = await str2OpenApiSchema(JSON.stringify(schema)); lafApp: appDetail,
const filterPostSchema = openApiSchema.pathData.filter((item) => item.method === 'post'); lafFunctions: filterPostSchema.map((item) => ({
...item,
return { requestUrl: `https://${appDetail?.domain.domain}${item.path}`
lafApp: appDetail, }))
lafFunctions: filterPostSchema.map((item) => ({ };
...item, } catch (err) {
requestUrl: `https://${appDetail?.domain.domain}${item.path}` await putUpdateTeam({
})) teamId: userInfo?.team.teamId || '',
}; lafAccount: { token: '', appid: '', pat: '' }
});
initUserInfo();
}
}, },
{ {
enabled: !!token && !!appid,
onError(err) { onError(err) {
toast({ toast({
status: 'error', status: 'error',
@@ -155,14 +155,14 @@ const NodeLaf = (props: NodeProps<FlowNodeItemType>) => {
desc: bodyParams[key].description, desc: bodyParams[key].description,
required: requiredParams?.includes(key) || false, required: requiredParams?.includes(key) || false,
value: `{{${key}}}`, value: `{{${key}}}`,
type: 'string' type: bodyParams[key].type
})) }))
].filter((item) => !inputs.find((input) => input.key === item.name)); ].filter((item) => !inputs.find((input) => input.key === item.name));
allParams.forEach((param) => { allParams.forEach((param) => {
const newInput: FlowNodeInputItemType = { const newInput: FlowNodeInputItemType = {
key: param.name, key: param.name,
valueType: WorkflowIOValueTypeEnum.string, valueType: param.type,
label: param.name, label: param.name,
renderTypeList: [FlowNodeInputTypeEnum.reference], renderTypeList: [FlowNodeInputTypeEnum.reference],
required: param.required, required: param.required,
@@ -215,54 +215,63 @@ const NodeLaf = (props: NodeProps<FlowNodeItemType>) => {
successToast: t('common.Sync success') successToast: t('common.Sync success')
}); });
return ( // not config laf
<NodeCard minW={'350px'} selected={selected} {...data}> if (!token || !appid) {
<Container> return (
{/* select function */} <NodeCard minW={'350px'} selected={selected} {...data}>
<MySelect <ConfigLaf />
isLoading={isLoadingFunctions} </NodeCard>
list={lafFunctionSelectList} );
placeholder={t('core.module.laf.Select laf function')} } else {
onchange={(e) => { return (
onChangeNode({ <NodeCard minW={'350px'} selected={selected} {...data}>
nodeId, <Container>
type: 'updateInput', {/* select function */}
key: NodeInputKeyEnum.httpReqUrl, <MySelect
value: { isLoading={isLoadingFunctions}
...requestUrl, list={lafFunctionSelectList}
value: e placeholder={t('core.module.laf.Select laf function')}
} onchange={(e) => {
}); onChangeNode({
}} nodeId,
value={selectedFunction} type: 'updateInput',
/> key: NodeInputKeyEnum.httpReqUrl,
{/* auto set params and go to edit */} value: {
{!!selectedFunction && ( ...requestUrl,
<Flex justifyContent={'flex-end'} mt={2} gap={2}> value: e
<Button isLoading={isSyncing} variant={'grayBase'} size={'sm'} onClick={onSyncParams}> }
{t('core.module.Laf sync params')} });
</Button> }}
<Button value={selectedFunction}
variant={'grayBase'} />
size={'sm'} {/* auto set params and go to edit */}
onClick={() => { {!!selectedFunction && (
const lafFunction = lafData?.lafFunctions.find( <Flex justifyContent={'flex-end'} mt={2} gap={2}>
(item) => item.requestUrl === selectedFunction <Button isLoading={isSyncing} variant={'grayBase'} size={'sm'} onClick={onSyncParams}>
); {t('core.module.Laf sync params')}
</Button>
<Button
variant={'grayBase'}
size={'sm'}
onClick={() => {
const lafFunction = lafData?.lafFunctions.find(
(item) => item.requestUrl === selectedFunction
);
if (!lafFunction) return; if (!lafFunction) return;
const url = `${feConfigs.lafEnv}/app/${lafData?.lafApp?.appid}/function${lafFunction?.path}?templateid=FastGPT_Laf`; const url = `${feConfigs.lafEnv}/app/${lafData?.lafApp?.appid}/function${lafFunction?.path}?templateid=FastGPT_Laf`;
window.open(url, '_blank'); window.open(url, '_blank');
}} }}
> >
{t('plugin.go to laf')} {t('plugin.go to laf')}
</Button> </Button>
</Flex> </Flex>
)} )}
</Container> </Container>
{!!selectedFunction && <RenderIO {...props} />} {!!selectedFunction && <RenderIO {...props} />}
</NodeCard> </NodeCard>
); );
}
}; };
export default React.memo(NodeLaf); export default React.memo(NodeLaf);

View File

@@ -67,7 +67,7 @@ const LafAccountModal = ({
enabled: !!lafToken, enabled: !!lafToken,
onSuccess: (data) => { onSuccess: (data) => {
if (!getValues('appid') && data.length > 0) { if (!getValues('appid') && data.length > 0) {
setValue('appid', data[0].appid); setValue('appid', data.filter((app) => app.state === 'Running')[0]?.appid);
} }
}, },
onError: (err) => { onError: (err) => {
@@ -175,7 +175,13 @@ const LafAccountModal = ({
)} )}
</ModalBody> </ModalBody>
<ModalFooter> <ModalFooter>
<Button variant={'whiteBase'} onClick={onClose}> <Button
variant={'whiteBase'}
onClick={() => {
initUserInfo();
onClose();
}}
>
{t('common.Close')} {t('common.Close')}
</Button> </Button>
{appid && ( {appid && (