diff --git a/apps/application/flow/step_node/data_source_local_node/__init__.py b/apps/application/flow/step_node/data_source_local_node/__init__.py new file mode 100644 index 00000000000..bbf804a7079 --- /dev/null +++ b/apps/application/flow/step_node/data_source_local_node/__init__.py @@ -0,0 +1,8 @@ +# coding=utf-8 +""" + @project: MaxKB + @Author:虎虎 + @file: __init__.py.py + @date:2025/11/11 10:06 + @desc: +""" diff --git a/apps/application/flow/step_node/data_source_local_node/i_data_source_local_node.py b/apps/application/flow/step_node/data_source_local_node/i_data_source_local_node.py new file mode 100644 index 00000000000..ec06f36d570 --- /dev/null +++ b/apps/application/flow/step_node/data_source_local_node/i_data_source_local_node.py @@ -0,0 +1,38 @@ +# coding=utf-8 +""" + @project: MaxKB + @Author:虎虎 + @file: i_data_source_local_node.py + @date:2025/11/11 10:06 + @desc: +""" +from abc import abstractmethod +from typing import Type + +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers + +from application.flow.i_step_node import INode, NodeResult + + +class DataSourceLocalNodeParamsSerializer(serializers.Serializer): + file_format = serializers.ListField(child=serializers.CharField) + max_file_number = serializers.IntegerField(required=True, label=_("Number of uploaded files")) + file_max_size = serializers.IntegerField(required=True, label=_("Upload file size")) + + +class IDataSourceLocalNode(INode): + type = 'data-source-local-node' + + @abstractmethod + def get_form_class(self): + pass + + def get_node_params_serializer_class(self) -> Type[serializers.Serializer]: + return DataSourceLocalNodeParamsSerializer + + def _run(self): + return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data) + + def execute(self, file_format, max_file_number, file_max_size, **kwargs) -> NodeResult: + pass diff --git a/apps/application/flow/step_node/data_source_local_node/impl/__init__.py b/apps/application/flow/step_node/data_source_local_node/impl/__init__.py new file mode 100644 index 00000000000..6f830151971 --- /dev/null +++ b/apps/application/flow/step_node/data_source_local_node/impl/__init__.py @@ -0,0 +1,8 @@ +# coding=utf-8 +""" + @project: MaxKB + @Author:虎虎 + @file: __init__.py.py + @date:2025/11/11 10:08 + @desc: +""" diff --git a/apps/application/flow/step_node/data_source_local_node/impl/base_data_source_local_node.py b/apps/application/flow/step_node/data_source_local_node/impl/base_data_source_local_node.py new file mode 100644 index 00000000000..515c0134cc3 --- /dev/null +++ b/apps/application/flow/step_node/data_source_local_node/impl/base_data_source_local_node.py @@ -0,0 +1,27 @@ +# coding=utf-8 +""" + @project: MaxKB + @Author:虎虎 + @file: base_data_source_local_node.py + @date:2025/11/11 10:30 + @desc: +""" +from application.flow.i_step_node import NodeResult +from application.flow.step_node.data_source_local_node.i_data_source_local_node import IDataSourceLocalNode +from common import forms +from common.forms import BaseForm + + +class BaseDataSourceLocalNodeForm(BaseForm): + api_key = forms.PasswordInputField('API Key', required=True) + + +class BaseDataSourceLocalNode(IDataSourceLocalNode): + def save_context(self, details, workflow_manage): + pass + + def get_form_class(self): + return BaseDataSourceLocalNodeForm() + + def execute(self, file_format, max_file_number, file_max_size, **kwargs) -> NodeResult: + pass diff --git a/apps/common/constants/permission_constants.py b/apps/common/constants/permission_constants.py index 67cb272a13e..58448a6a5d2 100644 --- a/apps/common/constants/permission_constants.py +++ b/apps/common/constants/permission_constants.py @@ -39,9 +39,12 @@ class Group(Enum): SYSTEM_RES_KNOWLEDGE = "SYSTEM_RESOURCE_KNOWLEDGE" KNOWLEDGE_HIT_TEST = "KNOWLEDGE_HIT_TEST" KNOWLEDGE_DOCUMENT = "KNOWLEDGE_DOCUMENT" + KNOWLEDGE_WORKFLOW = "KNOWLEDGE_WORKFLOW" KNOWLEDGE_TAG = "KNOWLEDGE_TAG" SYSTEM_KNOWLEDGE_DOCUMENT = "SYSTEM_KNOWLEDGE_DOCUMENT" + SYSTEM_KNOWLEDGE_WORKFLOW = "SYSTEM_KNOWLEDGE_WORKFLOW" SYSTEM_RES_KNOWLEDGE_DOCUMENT = "SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT" + SYSTEM_RES_KNOWLEDGE_WORKFLOW = "SYSTEM_RESOURCE_KNOWLEDGE_WORKFLOW" SYSTEM_RES_KNOWLEDGE_TAG = "SYSTEM_RES_KNOWLEDGE_TAG" SYSTEM_KNOWLEDGE_TAG = "SYSTEM_KNOWLEDGE_TAG" @@ -328,6 +331,7 @@ def get_workspace_role(self): Group.APPLICATION.value: _("Application"), Group.KNOWLEDGE.value: _("Knowledge"), Group.KNOWLEDGE_DOCUMENT.value: _("Document"), + Group.KNOWLEDGE_WORKFLOW.value: _("Workflow"), Group.KNOWLEDGE_TAG.value: _("Tag"), Group.KNOWLEDGE_PROBLEM.value: _("Problem"), Group.KNOWLEDGE_HIT_TEST.value: _("Hit-Test"), @@ -375,6 +379,7 @@ def get_workspace_role(self): Group.SYSTEM_MODEL.value: _("Model"), Group.SYSTEM_KNOWLEDGE.value: _("Knowledge"), Group.SYSTEM_KNOWLEDGE_DOCUMENT.value: _("Document"), + Group.SYSTEM_KNOWLEDGE_WORKFLOW.value: _("Workflow"), Group.SYSTEM_KNOWLEDGE_TAG.value: _("Tag"), Group.SYSTEM_KNOWLEDGE_PROBLEM.value: _("Problem"), Group.SYSTEM_KNOWLEDGE_HIT_TEST.value: _("Hit-Test"), @@ -383,6 +388,7 @@ def get_workspace_role(self): Group.SYSTEM_RES_MODEL.value: _("Model"), Group.SYSTEM_RES_KNOWLEDGE.value: _("Knowledge"), Group.SYSTEM_RES_KNOWLEDGE_DOCUMENT.value: _("Document"), + Group.SYSTEM_RES_KNOWLEDGE_WORKFLOW.value: _("Workflow"), Group.SYSTEM_RES_KNOWLEDGE_TAG.value: _("Tag"), Group.SYSTEM_RES_KNOWLEDGE_PROBLEM.value: _("Problem"), Group.SYSTEM_RES_KNOWLEDGE_HIT_TEST.value: _("Hit-Test"), @@ -616,6 +622,16 @@ class PermissionConstants(Enum): resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE], parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE] ) + KNOWLEDGE_WORKFLOW_READ = Permission( + group=Group.KNOWLEDGE_WORKFLOW, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER], + resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW], + parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE] + ) + KNOWLEDGE_WORKFLOW_EDIT = Permission( + group=Group.KNOWLEDGE_WORKFLOW, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER], + resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE], + parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE] + ) KNOWLEDGE_DOCUMENT_READ = Permission( group=Group.KNOWLEDGE_DOCUMENT, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER], @@ -1209,6 +1225,14 @@ class PermissionConstants(Enum): group=Group.SYSTEM_KNOWLEDGE, operate=Operate.DELETE, role_list=[RoleConstants.ADMIN], parent_group=[SystemGroup.SHARED_KNOWLEDGE], is_ee=settings.edition == "EE" ) + SHARED_KNOWLEDGE_WORKFLOW_READ = Permission( + group=Group.SYSTEM_KNOWLEDGE_WORKFLOW, operate=Operate.READ, role_list=[RoleConstants.ADMIN], + parent_group=[SystemGroup.SHARED_KNOWLEDGE], is_ee=settings.edition == "EE" + ) + SHARED_KNOWLEDGE_WORKFLOW_EDIT = Permission( + group=Group.SYSTEM_KNOWLEDGE_WORKFLOW, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN], + parent_group=[SystemGroup.SHARED_KNOWLEDGE], is_ee=settings.edition == "EE" + ) SHARED_KNOWLEDGE_DOCUMENT_READ = Permission( group=Group.SYSTEM_KNOWLEDGE_DOCUMENT, operate=Operate.READ, role_list=[RoleConstants.ADMIN], parent_group=[SystemGroup.SHARED_KNOWLEDGE], is_ee=settings.edition == "EE" @@ -1437,6 +1461,14 @@ class PermissionConstants(Enum): parent_group=[SystemGroup.RESOURCE_KNOWLEDGE], is_ee=settings.edition == "EE" ) # 文档 + RESOURCE_KNOWLEDGE_WORKFLOW_READ = Permission( + group=Group.SYSTEM_RES_KNOWLEDGE_WORKFLOW, operate=Operate.READ, role_list=[RoleConstants.ADMIN], + parent_group=[SystemGroup.RESOURCE_KNOWLEDGE], is_ee=settings.edition == "EE" + ) + RESOURCE_KNOWLEDGE_WORKFLOW_EDIT = Permission( + group=Group.SYSTEM_RES_KNOWLEDGE_WORKFLOW, operate=Operate.READ, role_list=[RoleConstants.ADMIN], + parent_group=[SystemGroup.RESOURCE_KNOWLEDGE], is_ee=settings.edition == "EE" + ) RESOURCE_KNOWLEDGE_DOCUMENT_READ = Permission( group=Group.SYSTEM_RES_KNOWLEDGE_DOCUMENT, operate=Operate.READ, role_list=[RoleConstants.ADMIN], parent_group=[SystemGroup.RESOURCE_KNOWLEDGE], is_ee=settings.edition == "EE" diff --git a/apps/knowledge/api/knowledge_workflow.py b/apps/knowledge/api/knowledge_workflow.py new file mode 100644 index 00000000000..38296bb893e --- /dev/null +++ b/apps/knowledge/api/knowledge_workflow.py @@ -0,0 +1,11 @@ +# coding=utf-8 + +from common.mixins.api_mixin import APIMixin + + +class KnowledgeWorkflowApi(APIMixin): + pass + + +class KnowledgeWorkflowVersionApi(APIMixin): + pass diff --git a/apps/knowledge/migrations/0004_alter_document_type_alter_knowledge_type_and_more.py b/apps/knowledge/migrations/0004_alter_document_type_alter_knowledge_type_and_more.py new file mode 100644 index 00000000000..374aa4e3822 --- /dev/null +++ b/apps/knowledge/migrations/0004_alter_document_type_alter_knowledge_type_and_more.py @@ -0,0 +1,59 @@ +# Generated by Django 5.2.4 on 2025-11-04 05:54 + +import django.db.models.deletion +import uuid_utils.compat +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('knowledge', '0003_tag_documenttag'), + ] + + operations = [ + migrations.AlterField( + model_name='document', + name='type', + field=models.IntegerField(choices=[(0, '通用类型'), (1, 'web站点类型'), (2, '飞书类型'), (3, '语雀类型'), (4, '工作流类型')], db_index=True, default=0, verbose_name='类型'), + ), + migrations.AlterField( + model_name='knowledge', + name='type', + field=models.IntegerField(choices=[(0, '通用类型'), (1, 'web站点类型'), (2, '飞书类型'), (3, '语雀类型'), (4, '工作流类型')], db_index=True, default=0, verbose_name='类型'), + ), + migrations.CreateModel( + name='KnowledgeWorkflow', + fields=[ + ('create_time', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, db_index=True, verbose_name='修改时间')), + ('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')), + ('workspace_id', models.CharField(db_index=True, default='default', max_length=64, verbose_name='工作空间id')), + ('work_flow', models.JSONField(default=dict, verbose_name='工作流数据')), + ('is_publish', models.BooleanField(db_index=True, default=False, verbose_name='是否发布')), + ('publish_time', models.DateTimeField(blank=True, null=True, verbose_name='发布时间')), + ('knowledge', models.OneToOneField(db_constraint=False, on_delete=django.db.models.deletion.CASCADE, related_name='workflow', to='knowledge.knowledge', verbose_name='知识库')), + ], + options={ + 'db_table': 'knowledge_workflow', + }, + ), + migrations.CreateModel( + name='KnowledgeWorkflowVersion', + fields=[ + ('create_time', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, db_index=True, verbose_name='修改时间')), + ('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')), + ('workspace_id', models.CharField(db_index=True, default='default', max_length=64, verbose_name='工作空间id')), + ('work_flow', models.JSONField(default=dict, verbose_name='工作流数据')), + ('publish_user_id', models.UUIDField(default=None, null=True, verbose_name='发布者id')), + ('publish_user_name', models.CharField(default='', max_length=128, verbose_name='发布者名称')), + ('knowledge', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.CASCADE, to='knowledge.knowledge', verbose_name='知识库')), + ('workflow', models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='knowledge.knowledgeworkflow', verbose_name='工作流')), + ], + options={ + 'db_table': 'knowledge_workflow_version', + 'unique_together': {('knowledge',)}, + }, + ), + ] diff --git a/apps/knowledge/models/knowledge.py b/apps/knowledge/models/knowledge.py index dca940b4878..95c695eb7b6 100644 --- a/apps/knowledge/models/knowledge.py +++ b/apps/knowledge/models/knowledge.py @@ -23,6 +23,7 @@ class KnowledgeType(models.IntegerChoices): WEB = 1, 'web站点类型' LARK = 2, '飞书类型' YUQUE = 3, '语雀类型' + WORKFLOW = 4, '工作流类型' class TaskType(Enum): @@ -135,6 +136,40 @@ class Meta: db_table = "knowledge" +class KnowledgeWorkflow(AppModelMixin): + """ + 知识库工作流表 + """ + id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id") + knowledge = models.OneToOneField(Knowledge, on_delete=models.CASCADE, verbose_name="知识库", + db_constraint=False, related_name='workflow') + workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True) + work_flow = models.JSONField(verbose_name="工作流数据", default=dict) + is_publish = models.BooleanField(verbose_name="是否发布", default=False, db_index=True) + publish_time = models.DateTimeField(verbose_name="发布时间", null=True, blank=True) + + class Meta: + db_table = "knowledge_workflow" + + +class KnowledgeWorkflowVersion(AppModelMixin): + """ + 知识库工作流版本表 - 记录工作流历史版本 + """ + id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id") + knowledge = models.ForeignKey(Knowledge, on_delete=models.CASCADE, verbose_name="知识库", db_constraint=False) + workflow = models.ForeignKey(KnowledgeWorkflow, on_delete=models.CASCADE, verbose_name="工作流", + db_constraint=False, related_name='versions') + workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True) + work_flow = models.JSONField(verbose_name="工作流数据", default=dict) + publish_user_id = models.UUIDField(verbose_name="发布者id", max_length=128, default=None, null=True) + publish_user_name = models.CharField(verbose_name="发布者名称", max_length=128, default="") + + class Meta: + db_table = "knowledge_workflow_version" + unique_together = [['knowledge']] # 同一知识库的版本号唯一 + + def get_default_status(): return Status('').__str__() @@ -162,6 +197,7 @@ class Document(AppModelMixin): class Meta: db_table = "document" + class Tag(AppModelMixin): """ 标签表 - 存储标签的key-value定义 diff --git a/apps/knowledge/serializers/knowledge.py b/apps/knowledge/serializers/knowledge.py index 9daeb7dad8f..d8e347dc5c2 100644 --- a/apps/knowledge/serializers/knowledge.py +++ b/apps/knowledge/serializers/knowledge.py @@ -342,8 +342,15 @@ def one(self): ) ) ), with_search_one=True) + workflow = {} + if knowledge_dict.get('type') == 4: + from knowledge.models import KnowledgeWorkflow + k = QuerySet(KnowledgeWorkflow).filter(knowledge_id=knowledge_dict.get('id')).first() + if k: + workflow = k.work_flow return { **knowledge_dict, + 'workflow': workflow, 'meta': json.loads(knowledge_dict.get('meta', '{}')), 'application_id_list': list(filter( lambda application_id: all_application_list.__contains__(application_id), diff --git a/apps/knowledge/serializers/knowledge_workflow.py b/apps/knowledge/serializers/knowledge_workflow.py new file mode 100644 index 00000000000..2473d3868ef --- /dev/null +++ b/apps/knowledge/serializers/knowledge_workflow.py @@ -0,0 +1,101 @@ +# coding=utf-8 + +from typing import Dict + +import uuid_utils.compat as uuid +from django.db import transaction +from django.db.models import QuerySet +from django.utils.translation import gettext_lazy as _ +from rest_framework import serializers + +from application.flow.step_node import get_node +from common.exception.app_exception import AppApiException +from knowledge.models import KnowledgeScope, Knowledge, KnowledgeType, KnowledgeWorkflow +from knowledge.serializers.knowledge import KnowledgeModelSerializer +from system_manage.models import AuthTargetType +from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer +from tools.models import Tool + + +class KnowledgeWorkflowModelSerializer(serializers.ModelSerializer): + class Meta: + model = KnowledgeWorkflow + fields = '__all__' + + +class KnowledgeWorkflowSerializer(serializers.Serializer): + class Form(serializers.Serializer): + type = serializers.CharField(required=True, label=_('type')) + id = serializers.CharField(required=True, label=_('type')) + + def get_form_list(self): + self.is_valid(raise_exception=True) + if self.data.get('type') == 'local': + node = get_node(self.data.get('id')) + return node.get_form_class()().to_form_list() + elif self.data.get('type') == 'tool': + tool = QuerySet(Tool).filter(id=self.data.get("id")).first() + # todo 调用工具数据源的函数获取表单列表 + return None + + class Create(serializers.Serializer): + user_id = serializers.UUIDField(required=True, label=_('user id')) + workspace_id = serializers.CharField(required=True, label=_('workspace id')) + scope = serializers.ChoiceField( + required=False, label=_('scope'), default=KnowledgeScope.WORKSPACE, choices=KnowledgeScope.choices + ) + + @transaction.atomic + def save_workflow(self, instance: Dict): + self.is_valid(raise_exception=True) + + folder_id = instance.get('folder_id', self.data.get('workspace_id')) + if QuerySet(Knowledge).filter( + workspace_id=self.data.get('workspace_id'), folder_id=folder_id, name=instance.get('name') + ).exists(): + raise AppApiException(500, _('Knowledge base name duplicate!')) + + knowledge_id = uuid.uuid7() + knowledge = Knowledge( + id=knowledge_id, + name=instance.get('name'), + desc=instance.get('desc'), + user_id=self.data.get('user_id'), + type=instance.get('type', KnowledgeType.WORKFLOW), + scope=self.data.get('scope', KnowledgeScope.WORKSPACE), + folder_id=folder_id, + workspace_id=self.data.get('workspace_id'), + embedding_model_id=instance.get('embedding_model_id'), + meta={}, + ) + knowledge.save() + # 自动资源给授权当前用户 + UserResourcePermissionSerializer(data={ + 'workspace_id': self.data.get('workspace_id'), + 'user_id': self.data.get('user_id'), + 'auth_target_type': AuthTargetType.KNOWLEDGE.value + }).auth_resource(str(knowledge_id)) + + knowledge_workflow = KnowledgeWorkflow( + id=uuid.uuid7(), + knowledge_id=knowledge_id, + workspace_id=self.data.get('workspace_id'), + work_flow=instance.get('work_flow', {}), + ) + + knowledge_workflow.save() + + return {**KnowledgeModelSerializer(knowledge).data, 'document_list': []} + + class Operate(serializers.Serializer): + user_id = serializers.UUIDField(required=True, label=_('user id')) + workspace_id = serializers.CharField(required=True, label=_('workspace id')) + knowledge_id = serializers.UUIDField(required=True, label=_('knowledge id')) + + def edit(self, instance: Dict): + pass + + def one(self): + self.is_valid(raise_exception=True) + workflow = QuerySet(KnowledgeWorkflow).filter(knowledge_id=self.data.get('knowledge_id')).first() + return {**KnowledgeWorkflowModelSerializer(workflow).data} diff --git a/apps/knowledge/urls.py b/apps/knowledge/urls.py index 3b41be1e9ff..1ff53a9cf9a 100644 --- a/apps/knowledge/urls.py +++ b/apps/knowledge/urls.py @@ -9,12 +9,14 @@ path('workspace/knowledge/document/table_template/export', views.TableTemplate.as_view()), path('workspace//knowledge', views.KnowledgeView.as_view()), path('workspace//knowledge/base', views.KnowledgeBaseView.as_view()), + path('workspace//knowledge/workflow', views.KnowledgeWorkflowView.as_view()), path('workspace//knowledge/web', views.KnowledgeWebView.as_view()), path('workspace//knowledge/model', views.KnowledgeView.Model.as_view()), path('workspace//knowledge/embedding_model', views.KnowledgeView.EmbeddingModel.as_view()), path('workspace//knowledge/tags', views.KnowledgeView.Tags.as_view()), path('workspace//knowledge/', views.KnowledgeView.Operate.as_view()), path('workspace//knowledge//sync', views.KnowledgeView.SyncWeb.as_view()), + path('workspace//knowledge//workfolw', views.KnowledgeWorkflowView.Operate.as_view()), path('workspace//knowledge//generate_related', views.KnowledgeView.GenerateRelated.as_view()), path('workspace//knowledge//embedding', views.KnowledgeView.Embedding.as_view()), path('workspace//knowledge//hit_test', views.KnowledgeView.HitTest.as_view()), diff --git a/apps/knowledge/views/__init__.py b/apps/knowledge/views/__init__.py index ed401ad8a53..98a57a22884 100644 --- a/apps/knowledge/views/__init__.py +++ b/apps/knowledge/views/__init__.py @@ -3,3 +3,4 @@ from .paragraph import * from .problem import * from .tag import * +from .knowledge_workflow import * diff --git a/apps/knowledge/views/knowledge_workflow.py b/apps/knowledge/views/knowledge_workflow.py new file mode 100644 index 00000000000..15d7b11660a --- /dev/null +++ b/apps/knowledge/views/knowledge_workflow.py @@ -0,0 +1,104 @@ +# coding=utf-8 + +from django.utils.translation import gettext_lazy as _ +from drf_spectacular.utils import extend_schema +from rest_framework.request import Request +from rest_framework.views import APIView + +from common.auth import TokenAuth +from common.auth.authentication import has_permissions +from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants +from common.log.log import log +from common.result import result +from knowledge.api.knowledge_workflow import KnowledgeWorkflowApi +from knowledge.serializers.common import get_knowledge_operation_object +from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowSerializer + + +class KnowledgeWorkflowFormView(APIView): + authentication_classes = [TokenAuth] + + def get(self): + return result.success(KnowledgeWorkflowSerializer.Form().get_form_list()) + + +class KnowledgeWorkflowView(APIView): + authentication_classes = [TokenAuth] + + @extend_schema( + methods=['POST'], + description=_('Create knowledge workflow'), + summary=_('Create knowledge workflow'), + operation_id=_('Create knowledge workflow'), # type: ignore + parameters=KnowledgeWorkflowApi.get_parameters(), + responses=KnowledgeWorkflowApi.get_response(), + tags=[_('Knowledge Base')] # type: ignore + ) + @has_permissions( + PermissionConstants.KNOWLEDGE_CREATE.get_workspace_permission(), + RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role() + ) + def post(self, request: Request, workspace_id: str): + return result.success(KnowledgeWorkflowSerializer.Create( + data={'user_id': request.user.id, 'workspace_id': workspace_id} + ).save_workflow(request.data)) + + class Operate(APIView): + authentication_classes = [TokenAuth] + + @extend_schema( + methods=['PUT'], + description=_('Edit knowledge workflow'), + summary=_('Edit knowledge workflow'), + operation_id=_('Edit knowledge workflow'), # type: ignore + parameters=KnowledgeWorkflowApi.get_parameters(), + request=KnowledgeWorkflowApi.get_request(), + responses=KnowledgeWorkflowApi.get_response(), + tags=[_('Knowledge Base')] # type: ignore + ) + @has_permissions( + PermissionConstants.KNOWLEDGE_EDIT.get_workspace_knowledge_permission(), + PermissionConstants.KNOWLEDGE_EDIT.get_workspace_permission_workspace_manage_role(), + RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), + ViewPermission( + [RoleConstants.USER.get_workspace_role()], + [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], + CompareConstants.AND + ) + ) + @log( + menu='Knowledge Base', operate="Modify knowledge workflow", + get_operation_object=lambda r, keywords: get_knowledge_operation_object(keywords.get('knowledge_id')), + ) + def put(self, request: Request, workspace_id: str, knowledge_id: str): + return result.success(KnowledgeWorkflowSerializer.Operate( + data={'user_id': request.user.id, 'workspace_id': workspace_id, 'knowledge_id': knowledge_id} + ).edit(request.data)) + + @extend_schema( + methods=['GET'], + description=_('Get knowledge workflow'), + summary=_('Get knowledge workflow'), + operation_id=_('Get knowledge workflow'), # type: ignore + parameters=KnowledgeWorkflowApi.get_parameters(), + responses=KnowledgeWorkflowApi.get_response(), + tags=[_('Knowledge Base')] # type: ignore + ) + @has_permissions( + PermissionConstants.KNOWLEDGE_READ.get_workspace_knowledge_permission(), + PermissionConstants.KNOWLEDGE_READ.get_workspace_permission_workspace_manage_role(), + RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), + ViewPermission( + [RoleConstants.USER.get_workspace_role()], + [PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()], + CompareConstants.AND + ), + ) + def get(self, request: Request, workspace_id: str, knowledge_id: str): + return result.success(KnowledgeWorkflowSerializer.Operate( + data={'user_id': request.user.id, 'workspace_id': workspace_id, 'knowledge_id': knowledge_id} + ).one()) + + +class KnowledgeWorkflowVersionView(APIView): + pass diff --git a/ui/src/api/knowledge/knowledge.ts b/ui/src/api/knowledge/knowledge.ts index 5e0e79ecc19..d36f9b03741 100644 --- a/ui/src/api/knowledge/knowledge.ts +++ b/ui/src/api/knowledge/knowledge.ts @@ -196,6 +196,18 @@ const postKnowledge: (data: knowledgeData, loading?: Ref) => Promise) => Promise> = ( + data, + loading, +) => { + return post(`${prefix.value}/workflow`, data, undefined, loading) +} /** * 获取当前用户可使用的向量化模型列表 (没用到) * @param application_id @@ -250,7 +262,7 @@ const postLarkKnowledge: (data: any, loading?: Ref) => Promise + loading?: Ref, ) => Promise> = (knowledge_id, data, loading) => { return put(`${prefix.value}/lark/${knowledge_id}`, data, undefined, loading) } @@ -262,45 +274,45 @@ const getAllTags: (params: any, loading?: Ref) => Promise> return get(`${prefix.value}/tags`, params, loading) } -const getTags: (knowledge_id: string, params: any, loading?: Ref) => Promise> = ( - knowledge_id, - params, - loading, -) => { +const getTags: ( + knowledge_id: string, + params: any, + loading?: Ref, +) => Promise> = (knowledge_id, params, loading) => { return get(`${prefix.value}/${knowledge_id}/tags`, params, loading) } -const postTags: (knowledge_id: string, tags: any, loading?: Ref) => Promise> = ( - knowledge_id, - tags, - loading, -) => { +const postTags: ( + knowledge_id: string, + tags: any, + loading?: Ref, +) => Promise> = (knowledge_id, tags, loading) => { return post(`${prefix.value}/${knowledge_id}/tags`, tags, null, loading) } -const putTag: (knowledge_id: string, tag_id: string, tag: any, loading?: Ref) => Promise> = ( - knowledge_id, - tag_id, - tag, - loading, -) => { +const putTag: ( + knowledge_id: string, + tag_id: string, + tag: any, + loading?: Ref, +) => Promise> = (knowledge_id, tag_id, tag, loading) => { return put(`${prefix.value}/${knowledge_id}/tags/${tag_id}`, tag, null, loading) } -const delTag: (knowledge_id: string, tag_id: string, type: string, loading?: Ref) => Promise> = ( - knowledge_id, - tag_id, - type, - loading, -) => { +const delTag: ( + knowledge_id: string, + tag_id: string, + type: string, + loading?: Ref, +) => Promise> = (knowledge_id, tag_id, type, loading) => { return del(`${prefix.value}/${knowledge_id}/tags/${tag_id}/${type}`, null, loading) } -const delMulTag: (knowledge_id: string, tags: any, loading?: Ref) => Promise> = ( - knowledge_id, - tags, - loading, -) => { +const delMulTag: ( + knowledge_id: string, + tags: any, + loading?: Ref, +) => Promise> = (knowledge_id, tags, loading) => { return put(`${prefix.value}/${knowledge_id}/tags/batch_delete`, tags, null, loading) } @@ -326,5 +338,6 @@ export default { postTags, putTag, delTag, - delMulTag + delMulTag, + createWorkflowKnowledge, } diff --git a/ui/src/assets/knowledge/logo_workflow.svg b/ui/src/assets/knowledge/logo_workflow.svg new file mode 100644 index 00000000000..28f4b0fdaae --- /dev/null +++ b/ui/src/assets/knowledge/logo_workflow.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/ui/src/enums/application.ts b/ui/src/enums/application.ts index 930988c4658..873c77b6764 100644 --- a/ui/src/enums/application.ts +++ b/ui/src/enums/application.ts @@ -6,6 +6,7 @@ export enum SearchMode { export enum WorkflowType { Base = 'base-node', + KnowledgeBase = 'knowledge-base-node', Start = 'start-node', AiChat = 'ai-chat-node', SearchKnowledge = 'search-knowledge-node', @@ -37,10 +38,18 @@ export enum WorkflowType { VariableAggregationNode = 'variable-aggregation-node', VideoUnderstandNode = 'video-understand-node', ParameterExtractionNode = 'parameter-extraction-node', + DataSourceLocalNode = 'data-source-local-node', +} +export enum WorkflowKind { + DataSource = 'data-source', } export enum WorkflowMode { // 应用工作流 Application = 'application', // 应用工作流循环 ApplicationLoop = 'application-loop', + // 知识库工作流 + Knowledge = 'knowledge', + // 知识库工作流循环体 + KnowledgeLoop = 'knowledge-loop', } diff --git a/ui/src/locales/lang/en-US/views/index.ts b/ui/src/locales/lang/en-US/views/index.ts index d5af697347c..954a5ccba46 100644 --- a/ui/src/locales/lang/en-US/views/index.ts +++ b/ui/src/locales/lang/en-US/views/index.ts @@ -16,6 +16,7 @@ import chatLog from './chat-log' import chatUser from './chat-user' import operateLog from './operate-log' import shared from './shared' +import knowledgeWorkflow from './knowledge-workflow' export default { login, model, @@ -34,5 +35,6 @@ export default { chatLog, chatUser, operateLog, - shared + shared, + knowledgeWorkflow, } diff --git a/ui/src/locales/lang/en-US/views/knowledge-workflow.ts b/ui/src/locales/lang/en-US/views/knowledge-workflow.ts new file mode 100644 index 00000000000..dc20ddd6adc --- /dev/null +++ b/ui/src/locales/lang/en-US/views/knowledge-workflow.ts @@ -0,0 +1,479 @@ +export default { + node: 'Node', + nodeName: 'Node Name', + baseComponent: 'Basic', + nodeSetting: 'Node Settings', + workflow: 'Workflow', + searchBar: { + placeholder: 'Search by name', + }, + info: { + previewVersion: 'Preview Version:', + saveTime: 'Last Saved:', + }, + setting: { + restoreVersion: 'Restore Previous Version"', + restoreCurrentVersion: 'Restore to This Version', + addComponent: 'Add', + releaseHistory: 'Release History', + autoSave: 'Auto Save', + latestRelease: 'Latest Release', + copyParam: 'Copy Parameters', + debug: 'Run', + exit: 'Exit', + exitSave: 'Save & Exit', + }, + tip: { + noData: 'No related results found', + nameMessage: 'Name cannot be empty!', + onlyRight: 'Connections can only be made from the right anchor', + notRecyclable: 'Loop connections are not allowed', + onlyLeft: 'Connections can only be made to the left anchor', + applicationNodeError: 'This application is unavailable', + toolNodeError: 'This tool node is unavailable', + repeatedNodeError: 'A node with this name already exists', + cannotCopy: 'Cannot be copied', + copyError: 'Node already copied', + paramErrorMessage: 'Parameter already exists: ', + saveMessage: 'Current changes have not been saved. Save before exiting?', + }, + delete: { + confirmTitle: 'Confirm to delete this node?', + deleteMessage: 'This node cannot be deleted', + }, + control: { + zoomOut: 'Zoom Out', + zoomIn: 'Zoom In', + fitView: 'Fit to Screen', + retract: 'Collapse All', + extend: 'Expand All', + beautify: 'Auto-Arrange', + }, + variable: { + global: 'Global Variable', + Referencing: 'Referenced Variable', + ReferencingRequired: 'Referenced variable is required', + ReferencingError: 'Invalid referenced variable', + NoReferencing: 'Referenced variable does not exist', + placeholder: 'Please select a variable', + inputPlaceholder: 'Please enter variable', + loop: 'Loop Variable', + }, + condition: { + title: 'Execution Condition', + front: 'Precondition', + AND: 'All', + OR: 'Any', + text: 'After the connected node is executed, execute the current node', + }, + validate: { + startNodeRequired: 'Start node is required', + startNodeOnly: 'Only one start node is allowed', + baseNodeRequired: 'Base information node is required', + baseNodeOnly: 'Only one base information node is allowed', + notInWorkFlowNode: 'Node not in workflow', + noNextNode: 'Next node does not exist', + nodeUnavailable: 'Node unavailable', + needConnect1: 'The branch of the node needs to be connected', + cannotEndNode: 'This node cannot be used as an end node', + loopNodeBreakNodeRequired: 'Wireless loop must have a Break node', + }, + nodes: { + classify: { + aiCapability: 'AI capability', + businessLogic: 'Business logic', + other: 'Other', + dataProcessing: 'Data Processing', + }, + startNode: { + label: 'Start', + question: 'User Question', + currentTime: 'Current Time', + }, + baseNode: { + label: 'Base Information', + appName: { + label: 'App Name', + }, + appDescription: { + label: 'App Description', + }, + fileUpload: { + label: 'File Upload', + tooltip: 'When enabled, the Q&A page will display a file upload button.', + }, + FileUploadSetting: { + title: 'File Upload Settings', + maxFiles: 'Maximum number of files per upload', + fileLimit: 'Maximum size per file (MB)', + fileUploadType: { + label: 'File types allowed for upload', + documentText: 'Requires "Document Content Extraction" node to parse document content', + imageText: 'Requires "Image Understanding" node to parse image content', + videoText: 'Requires "Video Understanding" node to parse video content', + audioText: 'Requires "Speech-to-Text" node to parse audio content', + }, + }, + }, + aiChatNode: { + label: 'AI Chat', + text: 'Chat with an AI model', + answer: 'AI Content', + returnContent: { + label: 'Return Content', + tooltip: `If turned off, the content of this node will not be output to the user. + If you want the user to see the output of this node, please turn on the switch.`, + }, + defaultPrompt: 'Known Information', + think: 'Thinking Process', + historyMessage: 'Historical chat records', + }, + searchKnowledgeNode: { + label: 'Knowledge Retrieval', + text: 'Allows you to query text content related to user questions from the Knowledge', + paragraph_list: 'List of retrieved segments', + is_hit_handling_method_list: 'List of segments that meet direct response criteria', + result: 'Search Result', + directly_return: 'Content of segments that meet direct response criteria', + searchParam: 'Retrieval Parameters', + searchQuestion: { + label: 'Question', + placeholder: 'Please select a search question', + requiredMessage: 'Please select a search question', + }, + }, + searchDocumentNode: { + label: 'Document Tag Retrieval', + text: 'Search for documents that meet the conditions based on the document label within the specified search scope', + selectKnowledge: 'Search Scope', + searchSetting: 'Search Settings', + custom: 'Manual', + customTooltip: 'Manually set tag filtering conditions', + auto: 'Automatic', + autoTooltip: 'Automatically filter setting tag conditions based on the search question', + document_list: 'Document List', + knowledge_list: 'Knowledge Base List', + result: 'Search Results', + searchParam: 'Search Parameters', + select_variable: 'Select Variable', + valueMessage: `Value or {name} `, + showKnowledge: { + label: 'Results are displayed in the knowledge source', + requiredMessage: 'Please set parameters', + }, + searchQuestion: { + label: 'Search Question', + placeholder: 'Please select a search question', + requiredMessage: 'Please select a search question', + }, + }, + questionNode: { + label: 'Question Optimization', + text: 'Optimize and improve the current question based on historical chat records to better match knowledge segments', + result: 'Optimized Question Result', + systemDefault: `#Role +You are a master of problem optimization, adept at accurately inferring user intentions based on context and optimizing the questions raised by users. + +##Skills +###Skill 1: Optimizing Problems +2. Receive user input questions. +3. Carefully analyze the meaning of the problem based on the context. +4. Output optimized problems. + +##Limitations: +-Only return the optimized problem without any additional explanation or clarification. +-Ensure that the optimized problem accurately reflects the original problem intent and does not alter the original intention.`, + }, + conditionNode: { + label: 'Conditional Branch', + text: 'Trigger different nodes based on conditions', + branch_name: 'Branch Name', + conditions: { + label: 'Conditions', + info: 'Meets the following', + requiredMessage: 'Please select conditions', + }, + valueMessage: 'Please enter a value', + addCondition: 'Add Condition', + addBranch: 'Add Branch', + }, + replyNode: { + label: 'Specified Reply', + text: 'Specify reply content, referenced variables will be converted to strings for output', + replyContent: 'Reply Content', + }, + rerankerNode: { + label: 'Multi-path Recall', + text: 'Use a re-ranking model to refine retrieval results from multiple knowledge sources', + result_list: 'Re-ranked Results List', + result: 'Re-ranking Result', + rerankerContent: { + label: 'Re-ranking Content', + requiredMessage: 'Please select re-ranking content', + }, + higher: 'Higher', + ScoreTooltip: 'The higher the Score, the stronger the relevance.', + max_paragraph_char_number: 'Maximum Character', + reranker_model: { + label: 'Rerank', + placeholder: 'Please select a rerank', + }, + }, + formNode: { + label: 'Form Input', + text: 'Collect user input during Q&A and use it in subsequent processes', + form_content_format1: 'Hello, please fill out the form below:', + form_content_format2: 'Click the [Submit] button after filling it out.', + form_data: 'All Form Content', + formContent: { + label: 'Form Output Content', + requiredMessage: + 'Please set the output content of this node, { form } is a placeholder for the form.', + tooltip: 'Define the output content of this node. { form } is a placeholder for the form', + }, + formAllContent: 'All Form Content', + formSetting: 'Form Configuration', + }, + documentExtractNode: { + label: 'Document Content Extraction', + text: 'Extract content from documents', + content: 'Document Content', + }, + imageUnderstandNode: { + label: 'Image Understanding', + text: 'Analyze images to identify objects, scenes, and provide answers', + answer: 'AI Content', + model: { + label: 'Vision Model', + requiredMessage: 'Please select a vision model', + }, + image: { + label: 'Select Image', + requiredMessage: 'Please select an image', + }, + }, + variableAssignNode: { + label: 'Variable Assign', + text: 'Update the value of the global variable', + assign: 'Set Value', + }, + variableAggregationNode: { + label: 'Variable Aggregation', + text: 'Aggregate variables of each group according to the aggregation strategy', + Strategy: 'Aggregation Strategy', + placeholder: 'Return the first non-null value of each group', + placeholder1: 'Return the set of variables for each group', + group: { + noneError: 'Name cannot be empty', + dupError: 'Name cannot be duplicated', + }, + addGroup: 'Add Group', + editGroup: 'Edit Group', + }, + mcpNode: { + label: 'MCP Node', + text: 'Call external MCP services to process data', + getToolsSuccess: 'Tools fetched successfully', + getTool: 'Fetch Tools', + toolParam: 'Tool Parameters', + mcpServerTip: 'Please enter MCP server configuration in JSON format', + mcpToolTip: 'Please select a tool', + configLabel: 'MCP Server Config (Only SSE/Streamable HTTP calls are supported)', + reference: 'Reference MCP', + }, + imageGenerateNode: { + label: 'Image Generation', + text: 'Generate images based on provided text content', + answer: 'AI Content', + model: { + label: 'Image Generation Model', + requiredMessage: 'Please select an image generation model', + }, + prompt: { + label: 'Positive Prompt', + tooltip: 'Describe elements and visual features you want in the generated image', + }, + negative_prompt: { + label: 'Negative Prompt', + tooltip: 'Describe elements you want to exclude from the generated image', + placeholder: + 'Please describe content you do not want to generate, such as color, bloody content', + }, + }, + textToVideoGenerate: { + label: 'Text-to-Video', + text: 'Generate video based on provided text content', + answer: 'AI Response Content', + model: { + label: 'Text-to-Video Model', + requiredMessage: 'Please select a text-to-video model', + }, + prompt: { + label: 'Prompt (Positive)', + tooltip: + 'Positive prompt, used to describe elements and visual features expected in the generated video', + }, + negative_prompt: { + label: 'Prompt (Negative)', + tooltip: + "Negative prompt, used to describe content you don't want to see in the video, which can restrict the video generation", + placeholder: + "Please describe video content you don't want to generate, such as: colors, bloody content", + }, + }, + imageToVideoGenerate: { + label: 'Image-to-Video', + text: 'Generate video based on provided images', + answer: 'AI Response Content', + model: { + label: 'Image-to-Video Model', + requiredMessage: 'Please select an image-to-video model', + }, + prompt: { + label: 'Prompt (Positive)', + tooltip: + 'Positive prompt, used to describe elements and visual features expected in the generated video', + }, + negative_prompt: { + label: 'Prompt (Negative)', + tooltip: + "Negative prompt, used to describe content you don't want to see in the video, which can restrict the video generation", + placeholder: + "Please describe video content you don't want to generate, such as: colors, bloody content", + }, + first_frame: { + label: 'First Frame Image', + requiredMessage: 'Please select the first frame image', + }, + last_frame: { + label: 'Last Frame Image', + requiredMessage: 'Please select the last frame image', + }, + }, + speechToTextNode: { + label: 'Speech2Text', + text: 'Convert audio to text through speech recognition model', + stt_model: { + label: 'Speech Recognition Model', + }, + audio: { + label: 'Select Audio File', + placeholder: 'Please select an audio file', + }, + }, + textToSpeechNode: { + label: 'TTS', + text: 'Convert text to audio through speech synthesis model', + tts_model: { + label: 'Speech Synthesis Model', + }, + content: { + label: 'Select Text Content', + }, + }, + toolNode: { + label: 'Custom Tool', + text: 'Execute custom scripts to achieve data processing', + }, + intentNode: { + label: 'IntentNode', + text: 'Match user questions with user-defined intent classifications', + other: 'other', + error2: 'Repeated intent', + placeholder: 'Please choose a classification option', + classify: { + label: 'Intent classify', + placeholder: 'Please input', + }, + input: { + label: 'Input', + }, + }, + applicationNode: { + label: 'APP Node', + }, + loopNode: { + label: 'Loop Node', + text: 'Repeat a series of tasks by setting the number of loops and logic', + loopType: { + label: 'Loop Type', + requiredMessage: 'Please select a loop type', + arrayLoop: 'Array Loop', + numberLoop: 'Loop for Specified Times', + infiniteLoop: 'Infinite Loop', + }, + loopNumber: { + label: 'Loop Number', + requiredMessage: 'Please enter the number of loops', + }, + loopArray: { + label: 'Circular Array', + requiredMessage: 'Circular Array is required', + placeholder: 'Please select a circular array', + }, + loopSetting: 'Loop Settings', + loopDetail: 'Loop Details', + }, + loopStartNode: { + label: 'Loop Start', + loopIndex: 'Index', + loopItem: 'Loop Element', + }, + loopBodyNode: { + label: 'Loop Body', + text: 'Loop Body', + }, + loopContinueNode: { + label: 'Continue', + text: 'Used to terminate the current loop and proceed to the next one.', + isContinue: 'Continue', + }, + loopBreakNode: { + label: 'Break', + text: 'Terminate the current loop and exit the loop body', + isBreak: 'Break', + }, + variableSplittingNode: { + label: 'Variable Splitting', + text: 'By configuring JSON Path expressions, parse and split the input JSON format variable', + result: 'Result', + splitVariables: 'Split Variables', + inputVariables: 'Input Variable', + addVariables: 'Add Variables', + editVariables: 'Edit Variables', + variableListPlaceholder: 'Please add split variables', + expression: { + label: 'Expression', + placeholder: 'Please enter expression', + tooltip: 'Please use JSON Path expressions to split variables, e.g.: $.store.book', + }, + }, + parameterExtractionNode: { + label: 'Parameter Extraction', + text: 'Use AI models to extract structured parameters', + extractParameters: { + label: 'Extract Parameters', + variableListPlaceholder: 'Please add extraction parameters', + parameterType: 'Parameter Type', + }, + }, + }, + compare: { + is_null: 'Is null', + is_not_null: 'Is not null', + contain: 'Contains', + not_contain: 'Does not contain', + eq: 'Equal to', + ge: 'Greater than or equal to', + gt: 'Greater than', + le: 'Less than or equal to', + lt: 'Less than', + len_eq: 'Length equal to', + len_ge: 'Length greater than or equal to', + len_gt: 'Length greater than', + len_le: 'Length less than or equal to', + len_lt: 'Length less than', + }, + SystemPromptPlaceholder: 'System Prompt, can reference variables in the system, such as', + UserPromptPlaceholder: 'User Prompt, can reference variables in the system, such as', +} diff --git a/ui/src/locales/lang/en-US/views/knowledge.ts b/ui/src/locales/lang/en-US/views/knowledge.ts index b8307c421ac..616855ad34f 100644 --- a/ui/src/locales/lang/en-US/views/knowledge.ts +++ b/ui/src/locales/lang/en-US/views/knowledge.ts @@ -6,6 +6,9 @@ export default { searchBar: { placeholder: 'Search by name', }, + operation: { + publish: 'Publish', + }, setting: { vectorization: 'Vectorization', sync: 'Sync', @@ -27,6 +30,7 @@ export default { generalKnowledge: 'General Knowledge', webKnowledge: 'Web Knowledge', larkKnowledge: 'Lark Knowledge', + workflowKnowledge: 'Workflow Knowledge', yuqueKnowledge: 'Yuque Knowledge', generalInfo: 'Upload local documents', webInfo: 'Sync text data from a web site', @@ -36,6 +40,8 @@ export default { createWebKnowledge: 'Create Web Knowledge', createLarkKnowledge: 'Create Lark Knowledge', createYuqueKnowledge: 'Create Yuque Knowledge', + createWorkflowKnowledge: 'Create Workflow Knowledge', + workflowInfo: 'Building a knowledge base through custom workflow methods', }, form: { knowledgeName: { diff --git a/ui/src/locales/lang/zh-CN/views/index.ts b/ui/src/locales/lang/zh-CN/views/index.ts index d5af697347c..954a5ccba46 100644 --- a/ui/src/locales/lang/zh-CN/views/index.ts +++ b/ui/src/locales/lang/zh-CN/views/index.ts @@ -16,6 +16,7 @@ import chatLog from './chat-log' import chatUser from './chat-user' import operateLog from './operate-log' import shared from './shared' +import knowledgeWorkflow from './knowledge-workflow' export default { login, model, @@ -34,5 +35,6 @@ export default { chatLog, chatUser, operateLog, - shared + shared, + knowledgeWorkflow, } diff --git a/ui/src/locales/lang/zh-CN/views/knowledge-workflow.ts b/ui/src/locales/lang/zh-CN/views/knowledge-workflow.ts new file mode 100644 index 00000000000..a712ba81e21 --- /dev/null +++ b/ui/src/locales/lang/zh-CN/views/knowledge-workflow.ts @@ -0,0 +1,492 @@ +export default { + node: '节点', + nodeName: '节点名称', + baseComponent: '基础组件', + nodeSetting: '节点设置', + workflow: '工作流', + searchBar: { + placeholder: '按名称搜索', + }, + info: { + previewVersion: '预览版本:', + saveTime: '保存时间:', + }, + setting: { + restoreVersion: '恢复版本', + restoreCurrentVersion: '恢复此版本', + addComponent: '添加组件', + releaseHistory: '发布历史', + autoSave: '自动保存', + latestRelease: '最近发布', + copyParam: '复制参数', + debug: '调试', + exit: '直接退出', + exitSave: '保存并退出', + }, + tip: { + noData: '没有找到相关结果', + nameMessage: '名字不能为空!', + onlyRight: '只允许从右边的锚点连出', + notRecyclable: '不可循环连线', + onlyLeft: '只允许连接左边的锚点', + applicationNodeError: '该应用不可用', + toolNodeError: '该工具不可用', + repeatedNodeError: '节点名称已存在!', + cannotCopy: '不能被复制', + copyError: '已复制节点', + paramErrorMessage: '参数已存在: ', + saveMessage: '当前的更改尚未保存,是否保存后退出?', + }, + delete: { + confirmTitle: '确定删除该节点?', + deleteMessage: '节点不允许删除', + }, + control: { + zoomOut: '缩小', + zoomIn: '放大', + fitView: '适应', + retract: '收起全部节点', + extend: '展开全部节点', + beautify: '一键美化', + }, + variable: { + global: '全局变量', + chat: '会话变量', + Referencing: '引用变量', + ReferencingRequired: '引用变量必填', + ReferencingError: '引用变量错误', + NoReferencing: '不存在的引用变量', + placeholder: '请选择变量', + inputPlaceholder: '请输入变量', + loop: '循环变量', + }, + condition: { + title: '执行条件', + front: '前置', + AND: '所有', + OR: '任一', + text: '连线节点执行完,执行当前节点', + }, + validate: { + startNodeRequired: '开始节点必填', + startNodeOnly: '开始节点只能有一个', + baseNodeRequired: '基本信息节点必填', + baseNodeOnly: '基本信息节点只能有一个', + notInWorkFlowNode: '未在流程中的节点', + noNextNode: '不存在的下一个节点', + nodeUnavailable: '节点不可用', + needConnect1: '节点的', + needConnect2: '分支需要连接', + cannotEndNode: '节点不能当做结束节点', + loopNodeBreakNodeRequired: '无限循环 必须存在 Break 节点', + }, + nodes: { + classify: { + aiCapability: 'AI能力', + businessLogic: '业务逻辑', + other: '其他', + dataProcessing: '数据处理', + }, + startNode: { + label: '开始', + question: '用户问题', + currentTime: '当前时间', + }, + baseNode: { + label: '基本信息', + appName: { + label: '应用名称', + }, + appDescription: { + label: '应用描述', + }, + fileUpload: { + label: '文件上传', + tooltip: '开启后,问答页面会显示上传文件的按钮。', + }, + FileUploadSetting: { + title: '文件上传设置', + maxFiles: '单次上传最多文件数', + fileLimit: '每个文件最大(MB)', + fileUploadType: { + label: '上传的文件类型', + documentText: '需要使用“文档内容提取”节点解析文档内容', + imageText: '需要使用“视觉模型”节点解析图片内容', + audioText: '需要使用“语音转文本”节点解析音频内容', + videoText: '需要使用“视频理解”节点解析视频内容', + otherText: '需要自行解析该类型文件', + }, + }, + }, + aiChatNode: { + label: 'AI 对话', + text: '与 AI 大模型进行对话', + answer: 'AI 回答内容', + returnContent: { + label: '返回内容', + tooltip: `关闭后该节点的内容则不输出给用户。 + 如果你想让用户看到该节点的输出内容,请打开开关。`, + }, + defaultPrompt: '已知信息', + think: '思考过程', + historyMessage: '历史聊天记录', + }, + searchKnowledgeNode: { + label: '知识库检索', + text: '关联知识库,查找与问题相关的分段', + paragraph_list: '检索结果的分段列表', + is_hit_handling_method_list: '满足直接回答的分段列表', + result: '检索结果', + directly_return: '满足直接回答的分段内容', + searchParam: '检索参数', + showKnowledge: { + label: '结果显示在知识来源中', + requiredMessage: '请设置参数', + }, + searchQuestion: { + label: '检索问题', + placeholder: '请选择检索问题', + requiredMessage: '请选择检索问题', + }, + }, + searchDocumentNode: { + label: '文档标签检索', + text: '从设定的检索范围中,根据文档标签检索出满足条件的文档', + selectKnowledge: '检索范围', + searchSetting: '检索设置', + custom: '手动', + customTooltip: '手动设置标签过滤条件', + auto: '自动', + autoTooltip: '根据检索问题自动匹配文档标签', + document_list: '文档列表', + knowledge_list: '知识库列表', + result: '检索结果', + searchParam: '检索参数', + select_variable: '选择变量', + valueMessage: `值或{name}`, + showKnowledge: { + label: '结果显示在知识来源中', + requiredMessage: '请设置参数', + }, + searchQuestion: { + label: '检索问题', + placeholder: '请选择检索问题', + requiredMessage: '请选择检索问题', + }, + }, + questionNode: { + label: '问题优化', + text: '根据历史聊天记录优化完善当前问题,更利于匹配知识库分段', + result: '问题优化结果', + systemDefault: `# 角色 +你是一位问题优化大师,擅长根据上下文精准揣测用户意图,并对用户提出的问题进行优化。 + +## 技能 +### 技能 1: 优化问题 +2. 接收用户输入的问题。 +3. 依据上下文仔细分析问题含义。 +4. 输出优化后的问题。 + +## 限制: +- 仅返回优化后的问题,不进行额外解释或说明。 +- 确保优化后的问题准确反映原始问题意图,不得改变原意。`, + }, + conditionNode: { + label: '判断器', + text: '根据不同条件执行不同的节点', + branch_name: '分支名称', + conditions: { + label: '条件', + info: '符合以下', + requiredMessage: '请选择条件', + }, + valueMessage: '请输入值', + addCondition: '添加条件', + addBranch: '添加分支', + }, + replyNode: { + label: '指定回复', + text: '指定回复内容,引用变量会转换为字符串进行输出', + replyContent: '回复内容', + }, + rerankerNode: { + label: '多路召回', + text: '使用重排模型对多个知识库的检索结果进行二次召回', + result_list: '重排结果列表', + result: '重排结果', + rerankerContent: { + label: '重排内容', + requiredMessage: '请选择重排内容', + }, + higher: '高于', + ScoreTooltip: 'Score越高相关性越强。', + max_paragraph_char_number: '最大引用字符数', + reranker_model: { + label: '重排模型', + placeholder: '请选择重排模型', + }, + }, + formNode: { + label: '表单收集', + text: '在问答过程中用于收集用户信息,可以根据收集到表单数据执行后续流程', + form_content_format1: '你好,请先填写下面表单内容:', + form_content_format2: '填写后请点击【提交】按钮进行提交。', + form_data: '表单全部内容', + formContent: { + label: '表单输出内容', + requiredMessage: '请表单输出内容', + tooltip: '设置执行该节点输出的内容,{ form } 为表单的占位符。', + }, + formAllContent: '表单全部内容', + formSetting: '表单配置', + }, + documentExtractNode: { + label: '文档内容提取', + text: '提取文档中的内容', + content: '文档内容', + }, + imageUnderstandNode: { + label: '图片理解', + text: '识别出图片中的对象、场景等信息回答用户问题', + answer: 'AI 回答内容', + model: { + label: '视觉模型', + requiredMessage: '请选择视觉模型', + }, + image: { + label: '选择图片', + requiredMessage: '请选择图片', + }, + }, + variableAggregationNode: { + label: '变量聚合', + text: '按聚合策略聚合每组的变量', + Strategy: '聚合策略', + placeholder: '返回每组的第一个非空值', + placeholder1: '返回每组变量的集合', + group: { + noneError: '名称不能为空', + dupError: '名称不能重复', + }, + addGroup: '添加分组', + editGroup: '编辑分组', + }, + variableAssignNode: { + label: '变量赋值', + text: '更新全局变量的值', + assign: '赋值', + }, + mcpNode: { + label: 'MCP 调用', + text: '通过SSE/Streamable HTTP方式执行MCP服务中的工具', + getToolsSuccess: '获取工具成功', + getTool: '获取工具', + toolParam: '工具参数', + mcpServerTip: '请输入JSON格式的MCP服务器配置', + mcpToolTip: '请选择工具', + configLabel: 'MCP Server Config (仅支持SSE/Streamable HTTP调用方式)', + reference: '引用MCP', + }, + imageGenerateNode: { + label: '图片生成', + text: '根据提供的文本内容生成图片', + answer: 'AI 回答内容', + model: { + label: '图片生成模型', + requiredMessage: '请选择图片生成模型', + }, + prompt: { + label: '提示词(正向)', + tooltip: '正向提示词,用来描述生成图像中期望包含的元素和视觉特点', + }, + negative_prompt: { + label: '提示词(负向)', + tooltip: '反向提示词,用来描述不希望在画面中看到的内容,可以对画面进行限制。', + placeholder: '请描述不想生成的图片内容,比如:颜色、血腥内容', + }, + }, + textToVideoGenerate: { + label: '文生视频', + text: '根据提供的文本内容生成视频', + answer: 'AI 回答内容', + model: { + label: '文生视频模型', + requiredMessage: '请选择文生视频模型', + }, + prompt: { + label: '提示词(正向)', + tooltip: '正向提示词,用来描述生成视频中期望包含的元素和视觉特点', + }, + negative_prompt: { + label: '提示词(负向)', + tooltip: '反向提示词,用来描述不希望在视频中看到的内容,可以对视频进行限制。', + placeholder: '请描述不想生成的视频内容,比如:颜色、血腥内容', + }, + }, + videoUnderstandNode: { + label: '视频理解', + text: '识别出视频中的对象、场景等信息回答用户问题', + answer: 'AI 回答内容', + model: { + label: '视觉模型', + requiredMessage: '请选择视觉模型', + }, + image: { + label: '选择视频', + requiredMessage: '请选择视频', + }, + }, + imageToVideoGenerate: { + label: '图生视频', + text: '根据提供的图片生成视频', + answer: 'AI 回答内容', + model: { + label: '图生视频模型', + requiredMessage: '请选择图生视频模型', + }, + prompt: { + label: '提示词(正向)', + tooltip: '正向提示词,用来描述生成视频中期望包含的元素和视觉特点', + }, + negative_prompt: { + label: '提示词(负向)', + tooltip: '反向提示词,用来描述不希望在视频中看到的内容,可以对视频进行限制。', + placeholder: '请描述不想生成的视频内容,比如:颜色、血腥内容', + }, + first_frame: { + label: '首帧图片', + requiredMessage: '请选择首帧图片', + }, + last_frame: { + label: '尾帧图片', + requiredMessage: '请选择尾帧图片', + }, + }, + speechToTextNode: { + label: '语音转文本', + text: '将音频通过语音识别模型转换为文本', + stt_model: { + label: '语音识别模型', + }, + audio: { + label: '选择语音文件', + placeholder: '请选择语音文件', + }, + }, + textToSpeechNode: { + label: '文本转语音', + text: '将文本通过语音合成模型转换为音频', + tts_model: { + label: '语音合成模型', + }, + content: { + label: '选择文本内容', + }, + }, + toolNode: { + label: '自定义工具', + text: '通过执行自定义脚本,实现数据处理', + }, + intentNode: { + label: '意图识别', + text: '将用户问题与用户预设的意图分类进行匹配', + other: '其他', + error2: '意图重复', + placeholder: '请选择分类项', + classify: { + label: '意图分类', + placeholder: '请输入', + }, + input: { + label: '输入', + }, + }, + applicationNode: { + label: '应用节点', + }, + loopNode: { + label: '循环节点', + text: '通过设置循环次数和逻辑,重复执行一系列任务', + loopType: { + label: '循环类型', + requiredMessage: '请选择循环类型', + arrayLoop: '数组循环', + numberLoop: '指定次数循环', + infiniteLoop: '无限循环', + }, + loopNumber: { + label: '循环次数', + requiredMessage: '循环次数必填', + }, + loopArray: { + label: '循环数组', + requiredMessage: '循环数组必填', + placeholder: '请选择循环数组', + }, + loopSetting: '循环设置', + loopDetail: '循环详情', + }, + loopStartNode: { + label: '循环开始', + loopIndex: '下标', + loopItem: '循环元素', + }, + loopBodyNode: { + label: '循环体', + text: '循环体', + }, + loopContinueNode: { + label: 'Continue', + text: '用于终止当前循环,执行下次循环', + isContinue: 'Continue', + }, + loopBreakNode: { + label: 'Break', + text: '终止当前循环,跳出循环体', + isBreak: 'Break', + }, + variableSplittingNode: { + label: '变量拆分', + text: '通过配置JSON Path 表达式,对输入的 JSON 格式变量进行解析和拆分', + splitVariables: '拆分变量', + inputVariables: '输入变量', + addVariables: '添加变量', + editVariables: '编辑变量', + variableListPlaceholder: '请添加拆分变量', + expression: { + label: '表达式', + placeholder: '请输入表达式', + tooltip: '请使用JSON Path 表达式拆分变量,例如:$.store.book', + }, + }, + parameterExtractionNode: { + label: '参数提取', + text: '利用 AI 模型提取结构化参数', + extractParameters: { + label: '提取参数', + variableListPlaceholder: '请添加提取参数', + parameterType: '参数类型', + }, + }, + }, + compare: { + is_null: '为空', + is_not_null: '不为空', + contain: '包含', + not_contain: '不包含', + eq: '等于', + ge: '大于等于', + gt: '大于', + le: '小于等于', + lt: '小于', + len_eq: '长度等于', + len_ge: '长度大于等于', + len_gt: '长度大于', + len_le: '长度小于等于', + len_lt: '长度小于', + is_true: '为真', + is_not_true: '不为真', + }, + SystemPromptPlaceholder: '系统提示词,可以引用系统中的变量:如', + UserPromptPlaceholder: '用户提示词,可以引用系统中的变量:如', +} diff --git a/ui/src/locales/lang/zh-CN/views/knowledge.ts b/ui/src/locales/lang/zh-CN/views/knowledge.ts index 681ebe5045d..022b8b2ce48 100644 --- a/ui/src/locales/lang/zh-CN/views/knowledge.ts +++ b/ui/src/locales/lang/zh-CN/views/knowledge.ts @@ -6,6 +6,9 @@ export default { vectorization: '向量化', sync: '同步', }, + operation: { + publish: '发布', + }, tip: { professionalMessage: '社区版最多支持 50 个知识库,如需拥有更多知识库,请升级为专业版。', syncSuccess: '同步任务发送成功', @@ -21,6 +24,7 @@ export default { generalKnowledge: '通用知识库', webKnowledge: 'web知识库', larkKnowledge: '飞书知识库', + workflowKnowledge: '工作流知识库', yuqueKnowledge: '语雀知识库', generalInfo: '通过上传文件或手动录入构建知识库', webInfo: '通过网站链接构建知识库', @@ -30,6 +34,8 @@ export default { createWebKnowledge: '创建 web 知识库', createLarkKnowledge: '创建飞书知识库', createYuqueKnowledge: '创建语雀知识库', + createWorkflowKnowledge: '创建工作流知识库', + workflowInfo: '通过自定义工作流方式构建知识库', }, form: { knowledgeName: { diff --git a/ui/src/locales/lang/zh-Hant/views/index.ts b/ui/src/locales/lang/zh-Hant/views/index.ts index 5a5b899035e..7da9ed6dcf3 100644 --- a/ui/src/locales/lang/zh-Hant/views/index.ts +++ b/ui/src/locales/lang/zh-Hant/views/index.ts @@ -16,6 +16,7 @@ import applicationWorkflow from './application-workflow' import login from './login' import operateLog from './operate-log' import shared from './shared' +import knowledgeWorkflow from './knowledge-workflow' export default { application, applicationOverview, @@ -34,5 +35,6 @@ export default { role, workspace, chatUser, - shared + shared, + knowledgeWorkflow, } diff --git a/ui/src/locales/lang/zh-Hant/views/knowledge-workflow.ts b/ui/src/locales/lang/zh-Hant/views/knowledge-workflow.ts new file mode 100644 index 00000000000..5f77aa346b2 --- /dev/null +++ b/ui/src/locales/lang/zh-Hant/views/knowledge-workflow.ts @@ -0,0 +1,465 @@ +export default { + node: '節點', + nodeName: '節點名稱', + baseComponent: '基礎組件', + nodeSetting: '節點設置', + workflow: '工作流', + searchBar: { + placeholder: '按名稱搜索', + }, + info: { + previewVersion: '預覽版本:', + saveTime: '保存時間:', + }, + setting: { + restoreVersion: '恢復版本', + restoreCurrentVersion: '恢復此版本', + addComponent: '添加組件', + releaseHistory: '發布歷史', + autoSave: '自動保存', + latestRelease: '最近發布', + copyParam: '複製參數', + debug: '調試', + exit: '直接退出', + exitSave: '保存並退出', + }, + tip: { + noData: '沒有找到相關結果', + nameMessage: '名字不能為空!', + onlyRight: '只允許從右邊的錨點連出', + notRecyclable: '不可循環連線', + onlyLeft: '只允許連接左邊的錨點', + applicationNodeError: '該應用不可用', + toolNodeError: '該函數不可用', + repeatedNodeError: '節點名稱已存在!', + cannotCopy: '不能被複製', + copyError: '已複製節點', + paramErrorMessage: '參數已存在: ', + saveMessage: '當前修改未保存,是否保存後退出?', + }, + delete: { + confirmTitle: '確定刪除該節點?', + deleteMessage: '節點不允許刪除', + }, + control: { + zoomOut: '縮小', + zoomIn: '放大', + fitView: '適應', + retract: '收起全部節點', + extend: '展開全部節點', + beautify: '一鍵美化', + }, + variable: { + global: '全局變量', + Referencing: '引用變量', + ReferencingRequired: '引用變量必填', + ReferencingError: '引用變量錯誤', + NoReferencing: '不存在的引用變量', + placeholder: '請選擇變量', + inputPlaceholder: '請輸入變量', + loop: '循環變量', + }, + condition: { + title: '執行條件', + front: '前置', + AND: '所有', + OR: '任一', + text: '連線節點執行完,執行當前節點', + }, + validate: { + startNodeRequired: '開始節點必填', + startNodeOnly: '開始節點只能有一個', + baseNodeRequired: '基本信息節點必填', + baseNodeOnly: '基本信息節點只能有一個', + notInWorkFlowNode: '未在流程中的節點', + noNextNode: '不存在的下一個節點', + nodeUnavailable: '節點不可用', + needConnect1: '節點的', + needConnect2: '分支需要連接', + cannotEndNode: '節點不能當做結束節點', + loopNodeBreakNodeRequired: '無限循環必須存在Break節點', + }, + nodes: { + classify: { + aiCapability: 'AI能力', + businessLogic: '業務邏輯', + other: '其他', + dataProcessing: '數據處理', + }, + startNode: { + label: '開始', + question: '用戶問題', + currentTime: '當前時間', + }, + baseNode: { + label: '基本信息', + appName: { + label: '應用名稱', + }, + appDescription: { + label: '應用描述', + }, + fileUpload: { + label: '文件上傳', + tooltip: '開啟後,問答頁面會顯示上傳文件的按鈕。', + }, + FileUploadSetting: { + title: '文件上傳設置', + maxFiles: '單次上傳最多文件數', + fileLimit: '每個文件最大(MB)', + fileUploadType: { + label: '上傳的文件類型', + documentText: '需要使用「文檔內容提取」節點解析文檔內容', + imageText: '需要使用「圖片理解」節點解析圖片內容', + videoText: '需要使用「視頻理解」節點解析視頻內容', + audioText: '需要使用「語音轉文本」節點解析音頻內容', + }, + }, + }, + aiChatNode: { + label: 'AI 對話', + text: '與 AI 大模型進行對話', + answer: 'AI 回答內容', + returnContent: { + label: '返回內容', + tooltip: `關閉後該節點的內容則不輸出給用戶。 + 如果你想讓用戶看到該節點的輸出內容,請打開開關。`, + }, + defaultPrompt: '已知信息', + think: '思考過程', + historyMessage: '歷史聊天記錄', + }, + searchKnowledgeNode: { + label: '知識庫檢索', + text: '關聯知識庫,查找與問題相關的分段', + paragraph_list: '檢索結果的分段列表', + is_hit_handling_method_list: '滿足直接回答的分段列表', + result: '檢索結果', + directly_return: '滿足直接回答的分段內容', + searchParam: '檢索參數', + searchQuestion: { + label: '檢索問題', + placeholder: '請選擇檢索問題', + requiredMessage: '請選擇檢索問題', + }, + }, + searchDocumentNode: { + label: '文檔標籤檢索', + text: '從設定的檢索範圍中,根據文檔標籤檢索出符合條件的文檔', + selectKnowledge: '檢索範圍', + searchSetting: '檢索設定', + custom: '手動', + customTooltip: '手動設置標籤過濾條件', + auto: '自動', + autoTooltip: '根據檢索問題自動匹配文檔標簽', + document_list: '文件清單', + knowledge_list: '知識庫列表', + result: '檢索結果', + searchParam: '檢索參數', + select_variable: '選擇變數', + valueMessage: `值或{name}`, + showKnowledge: { + label: '結果顯示在知識來源', + requiredMessage: '請設定參數', + }, + searchQuestion: { + label: '檢索問題', + placeholder: '請選擇檢索問題', + requiredMessage: '請選擇檢索問題', + }, + }, + questionNode: { + label: '問題優化', + text: '根據歷史聊天記錄優化完善當前問題,更利於匹配知識庫分段', + result: '問題優化結果', + systemDefault: `# 角色 +妳是壹位問題優化大師,擅長根據上下文精準揣測用戶意圖,並對用戶提出的問題進行優化。 + +## 技能 +### 技能 1: 優化問題 +2. 接收用戶輸入的問題。 +3. 依據上下文仔細分析問題含義。 +4. 輸出優化後的問題。 + +## 限制: +- 僅返回優化後的問題,不進行額外解釋或說明。 +- 確保優化後的問題準確反映原始問題意圖,不得改變原意。`, + }, + conditionNode: { + label: '判斷器', + text: '根據不同條件執行不同的節點', + branch_name: '分支名稱', + conditions: { + label: '條件', + info: '符合以下', + requiredMessage: '請選擇條件', + }, + valueMessage: '請輸入值', + addCondition: '添加條件', + addBranch: '添加分支', + }, + replyNode: { + label: '指定回覆', + text: '指定回覆內容,引用變量會轉換為字符串進行輸出', + replyContent: '回覆內容', + }, + rerankerNode: { + label: '多路召回', + text: '使用重排模型對多個知識庫的檢索結果進行二次召回', + result_list: '重排結果列表', + result: '重排結果', + rerankerContent: { + label: '重排內容', + requiredMessage: '請選擇重排內容', + }, + higher: '高於', + ScoreTooltip: 'Score越高相關性越強。', + max_paragraph_char_number: '最大引用字符數', + reranker_model: { + label: '重排模型', + placeholder: '請選擇重排模型', + }, + }, + formNode: { + label: '表單收集', + text: '在問答過程中用於收集用戶信息,可以根據收集到表單數據執行後續流程', + form_content_format1: '你好,請先填寫下面表單內容:', + form_content_format2: '填寫後請點擊【提交】按鈕進行提交。', + form_data: '表單全部內容', + formContent: { + label: '表單輸出內容', + requiredMessage: '請表單輸出內容', + tooltip: '設置執行該節點輸出的內容,{ form } 為表單的佔位符。', + }, + formAllContent: '表單全部內容', + formSetting: '表單配置', + }, + documentExtractNode: { + label: '文檔內容提取', + text: '提取文檔中的內容', + content: '文檔內容', + }, + imageUnderstandNode: { + label: '圖片理解', + text: '識別出圖片中的物件、場景等信息回答用戶問題', + answer: 'AI 回答內容', + model: { + label: '視覺模型', + requiredMessage: '請選擇視覺模型', + }, + image: { + label: '選擇圖片', + requiredMessage: '請選擇圖片', + }, + }, + variableAssignNode: { + label: '變數賦值', + text: '更新全域變數的值', + assign: '賦值', + }, + variableAggregationNode: { + label: '變量聚合', + text: '按聚合策略聚合每組的變量', + Strategy: '聚合策略', + placeholder: '返回每組的第一個非空值', + placeholder1: '返回每組變量的集合', + group: { + noneError: '名稱不能為空', + dupError: '名稱不能重複', + }, + addGroup: '添加分組', + editGroup: '編輯分組', + }, + mcpNode: { + label: 'MCP 調用', + text: '通過SSE/Streamable HTTP方式執行MCP服務中的工具', + getToolsSuccess: '獲取工具成功', + getTool: '獲取工具', + toolParam: '工具參數', + mcpServerTip: '請輸入JSON格式的MCP服務器配置', + mcpToolTip: '請選擇工具', + configLabel: 'MCP Server Config (僅支持SSE/Streamable HTTP調用方式)', + reference: '引用MCP', + }, + imageGenerateNode: { + label: '圖片生成', + text: '根據提供的文本內容生成圖片', + answer: 'AI 回答內容', + model: { + label: '圖片生成模型', + requiredMessage: '請選擇圖片生成模型', + }, + prompt: { + label: '提示詞(正向)', + tooltip: '正向提示詞,用來描述生成圖像中期望包含的元素和視覺特點', + }, + negative_prompt: { + label: '提示詞(負向)', + tooltip: '反向提示詞,用來描述不希望在畫面中看到的內容,可以對畫面進行限制。', + placeholder: '請描述不想生成的圖片內容,比如:顏色、血腥內容', + }, + }, + textToVideoGenerate: { + label: '文生影片', + text: '根據提供的文字內容生成影片', + answer: 'AI 回答內容', + model: { + label: '文生影片模型', + requiredMessage: '請選擇文生影片模型', + }, + prompt: { + label: '提示詞(正向)', + tooltip: '正向提示詞,用來描述生成影片中期望包含的元素和視覺特點', + }, + negative_prompt: { + label: '提示詞(負向)', + tooltip: '反向提示詞,用來描述不希望在影片中看到的內容,可以對影片進行限制。', + placeholder: '請描述不想生成的影片內容,例如:顏色、血腥內容', + }, + }, + imageToVideoGenerate: { + label: '圖生影片', + text: '根據提供的圖片生成影片', + answer: 'AI 回答內容', + model: { + label: '圖生影片模型', + requiredMessage: '請選擇圖生影片模型', + }, + prompt: { + label: '提示詞(正向)', + tooltip: '正向提示詞,用來描述生成影片中期望包含的元素和視覺特點', + }, + negative_prompt: { + label: '提示詞(負向)', + tooltip: '反向提示詞,用來描述不希望在影片中看到的內容,可以對影片進行限制。', + placeholder: '請描述不想生成的影片內容,例如:顏色、血腥內容', + }, + first_frame: { + label: '首幀圖片', + requiredMessage: '請選擇首幀圖片', + }, + last_frame: { + label: '尾幀圖片', + requiredMessage: '請選擇尾幀圖片', + }, + }, + speechToTextNode: { + label: '語音轉文本', + text: '將音頻通過語音識別模型轉換為文本', + stt_model: { + label: '語音識別模型', + }, + audio: { + label: '選擇語音文件', + placeholder: '請選擇語音文件', + }, + }, + textToSpeechNode: { + label: '文本轉語音', + text: '將文本通過語音合成模型轉換為音頻', + tts_model: { + label: '語音合成模型', + }, + content: { + label: '選擇文本內容', + }, + }, + toolNode: { + label: '自定義工具', + text: '通過執行自定義腳本,實現數據處理', + }, + intentNode: { + label: '意圖識別', + text: '將用戶問題與用戶預設的意圖分類進行匹配', + other: '其他', + error2: '意圖重複', + placeholder: '請選擇分類項', + classify: { + label: '意圖分類', + placeholder: '請輸入', + }, + input: { + label: '輸入', + }, + }, + applicationNode: { + label: '應用節點', + }, + loopNode: { + label: '循環節點', + text: '通過設置循環次數和邏輯,重複執行一系列任務', + loopType: { + label: '循環類型', + requiredMessage: '請選擇循環類型', + arrayLoop: '數組循環', + numberLoop: '指定次數循環', + infiniteLoop: '無限循環', + }, + loopNumber: { + label: '循環次數', + requiredMessage: '請填寫循環次數', + }, + loopArray: { + label: '循環數組', + requiredMessage: '循環數組必填', + placeholder: '請選擇循環數組', + }, + loopSetting: '循環設置', + loopDetail: '循環詳情', + }, + loopStartNode: { + label: '循環開始', + loopIndex: '下標', + loopItem: '循環元素', + }, + loopBodyNode: { label: '循環體', text: '循環體' }, + loopContinueNode: { + label: 'Continue', + text: '用於終止當前循環,執行下次循環', + isContinue: 'Continue', + }, + loopBreakNode: { label: 'Break', text: '終止當前循環,跳出循環體', isBreak: 'Break' }, + variableSplittingNode: { + label: '變量拆分', + text: '通過配置 JSON Path 表達式,對輸入的 JSON 格式變量進行解析和拆分', + result: '結果', + splitVariables: '拆分變量', + inputVariables: '輸入變量', + addVariables: '添加變量', + editVariables: '編輯變量', + variableListPlaceholder: '請添加折開變數', + expression: { + label: '表達式', + placeholder: '請輸入表達式', + tooltip: '請使用JSON Path 表達式拆分變量,例如:$.store.book', + }, + }, + parameterExtractionNode: { + label: '參數提取', + text: '利用 AI 模型提取結構化參數', + extractParameters: { + label: '提取參數', + variableListPlaceholder: '請添加選取參數', + parameterType: '參數類型', + }, + }, + }, + compare: { + is_null: '為空', + is_not_null: '不為空', + contain: '包含', + not_contain: '不包含', + eq: '等於', + ge: '大於等於', + gt: '大於', + le: '小於等於', + lt: '小於', + len_eq: '長度等於', + len_ge: '長度大於等於', + len_gt: '長度大於', + len_le: '長度小於等於', + len_lt: '長度小於', + }, + SystemPromptPlaceholder: '系統提示詞,可以引用系統中的變量:如', + UserPromptPlaceholder: '用戶提示詞,可以引用系統中的變量:如', +} diff --git a/ui/src/locales/lang/zh-Hant/views/knowledge.ts b/ui/src/locales/lang/zh-Hant/views/knowledge.ts index f791c60fe76..2e657da8816 100644 --- a/ui/src/locales/lang/zh-Hant/views/knowledge.ts +++ b/ui/src/locales/lang/zh-Hant/views/knowledge.ts @@ -6,6 +6,9 @@ export default { searchBar: { placeholder: '按名稱搜尋', }, + operation: { + publish: '發佈', + }, setting: { vectorization: '向量化', sync: '同步', @@ -25,11 +28,14 @@ export default { generalKnowledge: '通用知識庫', webKnowledge: 'Web 知識庫', larkKnowledge: '飛書知識庫', + workflowKnowledge: '工作流知識庫', yuqueKnowledge: '語雀知識庫', generalInfo: '上傳本地檔案', webInfo: '同步Web網站文字資料', larkInfo: '通過飛書文檔構建知識庫', yuqueInfo: '通過語雀文檔構建知識庫', + createWorkflowKnowledge: '建立工作流知識庫', + workflowInfo: '通過自定義工作流管道構建知識庫', }, form: { knowledgeName: { diff --git a/ui/src/permission/knowledge/system-share.ts b/ui/src/permission/knowledge/system-share.ts index 76beff8bc50..2546c0701e3 100644 --- a/ui/src/permission/knowledge/system-share.ts +++ b/ui/src/permission/knowledge/system-share.ts @@ -3,235 +3,61 @@ import { ComplexPermission } from '@/utils/permission/type' import { EditionConst, PermissionConst, RoleConst } from '@/utils/permission/data' const share = { is_share: () => false, - create: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_CREATE - ], - 'OR' - ), - sync: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_SYNC - ], - 'OR' - ), - vector: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_VECTOR - ], - 'OR' - ), - generate: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_GENERATE - ], - 'OR' - ), - edit: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_EDIT - ], - 'OR' - ), - export: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_EXPORT - ], - 'OR' - ), - delete: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DELETE - ], - 'OR' - ), - - doc_read: () => false, - doc_create: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_CREATE - ], - 'OR' - ), - doc_vector: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_VECTOR - ], - 'OR' - ), - doc_generate: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_GENERATE - ], - 'OR' - ), - doc_migrate: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_MIGRATE - ], - 'OR' - ), - doc_edit: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_EDIT - ], - 'OR' - ), - doc_sync: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_SYNC - ], - 'OR' - ), - doc_delete: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_DELETE - ], - 'OR' - ), - doc_export: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_EXPORT - ], - 'OR' - ), - doc_download: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE - ], - 'OR' - ), - doc_tag: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_TAG - ], - 'OR' - ), - doc_replace: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_REPLACE - ], - 'OR' - ), - problem_create: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_PROBLEM_CREATE - ], - 'OR' - ), - knowledge_chat_user_read: () => false, - knowledge_chat_user_edit: () => - hasPermission( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_CHAT_USER_EDIT - ], - 'OR' - ), - problem_read: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_PROBLEM_READ - ], - 'OR' - ), - problem_relate: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_PROBLEM_RELATE - ], - 'OR' - ), - problem_delete: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_PROBLEM_DELETE - ], - 'OR' - ), - problem_edit: () => - hasPermission ( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_PROBLEM_EDIT - ], - 'OR' - ), - tag_read: () => - hasPermission( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_TAG_READ - ], - 'OR', - ), - tag_create: () => - hasPermission( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_TAG_CREATE - ], - 'OR', - ), - tag_edit: () => - hasPermission( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_TAG_EDIT - ], - 'OR', - ), - tag_delete: () => + create: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_CREATE], 'OR'), + sync: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_SYNC], 'OR'), + vector: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_VECTOR], 'OR'), + generate: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_GENERATE], 'OR'), + edit: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_EDIT], 'OR'), + export: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_EXPORT], 'OR'), + delete: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DELETE], 'OR'), + + doc_read: () => false, + doc_create: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_CREATE], 'OR'), + doc_vector: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_VECTOR], 'OR'), + doc_generate: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_GENERATE], 'OR'), + doc_migrate: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_MIGRATE], 'OR'), + doc_edit: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_EDIT], 'OR'), + doc_sync: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_SYNC], 'OR'), + doc_delete: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_DELETE], 'OR'), + doc_export: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_EXPORT], 'OR'), + doc_download: () => hasPermission( - [ - RoleConst.ADMIN, - PermissionConst.SHARED_KNOWLEDGE_TAG_DELETE - ], + [RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE], 'OR', ), + doc_tag: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_TAG], 'OR'), + doc_replace: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_REPLACE], 'OR'), + problem_create: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_PROBLEM_CREATE], 'OR'), + knowledge_chat_user_read: () => false, + knowledge_chat_user_edit: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_CHAT_USER_EDIT], 'OR'), + problem_read: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_PROBLEM_READ], 'OR'), + problem_relate: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_PROBLEM_RELATE], 'OR'), + problem_delete: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_PROBLEM_DELETE], 'OR'), + problem_edit: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_PROBLEM_EDIT], 'OR'), + tag_read: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_TAG_READ], 'OR'), + tag_create: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_TAG_CREATE], 'OR'), + tag_edit: () => hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_TAG_EDIT], 'OR'), + tag_delete: () => + hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_TAG_DELETE], 'OR'), - chat_user_edit: () =>false, + chat_user_edit: () => false, auth: () => false, folderRead: () => false, @@ -241,5 +67,6 @@ const share = { folderAuth: () => false, folderDelete: () => false, hit_test: () => false, + debug: (source_id: string) => true, } export default share diff --git a/ui/src/permission/knowledge/workspace-share.ts b/ui/src/permission/knowledge/workspace-share.ts index 65d9a0b0efe..6b82df5c74c 100644 --- a/ui/src/permission/knowledge/workspace-share.ts +++ b/ui/src/permission/knowledge/workspace-share.ts @@ -12,7 +12,7 @@ const workspaceShare = { delete: () => false, auth: () => false, - doc_read: () => false, + doc_read: () => false, doc_create: () => false, doc_vector: () => false, doc_generate: () => false, @@ -32,13 +32,13 @@ const workspaceShare = { tag_create: () => false, tag_delete: () => false, tag_edit: () => false, - + problem_read: () => false, problem_create: () => false, problem_relate: () => false, problem_delete: () => false, problem_edit: () => false, - chat_user_edit: () =>false, + chat_user_edit: () => false, folderRead: () => false, folderManage: () => false, @@ -47,6 +47,7 @@ const workspaceShare = { folderAuth: () => false, folderDelete: () => false, hit_test: () => false, + debug: (source_id: string) => true, } export default workspaceShare diff --git a/ui/src/permission/knowledge/workspace.ts b/ui/src/permission/knowledge/workspace.ts index a0e7307ab19..0c44a10a275 100644 --- a/ui/src/permission/knowledge/workspace.ts +++ b/ui/src/permission/knowledge/workspace.ts @@ -5,9 +5,14 @@ const workspace = { is_share: () => hasPermission( new ComplexPermission( - [RoleConst.USER.getWorkspaceRole,RoleConst.WORKSPACE_MANAGE.getWorkspaceRole], - [PermissionConst.KNOWLEDGE_READ.getWorkspacePermission,PermissionConst.KNOWLEDGE_READ.getWorkspacePermissionWorkspaceManageRole], - [EditionConst.IS_EE],'OR'), + [RoleConst.USER.getWorkspaceRole, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole], + [ + PermissionConst.KNOWLEDGE_READ.getWorkspacePermission, + PermissionConst.KNOWLEDGE_READ.getWorkspacePermissionWorkspaceManageRole, + ], + [EditionConst.IS_EE], + 'OR', + ), 'OR', ), create: () => @@ -20,350 +25,540 @@ const workspace = { ], 'OR', ), - folderRead: (folder_id: string) => - hasPermission( - [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)],[],'AND'), - RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_FOLDER_READ.getKnowledgeWorkspaceResourcePermission(folder_id), - PermissionConst.KNOWLEDGE_READ.getWorkspacePermissionWorkspaceManageRole, - ], - 'OR' + folderRead: (folder_id: string) => + hasPermission( + [ + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)], + [], + 'AND', + ), + RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, + PermissionConst.KNOWLEDGE_FOLDER_READ.getKnowledgeWorkspaceResourcePermission(folder_id), + PermissionConst.KNOWLEDGE_READ.getWorkspacePermissionWorkspaceManageRole, + ], + 'OR', ), folderManage: () => true, - folderAuth: (folder_id: string) => - hasPermission( - [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)],[],'AND'), - RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), - PermissionConst.KNOWLEDGE_RESOURCE_AUTHORIZATION.getWorkspacePermissionWorkspaceManageRole, - ], - 'OR' - ), - folderCreate: (folder_id: string) => - hasPermission( - [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)],[],'AND'), - RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), - PermissionConst.KNOWLEDGE_CREATE.getWorkspacePermissionWorkspaceManageRole, - ], - 'OR' - ), - folderDelete: (folder_id: string) => - hasPermission( - [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)],[],'AND'), - RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), - PermissionConst.KNOWLEDGE_DELETE.getWorkspacePermissionWorkspaceManageRole, - ], - 'OR' - ), - folderEdit: (folder_id: string) => - hasPermission( - [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)],[],'AND'), - RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), - PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermissionWorkspaceManageRole, - ], - 'OR' - ), - sync: (source_id:string) => - hasPermission( - [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + folderAuth: (folder_id: string) => + hasPermission( + [ + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)], + [], + 'AND', + ), + RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, + PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), + PermissionConst.KNOWLEDGE_RESOURCE_AUTHORIZATION.getWorkspacePermissionWorkspaceManageRole, + ], + 'OR', + ), + folderCreate: (folder_id: string) => + hasPermission( + [ + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)], + [], + 'AND', + ), + RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, + PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), + PermissionConst.KNOWLEDGE_CREATE.getWorkspacePermissionWorkspaceManageRole, + ], + 'OR', + ), + folderDelete: (folder_id: string) => + hasPermission( + [ + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)], + [], + 'AND', + ), + RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, + PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), + PermissionConst.KNOWLEDGE_DELETE.getWorkspacePermissionWorkspaceManageRole, + ], + 'OR', + ), + folderEdit: (folder_id: string) => + hasPermission( + [ + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(folder_id)], + [], + 'AND', + ), + RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, + PermissionConst.KNOWLEDGE_FOLDER_EDIT.getKnowledgeWorkspaceResourcePermission(folder_id), + PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermissionWorkspaceManageRole, + ], + 'OR', + ), + sync: (source_id: string) => + hasPermission( + [ + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_SYNC.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_SYNC.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - vector: (source_id:string) => + vector: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_VECTOR.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_VECTOR.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - generate: (source_id:string) => + generate: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_GENERATE.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_GENERATE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - edit: (source_id:string) => + edit: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_EDIT.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - auth: (source_id:string) => + auth: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_RESOURCE_AUTHORIZATION.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_RESOURCE_AUTHORIZATION.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_RESOURCE_AUTHORIZATION.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - export: (source_id:string) => + export: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_EXPORT.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_EXPORT.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - delete: (source_id:string) => + delete: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_DELETE.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_DELETE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_read: () => false, - doc_create: (source_id:string) => + doc_read: () => false, + doc_create: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_CREATE.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_DOCUMENT_CREATE.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_DOCUMENT_CREATE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_vector: (source_id:string) => + doc_vector: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_VECTOR.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_DOCUMENT_VECTOR.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_DOCUMENT_VECTOR.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_generate: (source_id:string) => + doc_generate: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_GENERATE.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_DOCUMENT_GENERATE.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_DOCUMENT_GENERATE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_migrate: (source_id:string) => + doc_migrate: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_MIGRATE.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_DOCUMENT_MIGRATE.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_DOCUMENT_MIGRATE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_edit: (source_id:string) => + doc_edit: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_DOCUMENT_EDIT.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_DOCUMENT_EDIT.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_sync: (source_id:string) => + doc_sync: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_DOCUMENT_SYNC.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_DOCUMENT_SYNC.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_delete: (source_id:string) => + doc_delete: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_DELETE.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_DOCUMENT_DELETE.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_DOCUMENT_DELETE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_export: (source_id:string) => + doc_export: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_EXPORT.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_DOCUMENT_EXPORT.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_DOCUMENT_EXPORT.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_download: (source_id:string) => + doc_download: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE.getKnowledgeWorkspaceResourcePermission(source_id), - PermissionConst.KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE.getWorkspacePermissionWorkspaceManageRole, + PermissionConst.KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE.getKnowledgeWorkspaceResourcePermission( + source_id, + ), + PermissionConst.KNOWLEDGE_DOCUMENT_DOWNLOAD_SOURCE_FILE + .getWorkspacePermissionWorkspaceManageRole, ], 'OR', - ), - doc_tag: (source_id:string) => + ), + doc_tag: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_DOCUMENT_TAG.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_DOCUMENT_TAG.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - doc_replace: (source_id:string) => + doc_replace: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, - PermissionConst.KNOWLEDGE_DOCUMENT_REPLACE.getKnowledgeWorkspaceResourcePermission(source_id), + PermissionConst.KNOWLEDGE_DOCUMENT_REPLACE.getKnowledgeWorkspaceResourcePermission( + source_id, + ), PermissionConst.KNOWLEDGE_DOCUMENT_REPLACE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - knowledge_chat_user_read: (source_id:string) => false, - knowledge_chat_user_edit: (source_id:string) => + knowledge_chat_user_read: (source_id: string) => false, + knowledge_chat_user_edit: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_CHAT_USER_EDIT.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_CHAT_USER_EDIT.getWorkspacePermissionWorkspaceManageRole, - ] - ,'OR' + ], + 'OR', ), - problem_read: (source_id:string) => + problem_read: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_PROBLEM_READ.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_PROBLEM_READ.getWorkspacePermissionWorkspaceManageRole, ], 'OR', - ), - problem_create: (source_id:string) => + ), + problem_create: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_PROBLEM_CREATE.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_PROBLEM_CREATE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - problem_relate: (source_id:string) => + problem_relate: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_PROBLEM_RELATE.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_PROBLEM_RELATE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - problem_delete: (source_id:string) => + problem_delete: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_PROBLEM_DELETE.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_PROBLEM_DELETE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - problem_edit: (source_id:string) => + problem_edit: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_PROBLEM_EDIT.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_PROBLEM_EDIT.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - tag_read: (source_id:string) => + tag_read: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_TAG_READ.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_TAG_READ.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - tag_create: (source_id:string) => + tag_create: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_TAG_CREATE.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_TAG_CREATE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - tag_edit: (source_id:string) => + tag_edit: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_TAG_EDIT.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_TAG_EDIT.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - tag_delete: (source_id:string) => + tag_delete: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_TAG_DELETE.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_TAG_DELETE.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - chat_user_edit: (source_id:string) => + chat_user_edit: (source_id: string) => hasPermission( [ - new ComplexPermission([RoleConst.USER],[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],[],'AND'), + new ComplexPermission( + [RoleConst.USER], + [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)], + [], + 'AND', + ), RoleConst.WORKSPACE_MANAGE.getWorkspaceRole, PermissionConst.KNOWLEDGE_CHAT_USER_EDIT.getKnowledgeWorkspaceResourcePermission(source_id), PermissionConst.KNOWLEDGE_CHAT_USER_EDIT.getWorkspacePermissionWorkspaceManageRole, ], 'OR', ), - hit_test: () => false, + debug: (source_id: string) => true, + hit_test: () => false, } export default workspace diff --git a/ui/src/router/modules/document.ts b/ui/src/router/modules/document.ts index b5c98c511b7..40d2a146bb0 100644 --- a/ui/src/router/modules/document.ts +++ b/ui/src/router/modules/document.ts @@ -3,7 +3,7 @@ import { get_next_route } from '@/utils/permission' import { EditionConst, PermissionConst, RoleConst } from '@/utils/permission/data' import { ComplexPermission } from '@/utils/permission/type' const DocumentRouter = { - path: '/knowledge/:id/:folderId', + path: '/knowledge/:id/:folderId/:type', name: 'KnowledgeDetail', meta: { title: 'common.fileUpload.document', activeMenu: '/knowledge', breadcrumb: true }, component: () => import('@/layout/layout-template/MainLayout.vue'), @@ -17,21 +17,34 @@ const DocumentRouter = { iconActive: 'app-document-active', title: 'common.fileUpload.document', active: 'document', - parentPath: '/knowledge/:id/:folderId', + parentPath: '/knowledge/:id/:folderId/:type', parentName: 'KnowledgeDetail', group: 'KnowledgeDetail', permission: [ () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return new ComplexPermission([RoleConst.USER], [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(to ? to.params.id : '',)], [], 'AND') } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return new ComplexPermission( + [RoleConst.USER], + [ + PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ), + ], + [], + 'AND', + ) + } }, () => { const to: any = get_next_route() if (to.params.folderId == 'shared') { return RoleConst.ADMIN - } else if (to.params.folderId == 'resource-management') { } - else { + } else if (to.params.folderId == 'resource-management') { + } else { return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() } }, @@ -39,8 +52,8 @@ const DocumentRouter = { const to: any = get_next_route() if (to.params.folderId == 'shared') { return PermissionConst.SHARED_KNOWLEDGE_DOCUMENT_READ - } else if (to.params.folderId == 'resource-management') { } - else { + } else if (to.params.folderId == 'resource-management') { + } else { return PermissionConst.KNOWLEDGE_DOCUMENT_READ.getKnowledgeWorkspaceResourcePermission( to ? to.params.id : '', ) @@ -48,15 +61,22 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { return PermissionConst.KNOWLEDGE_DOCUMENT_READ.getWorkspacePermissionWorkspaceManageRole() } }, () => { const to: any = get_next_route() if (to.params.folderId == 'share') { - return new ComplexPermission([RoleConst.EXTENDS_USER.getWorkspaceRole()], [PermissionConst.KNOWLEDGE_DOCUMENT_READ.getWorkspacePermission()], [], 'AND') + return new ComplexPermission( + [RoleConst.EXTENDS_USER.getWorkspaceRole()], + [PermissionConst.KNOWLEDGE_DOCUMENT_READ.getWorkspacePermission()], + [], + 'AND', + ) } }, () => { @@ -67,16 +87,118 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return RoleConst.ADMIN } + if (to.params.folderId == 'resource-management') { + return RoleConst.ADMIN + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return PermissionConst.RESOURCE_KNOWLEDGE_DOCUMENT_READ } + if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_DOCUMENT_READ + } }, ], }, component: () => import('@/views/document/index.vue'), }, + { + path: 'knowledge-workflow-setting', + name: 'knowledgeWorkflowSetting', + meta: { + title: '知识库工作流', + icon: 'app-problems', + activeMenu: '/knowledge', + sameRoute: 'knowledge', + permission: [ + () => { + const to: any = get_next_route() + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return new ComplexPermission( + [RoleConst.USER], + [ + PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ), + ], + [], + 'AND', + ) + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'shared') { + return PermissionConst.SHARED_KNOWLEDGE_WORKFLOW_READ + } else if (to.params.folderId == 'resource-management') { + } else { + return PermissionConst.KNOWLEDGE_WORKFLOW_READ.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ) + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return PermissionConst.KNOWLEDGE_WORKFLOW_READ.getWorkspacePermissionWorkspaceManageRole() + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'share') { + return new ComplexPermission( + [RoleConst.EXTENDS_USER.getWorkspaceRole()], + [PermissionConst.KNOWLEDGE_WORKFLOW_READ.getWorkspacePermission()], + [], + 'AND', + ) + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'share') { + return RoleConst.USER.getWorkspaceRole() + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'resource-management') { + return RoleConst.ADMIN + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_WORKFLOW_READ + } + }, + ].map(p => () => { + const to: any = get_next_route() + if (to.params.type !== '4') {return false} + return p() + }), + }, + redirect: (menu: any) => { + const from = 'workspace' + console.log(`/knowledge/${from}/${menu.params.id}/workflow`) + return `/knowledge/${from}/${menu.params.id}/workflow` + }, + component: () => import('@/views/knowledge/index.vue'), + }, { path: 'problem', name: 'Problem', @@ -85,24 +207,43 @@ const DocumentRouter = { iconActive: 'QuestionFilled', title: 'views.problem.title', active: 'problem', - parentPath: '/knowledge/:id/:folderId', + parentPath: '/knowledge/:id/:folderId/:type', parentName: 'KnowledgeDetail', group: 'KnowledgeDetail', permission: [ () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return new ComplexPermission([RoleConst.USER], [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(to ? to.params.id : '',)], [], 'AND') } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return new ComplexPermission( + [RoleConst.USER], + [ + PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ), + ], + [], + 'AND', + ) + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return PermissionConst.SHARED_KNOWLEDGE_PROBLEM_READ } else if (to.params.folderId == 'resource-management') { } - else { + if (to.params.folderId == 'shared') { + return PermissionConst.SHARED_KNOWLEDGE_PROBLEM_READ + } else if (to.params.folderId == 'resource-management') { + } else { return PermissionConst.KNOWLEDGE_PROBLEM_READ.getKnowledgeWorkspaceResourcePermission( to ? to.params.id : '', ) @@ -110,13 +251,22 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return PermissionConst.KNOWLEDGE_PROBLEM_READ.getWorkspacePermissionWorkspaceManageRole() } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return PermissionConst.KNOWLEDGE_PROBLEM_READ.getWorkspacePermissionWorkspaceManageRole() + } }, () => { const to: any = get_next_route() if (to.params.folderId == 'share') { - return new ComplexPermission([RoleConst.EXTENDS_USER.getWorkspaceRole()], [PermissionConst.KNOWLEDGE_PROBLEM_READ.getWorkspacePermission()], [], 'AND') + return new ComplexPermission( + [RoleConst.EXTENDS_USER.getWorkspaceRole()], + [PermissionConst.KNOWLEDGE_PROBLEM_READ.getWorkspacePermission()], + [], + 'AND', + ) } }, () => { @@ -127,11 +277,15 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return RoleConst.ADMIN } + if (to.params.folderId == 'resource-management') { + return RoleConst.ADMIN + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return PermissionConst.RESOURCE_KNOWLEDGE_PROBLEM_READ } + if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_PROBLEM_READ + } }, ], }, @@ -144,24 +298,43 @@ const DocumentRouter = { icon: 'app-hit-test', title: 'views.application.hitTest.title', active: 'hit-test', - parentPath: '/knowledge/:id/:folderId', + parentPath: '/knowledge/:id/:folderId/:type', parentName: 'KnowledgeDetail', group: 'KnowledgeDetail', permission: [ () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return new ComplexPermission([RoleConst.USER], [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(to ? to.params.id : '',)], [], 'AND') } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return new ComplexPermission( + [RoleConst.USER], + [ + PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ), + ], + [], + 'AND', + ) + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return PermissionConst.SHARED_KNOWLEDGE_HIT_TEST_READ } else if (to.params.folderId == 'resource-management') { } - else { + if (to.params.folderId == 'shared') { + return PermissionConst.SHARED_KNOWLEDGE_HIT_TEST_READ + } else if (to.params.folderId == 'resource-management') { + } else { return PermissionConst.KNOWLEDGE_HIT_TEST_READ.getKnowledgeWorkspaceResourcePermission( to ? to.params.id : '', ) @@ -169,13 +342,22 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return PermissionConst.KNOWLEDGE_HIT_TEST_READ.getWorkspacePermissionWorkspaceManageRole() } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return PermissionConst.KNOWLEDGE_HIT_TEST_READ.getWorkspacePermissionWorkspaceManageRole() + } }, () => { const to: any = get_next_route() if (to.params.folderId == 'share') { - return new ComplexPermission([RoleConst.EXTENDS_USER.getWorkspaceRole()], [PermissionConst.KNOWLEDGE_HIT_TEST_READ.getWorkspacePermission()], [], 'AND') + return new ComplexPermission( + [RoleConst.EXTENDS_USER.getWorkspaceRole()], + [PermissionConst.KNOWLEDGE_HIT_TEST_READ.getWorkspacePermission()], + [], + 'AND', + ) } }, () => { @@ -186,11 +368,15 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return RoleConst.ADMIN } + if (to.params.folderId == 'resource-management') { + return RoleConst.ADMIN + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return PermissionConst.RESOURCE_KNOWLEDGE_HIT_TEST } + if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_HIT_TEST + } }, ], }, @@ -204,65 +390,100 @@ const DocumentRouter = { iconActive: 'app-user-chat-active', title: 'views.chatUser.title', active: 'chat-user', - parentPath: '/knowledge/:id/:folderId', + parentPath: '/knowledge/:id/:folderId/:type', parentName: 'KnowledgeDetail', resourceType: SourceTypeEnum.KNOWLEDGE, group: 'KnowledgeDetail', - permission: [new ComplexPermission([RoleConst.ADMIN, - () => { - const to: any = get_next_route() - if (to.params.folderId == 'shared') { - return RoleConst.ADMIN - } else if (to.params.folderId == 'resource-management') { return RoleConst.ADMIN } - else { - return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() - } - },], [ + permission: [ + new ComplexPermission( + [ + RoleConst.ADMIN, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + return RoleConst.ADMIN + } else { + return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() + } + }, + ], + [ + () => { + const to: any = get_next_route() + if (to.params.folderId == 'shared') { + return PermissionConst.SHARED_KNOWLEDGE_CHAT_USER_READ + } else if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_CHAT_USER_READ + } else { + return PermissionConst.KNOWLEDGE_CHAT_USER_READ.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ) + } + }, + () => { + const to: any = get_next_route() + if (to.params.folder_id == 'shared') { + return PermissionConst.SHARED_KNOWLEDGE_CHAT_USER_READ + } else if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_CHAT_USER_READ + } else { + return PermissionConst.KNOWLEDGE_CHAT_USER_READ.getWorkspacePermissionWorkspaceManageRole() + } + }, + ], + [EditionConst.IS_EE, EditionConst.IS_PE], + 'OR', + ), () => { const to: any = get_next_route() if (to.params.folderId == 'shared') { - return PermissionConst.SHARED_KNOWLEDGE_CHAT_USER_READ - } else if (to.params.folderId == 'resource-management') { return PermissionConst.RESOURCE_KNOWLEDGE_CHAT_USER_READ } - else { - return PermissionConst.KNOWLEDGE_CHAT_USER_READ.getKnowledgeWorkspaceResourcePermission( - to ? to.params.id : '', + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return new ComplexPermission( + [RoleConst.USER], + [ + PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ), + ], + [EditionConst.IS_EE, EditionConst.IS_PE], + 'AND', ) } }, () => { const to: any = get_next_route() - if (to.params.folder_id == 'shared') { - return PermissionConst.SHARED_KNOWLEDGE_CHAT_USER_READ - } else if (to.params.folderId == 'resource-management') { return PermissionConst.RESOURCE_KNOWLEDGE_CHAT_USER_READ } - else { return PermissionConst.KNOWLEDGE_CHAT_USER_READ.getWorkspacePermissionWorkspaceManageRole() } + if (to.params.folderId == 'share') { + return new ComplexPermission( + [RoleConst.EXTENDS_USER.getWorkspaceRole()], + [PermissionConst.KNOWLEDGE_CHAT_USER_READ.getWorkspacePermission()], + [], + 'AND', + ) + } }, - ], [EditionConst.IS_EE, EditionConst.IS_PE], 'OR'), - () => { - const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return new ComplexPermission([RoleConst.USER], [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(to ? to.params.id : '',)], [EditionConst.IS_EE, EditionConst.IS_PE], 'AND') } - }, - () => { - const to: any = get_next_route() - if (to.params.folderId == 'share') { - return new ComplexPermission([RoleConst.EXTENDS_USER.getWorkspaceRole()], [PermissionConst.KNOWLEDGE_CHAT_USER_READ.getWorkspacePermission()], [], 'AND') - } - }, - () => { - const to: any = get_next_route() - if (to.params.folderId == 'share') { - return RoleConst.USER.getWorkspaceRole() - } - }, - () => { - const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return RoleConst.ADMIN } - }, - () => { - const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return PermissionConst.RESOURCE_KNOWLEDGE_CHAT_USER_READ } - }, - ] + () => { + const to: any = get_next_route() + if (to.params.folderId == 'share') { + return RoleConst.USER.getWorkspaceRole() + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'resource-management') { + return RoleConst.ADMIN + } + }, + () => { + const to: any = get_next_route() + if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_CHAT_USER_READ + } + }, + ], }, component: () => import('@/views/chat-user/index.vue'), }, @@ -274,24 +495,43 @@ const DocumentRouter = { iconActive: 'app-setting-active', title: 'common.setting', active: 'setting', - parentPath: '/knowledge/:id/:folderId', + parentPath: '/knowledge/:id/:folderId/:type', parentName: 'KnowledgeDetail', group: 'KnowledgeDetail', permission: [ () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return new ComplexPermission([RoleConst.USER], [PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(to ? to.params.id : '',)], [], 'AND') } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return new ComplexPermission( + [RoleConst.USER], + [ + PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission( + to ? to.params.id : '', + ), + ], + [], + 'AND', + ) + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return RoleConst.WORKSPACE_MANAGE.getWorkspaceRole() + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return PermissionConst.SHARED_KNOWLEDGE_EDIT } else if (to.params.folderId == 'resource-management') { } - else { + if (to.params.folderId == 'shared') { + return PermissionConst.SHARED_KNOWLEDGE_EDIT + } else if (to.params.folderId == 'resource-management') { + } else { return PermissionConst.KNOWLEDGE_EDIT.getKnowledgeWorkspaceResourcePermission( to ? to.params.id : '', ) @@ -299,13 +539,22 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'shared') { return RoleConst.ADMIN } else if (to.params.folderId == 'resource-management') { } - else { return PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermissionWorkspaceManageRole() } + if (to.params.folderId == 'shared') { + return RoleConst.ADMIN + } else if (to.params.folderId == 'resource-management') { + } else { + return PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermissionWorkspaceManageRole() + } }, () => { const to: any = get_next_route() if (to.params.folderId == 'share') { - return new ComplexPermission([RoleConst.EXTENDS_USER.getWorkspaceRole()], [PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermission()], [], 'AND') + return new ComplexPermission( + [RoleConst.EXTENDS_USER.getWorkspaceRole()], + [PermissionConst.KNOWLEDGE_EDIT.getWorkspacePermission()], + [], + 'AND', + ) } }, () => { @@ -316,11 +565,15 @@ const DocumentRouter = { }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return RoleConst.ADMIN } + if (to.params.folderId == 'resource-management') { + return RoleConst.ADMIN + } }, () => { const to: any = get_next_route() - if (to.params.folderId == 'resource-management') { return PermissionConst.RESOURCE_KNOWLEDGE_EDIT } + if (to.params.folderId == 'resource-management') { + return PermissionConst.RESOURCE_KNOWLEDGE_EDIT + } }, ], }, diff --git a/ui/src/router/routes.ts b/ui/src/router/routes.ts index 5f9cc420bff..2bd42b2e0f8 100644 --- a/ui/src/router/routes.ts +++ b/ui/src/router/routes.ts @@ -36,6 +36,13 @@ export const routes: Array = [ meta: { activeMenu: '/application' }, component: () => import('@/views/application-workflow/index.vue'), }, + // 高级编排 + { + path: '/knowledge/:from/:id/workflow', + name: 'KnowledgeWorkflow', + meta: { activeMenu: '/knowledge' }, + component: () => import('@/views/knowledge-workflow/index.vue'), + }, // 对话 { path: '/chat/:accessToken', diff --git a/ui/src/utils/permission/data.ts b/ui/src/utils/permission/data.ts index fa79a84943b..3b2cd1af307 100644 --- a/ui/src/utils/permission/data.ts +++ b/ui/src/utils/permission/data.ts @@ -109,6 +109,9 @@ const PermissionConst = { KNOWLEDGE_EXPORT: new Permission('KNOWLEDGE:READ+EXPORT'), KNOWLEDGE_DELETE: new Permission('KNOWLEDGE:READ+DELETE'), KNOWLEDGE_GENERATE: new Permission('KNOWLEDGE:READ+GENERATE'), + + KNOWLEDGE_WORKFLOW_READ: new Permission('KNOWLEDGE_WORKFLOW:READ'), + KNOWLEDGE_WORKFLOW_EDIT: new Permission('KNOWLEDGE_WORKFLOW:READ+EDIT'), KNOWLEDGE_DOCUMENT_READ: new Permission('KNOWLEDGE_DOCUMENT:READ'), KNOWLEDGE_DOCUMENT_CREATE: new Permission('KNOWLEDGE_DOCUMENT:READ+CREATE'), @@ -190,6 +193,9 @@ const PermissionConst = { SHARED_KNOWLEDGE_EXPORT: new Permission('SYSTEM_KNOWLEDGE:READ+EXPORT'), SHARED_KNOWLEDGE_GENERATE: new Permission('SYSTEM_KNOWLEDGE:READ+GENERATE'), SHARED_KNOWLEDGE_DELETE: new Permission('SYSTEM_KNOWLEDGE:READ+DELETE'), + + SHARED_KNOWLEDGE_WORKFLOW_READ: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ'), + SHARED_KNOWLEDGE_WORKFLOW_EDIT: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ+EDIT'), SHARED_KNOWLEDGE_DOCUMENT_READ: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ'), SHARED_KNOWLEDGE_DOCUMENT_CREATE: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ+CREATE'), @@ -243,6 +249,9 @@ const PermissionConst = { RESOURCE_KNOWLEDGE_EXPORT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE:READ+EXPORT'), RESOURCE_KNOWLEDGE_DELETE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE:READ+DELETE'), RESOURCE_KNOWLEDGE_GENERATE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE:READ+GENERATE'), + + RESOURCE_KNOWLEDGE_WORKFLOW_READ: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_WORKFLOW:READ'), + RESOURCE_KNOWLEDGE_WORKFLOW_EDIT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_WORKFLOW:READ+EDIT'), RESOURCE_KNOWLEDGE_DOCUMENT_READ: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ'), RESOURCE_KNOWLEDGE_DOCUMENT_CREATE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ+CREATE'), @@ -377,3 +386,4 @@ const EditionConst = { IS_CE: new Edition('X-PACK-CE'), } export {PermissionConst, RoleConst, EditionConst} + diff --git a/ui/src/views/application-workflow/index.vue b/ui/src/views/application-workflow/index.vue index b2b96d46b3d..65c9b68efc7 100644 --- a/ui/src/views/application-workflow/index.vue +++ b/ui/src/views/application-workflow/index.vue @@ -159,7 +159,10 @@ import { ComplexPermission } from '@/utils/permission/type' import { EditionConst, PermissionConst, RoleConst } from '@/utils/permission/data' import permissionMap from '@/permission' import { loadSharedApi } from '@/utils/dynamics-api/shared-api' -provide('getApplicationDetail', () => detail) +import { WorkflowMode } from '@/enums/application' +provide('getResourceDetail', () => detail) +provide('workflowMode', WorkflowMode.Application) +provide('loopWorkflowMode', WorkflowMode.ApplicationLoop) const { theme } = useStore() const router = useRouter() const route = useRoute() diff --git a/ui/src/views/knowledge-workflow/component/DropdownMenu.vue b/ui/src/views/knowledge-workflow/component/DropdownMenu.vue new file mode 100644 index 00000000000..6706a612f83 --- /dev/null +++ b/ui/src/views/knowledge-workflow/component/DropdownMenu.vue @@ -0,0 +1,354 @@ + + + diff --git a/ui/src/views/knowledge-workflow/component/NodeContent.vue b/ui/src/views/knowledge-workflow/component/NodeContent.vue new file mode 100644 index 00000000000..1476242ac00 --- /dev/null +++ b/ui/src/views/knowledge-workflow/component/NodeContent.vue @@ -0,0 +1,122 @@ + + + + + diff --git a/ui/src/views/knowledge-workflow/component/PublishHistory.vue b/ui/src/views/knowledge-workflow/component/PublishHistory.vue new file mode 100644 index 00000000000..707ea88f494 --- /dev/null +++ b/ui/src/views/knowledge-workflow/component/PublishHistory.vue @@ -0,0 +1,157 @@ + + + diff --git a/ui/src/views/knowledge-workflow/component/action/index.vue b/ui/src/views/knowledge-workflow/component/action/index.vue new file mode 100644 index 00000000000..66c7715905f --- /dev/null +++ b/ui/src/views/knowledge-workflow/component/action/index.vue @@ -0,0 +1,11 @@ + + + diff --git a/ui/src/views/knowledge-workflow/index.vue b/ui/src/views/knowledge-workflow/index.vue new file mode 100644 index 00000000000..d808df5d273 --- /dev/null +++ b/ui/src/views/knowledge-workflow/index.vue @@ -0,0 +1,607 @@ + + + diff --git a/ui/src/views/knowledge/component/KnowledgeListContainer.vue b/ui/src/views/knowledge/component/KnowledgeListContainer.vue index e15d543a56c..03a8761a9d3 100644 --- a/ui/src/views/knowledge/component/KnowledgeListContainer.vue +++ b/ui/src/views/knowledge/component/KnowledgeListContainer.vue @@ -97,7 +97,7 @@ - +
@@ -147,33 +147,6 @@ > @@ -279,7 +247,7 @@ + + + + + + + + + diff --git a/ui/src/workflow/common/NodeContainer.vue b/ui/src/workflow/common/NodeContainer.vue index e62d1ee4b63..726dc22bf5a 100644 --- a/ui/src/workflow/common/NodeContainer.vue +++ b/ui/src/workflow/common/NodeContainer.vue @@ -345,9 +345,12 @@ const nodeFields = computed(() => { }) function showOperate(type: string) { - return ![WorkflowType.Start, WorkflowType.Base, WorkflowType.LoopStartNode.toString()].includes( - type, - ) + return ![ + WorkflowType.Start, + WorkflowType.Base, + WorkflowType.KnowledgeBase, + WorkflowType.LoopStartNode.toString(), + ].includes(type) } const openNodeMenu = (anchorValue: any) => { showAnchor.value = true diff --git a/ui/src/workflow/common/app-node.ts b/ui/src/workflow/common/app-node.ts index 2f1a929a0fb..fc0f7bed561 100644 --- a/ui/src/workflow/common/app-node.ts +++ b/ui/src/workflow/common/app-node.ts @@ -1,3 +1,4 @@ +import { WorkflowKind } from './../../enums/application' import Components from '@/components' import ElementPlus from 'element-plus' import * as ElementPlusIcons from '@element-plus/icons-vue' @@ -107,10 +108,11 @@ class AppNode extends HtmlResize.view { (pre, next) => [...pre, ...next], [], ) - const start_node_field_list = ( - this.props.graphModel.getNodeModelById('start-node') || - this.props.graphModel.getNodeModelById('loop-start-node') - ).get_node_field_list() + const start_node_field_list = + ( + this.props.graphModel.getNodeModelById('start-node') || + this.props.graphModel.getNodeModelById('loop-start-node') + )?.get_node_field_list() || [] return [...start_node_field_list, ...result] } @@ -413,9 +415,11 @@ class AppNodeModel extends HtmlResize.model { const { id, x, y, width } = this const showNode = this.properties.showNode === undefined ? true : this.properties.showNode const anchors: any = [] - - if (this.type !== WorkflowType.Base) { - if (![WorkflowType.Start, WorkflowType.LoopStartNode.toString()].includes(this.type)) { + if (![WorkflowType.Base as string, WorkflowType.KnowledgeBase as string].includes(this.type)) { + if ( + ![WorkflowType.Start, WorkflowType.LoopStartNode.toString()].includes(this.type) && + this.properties.kind != WorkflowKind.DataSource + ) { anchors.push({ x: x - width / 2 + 10, y: showNode ? y : y - 15, diff --git a/ui/src/workflow/common/data.ts b/ui/src/workflow/common/data.ts index 8587cc2635a..68b4734a4d7 100644 --- a/ui/src/workflow/common/data.ts +++ b/ui/src/workflow/common/data.ts @@ -1,3 +1,4 @@ +import { WorkflowKind } from './../../enums/application' import { WorkflowType, WorkflowMode } from '@/enums/application' import { t } from '@/locales' @@ -57,6 +58,47 @@ export const baseNode = { user_input_field_list: [], }, } +export const knowledgeBaseNode = { + id: WorkflowType.KnowledgeBase, + type: WorkflowType.KnowledgeBase, + x: 360, + y: 2761.3875, + text: '', + properties: { + height: 728.375, + stepName: t('views.applicationWorkflow.nodes.baseNode.label'), + input_field_list: [], + node_data: { + name: '', + desc: '', + prologue: t('views.application.form.defaultPrologue'), + tts_type: 'BROWSER', + }, + config: {}, + showNode: true, + user_input_config: { title: t('chat.userInput') }, + user_input_field_list: [], + }, +} +export const dataSourceLocalNode = { + id: WorkflowType.DataSourceLocalNode, + type: WorkflowType.DataSourceLocalNode, + x: 360, + y: 2761.3875, + text: t('views.applicationWorkflow.nodes.dataSourceLocalNode.text', '本地文件'), + label: t('views.applicationWorkflow.nodes.dataSourceLocalNode.label', '本地文件'), + properties: { + kind: WorkflowKind.DataSource, + height: 728.375, + stepName: t('views.applicationWorkflow.nodes.dataSourceLocalNode.label', '本地文件'), + input_field_list: [], + node_data: {}, + config: {}, + showNode: true, + user_input_config: {}, + user_input_field_list: [], + }, +} /** * 说明 * type 与 nodes 文件对应 @@ -618,6 +660,49 @@ export const loopBreakNode = { }, } +export const knowledgeMenuNodes = [ + { + label: t('views.applicationWorkflow.nodes.classify.dataSource', '数据源'), + list: [dataSourceLocalNode], + }, + { + label: t('views.applicationWorkflow.nodes.classify.aiCapability'), + list: [ + aiChatNode, + intentNode, + textToSpeechNode, + speechToTextNode, + imageGenerateNode, + imageUnderstandNode, + textToVideoNode, + imageToVideoNode, + videoUnderstandNode, + questionNode, + ], + }, + { + label: t('views.knowledge.title'), + list: [documentExtractNode], + }, + { + label: t('views.applicationWorkflow.nodes.classify.businessLogic'), + list: [conditionNode, formNode, replyNode, loopNode], + }, + { + label: t('views.applicationWorkflow.nodes.classify.dataProcessing'), + list: [ + variableAssignNode, + variableAggregationNode, + variableSplittingNode, + parameterExtractionNode, + ], + }, + { + label: t('views.applicationWorkflow.nodes.classify.other'), + list: [mcpNode, toolNode], + }, +] + export const menuNodes = [ { label: t('views.applicationWorkflow.nodes.classify.aiCapability'), @@ -694,6 +779,44 @@ export const applicationLoopMenuNodes = [ list: [mcpNode, toolNode], }, ] +export const knowledgeLoopMenuNodes = [ + { + label: t('views.applicationWorkflow.nodes.classify.aiCapability'), + list: [ + aiChatNode, + intentNode, + textToSpeechNode, + speechToTextNode, + imageGenerateNode, + imageUnderstandNode, + textToVideoNode, + imageToVideoNode, + videoUnderstandNode, + questionNode, + ], + }, + { + label: t('views.knowledge.title'), + list: [rerankerNode, documentExtractNode], + }, + { + label: t('views.applicationWorkflow.nodes.classify.businessLogic'), + list: [conditionNode, formNode, replyNode, loopContinueNode, loopBreakNode], + }, + { + label: t('views.applicationWorkflow.nodes.classify.dataProcessing', '数据处理'), + list: [ + variableAssignNode, + variableSplittingNode, + parameterExtractionNode, + variableAggregationNode, + ], + }, + { + label: t('views.applicationWorkflow.nodes.classify.other'), + list: [mcpNode, toolNode], + }, +] export const getMenuNodes = (workflowMode: WorkflowMode) => { if (workflowMode == WorkflowMode.Application) { @@ -702,6 +825,12 @@ export const getMenuNodes = (workflowMode: WorkflowMode) => { if (workflowMode == WorkflowMode.ApplicationLoop) { return applicationLoopMenuNodes } + if (workflowMode == WorkflowMode.Knowledge) { + return knowledgeMenuNodes + } + if (workflowMode == WorkflowMode.KnowledgeLoop) { + return knowledgeLoopMenuNodes + } } /** @@ -763,7 +892,6 @@ export const compareList = [ { value: 'start_with', label: 'startWith' }, { value: 'end_with', label: 'endWith' }, ] - export const nodeDict: any = { [WorkflowType.AiChat]: aiChatNode, [WorkflowType.SearchKnowledge]: searchKnowledgeNode, @@ -797,6 +925,8 @@ export const nodeDict: any = { [WorkflowType.VideoUnderstandNode]: videoUnderstandNode, [WorkflowType.ParameterExtractionNode]: parameterExtractionNode, [WorkflowType.VariableAggregationNode]: variableAggregationNode, + [WorkflowType.KnowledgeBase]: knowledgeBaseNode, + [WorkflowType.DataSourceLocalNode]: dataSourceLocalNode, } export function isWorkFlow(type: string | undefined) { diff --git a/ui/src/workflow/common/validate.ts b/ui/src/workflow/common/validate.ts index 50e7e94e948..913f6799e34 100644 --- a/ui/src/workflow/common/validate.ts +++ b/ui/src/workflow/common/validate.ts @@ -1,3 +1,4 @@ +import { WorkflowKind } from './../../enums/application' import { WorkflowType, WorkflowMode } from '@/enums/application' import { t } from '@/locales' @@ -43,7 +44,9 @@ const loop_end_nodes: Array = [ ] const end_nodes_dict = { [WorkflowMode.Application]: end_nodes, + [WorkflowMode.Knowledge]: end_nodes, [WorkflowMode.ApplicationLoop]: loop_end_nodes, + [WorkflowMode.KnowledgeLoop]: loop_end_nodes, } export class WorkFlowInstance { @@ -63,8 +66,10 @@ export class WorkFlowInstance { * 校验开始节点 */ private is_valid_start_node() { - const start_node_list = this.nodes.filter((item) => - [WorkflowType.Start, WorkflowType.LoopStartNode].includes(item.id), + const start_node_list = this.nodes.filter( + (item) => + [WorkflowType.Start, WorkflowType.LoopStartNode].includes(item.id) || + item.properties.kind == WorkflowKind.DataSource, ) if (start_node_list.length == 0) { throw t('views.applicationWorkflow.validate.startNodeRequired') @@ -77,6 +82,10 @@ export class WorkFlowInstance { * 校验基本信息节点 */ private is_valid_base_node() { + console.log(this.workflowModel) + if (this.workflowModel == WorkflowMode.Knowledge) { + return + } const start_node_list = this.nodes.filter((item) => item.id === WorkflowType.Base) if (start_node_list.length == 0) { throw t('views.applicationWorkflow.validate.baseNodeRequired') @@ -106,8 +115,10 @@ export class WorkFlowInstance { * @returns */ get_start_node() { - const start_node_list = this.nodes.filter((item) => - [WorkflowType.Start, WorkflowType.LoopStartNode].includes(item.id), + const start_node_list = this.nodes.filter( + (item) => + [WorkflowType.Start, WorkflowType.LoopStartNode].includes(item.id) || + item.properties.kind == WorkflowKind.DataSource, ) return start_node_list[0] } @@ -143,9 +154,26 @@ export class WorkFlowInstance { private is_valid_work_flow() { this.workFlowNodes = [] - this._is_valid_work_flow() + if (this.workflowModel == WorkflowMode.Knowledge) { + const start_node_list = this.nodes.filter( + (item) => + [WorkflowType.Start, WorkflowType.LoopStartNode].includes(item.id) || + item.properties.kind == WorkflowKind.DataSource, + ) + start_node_list.forEach((startNode) => { + this._is_valid_work_flow(startNode) + }) + } else { + this._is_valid_work_flow() + } + const notInWorkFlowNodes = this.nodes - .filter((node: any) => node.id !== WorkflowType.Start && node.id !== WorkflowType.Base) + .filter( + (node: any) => + node.id !== WorkflowType.Start && + node.id !== WorkflowType.Base && + node.id !== WorkflowType.KnowledgeBase, + ) .filter((node) => !this.workFlowNodes.includes(node)) if (notInWorkFlowNodes.length > 0) { throw `${t('views.applicationWorkflow.validate.notInWorkFlowNode')}:${notInWorkFlowNodes.map((node) => node.properties.stepName).join(',')}` @@ -175,7 +203,9 @@ export class WorkFlowInstance { if ( node.type !== WorkflowType.Base && node.type !== WorkflowType.Start && - node.type !== WorkflowType.LoopStartNode + node.type !== WorkflowType.LoopStartNode && + node.type !== WorkflowType.KnowledgeBase && + node.properties.kind !== WorkflowKind.DataSource ) { if (!this.edges.some((edge) => edge.targetNodeId === node.id)) { throw `${t('views.applicationWorkflow.validate.notInWorkFlowNode')}:${node.properties.stepName}` diff --git a/ui/src/workflow/icons/data-source-local-node-icon.vue b/ui/src/workflow/icons/data-source-local-node-icon.vue new file mode 100644 index 00000000000..f3457837ba9 --- /dev/null +++ b/ui/src/workflow/icons/data-source-local-node-icon.vue @@ -0,0 +1,6 @@ + + diff --git a/ui/src/workflow/icons/knowledge-base-node-icon.vue b/ui/src/workflow/icons/knowledge-base-node-icon.vue new file mode 100644 index 00000000000..9165d9e30ad --- /dev/null +++ b/ui/src/workflow/icons/knowledge-base-node-icon.vue @@ -0,0 +1,6 @@ + + diff --git a/ui/src/workflow/index.vue b/ui/src/workflow/index.vue index 73a17a4376b..a2e9f6566ed 100644 --- a/ui/src/workflow/index.vue +++ b/ui/src/workflow/index.vue @@ -78,7 +78,6 @@ const renderGraphData = (data?: any) => { strokeWidth: 1, }, }) - lf.value.graphModel.get = 'sdasdaad' lf.value.on('graph:rendered', () => { flowId.value = lf.value.graphModel.flowId }) diff --git a/ui/src/workflow/nodes/ai-chat-node/index.vue b/ui/src/workflow/nodes/ai-chat-node/index.vue index 2d1bf9d5174..a4896fe6059 100644 --- a/ui/src/workflow/nodes/ai-chat-node/index.vue +++ b/ui/src/workflow/nodes/ai-chat-node/index.vue @@ -335,7 +335,7 @@ import { useRoute } from 'vue-router' import { resetUrl } from '@/utils/common' import { relatedObject } from '@/utils/array.ts' -const getApplicationDetail = inject('getApplicationDetail') as any +const getResourceDetail = inject('getResourceDetail') as any const route = useRoute() const { @@ -431,14 +431,14 @@ const validate = () => { }) } -const application = getApplicationDetail() +const resource = getResourceDetail() function getSelectModel() { const obj = apiType.value === 'systemManage' ? { model_type: 'LLM', - workspace_id: application.value?.workspace_id, + workspace_id: resource.value?.workspace_id, } : { model_type: 'LLM', @@ -522,7 +522,7 @@ function getToolSelectOptions() { ? { scope: 'WORKSPACE', tool_type: 'CUSTOM', - workspace_id: application.value?.workspace_id, + workspace_id: resource.value?.workspace_id, } : { scope: 'WORKSPACE', @@ -545,7 +545,7 @@ function getMcpToolSelectOptions() { ? { scope: 'WORKSPACE', tool_type: 'MCP', - workspace_id: application.value?.workspace_id, + workspace_id: resource.value?.workspace_id, } : { scope: 'WORKSPACE', diff --git a/ui/src/workflow/nodes/base-node/index.ts b/ui/src/workflow/nodes/base-node/index.ts index 69ede8e06af..fac9d3090af 100644 --- a/ui/src/workflow/nodes/base-node/index.ts +++ b/ui/src/workflow/nodes/base-node/index.ts @@ -15,8 +15,9 @@ class BaseModel extends AppNodeModel { return 600 } } + export default { - type: 'base-node', + type: 'knowledge-base-node', model: BaseModel, - view: BaseNode + view: BaseNode, } diff --git a/ui/src/workflow/nodes/base-node/index.vue b/ui/src/workflow/nodes/base-node/index.vue index 940eb3b070a..4448a65eccd 100644 --- a/ui/src/workflow/nodes/base-node/index.vue +++ b/ui/src/workflow/nodes/base-node/index.vue @@ -179,7 +179,7 @@ import FileUploadSettingDialog from '@/workflow/nodes/base-node/component/FileUp import ChatFieldTable from './component/ChatFieldTable.vue' import { useRoute } from 'vue-router' import { loadSharedApi } from '@/utils/dynamics-api/shared-api' -const getApplicationDetail = inject('getApplicationDetail') as any +const getResourceDetail = inject('getResourceDetail') as any const route = useRoute() const { @@ -261,13 +261,13 @@ const validate = () => { }) } -const application = getApplicationDetail() +const resource = getResourceDetail() function getSTTModel() { const obj = apiType.value === 'systemManage' ? { model_type: 'STT', - workspace_id: application.value?.workspace_id, + workspace_id: resource.value?.workspace_id, } : { model_type: 'STT', @@ -284,7 +284,7 @@ function getTTSModel() { apiType.value === 'systemManage' ? { model_type: 'TTS', - workspace_id: application.value?.workspace_id, + workspace_id: resource.value?.workspace_id, } : { model_type: 'TTS', diff --git a/ui/src/workflow/nodes/data-source-local-node/index.ts b/ui/src/workflow/nodes/data-source-local-node/index.ts new file mode 100644 index 00000000000..c31422ad098 --- /dev/null +++ b/ui/src/workflow/nodes/data-source-local-node/index.ts @@ -0,0 +1,12 @@ +import DataSourceWebNodeVue from './index.vue' +import { AppNode, AppNodeModel } from '@/workflow/common/app-node' +class DataSourceWebNode extends AppNode { + constructor(props: any) { + super(props, DataSourceWebNodeVue) + } +} +export default { + type: 'data-source-local-node', + model: AppNodeModel, + view: DataSourceWebNode, +} diff --git a/ui/src/workflow/nodes/data-source-local-node/index.vue b/ui/src/workflow/nodes/data-source-local-node/index.vue new file mode 100644 index 00000000000..2ca58b13af6 --- /dev/null +++ b/ui/src/workflow/nodes/data-source-local-node/index.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/ui/src/workflow/nodes/data-source-web-node/index.ts b/ui/src/workflow/nodes/data-source-web-node/index.ts new file mode 100644 index 00000000000..0bc7c5283d4 --- /dev/null +++ b/ui/src/workflow/nodes/data-source-web-node/index.ts @@ -0,0 +1,12 @@ +import DataSourceWebNodeVue from './index.vue' +import { AppNode, AppNodeModel } from '@/workflow/common/app-node' +class DataSourceWebNode extends AppNode { + constructor(props: any) { + super(props, DataSourceWebNodeVue) + } +} +export default { + type: 'data-source-web-node', + model: AppNodeModel, + view: DataSourceWebNode, +} diff --git a/ui/src/workflow/nodes/data-source-web-node/index.vue b/ui/src/workflow/nodes/data-source-web-node/index.vue new file mode 100644 index 00000000000..f1d5d626000 --- /dev/null +++ b/ui/src/workflow/nodes/data-source-web-node/index.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/ui/src/workflow/nodes/image-generate/index.vue b/ui/src/workflow/nodes/image-generate/index.vue index a9829b30b98..559771edd58 100644 --- a/ui/src/workflow/nodes/image-generate/index.vue +++ b/ui/src/workflow/nodes/image-generate/index.vue @@ -161,7 +161,7 @@ import AIModeParamSettingDialog from '@/views/application/component/AIModeParamS import { t } from '@/locales' import { useRoute } from 'vue-router' import { loadSharedApi } from '@/utils/dynamics-api/shared-api' -const getApplicationDetail = inject('getApplicationDetail') as any +const getResourceDetail = inject('getResourceDetail') as any const route = useRoute() const { @@ -226,13 +226,13 @@ const form_data = computed({ }, }) -const application = getApplicationDetail() +const resource = getResourceDetail() function getSelectModel() { const obj = apiType.value === 'systemManage' ? { model_type: 'TTI', - workspace_id: application.value?.workspace_id, + workspace_id: resource.value?.workspace_id, } : { model_type: 'TTI', diff --git a/ui/src/workflow/nodes/image-to-video/index.vue b/ui/src/workflow/nodes/image-to-video/index.vue index cb315f19efd..e216011d43e 100644 --- a/ui/src/workflow/nodes/image-to-video/index.vue +++ b/ui/src/workflow/nodes/image-to-video/index.vue @@ -16,7 +16,9 @@ prop="model_id" :rules="{ required: true, - message: $t('views.applicationWorkflow.nodes.imageToVideoGenerate.model.requiredMessage'), + message: $t( + 'views.applicationWorkflow.nodes.imageToVideoGenerate.model.requiredMessage', + ), trigger: 'change', }" > @@ -24,8 +26,7 @@
{{ - $t('views.applicationWorkflow.nodes.imageToVideoGenerate.model.label') + >{{ $t('views.applicationWorkflow.nodes.imageToVideoGenerate.model.label') }}*
@@ -69,14 +70,13 @@
{{ - $t('views.applicationWorkflow.nodes.imageToVideoGenerate.prompt.label') + >{{ $t('views.applicationWorkflow.nodes.imageToVideoGenerate.prompt.label') }}*
@@ -103,13 +103,15 @@
{{ - $t('views.applicationWorkflow.nodes.imageToVideoGenerate.negative_prompt.label') - }} + $t('views.applicationWorkflow.nodes.imageToVideoGenerate.negative_prompt.label') + }}
@@ -118,7 +120,9 @@ + >{{ $t('views.applicationWorkflow.nodes.imageToVideoGenerate.last_frame.label') }} +
{{ - $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label') - }} + $t('views.applicationWorkflow.nodes.aiChatNode.returnContent.label') + }}
- + - + + diff --git a/ui/src/workflow/nodes/knowledge-base-node/component/UserInputFieldTable.vue b/ui/src/workflow/nodes/knowledge-base-node/component/UserInputFieldTable.vue new file mode 100644 index 00000000000..d90049455a8 --- /dev/null +++ b/ui/src/workflow/nodes/knowledge-base-node/component/UserInputFieldTable.vue @@ -0,0 +1,222 @@ + + + + + diff --git a/ui/src/workflow/nodes/knowledge-base-node/component/UserInputTitleDialog.vue b/ui/src/workflow/nodes/knowledge-base-node/component/UserInputTitleDialog.vue new file mode 100644 index 00000000000..08c2f48c32f --- /dev/null +++ b/ui/src/workflow/nodes/knowledge-base-node/component/UserInputTitleDialog.vue @@ -0,0 +1,83 @@ + + + diff --git a/ui/src/workflow/nodes/knowledge-base-node/index.ts b/ui/src/workflow/nodes/knowledge-base-node/index.ts new file mode 100644 index 00000000000..c51b52ea025 --- /dev/null +++ b/ui/src/workflow/nodes/knowledge-base-node/index.ts @@ -0,0 +1,22 @@ +import BaseNodeVue from './index.vue' +import { AppNode, AppNodeModel } from '@/workflow/common/app-node' + +class BaseNode extends AppNode { + constructor(props: any) { + super(props, BaseNodeVue) + } +} + +class BaseModel extends AppNodeModel { + constructor(data: any, graphModel: any) { + super(data, graphModel) + } + get_width() { + return 600 + } +} +export default { + type: 'knowledge-base-node', + model: BaseModel, + view: BaseNode, +} diff --git a/ui/src/workflow/nodes/knowledge-base-node/index.vue b/ui/src/workflow/nodes/knowledge-base-node/index.vue new file mode 100644 index 00000000000..8f986440bfc --- /dev/null +++ b/ui/src/workflow/nodes/knowledge-base-node/index.vue @@ -0,0 +1,30 @@ + + + diff --git a/ui/src/workflow/nodes/loop-body-node/LoopBodyContainer.vue b/ui/src/workflow/nodes/loop-body-node/LoopBodyContainer.vue index 6597f2e76ec..1b6a4c3e08a 100644 --- a/ui/src/workflow/nodes/loop-body-node/LoopBodyContainer.vue +++ b/ui/src/workflow/nodes/loop-body-node/LoopBodyContainer.vue @@ -110,16 +110,14 @@