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 @@ + + +