diff --git a/apps/application/sql/list_application_user.sql b/apps/application/sql/list_application_user.sql
index c21c70675..ecffcd93d 100644
--- a/apps/application/sql/list_application_user.sql
+++ b/apps/application/sql/list_application_user.sql
@@ -14,7 +14,7 @@ from (select application."id"::text, application."name",
application.icon
from application
left join "user" on user_id = "user".id
- where application."id" in (select target
+ where application."id"::text in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and 'VIEW' = any (permission_list))) temp
${application_query_set}
\ No newline at end of file
diff --git a/apps/folders/serializers/folder.py b/apps/folders/serializers/folder.py
index 99dad18c0..ec188cbc1 100644
--- a/apps/folders/serializers/folder.py
+++ b/apps/folders/serializers/folder.py
@@ -308,4 +308,4 @@ class FolderTreeSerializer(serializers.Serializer):
TreeSerializer = get_folder_tree_serializer(self.data.get('source')) # noqa
serializer = TreeSerializer(nodes, many=True)
- return serializer.data # 这是可序列化的字典
+ return [d for d in serializer.data if d.get('id') == d.get('workspace_id')] # 这是可序列化的字典
diff --git a/apps/knowledge/sql/list_knowledge_user.sql b/apps/knowledge/sql/list_knowledge_user.sql
index 161255e27..a9114be64 100644
--- a/apps/knowledge/sql/list_knowledge_user.sql
+++ b/apps/knowledge/sql/list_knowledge_user.sql
@@ -22,7 +22,7 @@ FROM (SELECT "temp_knowledge".id::text, "temp_knowledge".name,
"document_temp".document_count
FROM (SELECT knowledge.*
FROM knowledge knowledge ${knowledge_custom_sql}
- AND id in (select target
+ AND id::text in (select target
from workspace_user_resource_permission ${workspace_user_resource_permission_query_set}
and 'VIEW' = any (permission_list))) temp_knowledge
LEFT JOIN (SELECT "count"("id") AS document_count, "sum"("char_length") "char_length", knowledge_id
diff --git a/apps/tools/sql/list_tool_user.sql b/apps/tools/sql/list_tool_user.sql
index 873ffc654..975d506ff 100644
--- a/apps/tools/sql/list_tool_user.sql
+++ b/apps/tools/sql/list_tool_user.sql
@@ -20,7 +20,7 @@ FROM (SELECT tool."id"::text,
tool."is_active"
FROM (SELECT tool.*
FROM tool tool ${tool_query_set}
- AND tool.id IN (SELECT target
+ AND tool.id::text IN (SELECT target
FROM workspace_user_resource_permission
${workspace_user_resource_permission_query_set}
AND 'VIEW' = ANY (permission_list))) AS tool
diff --git a/ui/src/assets/workflow/icon_aggregation.svg b/ui/src/assets/workflow/icon_aggregation.svg
new file mode 100644
index 000000000..514db1e6f
--- /dev/null
+++ b/ui/src/assets/workflow/icon_aggregation.svg
@@ -0,0 +1,12 @@
+
diff --git a/ui/src/enums/application.ts b/ui/src/enums/application.ts
index 0be70d07f..930988c46 100644
--- a/ui/src/enums/application.ts
+++ b/ui/src/enums/application.ts
@@ -34,6 +34,7 @@ export enum WorkflowType {
LoopContinueNode = 'loop-continue-node',
LoopBreakNode = 'loop-break-node',
VariableSplittingNode = 'variable-splitting-node',
+ VariableAggregationNode = 'variable-aggregation-node',
VideoUnderstandNode = 'video-understand-node',
ParameterExtractionNode = 'parameter-extraction-node',
}
diff --git a/ui/src/locales/lang/en-US/views/application-workflow.ts b/ui/src/locales/lang/en-US/views/application-workflow.ts
index a38a7766d..bc0e7fdd0 100644
--- a/ui/src/locales/lang/en-US/views/application-workflow.ts
+++ b/ui/src/locales/lang/en-US/views/application-workflow.ts
@@ -259,6 +259,10 @@ You are a master of problem optimization, adept at accurately inferring user int
text: 'Update the value of the global variable',
assign: 'Set Value',
},
+ variableAggregationNode: {
+ label: 'Variable Aggregation',
+ text: 'Perform aggregation processing on the outputs of multiple branches',
+ },
mcpNode: {
label: 'MCP Node',
text: 'Call external MCP services to process data',
diff --git a/ui/src/locales/lang/zh-CN/views/application-workflow.ts b/ui/src/locales/lang/zh-CN/views/application-workflow.ts
index 09d2c0720..a5b27bcee 100644
--- a/ui/src/locales/lang/zh-CN/views/application-workflow.ts
+++ b/ui/src/locales/lang/zh-CN/views/application-workflow.ts
@@ -261,6 +261,10 @@ export default {
requiredMessage: '请选择图片',
},
},
+ variableAggregationNode: {
+ label: '变量聚合',
+ text: '对多个分支的输出进行聚合处理',
+ },
variableAssignNode: {
label: '变量赋值',
text: '更新全局变量的值',
diff --git a/ui/src/locales/lang/zh-Hant/views/application-workflow.ts b/ui/src/locales/lang/zh-Hant/views/application-workflow.ts
index a9f54f2c5..2fd049ae6 100644
--- a/ui/src/locales/lang/zh-Hant/views/application-workflow.ts
+++ b/ui/src/locales/lang/zh-Hant/views/application-workflow.ts
@@ -259,6 +259,10 @@ export default {
text: '更新全域變數的值',
assign: '賦值',
},
+ variableAggregationNode: {
+ label: '變量聚合',
+ text: '對多個分支的輸出進行聚合處理',
+ },
mcpNode: {
label: 'MCP 調用',
text: '通過SSE/Streamable HTTP方式執行MCP服務中的工具',
diff --git a/ui/src/workflow/common/data.ts b/ui/src/workflow/common/data.ts
index 8a006eac8..925b45c6d 100644
--- a/ui/src/workflow/common/data.ts
+++ b/ui/src/workflow/common/data.ts
@@ -333,6 +333,17 @@ export const videoUnderstandNode = {
},
},
}
+export const variableAggregationNode = {
+ type: WorkflowType.VariableAggregationNode,
+ text: t('views.applicationWorkflow.nodes.variableAggregationNode.text'),
+ label: t('views.applicationWorkflow.nodes.variableAggregationNode.label'),
+ height: 252,
+ properties: {
+ stepName: t('views.applicationWorkflow.nodes.variableAggregationNode.label'),
+ config: {},
+ },
+}
+
export const variableAssignNode = {
type: WorkflowType.VariableAssignNode,
@@ -626,6 +637,8 @@ export const menuNodes = [
list: [conditionNode, formNode, variableAssignNode, replyNode, loopNode],
},
{
+ label: t('views.applicationWorkflow.nodes.classify.dataProcessing', '数据处理'),
+ list: [variableSplittingNode, parameterExtractionNode, variableAggregationNode],
label: t('views.applicationWorkflow.nodes.classify.dataProcessing'),
list: [variableSplittingNode, parameterExtractionNode],
},
@@ -767,6 +780,7 @@ export const nodeDict: any = {
[WorkflowType.VariableSplittingNode]: variableSplittingNode,
[WorkflowType.VideoUnderstandNode]: videoUnderstandNode,
[WorkflowType.ParameterExtractionNode]: parameterExtractionNode,
+ [WorkflowType.VariableAggregationNode]: variableAggregationNode,
}
export function isWorkFlow(type: string | undefined) {
diff --git a/ui/src/workflow/icons/variable-aggregation-node-icon.vue b/ui/src/workflow/icons/variable-aggregation-node-icon.vue
new file mode 100644
index 000000000..5fb3e08b9
--- /dev/null
+++ b/ui/src/workflow/icons/variable-aggregation-node-icon.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ui/src/workflow/nodes/variable-aggregation-node/index.ts b/ui/src/workflow/nodes/variable-aggregation-node/index.ts
new file mode 100644
index 000000000..d7bb579c6
--- /dev/null
+++ b/ui/src/workflow/nodes/variable-aggregation-node/index.ts
@@ -0,0 +1,15 @@
+import VariableAggregationNodeVue from './index.vue'
+import { AppNode, AppNodeModel } from '@/workflow/common/app-node'
+
+class VariableAggregationNode extends AppNode {
+ constructor(props: any) {
+ super(props, VariableAggregationNodeVue)
+ }
+}
+
+
+export default {
+ type: 'variable-aggregation-node',
+ model: AppNodeModel,
+ view: VariableAggregationNode,
+}
\ No newline at end of file
diff --git a/ui/src/workflow/nodes/variable-aggregation-node/index.vue b/ui/src/workflow/nodes/variable-aggregation-node/index.vue
new file mode 100644
index 000000000..b2551a24c
--- /dev/null
+++ b/ui/src/workflow/nodes/variable-aggregation-node/index.vue
@@ -0,0 +1,20 @@
+
+
+ 变量聚合
+
+
+
+