diff --git a/docSite/content/docs/development/docker.md b/docSite/content/docs/development/docker.md index 930409cf142..2c21163cbcb 100644 --- a/docSite/content/docs/development/docker.md +++ b/docSite/content/docs/development/docker.md @@ -99,10 +99,7 @@ curl -O https://raw.githubusercontent.com/labring/FastGPT/main/projects/app/data 在 docker-compose.yml 同级目录下执行 ```bash -# 进入项目目录 -cd 项目目录 # 启动容器 -docker-compose pull docker-compose up -d ``` @@ -122,19 +119,20 @@ docker-compose up -d ## FAQ -### Mongo 启动失败 +### Mongo 副本集自动初始化失败 最新的 docker-compose 示例优化 Mongo 副本集初始化,实现了全自动。目前在 unbuntu20,22 centos7, wsl2, mac, window 均通过测试。如果你的环境特殊,可以手动初始化副本集: -1. 终端中执行: +1. 终端中执行下面命令,创建mongo密钥: ```bash openssl rand -base64 756 > ./mongodb.key chmod 600 ./mongodb.key +# 修改密钥权限,部分系统是admin,部分是root chown 999:root ./mongodb.key ``` -2. 修改 docker-compose.yml: +2. 修改 docker-compose.yml,挂载密钥 ```yml mongo: @@ -164,7 +162,6 @@ docker-compose up -d 4. 进入容器执行副本集合初始化 - ```bash # 查看 mongo 容器是否正常运行 docker ps @@ -174,7 +171,7 @@ docker exec -it mongo bash # 连接数据库(这里要填Mongo的用户名和密码) mongo -u myusername -p mypassword --authenticationDatabase admin -# 初始化副本集。如果需要外网访问,mongo:27017 可以改成 ip:27017。但是需要同时修改 FastGPT 连接的参数(MONGODB_URI=mongodb://myname:mypassword@mongo:27017/fastgpt?authSource=admin => MONGODB_URI=mongodb://myname:mypassword@ip:27017/fastgpt?authSource=admin) +# 初始化副本集。如果需要外网访问,mongo:27017 。如果需要外网访问,需要增加Mongo连接参数:directConnection=true rs.initiate({ _id: "rs0", members: [ @@ -262,10 +259,10 @@ mongo连接失败,查看mongo的运行状态对应日志。 可能原因: -1. mongo 服务有没有起来(有些 cpu 不支持 AVX,无法用 mongo5,需要换成 mongo4.x,可以dockerhub找个最新的4.x,修改镜像版本,重新运行) -2. 环境变量(账号密码,注意host和port) -3. 副本集启动失败。 +1. mongo 服务有没有起来(有些 cpu 不支持 AVX,无法用 mongo5,需要换成 mongo4.x,可以docker hub找个最新的4.x,修改镜像版本,重新运行) +2. 连接数据库的环境变量填写错误(账号密码,注意host和port,非容器网络连接,需要用公网ip并加上 directConnection=true) +3. 副本集启动失败。导致容器一直重启。 ### 首次部署,root用户提示未注册 -没有启动 Mongo 副本集模式。 +日志会有错误提示。大概率是没有启动 Mongo 副本集模式。 diff --git a/packages/global/core/module/template/system/datasetSearch.ts b/packages/global/core/module/template/system/datasetSearch.ts index d9d8ede3f00..5e93184c2f8 100644 --- a/packages/global/core/module/template/system/datasetSearch.ts +++ b/packages/global/core/module/template/system/datasetSearch.ts @@ -15,7 +15,7 @@ import { Output_Template_Finish, Output_Template_UserChatInput } from '../output import { DatasetSearchModeEnum } from '../../../dataset/constants'; export const Dataset_SEARCH_DESC = - '调用“语义检索”和“全文检索”能力,从数据库中查找“可能”与问题相关的内容'; + '调用“语义检索”和“全文检索”能力,从“知识库”中查找可能与问题相关的参考内容'; export const DatasetSearchModule: FlowNodeTemplateType = { id: FlowNodeTypeEnum.datasetSearchNode, diff --git a/projects/app/public/locales/en/common.json b/projects/app/public/locales/en/common.json index 94a98986ed8..a2fdd40181b 100644 --- a/projects/app/public/locales/en/common.json +++ b/projects/app/public/locales/en/common.json @@ -837,8 +837,6 @@ "Add props": "Add props", "AppId": "appId", "ChatId": "chatId", - "curl import": "curl Import", - "curl import placeholder": "Please enter the curl format content, and the request information for the first interface will be extracted.", "Current time": "Current time", "Histories": "histories", "Key already exists": "Key already exists", @@ -849,6 +847,8 @@ "ResponseChatItemId": "Ai response id", "Url and params have been split": "Path parameters are automatically added to Params", "Variables": "Global variables", + "curl import": "curl Import", + "curl import placeholder": "Please enter the curl format content, and the request information for the first interface will be extracted.", "params": "" }, "input": { @@ -1005,6 +1005,7 @@ "Custom headers": "Custom Headers", "Delete http plugin": "Are you sure to delete this group of HTTP plug-ins? All plug-ins in the directory are deleted.", "Get Plugin Module Detail Failed": "Load plugin failed", + "Http plugin intro placeholder": "Only for demonstration, no practical effect", "Intro placeholder": "If the plug-in is called as a tool, the introduction is used as the prompt word." }, "shareChat": { @@ -1223,7 +1224,7 @@ "Get Plugin Module Detail Failed": "Get plugin detail failed", "HTTP Plugin": "HTTP plugin", "Import Plugin": "Import HTTP plugin", - "Import from URL": "Import from URL", + "Import from URL": "Import from URL. https://xxxx", "Intro": "Plugin Intro", "Invalid Schema": "Invalid Schema", "Invalid URL": "Invalid URL", @@ -1259,6 +1260,7 @@ "Usage": "Usage" }, "outlink": { + "Delete link tip": "Are you sure to delete this no-sign link? After deletion, the link will be invalid immediately and the session log will still be retained. Please confirm!", "Max usage points": "Max usage", "Max usage points tip": "The maximum number of credits allowed for this link will not be used. -1 indicates no limit.", "Usage points": "Usage points", diff --git a/projects/app/public/locales/zh/common.json b/projects/app/public/locales/zh/common.json index d2fc709bb38..406e24bcbec 100644 --- a/projects/app/public/locales/zh/common.json +++ b/projects/app/public/locales/zh/common.json @@ -582,7 +582,8 @@ "success": "开始同步" } }, - "training": {} + "training": { + } }, "data": { "Auxiliary Data": "辅助数据", @@ -838,8 +839,6 @@ "Add props": "添加参数", "AppId": "应用的ID", "ChatId": "当前对话ID", - "curl import": "curl 导入", - "curl import placeholder": "请输入 curl 格式内容,将会提取第一个接口的请求信息。", "Current time": "当前时间", "Histories": "历史纪录,最多取10条", "Key already exists": "Key 已经存在", @@ -850,6 +849,8 @@ "ResponseChatItemId": "AI回复的ID", "Url and params have been split": "路径参数已被自动加入 Params 中", "Variables": "全局变量", + "curl import": "curl 导入", + "curl import placeholder": "请输入 curl 格式内容,将会提取第一个接口的请求信息。", "params": "Params" }, "input": { @@ -1006,6 +1007,7 @@ "Custom headers": "自定义请求头", "Delete http plugin": "确认删除该组HTTP插件?会删除该目录下所有插件。", "Get Plugin Module Detail Failed": "加载插件异常", + "Http plugin intro placeholder": "仅做展示,无实际效果", "Intro placeholder": "如果该插件作为工具被调用,则会使用该介绍作为提示词。" }, "shareChat": { @@ -1224,7 +1226,7 @@ "Get Plugin Module Detail Failed": "获取插件信息异常", "HTTP Plugin": "HTTP 插件", "Import Plugin": "导入 HTTP 插件", - "Import from URL": "URL 导入", + "Import from URL": "从URL导入。https://xxxx", "Intro": "插件介绍", "Invalid Schema": "Schema 无效", "Invalid URL": "URL 无效", @@ -1260,6 +1262,7 @@ "Usage": "已用额度(¥)" }, "outlink": { + "Delete link tip": "确认删除该免登录链接?删除后,该链接将会立即失效,对话日志仍会保留,请确认!", "Max usage points": "积分上限", "Max usage points tip": "该链接最多允许使用多少积分,超出后将无法使用。-1 代表无限制。", "Usage points": "积分消耗", diff --git a/projects/app/src/components/MyMenu/index.tsx b/projects/app/src/components/MyMenu/index.tsx index 6ce582ddd01..e593ea1edb2 100644 --- a/projects/app/src/components/MyMenu/index.tsx +++ b/projects/app/src/components/MyMenu/index.tsx @@ -1,7 +1,17 @@ import React, { useRef, useState } from 'react'; -import { Menu, MenuList, MenuItem, Box, useOutsideClick, MenuButton } from '@chakra-ui/react'; +import { + Menu, + MenuList, + MenuItem, + Box, + useOutsideClick, + MenuButton, + MenuItemProps +} from '@chakra-ui/react'; import MyIcon from '@fastgpt/web/components/common/Icon'; +type MenuItemType = 'primary' | 'danger'; + interface Props { width?: number | string; offset?: [number, number]; @@ -11,6 +21,7 @@ interface Props { isActive?: boolean; label: string | React.ReactNode; icon?: string; + type?: MenuItemType; onClick: () => any; }[]; } @@ -22,15 +33,25 @@ const MyMenu = ({ Button, menuList }: Props) => { - const menuItemStyles = { + const typeMapStyle: Record = { + primary: { + _hover: { + backgroundColor: 'primary.50', + color: 'primary.600' + } + }, + danger: { + _hover: { + color: 'red.600', + background: 'red.1' + } + } + }; + const menuItemStyles: MenuItemProps = { borderRadius: 'sm', py: 3, display: 'flex', - alignItems: 'center', - _hover: { - backgroundColor: 'myGray.05', - color: 'primary.600' - } + alignItems: 'center' }; const ref = useRef(null); const closeTimer = useRef(); @@ -92,6 +113,7 @@ const MyMenu = ({ { e.stopPropagation(); setIsOpen(false); diff --git a/projects/app/src/components/core/module/Flow/components/modules/VariableEdit.tsx b/projects/app/src/components/core/module/Flow/components/modules/VariableEdit.tsx index a5616c6c565..fb3ea556e45 100644 --- a/projects/app/src/components/core/module/Flow/components/modules/VariableEdit.tsx +++ b/projects/app/src/components/core/module/Flow/components/modules/VariableEdit.tsx @@ -124,12 +124,12 @@ const VariableEdit = ({ - - - - - + + + + + diff --git a/projects/app/src/components/support/apikey/Table.tsx b/projects/app/src/components/support/apikey/Table.tsx index 7632b24dfa8..03783ff9f69 100644 --- a/projects/app/src/components/support/apikey/Table.tsx +++ b/projects/app/src/components/support/apikey/Table.tsx @@ -18,7 +18,8 @@ import { MenuList, MenuItem, MenuButton, - Menu + Menu, + IconButton } from '@chakra-ui/react'; import { getOpenApiKeys, @@ -41,6 +42,7 @@ import { useRequest } from '@/web/common/hooks/useRequest'; import MyTooltip from '@/components/MyTooltip'; import { getDocPath } from '@/web/common/system/doc'; import MyMenu from '@/components/MyMenu'; +import { useConfirm } from '@/web/common/hooks/useConfirm'; type EditProps = EditApiKeyProps & { _id?: string }; const defaultEditData: EditProps = { @@ -59,6 +61,10 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => { const [baseUrl, setBaseUrl] = useState('https://fastgpt.in/api'); const [editData, setEditData] = useState(); const [apiKey, setApiKey] = useState(''); + const { ConfirmModal, openConfirm } = useConfirm({ + type: 'delete', + content: '确认删除该API密钥?删除后该密钥立即失效,对应的对话日志不会删除,请确认!' + }); const { mutate: onclickRemove, isLoading: isDeleting } = useMutation({ mutationFn: async (id: string) => delOpenApiById(id), @@ -181,13 +187,12 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => { } name={'more'} - w={'14px'} - p={2} - _hover={{ bg: 'myWhite.600 ' }} - cursor={'pointer'} - borderRadius={'md'} + variant={'whitePrimary'} + size={'sm'} + aria-label={''} /> } menuList={[ @@ -205,7 +210,8 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => { { label: t('common.Delete'), icon: 'delete', - onClick: () => onclickRemove(_id) + type: 'danger', + onClick: openConfirm(() => onclickRemove(_id)) } ]} /> @@ -216,6 +222,7 @@ const ApiKeyTable = ({ tips, appId }: { tips: string; appId?: string }) => {
- {t('core.module.variable.variable name')}{t('core.module.variable.key')}{t('common.Require Input')}
+ {t('core.module.variable.variable name')}{t('core.module.variable.key')}{t('common.Require Input')}
+ {!!editData && ( { }} /> )} + ) { try { const apiURL = req.body.url as string; - const api = await (SwaggerParser as any).validate(apiURL); + const api = await SwaggerParser.validate(apiURL); return jsonRes(res, { data: api diff --git a/projects/app/src/pages/app/detail/components/OutLink/SelectUsingWayModal.tsx b/projects/app/src/pages/app/detail/components/OutLink/SelectUsingWayModal.tsx index 578a6cb14fc..a4f2447776e 100644 --- a/projects/app/src/pages/app/detail/components/OutLink/SelectUsingWayModal.tsx +++ b/projects/app/src/pages/app/detail/components/OutLink/SelectUsingWayModal.tsx @@ -102,7 +102,10 @@ const SelectUsingWayModal = ({ share, onClose }: { share: OutLinkSchema; onClose data-open-icon="${getValues('scriptOpenIcon')}" data-close-icon="${getValues('scriptCloseIcon')}" defer -/>` +/> +` } }; diff --git a/projects/app/src/pages/app/detail/components/OutLink/Share.tsx b/projects/app/src/pages/app/detail/components/OutLink/Share.tsx index d5f6b08558d..b8ceee3d416 100644 --- a/projects/app/src/pages/app/detail/components/OutLink/Share.tsx +++ b/projects/app/src/pages/app/detail/components/OutLink/Share.tsx @@ -14,7 +14,8 @@ import { ModalBody, Input, Switch, - Link + Link, + IconButton } from '@chakra-ui/react'; import { QuestionOutlineIcon } from '@chakra-ui/icons'; import MyIcon from '@fastgpt/web/components/common/Icon'; @@ -42,6 +43,7 @@ import dayjs from 'dayjs'; import { getDocPath } from '@/web/common/system/doc'; import dynamic from 'next/dynamic'; import MyMenu from '@/components/MyMenu'; +import { useConfirm } from '@/web/common/hooks/useConfirm'; const SelectUsingWayModal = dynamic(() => import('./SelectUsingWayModal')); @@ -53,6 +55,10 @@ const Share = ({ appId }: { appId: string }) => { const [editLinkData, setEditLinkData] = useState(); const [selectedLinkData, setSelectedLinkData] = useState(); const { toast } = useToast(); + const { ConfirmModal, openConfirm } = useConfirm({ + content: t('support.outlink.Delete link tip'), + type: 'delete' + }); const { isFetching, @@ -130,25 +136,25 @@ const Share = ({ appId }: { appId: string }) => { )} {item.lastTime ? formatTimeToChatTime(item.lastTime) : t('common.Un used')} + } name={'more'} - _hover={{ bg: 'myGray.100 ' }} - cursor={'pointer'} - borderRadius={'md'} - w={'14px'} - p={2} + variant={'whiteBase'} + size={'sm'} + aria-label={''} /> } menuList={[ - { - label: t('core.app.outLink.Select Mode'), - icon: 'copy', - onClick: () => { - setSelectedLinkData(item); - } - }, { label: t('common.Edit'), icon: 'edit', @@ -163,7 +169,8 @@ const Share = ({ appId }: { appId: string }) => { { label: t('common.Delete'), icon: 'delete', - onClick: async () => { + type: 'danger', + onClick: openConfirm(async () => { setIsLoading(true); try { await delShareChatById(item._id); @@ -172,7 +179,7 @@ const Share = ({ appId }: { appId: string }) => { console.log(error); } setIsLoading(false); - } + }) } ]} /> @@ -219,6 +226,7 @@ const Share = ({ appId }: { appId: string }) => { onClose={() => setSelectedLinkData(undefined)} /> )} + ); diff --git a/projects/app/src/pages/plugin/list/component/HttpPluginEditModal.tsx b/projects/app/src/pages/plugin/list/component/HttpPluginEditModal.tsx index edd33a951c4..33187e056c5 100644 --- a/projects/app/src/pages/plugin/list/component/HttpPluginEditModal.tsx +++ b/projects/app/src/pages/plugin/list/component/HttpPluginEditModal.tsx @@ -100,12 +100,6 @@ const HttpPluginEditModal = ({ } }, [apiSchemaStr, t, toast]); - const { - isOpen: isOpenUrlImport, - onOpen: onOpenUrlImport, - onClose: onCloseUrlImport - } = useDisclosure(); - const { mutate: onCreate, isLoading: isCreating } = useRequest({ mutationFn: async (data: CreateOnePluginParams) => { return postCreatePlugin(data); @@ -194,8 +188,6 @@ const HttpPluginEditModal = ({ const schema = await getApiSchemaByUrl(schemaUrl); setValue('metadata.apiSchemaStr', JSON.stringify(schema, null, 2)); - - onCloseUrlImport(); }, errorToast: t('plugin.Invalid Schema') }); @@ -251,7 +243,13 @@ const HttpPluginEditModal = ({ {t('plugin.Intro')} -