Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
d5073f98
authored
May 15, 2024
by
heheer
Committed by
GitHub
May 15, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf:change plugin version update position (#1493)
* perf:change plugin version update position * use nodeversion
parent
8386f707
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
98 additions
and
66 deletions
+98
-66
packages/global/core/plugin/type.d.ts
+2
-0
packages/global/core/workflow/type/index.d.ts
+1
-0
packages/service/core/plugin/controller.ts
+3
-1
packages/service/core/plugin/schema.ts
+4
-0
packages/service/core/workflow/dispatch/utils.ts
+1
-1
projects/app/i18n/en/app.json
+1
-0
projects/app/i18n/zh/app.json
+1
-0
projects/app/src/components/core/workflow/Flow/nodes/render/NodeCard.tsx
+60
-61
projects/app/src/components/core/workflow/utils.ts
+2
-1
projects/app/src/pages/api/core/plugin/update.ts
+23
-2
No files found.
packages/global/core/plugin/type.d.ts
View file @
d5073f98
...
...
@@ -23,6 +23,7 @@ export type PluginItemSchema = {
customHeaders
?:
string
;
};
version
?:
'v1'
|
'v2'
;
nodeVersion
?:
string
;
};
/* plugin template */
...
...
@@ -32,6 +33,7 @@ export type PluginTemplateType = PluginRuntimeType & {
source
:
`
${
PluginSourceEnum
}
`
;
templateType
:
FlowNodeTemplateType
[
'templateType'
];
intro
:
string
;
nodeVersion
:
string
;
};
export
type
PluginRuntimeType
=
{
...
...
packages/global/core/workflow/type/index.d.ts
View file @
d5073f98
...
...
@@ -64,6 +64,7 @@ export type FlowNodeTemplateType = FlowNodeCommonType & {
// action
forbidDelete
?:
boolean
;
// forbid delete
unique
?:
boolean
;
nodeVersion
?:
string
;
};
export
type
FlowNodeItemType
=
FlowNodeTemplateType
&
{
nodeId
:
string
;
...
...
packages/service/core/plugin/controller.ts
View file @
d5073f98
...
...
@@ -52,7 +52,8 @@ const getPluginTemplateById = async (id: string): Promise<PluginTemplateType> =>
nodes
:
item
.
modules
,
edges
:
item
.
edges
,
templateType
:
FlowNodeTemplateTypeEnum
.
personalPlugin
,
isTool
:
true
isTool
:
true
,
nodeVersion
:
item
?.
nodeVersion
||
''
};
}
return
Promise
.
reject
(
'plugin not found'
);
...
...
@@ -72,6 +73,7 @@ export async function getPluginPreviewNode({ id }: { id: string }): Promise<Flow
intro
:
plugin
.
intro
,
showStatus
:
plugin
.
showStatus
,
isTool
:
plugin
.
isTool
,
nodeVersion
:
plugin
.
nodeVersion
,
version
:
'481'
,
sourceHandle
:
getHandleConfig
(
true
,
true
,
true
,
true
),
targetHandle
:
getHandleConfig
(
true
,
true
,
true
,
true
),
...
...
packages/service/core/plugin/schema.ts
View file @
d5073f98
...
...
@@ -64,6 +64,10 @@ const PluginSchema = new Schema({
version
:
{
type
:
String
,
enum
:
[
'v1'
,
'v2'
]
},
nodeVersion
:
{
type
:
String
,
default
:
''
}
});
...
...
packages/service/core/workflow/dispatch/utils.ts
View file @
d5073f98
...
...
@@ -62,7 +62,7 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => {
return
JSON
.
stringify
(
value
);
}
if
(
type
===
'number'
)
return
Number
(
value
);
if
(
type
===
'boolean'
)
return
Boolean
(
value
)
;
if
(
type
===
'boolean'
)
return
value
===
'true'
?
true
:
false
;
try
{
if
(
type
===
WorkflowIOValueTypeEnum
.
datasetQuote
&&
!
Array
.
isArray
(
value
))
{
return
JSON
.
parse
(
value
);
...
...
projects/app/i18n/en/app.json
View file @
d5073f98
...
...
@@ -39,6 +39,7 @@
},
"module"
:
{
"Combine Modules"
:
"Combine Modules"
,
"Confirm Sync"
:
"Using the latest template will overwrite the existing one and may result in the loss of some previous configuration information. Please confirm."
,
"Custom Title Tip"
:
"This title will be displayed during the conversation"
,
"My Modules"
:
"My Modules"
,
"No Modules"
:
"No modules yet~"
,
...
...
projects/app/i18n/zh/app.json
View file @
d5073f98
...
...
@@ -38,6 +38,7 @@
},
"module"
:
{
"Combine Modules"
:
"组合模块"
,
"Confirm Sync"
:
"将会使用最新模板进行覆盖,可能会丢失一些旧的配置信息,请确认"
,
"Custom Title Tip"
:
"该标题名字会展示在对话过程中"
,
"My Modules"
:
""
,
"No Modules"
:
"还没有模块~"
,
...
...
projects/app/src/components/core/workflow/Flow/nodes/render/NodeCard.tsx
View file @
d5073f98
import
React
,
{
useCallback
,
use
Memo
}
from
'react'
;
import
React
,
{
useCallback
,
use
Effect
,
useMemo
,
useState
}
from
'react'
;
import
{
Box
,
Button
,
Card
,
Flex
}
from
'@chakra-ui/react'
;
import
MyIcon
from
'@fastgpt/web/components/common/Icon'
;
import
Avatar
from
'@/components/Avatar'
;
import
type
{
FlowNodeItemType
}
from
'@fastgpt/global/core/workflow/type/index.d'
;
import
type
{
FlowNodeItemType
,
FlowNodeTemplateType
}
from
'@fastgpt/global/core/workflow/type/index.d'
;
import
{
useTranslation
}
from
'next-i18next'
;
import
{
useEditTitle
}
from
'@/web/common/hooks/useEditTitle'
;
import
{
useToast
}
from
'@fastgpt/web/hooks/useToast'
;
import
{
FlowNodeTypeEnum
}
from
'@fastgpt/global/core/workflow/node/constant'
;
import
{
useSystemStore
}
from
'@/web/common/system/useSystemStore'
;
import
{
useConfirm
}
from
'@fastgpt/web/hooks/useConfirm'
;
import
{
LOGO_ICON
}
from
'@fastgpt/global/common/system/constants'
;
import
{
ToolTargetHandle
}
from
'./Handle/ToolHandle'
;
...
...
@@ -17,7 +19,6 @@ import { useDebug } from '../../hooks/useDebug';
import
{
ResponseBox
}
from
'@/components/ChatBox/WholeResponseModal'
;
import
EmptyTip
from
'@fastgpt/web/components/common/EmptyTip'
;
import
{
getPreviewPluginModule
}
from
'@/web/core/plugin/api'
;
import
{
getErrText
}
from
'@fastgpt/global/common/error/utils'
;
import
{
storeNode2FlowNode
,
updateFlowNodeVersion
}
from
'@/web/core/workflow/utils'
;
import
{
getNanoid
}
from
'@fastgpt/global/common/string/tools'
;
import
{
useContextSelector
}
from
'use-context-selector'
;
...
...
@@ -26,6 +27,8 @@ import { useI18n } from '@/web/context/I18n';
import
{
moduleTemplatesFlat
}
from
'@fastgpt/global/core/workflow/template/constants'
;
import
{
QuestionOutlineIcon
}
from
'@chakra-ui/icons'
;
import
MyTooltip
from
'@/components/MyTooltip'
;
import
{
isEqual
}
from
'lodash'
;
import
{
useSystemStore
}
from
'@/web/common/system/useSystemStore'
;
type
Props
=
FlowNodeItemType
&
{
children
?:
React
.
ReactNode
|
React
.
ReactNode
[]
|
string
;
...
...
@@ -69,6 +72,9 @@ const NodeCard = (props: Props) => {
const
onChangeNode
=
useContextSelector
(
WorkflowContext
,
(
v
)
=>
v
.
onChangeNode
);
const
onResetNode
=
useContextSelector
(
WorkflowContext
,
(
v
)
=>
v
.
onResetNode
);
const
[
hasNewVersion
,
setHasNewVersion
]
=
useState
(
false
);
const
{
setLoading
}
=
useSystemStore
();
// custom title edit
const
{
onOpenModal
:
onOpenCustomTitleModal
,
EditModal
:
EditTitleModal
}
=
useEditTitle
({
title
:
t
(
'common.Custom Title'
),
...
...
@@ -81,13 +87,50 @@ const NodeCard = (props: Props) => {
);
const
node
=
nodeList
.
find
((
node
)
=>
node
.
nodeId
===
nodeId
);
const
{
openConfirm
:
onOpenConfirmSync
,
ConfirmModal
:
ConfirmSyncModal
}
=
useConfirm
({
content
:
appT
(
'module.Confirm Sync'
)
});
useEffect
(()
=>
{
const
fetchPluginModule
=
async
()
=>
{
if
(
node
?.
flowNodeType
===
FlowNodeTypeEnum
.
pluginModule
)
{
if
(
!
node
?.
pluginId
)
return
;
const
template
=
await
getPreviewPluginModule
(
node
.
pluginId
);
setHasNewVersion
(
!!
template
.
nodeVersion
&&
node
.
nodeVersion
!==
template
.
nodeVersion
);
}
else
{
const
template
=
moduleTemplatesFlat
.
find
(
(
item
)
=>
item
.
flowNodeType
===
node
?.
flowNodeType
);
setHasNewVersion
(
node
?.
version
!==
template
?.
version
);
}
};
fetchPluginModule
();
},
[
node
]);
const
template
=
moduleTemplatesFlat
.
find
((
item
)
=>
item
.
flowNodeType
===
node
?.
flowNodeType
);
const
hasNewVersion
=
useMemo
(()
=>
{
return
(
template
?.
flowNodeType
!==
FlowNodeTypeEnum
.
pluginModule
&&
node
?.
version
!==
template
?.
version
);
},
[
node
?.
version
,
template
?.
flowNodeType
,
template
?.
version
]);
const
onClickSyncVersion
=
useCallback
(
async
()
=>
{
try
{
setLoading
(
true
);
if
(
!
node
||
!
template
)
return
;
if
(
node
?.
flowNodeType
===
'pluginModule'
)
{
if
(
!
node
.
pluginId
)
return
;
onResetNode
({
id
:
nodeId
,
node
:
await
getPreviewPluginModule
(
node
.
pluginId
)
});
}
else
{
onResetNode
({
id
:
nodeId
,
node
:
updateFlowNodeVersion
(
node
,
template
)
});
}
}
catch
(
error
)
{
console
.
error
(
'Error fetching plugin module:'
,
error
);
}
setLoading
(
false
);
},
[
node
,
nodeId
,
onResetNode
,
setLoading
,
template
]);
/* Node header */
const
Header
=
useMemo
(()
=>
{
...
...
@@ -149,13 +192,7 @@ const NodeCard = (props: Props) => {
fontWeight=
{
'medium'
}
cursor=
{
'pointer'
}
_hover=
{
{
bg
:
'yellow.100'
}
}
onClick=
{
()
=>
{
if
(
!
node
||
!
template
)
return
;
onResetNode
({
id
:
nodeId
,
node
:
updateFlowNodeVersion
(
node
,
template
)
});
}
}
onClick=
{
onOpenConfirmSync
(
onClickSyncVersion
)
}
>
<
Box
>
{
appT
(
'app.modules.has new version'
)
}
</
Box
>
<
QuestionOutlineIcon
ml=
{
1
}
/>
...
...
@@ -171,6 +208,7 @@ const NodeCard = (props: Props) => {
/>
<
NodeIntro
nodeId=
{
nodeId
}
intro=
{
intro
}
/>
</
Box
>
<
ConfirmSyncModal
/>
</
Box
>
);
},
[
...
...
@@ -181,16 +219,16 @@ const NodeCard = (props: Props) => {
name
,
menuForbid
,
hasNewVersion
,
appT
,
onOpenConfirmSync
,
onClickSyncVersion
,
pluginId
,
flowNodeType
,
intro
,
ConfirmSyncModal
,
onOpenCustomTitleModal
,
onChangeNode
,
toast
,
appT
,
node
,
template
,
onResetNode
toast
]);
return
(
...
...
@@ -249,21 +287,14 @@ const MenuRender = React.memo(function MenuRender({
menuForbid
?:
Props
[
'menuForbid'
];
})
{
const
{
t
}
=
useTranslation
();
const
{
toast
}
=
useToast
();
const
{
setLoading
}
=
useSystemStore
();
const
{
openDebugNode
,
DebugInputModal
}
=
useDebug
();
const
{
openConfirm
:
onOpenConfirmSync
,
ConfirmModal
:
ConfirmSyncModal
}
=
useConfirm
({
content
:
t
(
'module.Confirm Sync Plugin'
)
});
const
{
openConfirm
:
onOpenConfirmDeleteNode
,
ConfirmModal
:
ConfirmDeleteModal
}
=
useConfirm
({
content
:
t
(
'core.module.Confirm Delete Node'
),
type
:
'delete'
});
const
setNodes
=
useContextSelector
(
WorkflowContext
,
(
v
)
=>
v
.
setNodes
);
const
onResetNode
=
useContextSelector
(
WorkflowContext
,
(
v
)
=>
v
.
onResetNode
);
const
setEdges
=
useContextSelector
(
WorkflowContext
,
(
v
)
=>
v
.
setEdges
);
const
onCopyNode
=
useCallback
(
...
...
@@ -310,22 +341,6 @@ const MenuRender = React.memo(function MenuRender({
},
[
setEdges
,
setNodes
]
);
const
onClickSyncVersion
=
useCallback
(
async
()
=>
{
if
(
!
pluginId
)
return
;
try
{
setLoading
(
true
);
onResetNode
({
id
:
nodeId
,
node
:
await
getPreviewPluginModule
(
pluginId
)
});
}
catch
(
e
)
{
return
toast
({
status
:
'error'
,
title
:
getErrText
(
e
,
t
(
'plugin.Get Plugin Module Detail Failed'
))
});
}
setLoading
(
false
);
},
[
nodeId
,
onResetNode
,
pluginId
,
setLoading
,
t
,
toast
]);
const
Render
=
useMemo
(()
=>
{
const
menuList
=
[
...
...
@@ -349,17 +364,6 @@ const MenuRender = React.memo(function MenuRender({
onClick
:
()
=>
onCopyNode
(
nodeId
)
}
]),
...(
flowNodeType
===
FlowNodeTypeEnum
.
pluginModule
?
[
{
icon
:
'common/refreshLight'
,
label
:
t
(
'plugin.Synchronous version'
),
variant
:
'whiteBase'
,
onClick
:
onOpenConfirmSync
(
onClickSyncVersion
)
}
]
:
[]),
...(
menuForbid
?.
delete
?
[]
:
[
...
...
@@ -401,7 +405,6 @@ const MenuRender = React.memo(function MenuRender({
</
Box
>
))
}
</
Box
>
<
ConfirmSyncModal
/>
<
ConfirmDeleteModal
/>
<
DebugInputModal
/>
</>
...
...
@@ -411,11 +414,7 @@ const MenuRender = React.memo(function MenuRender({
menuForbid
?.
copy
,
menuForbid
?.
delete
,
t
,
flowNodeType
,
onOpenConfirmSync
,
onClickSyncVersion
,
onOpenConfirmDeleteNode
,
ConfirmSyncModal
,
ConfirmDeleteModal
,
DebugInputModal
,
openDebugNode
,
...
...
projects/app/src/components/core/workflow/utils.ts
View file @
d5073f98
...
...
@@ -22,7 +22,8 @@ export const flowNode2StoreNodes = ({
version
:
item
.
data
.
version
,
inputs
:
item
.
data
.
inputs
,
outputs
:
item
.
data
.
outputs
,
pluginId
:
item
.
data
.
pluginId
pluginId
:
item
.
data
.
pluginId
,
nodeVersion
:
item
.
data
.
nodeVersion
}));
// get all handle
...
...
projects/app/src/pages/api/core/plugin/update.ts
View file @
d5073f98
...
...
@@ -7,6 +7,8 @@ import { MongoPlugin } from '@fastgpt/service/core/plugin/schema';
import
{
mongoSessionRun
}
from
'@fastgpt/service/common/mongo/sessionRun'
;
import
{
ClientSession
}
from
'@fastgpt/service/common/mongo'
;
import
{
httpApiSchema2Plugins
}
from
'@fastgpt/global/core/plugin/httpPlugin/utils'
;
import
{
isEqual
}
from
'lodash'
;
import
{
nanoid
}
from
'nanoid'
;
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
<
any
>
)
{
try
{
...
...
@@ -22,7 +24,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
per
:
'owner'
});
const
updateData
=
{
const
originPlugin
=
await
MongoPlugin
.
findById
(
id
);
let
updateData
=
{
name
:
props
.
name
,
intro
:
props
.
intro
,
avatar
:
props
.
avatar
,
...
...
@@ -32,9 +36,26 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
modules
:
modules
}),
...(
edges
?.
length
&&
{
edges
}),
metadata
:
props
.
metadata
metadata
:
props
.
metadata
,
nodeVersion
:
originPlugin
?.
nodeVersion
};
const
isNodeVersionEqual
=
isEqual
(
originPlugin
?.
modules
.
map
((
module
)
=>
{
return
{
...
module
,
position
:
undefined
};
}),
updateData
.
modules
?.
map
((
module
)
=>
{
return
{
...
module
,
position
:
undefined
};
})
)
&&
isEqual
(
originPlugin
?.
edges
,
updateData
.
edges
);
if
(
!
isNodeVersionEqual
)
{
updateData
=
{
...
updateData
,
nodeVersion
:
nanoid
(
6
)
};
}
if
(
props
.
metadata
?.
apiSchemaStr
)
{
await
mongoSessionRun
(
async
(
session
)
=>
{
// update children
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment