mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 05:12:39 +00:00
Global variables support external variable; Extract module support default value (#921)
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
"immer": "^9.0.19",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jschardet": "^3.0.0",
|
||||
"json5": "^2.2.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mermaid": "^10.2.3",
|
||||
|
@@ -3,7 +3,9 @@
|
||||
1. 新增 - 知识库新增“增强处理”训练模式,可生成更多类型索引。
|
||||
2. 新增 - 完善了HTTP模块的变量提示。
|
||||
3. 新增 - HTTP模块支持OpenAI单接口导入。
|
||||
4. 优化 - 问题补全。增加英文类型。同时可以设置为单独模块,方便复用。
|
||||
5. [点击查看高级编排介绍文档](https://doc.fastgpt.in/docs/workflow/intro)
|
||||
6. [使用文档](https://doc.fastgpt.in/docs/intro/)
|
||||
7. [点击查看商业版](https://doc.fastgpt.in/docs/commercial/)
|
||||
4. 新增 - 全局变量支持增加外部变量。可通过分享链接的Query或 API 的 variables 参数传入。
|
||||
5. 新增 - 内容提取模块增加默认值。
|
||||
6. 优化 - 问题补全。增加英文类型。同时可以设置为单独模块,方便复用。
|
||||
7. [点击查看高级编排介绍文档](https://doc.fastgpt.in/docs/workflow/intro)
|
||||
8. [使用文档](https://doc.fastgpt.in/docs/intro/)
|
||||
9. [点击查看商业版](https://doc.fastgpt.in/docs/commercial/)
|
@@ -774,6 +774,8 @@
|
||||
"Input description": "",
|
||||
"label": "Dataset quote"
|
||||
},
|
||||
"Default value": "Default ",
|
||||
"Default value placeholder": "Null characters are returned by default",
|
||||
"Field Description": "Description",
|
||||
"Field Name": "Name",
|
||||
"Field Type": "Type",
|
||||
@@ -795,10 +797,14 @@
|
||||
"Field Edit": "Field Edit"
|
||||
},
|
||||
"extract": {
|
||||
"Add field": "Add",
|
||||
"Enum Description": "Lists the possible values for the field, one per row",
|
||||
"Enum Value": "Enum",
|
||||
"Field Description Placeholder": "Name/age /sql statement......",
|
||||
"Field Setting Title": "Extract field configuration"
|
||||
"Field Setting Title": "Extract field configuration",
|
||||
"Required": "Required",
|
||||
"Required Description": "Even if the field cannot be extracted, it is returned with the default value",
|
||||
"Target field": "Field"
|
||||
},
|
||||
"http": {
|
||||
"Add props": "Add props",
|
||||
@@ -939,6 +945,7 @@
|
||||
"string": "String"
|
||||
},
|
||||
"variable": {
|
||||
"External type": "External",
|
||||
"add option": "Add Option",
|
||||
"input type": "Text",
|
||||
"key": "Key",
|
||||
|
@@ -776,6 +776,8 @@
|
||||
"Input description": "可接收知识库搜索的结果。",
|
||||
"label": "知识库引用"
|
||||
},
|
||||
"Default value": "默认值",
|
||||
"Default value placeholder": "不填则默认返回空字符",
|
||||
"Field Description": "字段描述",
|
||||
"Field Name": "字段名",
|
||||
"Field Type": "字段类型",
|
||||
@@ -797,10 +799,14 @@
|
||||
"Field Edit": "字段编辑"
|
||||
},
|
||||
"extract": {
|
||||
"Add field": "新增字段",
|
||||
"Enum Description": "列举出该字段可能的值,每行一个",
|
||||
"Enum Value": "枚举值",
|
||||
"Field Description Placeholder": "姓名/年龄/sql语句……",
|
||||
"Field Setting Title": "提取字段配置"
|
||||
"Field Setting Title": "提取字段配置",
|
||||
"Required": "必须返回",
|
||||
"Required Description": "即使无法提取该字段,也会使用默认值进行返回",
|
||||
"Target field": "目标字段"
|
||||
},
|
||||
"http": {
|
||||
"Add props": "添加参数",
|
||||
@@ -941,6 +947,7 @@
|
||||
"string": "字符串"
|
||||
},
|
||||
"variable": {
|
||||
"External type": "外部传入",
|
||||
"add option": "添加选项",
|
||||
"input type": "文本",
|
||||
"key": "变量 key",
|
||||
|
@@ -186,6 +186,10 @@ const ChatBox = (
|
||||
() => splitGuideModule(userGuideModule),
|
||||
[userGuideModule]
|
||||
);
|
||||
const filterVariableModules = useMemo(
|
||||
() => variableModules.filter((item) => item.type !== VariableInputEnum.external),
|
||||
[variableModules]
|
||||
);
|
||||
|
||||
// compute variable input is finish.
|
||||
const chatForm = useForm<{
|
||||
@@ -200,17 +204,18 @@ const ChatBox = (
|
||||
|
||||
const [variableInputFinish, setVariableInputFinish] = useState(false); // clicked start chat button
|
||||
const variableIsFinish = useMemo(() => {
|
||||
if (!variableModules || variableModules.length === 0 || chatHistory.length > 0) return true;
|
||||
if (!filterVariableModules || filterVariableModules.length === 0 || chatHistory.length > 0)
|
||||
return true;
|
||||
|
||||
for (let i = 0; i < variableModules.length; i++) {
|
||||
const item = variableModules[i];
|
||||
for (let i = 0; i < filterVariableModules.length; i++) {
|
||||
const item = filterVariableModules[i];
|
||||
if (item.required && !variables[item.key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return variableInputFinish;
|
||||
}, [chatHistory.length, variableInputFinish, variableModules, variables]);
|
||||
}, [chatHistory.length, variableInputFinish, filterVariableModules, variables]);
|
||||
|
||||
// 滚动到底部
|
||||
const scrollToBottom = (behavior: 'smooth' | 'auto' = 'smooth') => {
|
||||
@@ -495,7 +500,7 @@ const ChatBox = (
|
||||
getChatHistories: () => chatHistory,
|
||||
resetVariables(e) {
|
||||
const defaultVal: Record<string, any> = {};
|
||||
variableModules?.forEach((item) => {
|
||||
filterVariableModules?.forEach((item) => {
|
||||
defaultVal[item.key] = '';
|
||||
});
|
||||
|
||||
@@ -519,13 +524,13 @@ const ChatBox = (
|
||||
feConfigs?.show_emptyChat &&
|
||||
showEmptyIntro &&
|
||||
chatHistory.length === 0 &&
|
||||
!variableModules?.length &&
|
||||
!filterVariableModules?.length &&
|
||||
!welcomeText,
|
||||
[
|
||||
chatHistory.length,
|
||||
feConfigs?.show_emptyChat,
|
||||
showEmptyIntro,
|
||||
variableModules?.length,
|
||||
filterVariableModules?.length,
|
||||
welcomeText
|
||||
]
|
||||
);
|
||||
@@ -604,10 +609,10 @@ const ChatBox = (
|
||||
{showEmpty && <Empty />}
|
||||
{!!welcomeText && <WelcomeText appAvatar={appAvatar} welcomeText={welcomeText} />}
|
||||
{/* variable input */}
|
||||
{!!variableModules?.length && (
|
||||
{!!filterVariableModules?.length && (
|
||||
<VariableInput
|
||||
appAvatar={appAvatar}
|
||||
variableModules={variableModules}
|
||||
variableModules={filterVariableModules}
|
||||
variableIsFinish={variableIsFinish}
|
||||
chatForm={chatForm}
|
||||
onSubmitVariables={onSubmitVariables}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { ModalContentProps } from '@chakra-ui/react';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import CustomModal from '@fastgpt/web/components/common/MyModal';
|
||||
import CustomModal from '@fastgpt/web/components/common/CustomModal';
|
||||
|
||||
export interface MyModalProps extends ModalContentProps {
|
||||
iconSrc?: string;
|
||||
|
@@ -178,7 +178,7 @@ export const FlowProvider = ({
|
||||
const source = nodes.find((node) => node.id === connect.source)?.data;
|
||||
const sourceType = (() => {
|
||||
if (source?.flowType === FlowNodeTypeEnum.classifyQuestion) {
|
||||
return ModuleIOValueTypeEnum.string;
|
||||
return ModuleIOValueTypeEnum.boolean;
|
||||
}
|
||||
if (source?.flowType === FlowNodeTypeEnum.pluginInput) {
|
||||
return source?.inputs.find((input) => input.key === connect.sourceHandle)?.valueType;
|
||||
@@ -189,7 +189,7 @@ export const FlowProvider = ({
|
||||
const targetType = nodes
|
||||
.find((node) => node.id === connect.target)
|
||||
?.data?.inputs.find((input) => input.key === connect.targetHandle)?.valueType;
|
||||
|
||||
console.log(source, targetType);
|
||||
if (!sourceType || !targetType) {
|
||||
return toast({
|
||||
status: 'warning',
|
||||
|
@@ -25,7 +25,7 @@ import {
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { QuestionOutlineIcon, SmallAddIcon } from '@chakra-ui/icons';
|
||||
import { VariableInputEnum } from '@fastgpt/global/core/module/constants';
|
||||
import { VariableInputEnum, variableMap } from '@fastgpt/global/core/module/constants';
|
||||
import type { VariableItemType } from '@fastgpt/global/core/module/type.d';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import { useForm } from 'react-hook-form';
|
||||
@@ -52,23 +52,12 @@ const VariableEdit = ({
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
|
||||
const VariableTypeList = useMemo(
|
||||
() => [
|
||||
{
|
||||
title: t('core.module.variable.input type'),
|
||||
icon: 'core/app/variable/input',
|
||||
value: VariableInputEnum.input
|
||||
},
|
||||
{
|
||||
title: t('core.module.variable.textarea type'),
|
||||
icon: 'core/app/variable/textarea',
|
||||
value: VariableInputEnum.textarea
|
||||
},
|
||||
{
|
||||
title: t('core.module.variable.select type'),
|
||||
icon: 'core/app/variable/select',
|
||||
value: VariableInputEnum.select
|
||||
}
|
||||
],
|
||||
() =>
|
||||
Object.entries(variableMap).map(([key, value]) => ({
|
||||
title: t(value.title),
|
||||
icon: value.icon,
|
||||
value: key
|
||||
})),
|
||||
[t]
|
||||
);
|
||||
|
||||
@@ -79,9 +68,12 @@ const VariableEdit = ({
|
||||
getValues: getValuesEdit,
|
||||
setValue: setValuesEdit,
|
||||
control: editVariableController,
|
||||
handleSubmit: handleSubmitEdit
|
||||
handleSubmit: handleSubmitEdit,
|
||||
watch
|
||||
} = useForm<{ variable: VariableItemType }>();
|
||||
|
||||
const variableType = watch('variable.type');
|
||||
|
||||
const {
|
||||
fields: selectEnums,
|
||||
append: appendEnums,
|
||||
@@ -140,11 +132,11 @@ const VariableEdit = ({
|
||||
<Table bg={'white'}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th w={'18px !important'} p={0} />
|
||||
<Th>{t('core.module.variable.variable name')}</Th>
|
||||
<Th>{t('core.module.variable.key')}</Th>
|
||||
<Th>{t('common.Require Input')}</Th>
|
||||
<Th></Th>
|
||||
<Th w={'18px !important'} p={0} bg={'myGray.50'} />
|
||||
<Th bg={'myGray.50'}>{t('core.module.variable.variable name')}</Th>
|
||||
<Th bg={'myGray.50'}>{t('core.module.variable.key')}</Th>
|
||||
<Th bg={'myGray.50'}>{t('common.Require Input')}</Th>
|
||||
<Th bg={'myGray.50'}></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
@@ -188,12 +180,15 @@ const VariableEdit = ({
|
||||
title={t('core.module.Variable Setting')}
|
||||
isOpen={isOpenEdit}
|
||||
onClose={onCloseEdit}
|
||||
maxW={['90vw', '500px']}
|
||||
>
|
||||
<ModalBody>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box w={'70px'}>{t('common.Require Input')}</Box>
|
||||
<Switch {...registerEdit('variable.required')} />
|
||||
</Flex>
|
||||
{variableType !== VariableInputEnum.external && (
|
||||
<Flex alignItems={'center'}>
|
||||
<Box w={'70px'}>{t('common.Require Input')}</Box>
|
||||
<Switch {...registerEdit('variable.required')} />
|
||||
</Flex>
|
||||
)}
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box w={'80px'}>{t('core.module.variable.variable name')}</Box>
|
||||
<Input
|
||||
@@ -216,8 +211,8 @@ const VariableEdit = ({
|
||||
</Box>
|
||||
<MyRadio
|
||||
gridGap={4}
|
||||
gridTemplateColumns={'repeat(3,1fr)'}
|
||||
value={getValuesEdit('variable.type')}
|
||||
gridTemplateColumns={'repeat(2,1fr)'}
|
||||
value={variableType}
|
||||
list={VariableTypeList}
|
||||
color={'myGray.600'}
|
||||
hiddenCircle
|
||||
@@ -227,7 +222,14 @@ const VariableEdit = ({
|
||||
}}
|
||||
/>
|
||||
|
||||
{getValuesEdit('variable.type') === VariableInputEnum.input && (
|
||||
{/* desc */}
|
||||
{variableMap[variableType]?.desc && (
|
||||
<Box mt={2} fontSize={'sm'} color={'myGray.500'} whiteSpace={'pre-wrap'}>
|
||||
{t(variableMap[variableType].desc)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{variableType === VariableInputEnum.input && (
|
||||
<>
|
||||
<Box mt={5} mb={2}>
|
||||
{t('core.module.variable.text max length')}
|
||||
@@ -251,7 +253,7 @@ const VariableEdit = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
{getValuesEdit('variable.type') === VariableInputEnum.select && (
|
||||
{variableType === VariableInputEnum.select && (
|
||||
<>
|
||||
<Box mt={5} mb={2}>
|
||||
{t('core.module.variable.variable options')}
|
||||
|
@@ -16,10 +16,11 @@ import { useTranslation } from 'next-i18next';
|
||||
import MyTooltip from '@/components/MyTooltip';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
|
||||
export const defaultField = {
|
||||
export const defaultField: ContextExtractAgentItemType = {
|
||||
required: false,
|
||||
defaultValue: '',
|
||||
desc: '',
|
||||
key: '',
|
||||
required: true,
|
||||
enum: ''
|
||||
};
|
||||
|
||||
@@ -33,9 +34,10 @@ const ExtractFieldModal = ({
|
||||
onSubmit: (data: ContextExtractAgentItemType) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { register, handleSubmit } = useForm<ContextExtractAgentItemType>({
|
||||
const { register, handleSubmit, watch } = useForm<ContextExtractAgentItemType>({
|
||||
defaultValues: defaultField
|
||||
});
|
||||
const required = watch('required');
|
||||
|
||||
return (
|
||||
<MyModal
|
||||
@@ -43,19 +45,41 @@ const ExtractFieldModal = ({
|
||||
iconSrc="/imgs/module/extract.png"
|
||||
title={t('core.module.extract.Field Setting Title')}
|
||||
onClose={onClose}
|
||||
w={['90vw', '500px']}
|
||||
>
|
||||
<ModalBody>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box flex={'0 0 70px'}>{t('common.Require Input')}</Box>
|
||||
<Flex mt={2} alignItems={'center'}>
|
||||
<Flex alignItems={'center'} flex={['0 0 80px', '0 0 100px']}>
|
||||
{t('core.module.extract.Required')}
|
||||
<MyTooltip label={t('core.module.extract.Required Description')} forceShow>
|
||||
<QuestionOutlineIcon ml={1} />
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
<Switch {...register('required')} />
|
||||
</Flex>
|
||||
{required && (
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Default value')}</Box>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
placeholder={t('core.module.Default value placeholder')}
|
||||
{...register('defaultValue')}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 70px'}>{t('core.module.Field key')}</Box>
|
||||
<Input placeholder="name/age/sql" {...register('key', { required: true })} />
|
||||
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Field key')}</Box>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
placeholder="name/age/sql"
|
||||
{...register('key', { required: true })}
|
||||
/>
|
||||
</Flex>
|
||||
<Flex mt={5} alignItems={'center'}>
|
||||
<Box flex={'0 0 70px'}>{t('core.module.Field Description')}</Box>
|
||||
<Box flex={['0 0 80px', '0 0 100px']}>{t('core.module.Field Description')}</Box>
|
||||
<Input
|
||||
bg={'myGray.50'}
|
||||
placeholder={t('core.module.extract.Field Description Placeholder')}
|
||||
{...register('desc', { required: true })}
|
||||
/>
|
||||
@@ -68,14 +92,16 @@ const ExtractFieldModal = ({
|
||||
</MyTooltip>
|
||||
</Flex>
|
||||
|
||||
<Textarea rows={5} placeholder={'apple\npeach\nwatermelon'} {...register('enum')} />
|
||||
<Textarea
|
||||
rows={5}
|
||||
bg={'myGray.50'}
|
||||
placeholder={'apple\npeach\nwatermelon'}
|
||||
{...register('enum')}
|
||||
/>
|
||||
</Box>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button variant={'whiteBase'} mr={3} onClick={onClose}>
|
||||
{t('common.Close')}
|
||||
</Button>
|
||||
<Button onClick={handleSubmit(onSubmit)}>{t('common.Confirm')}</Button>
|
||||
</ModalFooter>
|
||||
</MyModal>
|
||||
|
@@ -1,5 +1,16 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Box, Button, Table, Thead, Tbody, Tr, Th, Td, TableContainer } from '@chakra-ui/react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Table,
|
||||
Thead,
|
||||
Tbody,
|
||||
Tr,
|
||||
Th,
|
||||
Td,
|
||||
TableContainer,
|
||||
Flex
|
||||
} from '@chakra-ui/react';
|
||||
import { NodeProps } from 'reactflow';
|
||||
import { FlowModuleItemType } from '@fastgpt/global/core/module/type.d';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
@@ -36,75 +47,87 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
||||
}: {
|
||||
value?: ContextExtractAgentItemType[];
|
||||
}) => (
|
||||
<Box pt={2}>
|
||||
<Box position={'absolute'} top={0} right={0}>
|
||||
<Box>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box flex={'1 0 0'}>{t('core.module.extract.Target field')}</Box>
|
||||
<Button
|
||||
size={'sm'}
|
||||
variant={'whitePrimary'}
|
||||
leftIcon={<AddIcon fontSize={'10px'} />}
|
||||
onClick={() => setEditExtractField(defaultField)}
|
||||
>
|
||||
新增字段
|
||||
{t('core.module.extract.Add field')}
|
||||
</Button>
|
||||
</Box>
|
||||
<TableContainer>
|
||||
<Table>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>字段 key</Th>
|
||||
<Th>字段描述</Th>
|
||||
<Th>必须</Th>
|
||||
<Th></Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{extractKeys.map((item, index) => (
|
||||
<Tr
|
||||
key={index}
|
||||
position={'relative'}
|
||||
whiteSpace={'pre-wrap'}
|
||||
wordBreak={'break-all'}
|
||||
>
|
||||
<Td>{item.key}</Td>
|
||||
<Td>{item.desc}</Td>
|
||||
<Td>{item.required ? '✔' : ''}</Td>
|
||||
<Td whiteSpace={'nowrap'}>
|
||||
<MyIcon
|
||||
mr={3}
|
||||
name={'common/settingLight'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
setEditExtractField(item);
|
||||
}}
|
||||
/>
|
||||
<MyIcon
|
||||
name={'delete'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
onChangeNode({
|
||||
moduleId,
|
||||
type: 'updateInput',
|
||||
key: ModuleInputKeyEnum.extractKeys,
|
||||
value: {
|
||||
...props,
|
||||
value: extractKeys.filter((extract) => item.key !== extract.key)
|
||||
}
|
||||
});
|
||||
|
||||
onChangeNode({
|
||||
moduleId,
|
||||
type: 'delOutput',
|
||||
key: item.key
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Td>
|
||||
</Flex>
|
||||
<Box
|
||||
mt={2}
|
||||
borderRadius={'md'}
|
||||
overflow={'hidden'}
|
||||
borderWidth={'1px'}
|
||||
borderBottom="none"
|
||||
>
|
||||
<TableContainer>
|
||||
<Table bg={'white'}>
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th bg={'myGray.50'}>字段 key</Th>
|
||||
<Th bg={'myGray.50'}>字段描述</Th>
|
||||
<Th bg={'myGray.50'}>必须</Th>
|
||||
<Th bg={'myGray.50'}></Th>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{extractKeys.map((item, index) => (
|
||||
<Tr
|
||||
key={index}
|
||||
position={'relative'}
|
||||
whiteSpace={'pre-wrap'}
|
||||
wordBreak={'break-all'}
|
||||
>
|
||||
<Td>{item.key}</Td>
|
||||
<Td>{item.desc}</Td>
|
||||
<Td>{item.required ? '✔' : ''}</Td>
|
||||
<Td whiteSpace={'nowrap'}>
|
||||
<MyIcon
|
||||
mr={3}
|
||||
name={'common/settingLight'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
setEditExtractField(item);
|
||||
}}
|
||||
/>
|
||||
<MyIcon
|
||||
name={'delete'}
|
||||
w={'16px'}
|
||||
cursor={'pointer'}
|
||||
onClick={() => {
|
||||
onChangeNode({
|
||||
moduleId,
|
||||
type: 'updateInput',
|
||||
key: ModuleInputKeyEnum.extractKeys,
|
||||
value: {
|
||||
...props,
|
||||
value: extractKeys.filter(
|
||||
(extract) => item.key !== extract.key
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
onChangeNode({
|
||||
moduleId,
|
||||
type: 'delOutput',
|
||||
key: item.key
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}}
|
||||
@@ -142,7 +165,6 @@ const NodeExtract = ({ data }: NodeProps<FlowModuleItemType>) => {
|
||||
const newOutput = {
|
||||
key: data.key,
|
||||
label: `提取结果-${data.desc}`,
|
||||
description: '无法提取时不会返回',
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.source,
|
||||
targets: []
|
||||
|
@@ -31,10 +31,9 @@ export const Prompt_ExtractJson = `你可以从 <对话记录></对话记录>
|
||||
|
||||
<字段说明>
|
||||
1. 下面的 JSON 字符串均按照 JSON Schema 的规则描述。
|
||||
2. key 代表字段名;description 代表字段的描述;required 代表字段是否必须;enum 是可选值,代表可选的 value。
|
||||
3. 如果字段内容为空,你可以返回空字符串。
|
||||
|
||||
{{json}}
|
||||
2. key 代表字段名;description 代表字段的描述;enum 是可选值,代表可选的 value。
|
||||
3. 如果没有可提取的内容,忽略该字段。
|
||||
4. 本次需提取的JSON Schema:{{json}}
|
||||
</字段说明>
|
||||
|
||||
<对话记录>
|
||||
|
@@ -4,7 +4,7 @@ import Script from 'next/script';
|
||||
import Head from 'next/head';
|
||||
import { ChakraProvider, ColorModeScript } from '@chakra-ui/react';
|
||||
import Layout from '@/components/Layout';
|
||||
import { theme } from '@/web/styles/theme';
|
||||
import { theme } from '@fastgpt/web/styles/theme';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import NProgress from 'nprogress'; //nprogress module
|
||||
import Router from 'next/router';
|
||||
|
@@ -31,7 +31,6 @@ import Avatar from '@/components/Avatar';
|
||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||
import VariableEdit from '@/components/core/module/Flow/components/modules/VariableEdit';
|
||||
import MyTextarea from '@/components/common/Textarea/MyTextarea/index';
|
||||
import { DatasetSearchModeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import SelectAiModel from '@/components/Select/SelectAiModel';
|
||||
import PromptEditor from '@fastgpt/web/components/common/Textarea/PromptEditor';
|
||||
import { formatEditorVariablePickerIcon } from '@fastgpt/global/core/module/utils';
|
||||
|
@@ -30,24 +30,29 @@ import { MongoOutLink } from '@fastgpt/service/support/outLink/schema';
|
||||
import { OutLinkWithAppType } from '@fastgpt/global/support/outLink/type';
|
||||
|
||||
const OutLink = ({
|
||||
shareId,
|
||||
chatId,
|
||||
showHistory,
|
||||
authToken,
|
||||
appName,
|
||||
appIntro,
|
||||
appAvatar
|
||||
}: {
|
||||
shareId: string;
|
||||
chatId: string;
|
||||
showHistory: '0' | '1';
|
||||
authToken?: string;
|
||||
appName?: string;
|
||||
appIntro?: string;
|
||||
appAvatar?: string;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const {
|
||||
shareId = '',
|
||||
chatId = '',
|
||||
showHistory = '1',
|
||||
authToken,
|
||||
...customVariables
|
||||
} = router.query as {
|
||||
shareId: string;
|
||||
chatId: string;
|
||||
showHistory: '0' | '1';
|
||||
authToken: string;
|
||||
[key: string]: string;
|
||||
};
|
||||
const { toast } = useToast();
|
||||
const { isOpen: isOpenSlider, onClose: onCloseSlider, onOpen: onOpenSlider } = useDisclosure();
|
||||
const { isPc } = useSystemStore();
|
||||
@@ -56,11 +61,7 @@ const OutLink = ({
|
||||
const initSign = useRef(false);
|
||||
const [isEmbed, setIdEmbed] = useState(true);
|
||||
|
||||
const {
|
||||
localUId,
|
||||
shareChatHistory, // abandon
|
||||
clearLocalHistory // abandon
|
||||
} = useShareChatStore();
|
||||
const { localUId } = useShareChatStore();
|
||||
const {
|
||||
histories,
|
||||
loadHistories,
|
||||
@@ -83,7 +84,10 @@ const OutLink = ({
|
||||
const { responseText, responseData } = await streamFetch({
|
||||
data: {
|
||||
messages: prompts,
|
||||
variables,
|
||||
variables: {
|
||||
...customVariables,
|
||||
...variables
|
||||
},
|
||||
shareId,
|
||||
chatId: completionChatId,
|
||||
outLinkUid
|
||||
@@ -159,6 +163,7 @@ const OutLink = ({
|
||||
},
|
||||
[
|
||||
chatId,
|
||||
customVariables,
|
||||
shareId,
|
||||
outLinkUid,
|
||||
t,
|
||||
@@ -391,9 +396,6 @@ const OutLink = ({
|
||||
|
||||
export async function getServerSideProps(context: any) {
|
||||
const shareId = context?.query?.shareId || '';
|
||||
const chatId = context?.query?.chatId || '';
|
||||
const showHistory = context?.query?.showHistory || '1';
|
||||
const authToken = context?.query?.authToken || '';
|
||||
|
||||
const app = await (async () => {
|
||||
try {
|
||||
@@ -413,13 +415,9 @@ export async function getServerSideProps(context: any) {
|
||||
|
||||
return {
|
||||
props: {
|
||||
shareId,
|
||||
chatId,
|
||||
showHistory,
|
||||
authToken,
|
||||
appName: app?.appId?.name,
|
||||
appAvatar: app?.appId?.avatar,
|
||||
appIntro: app?.appId?.intro,
|
||||
appName: app?.appId?.name || '',
|
||||
appAvatar: app?.appId?.avatar || '',
|
||||
appIntro: app?.appId?.intro || '',
|
||||
...(await serviceSideProps(context))
|
||||
}
|
||||
};
|
||||
|
@@ -85,7 +85,7 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
||||
}
|
||||
setRequesting(false);
|
||||
},
|
||||
[loginSuccess, toast]
|
||||
[loginSuccess, t, toast]
|
||||
);
|
||||
|
||||
return (
|
||||
|
@@ -57,11 +57,10 @@ const Login = () => {
|
||||
|
||||
/* default login type */
|
||||
useEffect(() => {
|
||||
if (!feConfigs.oauth) return;
|
||||
setPageType(
|
||||
feConfigs.oauth?.wechat ? LoginPageTypeEnum.wechat : LoginPageTypeEnum.passwordLogin
|
||||
feConfigs?.oauth?.wechat ? LoginPageTypeEnum.wechat : LoginPageTypeEnum.passwordLogin
|
||||
);
|
||||
}, [feConfigs.oauth, feConfigs.oauth?.wechat]);
|
||||
}, [feConfigs.oauth]);
|
||||
useEffect(() => {
|
||||
clearToken();
|
||||
router.prefetch('/app/list');
|
||||
|
@@ -16,6 +16,7 @@ import { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||
import { getHistories } from '../utils';
|
||||
import { ModelTypeEnum, getLLMModel } from '@fastgpt/service/core/ai/model';
|
||||
import { formatModelChars2Points } from '@fastgpt/service/support/wallet/usage/utils';
|
||||
import json5 from 'json5';
|
||||
|
||||
type Props = ModuleDispatchProps<{
|
||||
[ModuleInputKeyEnum.history]?: ChatItemType[];
|
||||
@@ -64,7 +65,8 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
||||
|
||||
// remove invalid key
|
||||
for (let key in arg) {
|
||||
if (!extractKeys.find((item) => item.key === key)) {
|
||||
const item = extractKeys.find((item) => item.key === key);
|
||||
if (!item) {
|
||||
delete arg[key];
|
||||
}
|
||||
if (arg[key] === '') {
|
||||
@@ -72,12 +74,20 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
||||
}
|
||||
}
|
||||
|
||||
// auto fill required fields
|
||||
extractKeys.forEach((item) => {
|
||||
if (item.required && !arg[item.key]) {
|
||||
arg[item.key] = item.defaultValue || '';
|
||||
}
|
||||
});
|
||||
|
||||
// auth fields
|
||||
let success = !extractKeys.find((item) => !(item.key in arg));
|
||||
// auth empty value
|
||||
if (success) {
|
||||
for (const key in arg) {
|
||||
if (arg[key] === '') {
|
||||
const item = extractKeys.find((item) => item.key === key);
|
||||
if (!item) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
@@ -125,14 +135,8 @@ async function toolChoice({
|
||||
...histories,
|
||||
{
|
||||
obj: ChatRoleEnum.Human,
|
||||
value: `你的任务:
|
||||
value: `你的任务是根据上下文获取适当的 JSON 字符串。要求:
|
||||
"""
|
||||
${description || '根据用户要求获取适当的 JSON 字符串。'}
|
||||
"""
|
||||
|
||||
要求:
|
||||
"""
|
||||
- 如果字段为空,你返回空字符串。
|
||||
- 字符串不要换行。
|
||||
- 结合上下文和当前问题进行获取。
|
||||
"""
|
||||
@@ -167,8 +171,7 @@ ${description || '根据用户要求获取适当的 JSON 字符串。'}
|
||||
description,
|
||||
parameters: {
|
||||
type: 'object',
|
||||
properties,
|
||||
required: extractKeys.filter((item) => item.required).map((item) => item.key)
|
||||
properties
|
||||
}
|
||||
};
|
||||
const tools: any = [
|
||||
@@ -193,7 +196,7 @@ ${description || '根据用户要求获取适当的 JSON 字符串。'}
|
||||
|
||||
const arg: Record<string, any> = (() => {
|
||||
try {
|
||||
return JSON.parse(
|
||||
return json5.parse(
|
||||
response?.choices?.[0]?.message?.tool_calls?.[0]?.function?.arguments || '{}'
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -225,7 +228,7 @@ async function completions({
|
||||
json: extractKeys
|
||||
.map(
|
||||
(item) =>
|
||||
`{"key":"${item.key}", "description":"${item.desc}", "required":${item.required}${
|
||||
`{"key":"${item.key}", "description":"${item.desc}"${
|
||||
item.enum ? `, "enum":"[${item.enum.split('\n')}]"` : ''
|
||||
}}`
|
||||
)
|
||||
@@ -240,7 +243,6 @@ Human: ${content}`
|
||||
userKey: user.openaiAccount,
|
||||
timeout: 480000
|
||||
});
|
||||
|
||||
const data = await ai.chat.completions.create({
|
||||
model: extractModel.model,
|
||||
temperature: 0.01,
|
||||
@@ -260,19 +262,14 @@ Human: ${content}`
|
||||
arg: {}
|
||||
};
|
||||
|
||||
const jsonStr = answer
|
||||
.substring(start, end + 1)
|
||||
.replace(/(\\n|\\)/g, '')
|
||||
.replace(/ /g, '');
|
||||
|
||||
try {
|
||||
return {
|
||||
rawResponse: answer,
|
||||
tokens: countMessagesTokens(messages),
|
||||
|
||||
arg: JSON.parse(jsonStr) as Record<string, any>
|
||||
arg: json5.parse(answer) as Record<string, any>
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return {
|
||||
rawResponse: answer,
|
||||
tokens: countMessagesTokens(messages),
|
||||
|
@@ -1,532 +0,0 @@
|
||||
import { extendTheme, defineStyleConfig, ComponentStyleConfig } from '@chakra-ui/react';
|
||||
import {
|
||||
modalAnatomy,
|
||||
switchAnatomy,
|
||||
selectAnatomy,
|
||||
numberInputAnatomy,
|
||||
checkboxAnatomy
|
||||
} from '@chakra-ui/anatomy';
|
||||
import { createMultiStyleConfigHelpers, defineStyle } from '@chakra-ui/styled-system';
|
||||
|
||||
const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(
|
||||
modalAnatomy.keys
|
||||
);
|
||||
const { definePartsStyle: switchPart, defineMultiStyleConfig: switchMultiStyle } =
|
||||
createMultiStyleConfigHelpers(switchAnatomy.keys);
|
||||
const { definePartsStyle: selectPart, defineMultiStyleConfig: selectMultiStyle } =
|
||||
createMultiStyleConfigHelpers(selectAnatomy.keys);
|
||||
const { definePartsStyle: numInputPart, defineMultiStyleConfig: numInputMultiStyle } =
|
||||
createMultiStyleConfigHelpers(numberInputAnatomy.keys);
|
||||
const { definePartsStyle: checkBoxPart, defineMultiStyleConfig: checkBoxMultiStyle } =
|
||||
createMultiStyleConfigHelpers(checkboxAnatomy.keys);
|
||||
|
||||
// 按键
|
||||
const Button = defineStyleConfig({
|
||||
baseStyle: {
|
||||
_active: {
|
||||
transform: 'scale(0.98)'
|
||||
}
|
||||
},
|
||||
sizes: {
|
||||
xs: {
|
||||
fontSize: 'xs',
|
||||
px: '8px',
|
||||
py: '0',
|
||||
h: '24px',
|
||||
fontWeight: 'normal',
|
||||
borderRadius: '8px'
|
||||
},
|
||||
xsSquare: {
|
||||
fontSize: 'xs',
|
||||
px: '0',
|
||||
py: '0',
|
||||
h: '24px',
|
||||
w: '24px',
|
||||
fontWeight: 'normal',
|
||||
borderRadius: '4px'
|
||||
},
|
||||
sm: {
|
||||
fontSize: 'sm',
|
||||
px: '14px',
|
||||
py: 0,
|
||||
fontWeight: 'normal',
|
||||
h: '30px',
|
||||
borderRadius: '8px'
|
||||
},
|
||||
smSquare: {
|
||||
fontSize: 'sm',
|
||||
px: '0',
|
||||
py: 0,
|
||||
fontWeight: 'normal',
|
||||
h: '30px',
|
||||
w: '30px',
|
||||
borderRadius: '8px'
|
||||
},
|
||||
md: {
|
||||
fontSize: 'md',
|
||||
px: '20px',
|
||||
py: 0,
|
||||
h: '36px',
|
||||
fontWeight: 'normal',
|
||||
borderRadius: '8px'
|
||||
},
|
||||
mdSquare: {
|
||||
fontSize: 'md',
|
||||
px: '0',
|
||||
py: 0,
|
||||
h: '36px',
|
||||
w: '36px',
|
||||
fontWeight: 'normal',
|
||||
borderRadius: '6px'
|
||||
},
|
||||
lg: {
|
||||
fontSize: 'md',
|
||||
px: '20px',
|
||||
py: 0,
|
||||
h: '40px',
|
||||
fontWeight: 'normal',
|
||||
borderRadius: '8px'
|
||||
},
|
||||
lgSquare: {
|
||||
fontSize: 'md',
|
||||
px: '0',
|
||||
py: 0,
|
||||
h: '40px',
|
||||
w: '40px',
|
||||
fontWeight: 'normal',
|
||||
borderRadius: '6px'
|
||||
}
|
||||
},
|
||||
variants: {
|
||||
primary: {
|
||||
bg: 'primary.600',
|
||||
color: 'white',
|
||||
border: 'none',
|
||||
boxShadow: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 1px 2px 0px rgba(19, 51, 107, 0.05)',
|
||||
_hover: {
|
||||
filter: 'brightness(120%)'
|
||||
},
|
||||
_disabled: {
|
||||
bg: 'primary.7 !important'
|
||||
}
|
||||
},
|
||||
primaryOutline: {
|
||||
color: 'primary.600',
|
||||
border: '1px solid',
|
||||
borderColor: 'primary.300',
|
||||
bg: 'white',
|
||||
transition: 'background 0.1s',
|
||||
boxShadow: '1',
|
||||
_hover: {
|
||||
bg: 'primary.1'
|
||||
},
|
||||
_active: {
|
||||
color: 'primary.600'
|
||||
},
|
||||
_disabled: {
|
||||
bg: 'white !important'
|
||||
}
|
||||
},
|
||||
primaryGhost: {
|
||||
color: 'primary.600',
|
||||
border: '1px solid',
|
||||
borderColor: 'primary.300',
|
||||
bg: 'primary.50',
|
||||
transition: 'background 0.1s',
|
||||
boxShadow: '1',
|
||||
_hover: {
|
||||
bg: 'primary.600',
|
||||
color: 'white',
|
||||
borderColor: 'primary.600'
|
||||
},
|
||||
_disabled: {
|
||||
color: 'primary.600 !important',
|
||||
bg: 'primary.50 !important',
|
||||
borderColor: 'primary.300 !important'
|
||||
}
|
||||
},
|
||||
whiteBase: {
|
||||
color: 'myGray.600',
|
||||
border: '1px solid',
|
||||
borderColor: 'myGray.250',
|
||||
bg: 'white',
|
||||
transition: 'background 0.1s',
|
||||
boxShadow: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 1px 2px 0px rgba(19, 51, 107, 0.05)',
|
||||
_hover: {
|
||||
color: 'primary.600'
|
||||
},
|
||||
_active: {
|
||||
color: 'primary.600'
|
||||
},
|
||||
_disabled: {
|
||||
color: 'myGray.600 !important'
|
||||
}
|
||||
},
|
||||
whitePrimary: {
|
||||
color: 'myGray.600',
|
||||
border: '1px solid',
|
||||
borderColor: 'myGray.250',
|
||||
bg: 'white',
|
||||
transition: 'background 0.1s',
|
||||
boxShadow: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 1px 2px 0px rgba(19, 51, 107, 0.05)',
|
||||
_hover: {
|
||||
color: 'primary.600',
|
||||
background: 'primary.1',
|
||||
borderColor: 'primary.300'
|
||||
},
|
||||
_active: {
|
||||
color: 'primary.600'
|
||||
},
|
||||
_disabled: {
|
||||
color: 'myGray.600 !important'
|
||||
}
|
||||
},
|
||||
whiteDanger: {
|
||||
color: 'myGray.600',
|
||||
border: '1px solid',
|
||||
borderColor: 'myGray.250',
|
||||
bg: 'white',
|
||||
transition: 'background 0.1s',
|
||||
boxShadow: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 1px 2px 0px rgba(19, 51, 107, 0.05)',
|
||||
_hover: {
|
||||
color: 'red.600',
|
||||
background: 'red.1',
|
||||
borderColor: 'red.300'
|
||||
},
|
||||
_active: {
|
||||
color: 'red.600'
|
||||
}
|
||||
},
|
||||
grayBase: {
|
||||
bg: 'myGray.150',
|
||||
color: 'myGray.900',
|
||||
_hover: {
|
||||
color: 'primary.600',
|
||||
bg: 'primary.50'
|
||||
},
|
||||
_disabled: {
|
||||
bg: 'myGray.50'
|
||||
}
|
||||
}
|
||||
},
|
||||
defaultProps: {
|
||||
size: 'md',
|
||||
variant: 'primary'
|
||||
}
|
||||
});
|
||||
|
||||
const Input: ComponentStyleConfig = {
|
||||
baseStyle: {
|
||||
fontsize: '1rem'
|
||||
},
|
||||
sizes: {
|
||||
sm: defineStyle({
|
||||
field: {
|
||||
h: '32px',
|
||||
borderRadius: 'md'
|
||||
}
|
||||
}),
|
||||
md: defineStyle({
|
||||
field: {
|
||||
h: '40px',
|
||||
borderRadius: 'md'
|
||||
}
|
||||
})
|
||||
},
|
||||
variants: {
|
||||
outline: {
|
||||
field: {
|
||||
border: '1px solid',
|
||||
borderColor: 'borderColor.low',
|
||||
_focus: {
|
||||
borderColor: 'primary.500',
|
||||
boxShadow: '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)',
|
||||
bg: 'white'
|
||||
},
|
||||
_disabled: {
|
||||
color: 'myGray.400',
|
||||
bg: 'myWhite.300'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
defaultProps: {
|
||||
size: 'md',
|
||||
variant: 'outline'
|
||||
}
|
||||
};
|
||||
|
||||
const NumberInput = numInputMultiStyle({
|
||||
sizes: {
|
||||
sm: defineStyle({
|
||||
field: {
|
||||
h: '32px',
|
||||
borderRadius: 'md'
|
||||
}
|
||||
}),
|
||||
md: defineStyle({
|
||||
field: {
|
||||
h: '40px',
|
||||
borderRadius: 'md'
|
||||
}
|
||||
})
|
||||
},
|
||||
variants: {
|
||||
outline: numInputPart({
|
||||
field: {
|
||||
bg: 'myGray.50',
|
||||
border: '1px solid',
|
||||
borderColor: 'myGray.200',
|
||||
_focus: {
|
||||
borderColor: 'primary.500 !important',
|
||||
boxShadow: '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15) !important',
|
||||
bg: 'transparent'
|
||||
},
|
||||
_disabled: {
|
||||
color: 'myGray.400 !important',
|
||||
bg: 'myWhite.300 !important'
|
||||
}
|
||||
},
|
||||
stepper: {
|
||||
bg: 'transparent',
|
||||
border: 'none',
|
||||
color: 'myGray.600',
|
||||
_active: {
|
||||
color: 'primary.500'
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
defaultProps: {
|
||||
variant: 'outline'
|
||||
}
|
||||
});
|
||||
|
||||
const Textarea: ComponentStyleConfig = {
|
||||
variants: {
|
||||
outline: {
|
||||
border: '1px solid',
|
||||
borderRadius: 'md',
|
||||
borderColor: 'myGray.200',
|
||||
_hover: {
|
||||
borderColor: ''
|
||||
},
|
||||
_focus: {
|
||||
borderColor: 'primary.500',
|
||||
boxShadow: '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)',
|
||||
bg: 'white'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
defaultProps: {
|
||||
size: 'md',
|
||||
variant: 'outline'
|
||||
}
|
||||
};
|
||||
|
||||
const Switch = switchMultiStyle({
|
||||
baseStyle: switchPart({
|
||||
track: {
|
||||
bg: 'myGray.100',
|
||||
borderWidth: '1px',
|
||||
borderColor: 'borders.base',
|
||||
_checked: {
|
||||
bg: 'primary.600'
|
||||
}
|
||||
}
|
||||
}),
|
||||
defaultProps: {
|
||||
size: 'md'
|
||||
}
|
||||
});
|
||||
|
||||
const Select = selectMultiStyle({
|
||||
variants: {
|
||||
outline: selectPart({
|
||||
field: {
|
||||
borderColor: 'myGray.200',
|
||||
_focusWithin: {
|
||||
boxShadow: '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)',
|
||||
borderColor: 'primary.500'
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
const Checkbox = checkBoxMultiStyle({
|
||||
baseStyle: checkBoxPart({
|
||||
label: {
|
||||
fontFamily: 'mono' // change the font family of the label
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// 全局主题
|
||||
export const theme = extendTheme({
|
||||
styles: {
|
||||
global: {
|
||||
'html, body': {
|
||||
fontSize: '14px',
|
||||
color: 'myGray.900',
|
||||
fontWeight: 400,
|
||||
height: '100%',
|
||||
overflow: 'hidden'
|
||||
},
|
||||
a: {
|
||||
color: 'primary.600'
|
||||
}
|
||||
}
|
||||
},
|
||||
colors: {
|
||||
myWhite: {
|
||||
100: '#FEFEFE',
|
||||
200: '#FDFDFE',
|
||||
300: '#FBFBFC',
|
||||
400: '#F8FAFB',
|
||||
500: '#F6F8F9',
|
||||
600: '#F4F6F8',
|
||||
700: '#C3C5C6',
|
||||
800: '#929495',
|
||||
900: '#626263',
|
||||
1000: '#313132'
|
||||
},
|
||||
myGray: {
|
||||
'05': 'rgba(17, 24, 36, 0.05)',
|
||||
1: 'rgba(17, 24, 36, 0.1)',
|
||||
15: 'rgba(17, 24, 36, 0.15)',
|
||||
|
||||
25: '#FBFBFC',
|
||||
50: '#F7F8FA',
|
||||
100: '#F4F4F7',
|
||||
150: '#F0F1F6',
|
||||
200: '#E8EBF0',
|
||||
250: '#DFE2EA',
|
||||
300: '#C4CBD7',
|
||||
400: '#8A95A7',
|
||||
500: '#667085',
|
||||
600: '#485264',
|
||||
700: '#383F50',
|
||||
800: '#1D2532',
|
||||
900: '#111824'
|
||||
},
|
||||
primary: {
|
||||
1: 'rgba(51, 112, 255, 0.1)',
|
||||
'015': 'rgba(51, 112, 255, 0.15)',
|
||||
3: 'rgba(51, 112, 255, 0.3)',
|
||||
5: 'rgba(51, 112, 255, 0.5)',
|
||||
7: 'rgba(51, 112, 255, 0.7)',
|
||||
9: 'rgba(51, 112, 255, 0.9)',
|
||||
|
||||
50: '#F0F4FF',
|
||||
100: '#E1EAFF',
|
||||
200: '#C5D7FF',
|
||||
300: '#94B5FF',
|
||||
400: '#5E8FFF',
|
||||
500: '#487FFF',
|
||||
600: '#3370FF',
|
||||
700: '#2B5FD9',
|
||||
800: '#2450B5',
|
||||
900: '#1D4091'
|
||||
},
|
||||
red: {
|
||||
1: 'rgba(217,45,32,0.1)',
|
||||
3: 'rgba(217,45,32,0.3)',
|
||||
5: 'rgba(217,45,32,0.5)',
|
||||
|
||||
25: '#FFFBFA',
|
||||
50: '#FEF3F2',
|
||||
100: '#FEE4E2',
|
||||
200: '#FECDCA',
|
||||
300: '#FDA29B',
|
||||
400: '#F97066',
|
||||
500: '#F04438',
|
||||
600: '#D92D20',
|
||||
700: '#B42318',
|
||||
800: '#912018',
|
||||
900: '#7A271A'
|
||||
},
|
||||
green: {
|
||||
25: '#F9FEFB',
|
||||
50: '#EDFBF3',
|
||||
100: '#D1FADF',
|
||||
200: '#B9F4D1',
|
||||
300: '#76E4AA',
|
||||
400: '#32D583',
|
||||
500: '#12B76A',
|
||||
600: '#039855',
|
||||
700: '#027A48',
|
||||
800: '#05603A',
|
||||
900: '#054F31'
|
||||
},
|
||||
borderColor: {
|
||||
low: '#E8EBF0',
|
||||
base: '#DFE2EA',
|
||||
high: '#C4CBD7',
|
||||
highest: '#8A95A7'
|
||||
}
|
||||
},
|
||||
fonts: {
|
||||
body: 'PingFang,Noto Sans,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"'
|
||||
},
|
||||
fontSizes: {
|
||||
xs: '0.8rem',
|
||||
sm: '0.93rem',
|
||||
md: '1rem',
|
||||
lg: '1.15rem',
|
||||
xl: '1.3rem',
|
||||
'2xl': '1.45rem',
|
||||
'3xl': '1.6rem',
|
||||
'4xl': '1.75rem',
|
||||
'5xl': '1.9rem',
|
||||
'6xl': '2.05rem'
|
||||
},
|
||||
borders: {
|
||||
sm: '1px solid #E8EBF0',
|
||||
base: '1px solid #DFE2EA',
|
||||
md: '1px solid #DAE0E2',
|
||||
lg: '1px solid #D0E0E2'
|
||||
},
|
||||
radii: {
|
||||
xs: '4px',
|
||||
sm: '6px',
|
||||
md: '8px',
|
||||
lg: '12px',
|
||||
xl: '16px'
|
||||
},
|
||||
shadows: {
|
||||
1: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 1px 2px 0px rgba(19, 51, 107, 0.05)',
|
||||
1.5: '0px 0px 1px 0px rgba(19, 51, 107, 0.15), 0px 1px 2px 0px rgba(19, 51, 107, 0.10)',
|
||||
2: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 4px 4px 0px rgba(19, 51, 107, 0.05)',
|
||||
3: '0px 0px 1px 0px rgba(19, 51, 107, 0.08), 0px 4px 10px 0px rgba(19, 51, 107, 0.08)',
|
||||
3.5: '0px 0px 1px 0px rgba(19, 51, 107, 0.10), 0px 4px 10px 0px rgba(19, 51, 107, 0.10)',
|
||||
4: '0px 0px 1px 0px rgba(19, 51, 107, 0.20), 0px 12px 16px -4px rgba(19, 51, 107, 0.20)',
|
||||
5: '0px 0px 1px 0px rgba(19, 51, 107, 0.15), 0px 20px 24px -8px rgba(19, 51, 107, 0.15)',
|
||||
6: '0px 0px 1px 0px rgba(19, 51, 107, 0.20), 0px 24px 48px -12px rgba(19, 51, 107, 0.20)',
|
||||
7: '0px 0px 1px 0px rgba(19, 51, 107, 0.20), 0px 32px 64px -12px rgba(19, 51, 107, 0.20)',
|
||||
focus: '0px 0px 0px 2.4px rgba(51, 112, 255, 0.15)'
|
||||
},
|
||||
breakpoints: {
|
||||
sm: '900px',
|
||||
md: '1200px',
|
||||
lg: '1500px',
|
||||
xl: '1800px',
|
||||
'2xl': '2100px'
|
||||
},
|
||||
lgColor: {
|
||||
activeBlueGradient: 'linear-gradient(to bottom right, #d6e8ff 0%, #f0f7ff 100%)',
|
||||
hoverBlueGradient: 'linear-gradient(to top left, #d6e8ff 0%, #f0f7ff 100%)',
|
||||
primary: 'linear-gradient(to bottom right, #2152d9 0%,#3370ff 40%, #4e83fd 100%)',
|
||||
primary2: 'linear-gradient(to bottom right, #2152d9 0%,#3370ff 30%,#4e83fd 80%, #85b1ff 100%)'
|
||||
},
|
||||
components: {
|
||||
Button,
|
||||
Input,
|
||||
Textarea,
|
||||
Switch,
|
||||
Select,
|
||||
NumberInput,
|
||||
Checkbox
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user