From e247545afa8ebd80d52ddfc540f8c78bb73344ac Mon Sep 17 00:00:00 2001
From: Archer <545436317@qq.com>
Date: Wed, 26 Jun 2024 12:51:36 +0800
Subject: [PATCH] 4.8.5 perf (#1854)
* update yml
* perf: chat slider
* perf: workflow name
* i18n
* fix: ts
* fix: ts
---
.../zh-cn/docs/development/upgrading/485.md | 9 ++--
files/docker/docker-compose-milvus.yml | 1 +
files/docker/docker-compose-pgvector.yml | 1 +
files/docker/docker-compose-zilliz.yml | 1 +
packages/web/i18n/zh/common.json | 5 +-
.../common/folder/SelectOneResource.tsx | 2 +-
.../detail/components/SimpleApp/AppCard.tsx | 4 +-
.../Flow/NodeTemplatesModal.tsx | 51 ++++++++++++++++---
.../Flow/hooks/useKeyboard.tsx | 9 +++-
.../Flow/hooks/useUtils.tsx | 42 +++++++++++++++
.../Flow/nodes/render/NodeCard.tsx | 13 +++--
.../src/pages/app/list/components/List.tsx | 19 ++++---
projects/app/src/pages/app/list/index.tsx | 2 +-
.../chat/components/ChatHistorySlider.tsx | 5 +-
projects/app/src/web/core/workflow/utils.ts | 5 +-
15 files changed, 136 insertions(+), 33 deletions(-)
create mode 100644 projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useUtils.tsx
diff --git a/docSite/content/zh-cn/docs/development/upgrading/485.md b/docSite/content/zh-cn/docs/development/upgrading/485.md
index 6525465a7d2..2af99ec2592 100644
--- a/docSite/content/zh-cn/docs/development/upgrading/485.md
+++ b/docSite/content/zh-cn/docs/development/upgrading/485.md
@@ -53,7 +53,8 @@ curl --location --request POST 'https://{{host}}/api/admin/init/485' \
7. 优化 - 问答拆分/手动录入,当有`a`字段时,自动将`q`作为补充索引。
8. 优化 - 对话框页面代码
9. 修复 - SSR渲染
-10. 修复 - 定时任务无法实际关闭
-11. 修复 - 输入引导特殊字符导致正则报错
-12. 修复 - 文件包含特殊字符`%`,且为转义时会导致页面崩溃
-13. 修复 - 自定义输入选择知识库引用时页面崩溃
\ No newline at end of file
+10. 优化 - 工作流新节点自动增加序号名
+11. 修复 - 定时任务无法实际关闭
+12. 修复 - 输入引导特殊字符导致正则报错
+13. 修复 - 文件包含特殊字符`%`,且为转义时会导致页面崩溃
+14. 修复 - 自定义输入选择知识库引用时页面崩溃
\ No newline at end of file
diff --git a/files/docker/docker-compose-milvus.yml b/files/docker/docker-compose-milvus.yml
index e1cc47db922..9a201817f67 100644
--- a/files/docker/docker-compose-milvus.yml
+++ b/files/docker/docker-compose-milvus.yml
@@ -179,6 +179,7 @@ services:
oneapi:
container_name: oneapi
image: ghcr.io/songquanpeng/one-api:latest
+ # image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
ports:
- 3001:3000
depends_on:
diff --git a/files/docker/docker-compose-pgvector.yml b/files/docker/docker-compose-pgvector.yml
index a5098e69eb9..4699690b3b5 100644
--- a/files/docker/docker-compose-pgvector.yml
+++ b/files/docker/docker-compose-pgvector.yml
@@ -136,6 +136,7 @@ services:
oneapi:
container_name: oneapi
image: ghcr.io/songquanpeng/one-api:latest
+ # image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
ports:
- 3001:3000
depends_on:
diff --git a/files/docker/docker-compose-zilliz.yml b/files/docker/docker-compose-zilliz.yml
index db1192e4088..aa15b54b66e 100644
--- a/files/docker/docker-compose-zilliz.yml
+++ b/files/docker/docker-compose-zilliz.yml
@@ -117,6 +117,7 @@ services:
oneapi:
container_name: oneapi
image: ghcr.io/songquanpeng/one-api:latest
+ # image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
ports:
- 3001:3000
depends_on:
diff --git a/packages/web/i18n/zh/common.json b/packages/web/i18n/zh/common.json
index 49b46b557f9..82b7c382416 100644
--- a/packages/web/i18n/zh/common.json
+++ b/packages/web/i18n/zh/common.json
@@ -596,8 +596,7 @@
"success": "开始同步"
}
},
- "training": {
- }
+ "training": {}
},
"data": {
"Auxiliary Data": "辅助数据",
@@ -1461,7 +1460,7 @@
"Upgrade plan": "升级套餐",
"function": {
"History store": "{{amount}} 天对话记录保留",
- "Max app": "{{amount}} 个应用",
+ "Max app": "{{amount}} 个应用&插件",
"Max dataset": "{{amount}} 个知识库",
"Max dataset size": "{{amount}} 组知识库索引",
"Max members": "{{amount}} 个团队成员",
diff --git a/projects/app/src/components/common/folder/SelectOneResource.tsx b/projects/app/src/components/common/folder/SelectOneResource.tsx
index 3e71a4526de..2e1a6a61dde 100644
--- a/projects/app/src/components/common/folder/SelectOneResource.tsx
+++ b/projects/app/src/components/common/folder/SelectOneResource.tsx
@@ -136,7 +136,7 @@ const SelectOneResource = ({
)}
-
+
{item.name}
diff --git a/projects/app/src/pages/app/detail/components/SimpleApp/AppCard.tsx b/projects/app/src/pages/app/detail/components/SimpleApp/AppCard.tsx
index 1d710bd2c43..7d2862ffa8f 100644
--- a/projects/app/src/pages/app/detail/components/SimpleApp/AppCard.tsx
+++ b/projects/app/src/pages/app/detail/components/SimpleApp/AppCard.tsx
@@ -87,7 +87,7 @@ const AppCard = () => {
>
{appDetail.intro || t('core.app.tip.Add a intro to app')}
-
+
diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx
index c4cb490f8c9..5ca5d2f5714 100644
--- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx
+++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx
@@ -29,6 +29,7 @@ import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
import MyBox from '@fastgpt/web/components/common/MyBox';
import FolderPath from '@/components/common/folder/Path';
import { getAppFolderPath } from '@/web/core/app/api/app';
+import { useWorkflowUtils } from './hooks/useUtils';
type ModuleTemplateListProps = {
isOpen: boolean;
@@ -59,6 +60,13 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
WorkflowContext,
(v) => v
);
+ const [pluginBuffer, setPluginBuffer] = useState<{
+ systemPlugin: FlowNodeTemplateType[];
+ teamPlugin: FlowNodeTemplateType[];
+ }>({
+ [TemplateTypeEnum.systemPlugin]: [],
+ [TemplateTypeEnum.teamPlugin]: []
+ });
const [templateType, setTemplateType] = useState(TemplateTypeEnum.basic);
@@ -85,14 +93,34 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => {
});
}
if (templateType === TemplateTypeEnum.systemPlugin) {
- return getSystemPlugTemplates();
+ if (pluginBuffer.systemPlugin.length === 0) {
+ return getSystemPlugTemplates().then((res) => {
+ setPluginBuffer((state) => ({
+ ...state,
+ systemPlugin: res
+ }));
+ return res;
+ });
+ } else {
+ return pluginBuffer.systemPlugin;
+ }
}
if (templateType === TemplateTypeEnum.teamPlugin) {
- return getTeamPlugTemplates({
- parentId,
- searchKey,
- type: [AppTypeEnum.folder, AppTypeEnum.httpPlugin, AppTypeEnum.plugin]
- });
+ if (pluginBuffer.teamPlugin.length === 0) {
+ return getTeamPlugTemplates({
+ parentId,
+ searchKey,
+ type: [AppTypeEnum.folder, AppTypeEnum.httpPlugin, AppTypeEnum.plugin]
+ }).then((res) => {
+ setPluginBuffer((state) => ({
+ ...state,
+ teamPlugin: res
+ }));
+ return res;
+ });
+ } else {
+ return pluginBuffer.teamPlugin;
+ }
}
return [];
},
@@ -240,6 +268,7 @@ const RenderList = React.memo(function RenderList({
const { toast } = useToast();
const reactFlowWrapper = useContextSelector(WorkflowContext, (v) => v.reactFlowWrapper);
const setNodes = useContextSelector(WorkflowContext, (v) => v.setNodes);
+ const { computedNewNodeName } = useWorkflowUtils();
const formatTemplates = useMemo(() => {
const copy: nodeTemplateListType = JSON.parse(JSON.stringify(workflowNodeTemplateList(t)));
@@ -266,6 +295,8 @@ const RenderList = React.memo(function RenderList({
setLoading(false);
return res;
}
+
+ // base node
return { ...template };
} catch (e) {
toast({
@@ -284,7 +315,11 @@ const RenderList = React.memo(function RenderList({
const node = nodeTemplate2FlowNode({
template: {
...templateNode,
- name: t(templateNode.name),
+ name: computedNewNodeName({
+ templateName: t(templateNode.name),
+ flowNodeType: templateNode.flowNodeType,
+ pluginId: templateNode.pluginId
+ }),
intro: t(templateNode.intro || '')
},
position: { x: mouseX, y: mouseY - 20 },
@@ -301,7 +336,7 @@ const RenderList = React.memo(function RenderList({
.concat(node)
);
},
- [reactFlowWrapper, setLoading, setNodes, t, toast, x, y, zoom]
+ [computedNewNodeName, reactFlowWrapper, setLoading, setNodes, t, toast, x, y, zoom]
);
const Render = useMemo(() => {
diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useKeyboard.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useKeyboard.tsx
index ef8d06443be..0d44ebba400 100644
--- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useKeyboard.tsx
+++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useKeyboard.tsx
@@ -6,11 +6,13 @@ import { Node } from 'reactflow';
import { FlowNodeItemType } from '@fastgpt/global/core/workflow/type';
import { useContextSelector } from 'use-context-selector';
import { WorkflowContext, getWorkflowStore } from '../../context';
+import { useWorkflowUtils } from './useUtils';
export const useKeyboard = () => {
const { t } = useTranslation();
const { setNodes, onSaveWorkflow } = useContextSelector(WorkflowContext, (v) => v);
const { copyData } = useCopyData();
+ const { computedNewNodeName } = useWorkflowUtils();
const [isDowningCtrl, setIsDowningCtrl] = useState(false);
@@ -56,6 +58,11 @@ export const useKeyboard = () => {
id: nodeId,
data: {
...item.data,
+ name: computedNewNodeName({
+ templateName: item.data?.name || '',
+ flowNodeType: item.data?.flowNodeType || '',
+ pluginId: item.data?.pluginId
+ }),
nodeId
},
position: {
@@ -75,7 +82,7 @@ export const useKeyboard = () => {
.concat(newNodes)
);
} catch (error) {}
- }, [hasInputtingElement, setNodes]);
+ }, [computedNewNodeName, hasInputtingElement, setNodes]);
const handleKeyDown = useCallback(
(event: KeyboardEvent) => {
diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useUtils.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useUtils.tsx
new file mode 100644
index 00000000000..f0d973c6f10
--- /dev/null
+++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/hooks/useUtils.tsx
@@ -0,0 +1,42 @@
+import { useContextSelector } from 'use-context-selector';
+import { WorkflowContext } from '../../context';
+import { useTranslation } from 'next-i18next';
+import { useCallback } from 'react';
+import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
+
+export const useWorkflowUtils = () => {
+ const { t } = useTranslation();
+ const nodeList = useContextSelector(WorkflowContext, (v) => v.nodeList);
+
+ const computedNewNodeName = useCallback(
+ ({
+ templateName,
+ flowNodeType,
+ pluginId
+ }: {
+ templateName: string;
+ flowNodeType: FlowNodeTypeEnum;
+ pluginId?: string;
+ }) => {
+ const nodeLength = nodeList.filter((node) => {
+ if (node.flowNodeType === flowNodeType) {
+ if (node.flowNodeType === FlowNodeTypeEnum.pluginModule) {
+ return node.pluginId === pluginId;
+ } else {
+ return true;
+ }
+ }
+ }).length;
+ return nodeLength > 0 ? `${templateName}#${nodeLength + 1}` : templateName;
+ },
+ [nodeList]
+ );
+
+ return {
+ computedNewNodeName
+ };
+};
+
+export default function Dom() {
+ return <>>;
+}
diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx
index 97ea5aa36ca..589e13cd36e 100644
--- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx
+++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/render/NodeCard.tsx
@@ -27,6 +27,7 @@ import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
import { useSystemStore } from '@/web/common/system/useSystemStore';
import { useMount } from 'ahooks';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
+import { useWorkflowUtils } from '../../hooks/useUtils';
type Props = FlowNodeItemType & {
children?: React.ReactNode | React.ReactNode[] | string;
@@ -292,6 +293,7 @@ const MenuRender = React.memo(function MenuRender({
const setNodes = useContextSelector(WorkflowContext, (v) => v.setNodes);
const setEdges = useContextSelector(WorkflowContext, (v) => v.setEdges);
+ const { computedNewNodeName } = useWorkflowUtils();
const onCopyNode = useCallback(
(nodeId: string) => {
@@ -300,7 +302,11 @@ const MenuRender = React.memo(function MenuRender({
if (!node) return state;
const template = {
avatar: node.data.avatar,
- name: node.data.name,
+ name: computedNewNodeName({
+ templateName: node.data.name,
+ flowNodeType: node.data.flowNodeType,
+ pluginId: node.data.pluginId
+ }),
intro: node.data.intro,
flowNodeType: node.data.flowNodeType,
inputs: node.data.inputs,
@@ -323,12 +329,13 @@ const MenuRender = React.memo(function MenuRender({
inputs: template.inputs,
outputs: template.outputs,
version: template.version
- }
+ },
+ selected: true
})
);
});
},
- [setNodes]
+ [computedNewNodeName, setNodes]
);
const onDelNode = useCallback(
(nodeId: string) => {
diff --git a/projects/app/src/pages/app/list/components/List.tsx b/projects/app/src/pages/app/list/components/List.tsx
index 4860d556f71..a5a64e50ffe 100644
--- a/projects/app/src/pages/app/list/components/List.tsx
+++ b/projects/app/src/pages/app/list/components/List.tsx
@@ -36,6 +36,8 @@ const ConfigPerModal = dynamic(() => import('@/components/support/permission/Con
import type { EditHttpPluginProps } from './HttpPluginEditModal';
import { postCopyApp } from '@/web/core/app/api/app';
import { getTeamMembers } from '@/web/support/user/team/api';
+import { formatTimeToChatTime } from '@fastgpt/global/common/string/time';
+import { useSystem } from '@fastgpt/web/hooks/useSystem';
import { useSystemStore } from '@/web/common/system/useSystemStore';
const HttpEditModal = dynamic(() => import('./HttpPluginEditModal'));
@@ -43,6 +45,8 @@ const ListItem = () => {
const { t } = useTranslation();
const { appT } = useI18n();
const router = useRouter();
+ const { isPc } = useSystem();
+
const { myApps, loadMyApps, onUpdateApp, setMoveAppId, folderDetail, appType } =
useContextSelector(AppListContext, (v) => v);
const [loadingAppId, setLoadingAppId] = useState();
@@ -175,9 +179,6 @@ const ListItem = () => {
isFolder: app.type === AppTypeEnum.folder
})}
>
- {/*
-
- */}
@@ -188,7 +189,7 @@ const ListItem = () => {
{
- {/*
-
- {formatTimeToChatTime(app.updateTime)}
- */}
+ {isPc && (
+
+
+ {formatTimeToChatTime(app.updateTime)}
+
+ )}
{app.permission.hasManagePer && (
{
gap={5}
display={'flex'}
alignItems={'center'}
- fontSize={'md'}
+ fontSize={['sm', 'md']}
onChange={(e) => {
router.push({
query: {
diff --git a/projects/app/src/pages/chat/components/ChatHistorySlider.tsx b/projects/app/src/pages/chat/components/ChatHistorySlider.tsx
index 4043ad03c88..89babc04dd4 100644
--- a/projects/app/src/pages/chat/components/ChatHistorySlider.tsx
+++ b/projects/app/src/pages/chat/components/ChatHistorySlider.tsx
@@ -159,7 +159,10 @@ const ChatHistorySlider = ({
{!isPc && appId && (
flex={'1 0 0'}
- mr={2}
+ mr={1}
+ inlineStyles={{
+ px: 1
+ }}
list={[
{ label: t('core.chat.Recent use'), value: TabEnum.recently },
{ label: t('App'), value: TabEnum.app },
diff --git a/projects/app/src/web/core/workflow/utils.ts b/projects/app/src/web/core/workflow/utils.ts
index ee1822651ee..68868963716 100644
--- a/projects/app/src/web/core/workflow/utils.ts
+++ b/projects/app/src/web/core/workflow/utils.ts
@@ -58,9 +58,11 @@ export const nodeTemplate2FlowNode = ({
};
};
export const storeNode2FlowNode = ({
- item: storeNode
+ item: storeNode,
+ selected = false
}: {
item: StoreNodeItemType;
+ selected?: boolean;
}): Node => {
// init some static data
const template =
@@ -101,6 +103,7 @@ export const storeNode2FlowNode = ({
id: storeNode.nodeId,
type: storeNode.flowNodeType,
data: moduleItem,
+ selected,
position: storeNode.position || { x: 0, y: 0 }
};
};