feat: Knowledge workflow import and export
Some checks are pending
sync2gitee / repo-sync (push) Waiting to run
Typos Check / Spell Check with Typos (push) Waiting to run

This commit is contained in:
zhangzhanwei 2025-12-19 16:45:32 +08:00 committed by zhanweizhang7
parent 4fecd47904
commit ff2a14817e
16 changed files with 477 additions and 36 deletions

View File

@ -406,6 +406,9 @@ Permission_Label = {
Group.SYSTEM_RES_APPLICATION_ACCESS.value: _("Application Access"),
Group.SYSTEM_RES_APPLICATION_CHAT_USER.value: _("Dialogue users"),
Group.SYSTEM_RES_APPLICATION_CHAT_LOG.value: _("Conversation log"),
Group.APPLICATION_FOLDER.value: _("Folder"),
Group.KNOWLEDGE_FOLDER.value: _("Folder"),
Group.TOOL_FOLDER.value: _("Folder"),
# SystemGroup.RESOURCE.value: _("Resource"),
}
@ -468,31 +471,6 @@ class PermissionConstants(Enum):
TOOL = Permission(
group=Group.TOOL, operate=Operate.SELF, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
)
APPLICATION_FOLDER_READ = Permission(
group=Group.APPLICATION_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_VIEW]
)
APPLICATION_FOLDER_EDIT = Permission(
group=Group.APPLICATION_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
)
KNOWLEDGE_FOLDER_READ = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW]
)
KNOWLEDGE_FOLDER_EDIT = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE]
)
TOOL_FOLDER_READ = Permission(
group=Group.TOOL_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
)
TOOL_FOLDER_EDIT = Permission(
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
)
USER_READ = Permission(
group=Group.USER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[SystemGroup.USER_MANAGEMENT]
@ -578,6 +556,26 @@ class PermissionConstants(Enum):
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
)
TOOL_FOLDER_READ = Permission(
group=Group.TOOL_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
)
TOOL_FOLDER_CREATE = Permission(
group=Group.TOOL_FOLDER, operate=Operate.CREATE, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
resource_permission_group_list=[ResourcePermissionConst.TOOL_VIEW]
)
TOOL_FOLDER_EDIT = Permission(
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
)
TOOL_FOLDER_DELETE = Permission(
group=Group.TOOL_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.TOOL, UserGroup.TOOL],
resource_permission_group_list=[ResourcePermissionConst.TOOL_MANGE]
)
KNOWLEDGE_READ = Permission(
group=Group.KNOWLEDGE, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
@ -623,6 +621,26 @@ class PermissionConstants(Enum):
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
)
KNOWLEDGE_FOLDER_READ = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.READ, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
parent_group = [WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
)
KNOWLEDGE_FOLDER_CREATE = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.CREATE, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_VIEW],
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
)
KNOWLEDGE_FOLDER_EDIT = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
)
KNOWLEDGE_FOLDER_DELETE = Permission(
group=Group.KNOWLEDGE_FOLDER, operate=Operate.DELETE, role_list=[RoleConstants.ADMIN, RoleConstants.USER],
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],
@ -633,6 +651,11 @@ class PermissionConstants(Enum):
resource_permission_group_list=[ResourcePermissionConst.KNOWLEDGE_MANGE],
parent_group=[WorkspaceGroup.KNOWLEDGE, UserGroup.KNOWLEDGE]
)
KNOWLEDGE_WORKFLOW_EXPORT = Permission(
group=Group.KNOWLEDGE_WORKFLOW, operate=Operate.EXPORT, 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],
@ -926,6 +949,26 @@ class PermissionConstants(Enum):
resource_permission_group_list=[
ResourcePermissionConst.APPLICATION_MANGE],
)
APPLICATION_FOLDER_READ = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.READ,
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_VIEW]
)
APPLICATION_FOLDER_CREATE = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.EDIT,
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
)
APPLICATION_FOLDER_EDIT = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.EDIT,
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
)
APPLICATION_FOLDER_DELETE = Permission(group=Group.APPLICATION_FOLDER, operate=Operate.DELETE,
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],
resource_permission_group_list=[ResourcePermissionConst.APPLICATION_MANGE]
)
APPLICATION_OVERVIEW_READ = Permission(group=Group.APPLICATION_OVERVIEW, operate=Operate.READ,
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[WorkspaceGroup.APPLICATION, UserGroup.APPLICATION],

View File

@ -298,7 +298,8 @@ ALLOWED_CLASSES = {
("builtins", "dict"),
('uuid', 'UUID'),
("application.serializers.application", "MKInstance"),
("tools.serializers.tool", "ToolInstance")
("tools.serializers.tool", "ToolInstance"),
("knowledge.serializers.knowledge_workflow", "KBWFInstance")
}

View File

@ -3,7 +3,9 @@ from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter
from common.mixins.api_mixin import APIMixin
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowActionRequestSerializer
from common.result import DefaultResultSerializer
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowActionRequestSerializer, \
KnowledgeWorkflowImportRequest
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowActionListQuerySerializer
@ -71,3 +73,39 @@ class KnowledgeWorkflowActionApi(APIMixin):
required=True,
)
]
class KnowledgeWorkflowExportApi(APIMixin):
@staticmethod
def get_parameters():
return [
OpenApiParameter(
name="workspace_id",
description="工作空间id",
type=OpenApiTypes.STR,
location='path',
required=True,
),
OpenApiParameter(
name="knowledge_id",
description="知识库id",
type=OpenApiTypes.STR,
location='path',
required=True,
),
]
@staticmethod
def get_response():
return DefaultResultSerializer
class KnowledgeWorkflowImportApi(APIMixin):
@staticmethod
def get_parameters():
return KnowledgeWorkflowExportApi.get_parameters()
@staticmethod
def get_request():
return KnowledgeWorkflowImportRequest
@staticmethod
def get_response():
return DefaultResultSerializer

View File

@ -1,14 +1,17 @@
# coding=utf-8
import asyncio
import json
from typing import Dict
import pickle
from functools import reduce
from typing import Dict, List
import uuid_utils.compat as uuid
from django.db import transaction
from django.db.models import QuerySet
from django.http import HttpResponse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from rest_framework import serializers, status
from application.flow.common import Workflow, WorkflowMode
from application.flow.i_step_node import KnowledgeWorkflowPostHandler
@ -18,6 +21,9 @@ from application.serializers.application import get_mcp_tools
from common.constants.cache_version import Cache_Version
from common.db.search import page_search
from common.exception.app_exception import AppApiException
from common.field.common import UploadedFileField
from common.result import result
from common.utils.common import restricted_loads, generate_uuid
from common.utils.rsa_util import rsa_long_decrypt
from common.utils.tool_code import ToolExecutor
from knowledge.models import KnowledgeScope, Knowledge, KnowledgeType, KnowledgeWorkflow, KnowledgeWorkflowVersion
@ -26,12 +32,22 @@ from knowledge.serializers.knowledge import KnowledgeModelSerializer
from django.core.cache import cache
from system_manage.models import AuthTargetType
from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer
from tools.models import Tool
from tools.models import Tool, ToolScope
from tools.serializers.tool import ToolExportModelSerializer
from users.models import User
tool_executor = ToolExecutor()
def hand_node(node, update_tool_map):
if node.get('type') == 'tool-lib-node':
tool_lib_id = (node.get('properties', {}).get('node_data', {}).get('tool_lib_id') or '')
node.get('properties', {}).get('node_data', {})['tool_lib_id'] = update_tool_map.get(tool_lib_id, tool_lib_id)
if node.get('type') == 'search-knowledge-node':
node.get('properties', {}).get('node_data', {})['knowledge_id_list'] = []
class KnowledgeWorkflowModelSerializer(serializers.ModelSerializer):
class Meta:
model = KnowledgeWorkflow
@ -43,10 +59,24 @@ class KnowledgeWorkflowActionRequestSerializer(serializers.Serializer):
knowledge_base = serializers.DictField(required=True, label=_('knowledge base data'))
class KnowledgeWorkflowImportRequest(serializers.Serializer):
file = UploadedFileField(required=True, label=_("file"))
class KnowledgeWorkflowActionListQuerySerializer(serializers.Serializer):
user_name = serializers.CharField(required=False, label=_('Name'), allow_blank=True, allow_null=True)
state = serializers.CharField(required=False, label=_("State"), allow_blank=True, allow_null=True)
class KBWFInstance:
def __init__(self, knowledge_workflow: dict, function_lib_list: List[dict], version: str, tool_list: List[dict]):
self.knowledge_workflow = knowledge_workflow
self.function_lib_list = function_lib_list
self.version = version
self.tool_list = tool_list
def get_tool_list(self):
return [*(self.tool_list or []), *(self.function_lib_list or [])]
class KnowledgeWorkflowActionSerializer(serializers.Serializer):
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
@ -217,6 +247,130 @@ class KnowledgeWorkflowSerializer(serializers.Serializer):
return {**KnowledgeModelSerializer(knowledge).data, 'document_list': []}
class Import(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 import_(self, instance: dict, is_import_tool, with_valid=True):
if with_valid:
self.is_valid()
KnowledgeWorkflowImportRequest(data=instance).is_valid(raise_exception=True)
user_id = self.data.get('user_id')
workspace_id = self.data.get('workspace_id')
knowledge_id = self.data.get('knowledge_id')
kbwf_instance_bytes = instance.get('file').read()
try:
kbwf_instance = restricted_loads(kbwf_instance_bytes)
except Exception as e:
raise AppApiException(1001, _("Unsupported file format"))
knowledge_workflow = kbwf_instance.knowledge_workflow
tool_list = kbwf_instance.get_tool_list()
update_tool_map = {}
if len(tool_list) > 0:
tool_id_list = reduce(lambda x, y: [*x, *y],
[[tool.get('id'), generate_uuid((tool.get('id') + workspace_id or ''))]
for tool
in
tool_list], [])
# 存在的工具列表
exits_tool_id_list = [str(tool.id) for tool in
QuerySet(Tool).filter(id__in=tool_id_list, workspace_id=workspace_id)]
# 需要更新的工具集合
update_tool_map = {tool.get('id'): generate_uuid((tool.get('id') + workspace_id or '')) for tool
in
tool_list if
not exits_tool_id_list.__contains__(
tool.get('id'))}
tool_list = [{**tool, 'id': update_tool_map.get(tool.get('id'))} for tool in tool_list if
not exits_tool_id_list.__contains__(
tool.get('id')) and not exits_tool_id_list.__contains__(
generate_uuid((tool.get('id') + workspace_id or '')))]
work_flow = self.to_knowledge_workflow(
knowledge_workflow,
update_tool_map,
)
tool_model_list = [self.to_tool(tool, workspace_id, user_id) for tool in tool_list]
KnowledgeWorkflow.objects.filter(workspace_id=workspace_id,knowledge_id=knowledge_id).update(
work_flow=work_flow
)
if is_import_tool:
if len(tool_model_list) > 0:
QuerySet(Tool).bulk_create(tool_model_list)
UserResourcePermissionSerializer(data={
'workspace_id': self.data.get('workspace_id'),
'user_id': self.data.get('user_id'),
'auth_target_type': AuthTargetType.TOOL.value
}).auth_resource_batch([t.id for t in tool_model_list])
return True
@staticmethod
def to_knowledge_workflow(knowledge_workflow, update_tool_map):
work_flow = knowledge_workflow.get("work_flow")
for node in work_flow.get('nodes', []):
hand_node(node, update_tool_map)
if node.get('type') == 'loop_node':
for n in node.get('properties', {}).get('node_data', {}).get('loop_body', {}).get('nodes', []):
hand_node(n, update_tool_map)
return work_flow
@staticmethod
def to_tool(tool, workspace_id, user_id):
return Tool(id=tool.get('id'),
user_id=user_id,
name=tool.get('name'),
code=tool.get('code'),
template_id=tool.get('template_id'),
input_field_list=tool.get('input_field_list'),
init_field_list=tool.get('init_field_list'),
is_active=False if len((tool.get('init_field_list') or [])) > 0 else tool.get('is_active'),
scope=ToolScope.WORKSPACE,
folder_id=workspace_id,
workspace_id=workspace_id)
class Export(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 export(self, with_valid=True):
try:
if with_valid:
self.is_valid()
knowledge_id = self.data.get('knowledge_id')
knowledge_workflow = QuerySet(KnowledgeWorkflow).filter(knowledge_id=knowledge_id).first()
knowledge = QuerySet(Knowledge).filter(id=knowledge_id).first()
tool_id_list = [node.get('properties', {}).get('node_data', {}).get('tool_lib_id') for node
in
knowledge_workflow.work_flow.get('nodes', []) + reduce(lambda x, y: [*x, *y], [
n.get('properties', {}).get('node_data', {}).get('loop_body', {}).get('nodes', [])
for n
in
knowledge_workflow.work_flow.get('nodes', []) if n.get('type') == 'loop-node'], [])
if
node.get('type') == 'tool-lib-node']
tool_list = []
if len(tool_id_list) > 0:
tool_list = QuerySet(Tool).filter(id__in=tool_id_list).exclude(scope=ToolScope.SHARED)
knowledge_workflow_dict = KnowledgeWorkflowModelSerializer(knowledge_workflow).data
kbwf_instance = KBWFInstance(
knowledge_workflow_dict,
[],
'v2',
[ToolExportModelSerializer(tool).data for tool in tool_list]
)
knowledge_workflow_pickle = pickle.dumps(kbwf_instance)
response = HttpResponse(content_type='text/plain', content=knowledge_workflow_pickle)
response['Content-Disposition'] = f'attachment; filename="{knowledge.name}.kbwf"'
return response
except Exception as e:
return result.error(str(e), response_status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class Operate(serializers.Serializer):
user_id = serializers.UUIDField(required=True, label=_('user id'))
workspace_id = serializers.CharField(required=True, label=_('workspace id'))

View File

@ -17,6 +17,8 @@ urlpatterns = [
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>', views.KnowledgeView.Operate.as_view()),
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/sync', views.KnowledgeView.SyncWeb.as_view()),
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow', views.KnowledgeWorkflowView.Operate.as_view()),
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow/export', views.KnowledgeWorkflowView.Export.as_view()),
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow/import', views.KnowledgeWorkflowView.Import.as_view()),
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/generate_related', views.KnowledgeView.GenerateRelated.as_view()),
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/embedding', views.KnowledgeView.Embedding.as_view()),
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/hit_test', views.KnowledgeView.HitTest.as_view()),

View File

@ -7,12 +7,12 @@ from rest_framework.views import APIView
from application.api.application_api import SpeechToTextAPI
from common.auth import TokenAuth
from common.auth.authentication import has_permissions
from common.auth.authentication import has_permissions, get_is_permissions
from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
from common.log.log import log
from common.result import result, DefaultResultSerializer
from knowledge.api.knowledge_workflow import KnowledgeWorkflowApi, KnowledgeWorkflowActionApi, \
KnowledgeWorkflowActionPageApi
KnowledgeWorkflowActionPageApi, KnowledgeWorkflowExportApi, KnowledgeWorkflowImportApi
from knowledge.serializers.common import get_knowledge_operation_object
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowSerializer, KnowledgeWorkflowActionSerializer, \
KnowledgeWorkflowMcpSerializer
@ -244,6 +244,73 @@ class KnowledgeWorkflowView(APIView):
data={'knowledge_id': knowledge_id, 'user_id': request.user.id,
'workspace_id': workspace_id, }).publish())
class Export(APIView):
authentication_classes = [TokenAuth]
@extend_schema(
methods=['GET'],
description=_('Export knowledge workflow'),
summary=_('Export knowledge workflow'),
operation_id=_('Export knowledge workflow'), # type: ignore
parameters=KnowledgeWorkflowExportApi.get_parameters(),
request=None,
responses=KnowledgeWorkflowExportApi.get_response(),
tags=[_('Knowledge Base')] # type: ignore
)
@has_permissions(
PermissionConstants.KNOWLEDGE_WORKFLOW_EXPORT.get_workspace_knowledge_permission(),
PermissionConstants.KNOWLEDGE_WORKFLOW_EXPORT.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', operate="Export knowledge workflow",
get_operation_object=lambda r, k: get_knowledge_operation_object(k.get('knowledge_id')),
)
def get(self, request: Request, workspace_id: str, knowledge_id: str):
return KnowledgeWorkflowSerializer.Export(
data={'knowledge_id': knowledge_id,'user_id': request.user.id,'workspace_id': workspace_id}
).export()
class Import(APIView):
authentication_classes = [TokenAuth]
@extend_schema(
methods=['POST'],
description=_('Import knowledge workflow'),
summary=_('Import knowledge workflow'),
operation_id=_('Import knowledge workflow'), # type: ignore
parameters=KnowledgeWorkflowImportApi.get_parameters(),
request=KnowledgeWorkflowImportApi.get_request(),
responses=KnowledgeWorkflowImportApi.get_response(),
tags=[_('Knowledge Base')] # type: ignore
)
@has_permissions(
PermissionConstants.KNOWLEDGE_WORKFLOW_EDIT.get_workspace_knowledge_permission(),
PermissionConstants.KNOWLEDGE_WORKFLOW_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', operate="Import knowledge workflow",
get_operation_object=lambda r, k: get_knowledge_operation_object(k.get('knowledge_id')),
)
def post(self, request: Request, workspace_id:str, knowledge_id: str):
is_import_tool = get_is_permissions(request, workspace_id=workspace_id)(
PermissionConstants.TOOL_IMPORT.get_workspace_permission(),
PermissionConstants.TOOL_IMPORT.get_workspace_permission_workspace_manage_role(),
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
)
return result.success(KnowledgeWorkflowSerializer.Import(data={
'knowledge_id': knowledge_id, 'user_id': request.user.id, 'workspace_id': workspace_id
}).import_({'file': request.FILES.get('file')}, is_import_tool))
class Operate(APIView):
authentication_classes = [TokenAuth]

View File

@ -8874,4 +8874,10 @@ msgid "This account has been locked for %s minutes, please try again later"
msgstr ""
msgid "User does not have permission to use API Key"
msgstr ""
msgid "Import knowledge workflow"
msgstr ""
msgid "Export knowledge workflow"
msgstr ""

View File

@ -9000,4 +9000,10 @@ msgid "This account has been locked for %s minutes, please try again later"
msgstr "该账号已被锁定 %s 分钟,请稍后再试"
msgid "User does not have permission to use API Key"
msgstr "用户没有使用 API Key 的权限"
msgstr "用户没有使用 API Key 的权限"
msgid "Import knowledge workflow"
msgstr "导入知识工作流"
msgid "Export knowledge workflow"
msgstr "导出知识工作流"

View File

@ -9001,3 +9001,9 @@ msgstr "該帳號已被鎖定 %s 分鐘,請稍後再試"
msgid "User does not have permission to use API Key"
msgstr "使用者沒有使用 API Key 的權限"
msgid "Import knowledge workflow"
msgstr "匯入知識工作流"
msgid "Export knowledge workflow"
msgstr "匯出知識工作流"

View File

@ -5,6 +5,7 @@ import type { Dict, pageRequest } from '@/api/type/common'
import type { knowledgeData } from '@/api/type/knowledge'
import useStore from '@/stores'
import knowledge from '../system-shared/knowledge'
const prefix: any = { _value: '/workspace/' }
Object.defineProperty(prefix, 'value', {
get: function () {
@ -395,6 +396,37 @@ const putKnowledgeWorkflow: (
return put(`${prefix.value}/${knowledge_id}/workflow`, data, undefined, loading)
}
/**
*
* @param knowledge_id
* @param knowledge_name
* @param loading
* @returns
*/
const exportKnowledgeWorkflow = (
knowledge_id: string,
knowledge_name: string,
loading?: Ref<boolean>
) => {
return exportFile(
knowledge_name + '.kbwf',
`${prefix.value}/${knowledge_id}/workflow/export`,
undefined,
loading
)
}
/**
*
*/
const importKnowledgeWorkflow: (
knowledge_id: string,
data: any,
loading?:Ref<boolean>
) => Promise<Result<any>> = (knowledge_id, data, loading)=>{
return post(`${prefix.value}/${knowledge_id}/workflow/import`,data,undefined,loading)
}
const listKnowledgeVersion: (
knowledge_id: string,
loading?: Ref<boolean>,
@ -487,4 +519,6 @@ export default {
workflowUpload,
getWorkflowActionPage,
cancelWorkflowAction,
exportKnowledgeWorkflow,
importKnowledgeWorkflow
}

View File

@ -197,6 +197,12 @@ const systemManage = {
PermissionConst.RESOURCE_KNOWLEDGE_WORKFLOW_EDIT
],'OR'
),
workflow_export: () =>
hasPermission([
RoleConst.ADMIN,
PermissionConst.RESOURCE_KNOWLEDGE_WORKFLOW_EXPORT
],'OR'
),
chat_user_edit: () =>false,

View File

@ -60,7 +60,8 @@ const share = {
hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_WORKFLOW_READ], 'OR'),
workflow_edit: () =>
hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_WORKFLOW_EDIT], 'OR'),
workflow_export: () =>
hasPermission([RoleConst.ADMIN, PermissionConst.SHARED_KNOWLEDGE_WORKFLOW_EXPORT], 'OR'),
chat_user_edit: () => false,
auth: () => false,

View File

@ -47,8 +47,9 @@ const workspaceShare = {
folderAuth: () => false,
folderDelete: () => false,
hit_test: () => false,
debug: () => true,
workflow_edit: () => true,
debug: () => false,
workflow_edit: () => false,
workflow_export: () => false,
}
export default workspaceShare

View File

@ -587,6 +587,21 @@ const workspace = {
],
'OR',
),
workflow_export: (source_id: string) =>
hasPermission(
[
new ComplexPermission(
[RoleConst.USER],
[PermissionConst.KNOWLEDGE.getKnowledgeWorkspaceResourcePermission(source_id)],
[],
'AND',
),
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
PermissionConst.KNOWLEDGE_WORKFLOW_EXPORT.getKnowledgeWorkspaceResourcePermission(source_id),
PermissionConst.KNOWLEDGE_WORKFLOW_EXPORT.getWorkspacePermissionWorkspaceManageRole,
],
'OR',
),
hit_test: () => false,
}

View File

@ -112,6 +112,7 @@ const PermissionConst = {
KNOWLEDGE_WORKFLOW_READ: new Permission('KNOWLEDGE_WORKFLOW:READ'),
KNOWLEDGE_WORKFLOW_EDIT: new Permission('KNOWLEDGE_WORKFLOW:READ+EDIT'),
KNOWLEDGE_WORKFLOW_EXPORT: new Permission('KNOWLEDGE_WORKFLOW:READ+EXPORT'),
KNOWLEDGE_DOCUMENT_READ: new Permission('KNOWLEDGE_DOCUMENT:READ'),
KNOWLEDGE_DOCUMENT_CREATE: new Permission('KNOWLEDGE_DOCUMENT:READ+CREATE'),
@ -196,6 +197,7 @@ const PermissionConst = {
SHARED_KNOWLEDGE_WORKFLOW_READ: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ'),
SHARED_KNOWLEDGE_WORKFLOW_EDIT: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ+EDIT'),
SHARED_KNOWLEDGE_WORKFLOW_EXPORT: new Permission('SYSTEM_KNOWLEDGE_WORKFLOW:READ+EXPORT'),
SHARED_KNOWLEDGE_DOCUMENT_READ: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ'),
SHARED_KNOWLEDGE_DOCUMENT_CREATE: new Permission('SYSTEM_KNOWLEDGE_DOCUMENT:READ+CREATE'),
@ -252,6 +254,7 @@ const PermissionConst = {
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_WORKFLOW_EXPORT: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_WORKFLOW:READ+EXPORT'),
RESOURCE_KNOWLEDGE_DOCUMENT_READ: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ'),
RESOURCE_KNOWLEDGE_DOCUMENT_CREATE: new Permission('SYSTEM_RESOURCE_KNOWLEDGE_DOCUMENT:READ+CREATE'),

View File

@ -52,6 +52,30 @@
<AppIcon iconName="app-to-import-doc" class="color-secondary"></AppIcon>
{{ $t('workflow.operation.toImportDoc') }}
</el-dropdown-item>
<el-dropdown-item
@click.stop="exportKnowledgeWorkflow(detail.name, detail.id)"
v-if="permissionPrecise.workflow_export(id)"
>
<AppIcon iconName="app-export" class="color-secondary"></AppIcon>
{{ $t('common.export') }}
</el-dropdown-item>
<el-upload
class="import-button"
ref="elUploadRef"
:file-list="[]"
action="#"
multiple
:auto-upload="false"
:show-file-list="false"
:limit="1"
:on-change="(file: any, fileList: any) => importKnowledgeWorkflow(file)"
v-if="permissionPrecise.workflow_edit(id)"
>
<el-dropdown-item>
<AppIcon iconName="app-import" class="color-secondary"></AppIcon>
{{ $t('common.import', '导入') }}
</el-dropdown-item>
</el-upload>
<el-dropdown-item @click="openListAction" divided>
<AppIcon iconName="app-execution-record" class="color-secondary"></AppIcon>
{{ $t('workflow.ExecutionRecord') }}
@ -366,6 +390,40 @@ const publish = () => {
})
}
const elUploadRef = ref()
const importKnowledgeWorkflow = (file: any) => {
const formData = new FormData()
formData.append('file', file.raw)
elUploadRef.value.clearFiles()
loadSharedApi({ type: 'knowledge', isShared: isShared.value, systemType: apiType.value })
.importKnowledgeWorkflow(id, formData, loading)
.then(() => {
getDetail()
})
.catch((error: any) => {
if (error.code === 400) {
MsgConfirm(t('common.tip'), t('views.application.tip.professionalMessage'), {
cancelButtonText: t('common.confirm'),
confirmButtonText: t('common.professional'),
}).then(() => {
window.open('https://maxkb.cn/pricing.html', '_blank')
})
}
})
}
function exportKnowledgeWorkflow(name: string, id: string) {
loadSharedApi({ type: 'knowledge', isShared: isShared.value, systemType: apiType.value })
.exportKnowledgeWorkflow(id, name, loading)
.catch((error: any) => {
if (error.response.status !== 403) {
error.response.data.text().then((res: string) => {
MsgError(`${t('views.application.tip.ExportError')}:${JSON.parse(res).message}`)
})
}
})
}
const clickShowDebug = () => {
workflowRef.value
?.validate()