Skip to content

Commit 12c1b07

Browse files
committed
feat: Batch delete and move knowledges
1 parent 9877e17 commit 12c1b07

File tree

7 files changed

+205
-6
lines changed

7 files changed

+205
-6
lines changed

apps/knowledge/api/knowledge.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from common.mixins.api_mixin import APIMixin
55
from common.result import ResultSerializer, DefaultResultSerializer
6+
from knowledge.serializers.common import BatchSerializer, BatchMoveSerializer
67
from knowledge.serializers.common import GenerateRelatedSerializer
78
from knowledge.serializers.knowledge import KnowledgeBaseCreateRequest, KnowledgeModelSerializer, KnowledgeEditRequest, \
89
KnowledgeWebCreateRequest, HitTestSerializer
@@ -282,4 +283,26 @@ def get_parameters():
282283

283284
@staticmethod
284285
def get_response():
285-
return DefaultResultSerializer
286+
return DefaultResultSerializer
287+
288+
289+
class KnowledgeBatchOperateAPI(APIMixin):
290+
@staticmethod
291+
def get_parameters():
292+
return [
293+
OpenApiParameter(
294+
name="workspace_id",
295+
description="工作空间id",
296+
type=OpenApiTypes.STR,
297+
location='path',
298+
required=True,
299+
)
300+
]
301+
302+
@staticmethod
303+
def get_request():
304+
return BatchSerializer
305+
306+
@staticmethod
307+
def get_move_request():
308+
return BatchMoveSerializer

apps/knowledge/serializers/knowledge.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from common.utils.split_model import get_split_model
3535
from knowledge.models import Knowledge, KnowledgeScope, KnowledgeType, Document, Paragraph, Problem, \
3636
ProblemParagraphMapping, TaskType, State, SearchMode, KnowledgeFolder, File, Tag, KnowledgeWorkflow
37+
from knowledge.serializers.common import BatchSerializer, BatchMoveSerializer
3738
from knowledge.serializers.common import ProblemParagraphManage, drop_knowledge_index, \
3839
get_embedding_model_id_by_knowledge_id, MetaSerializer, \
3940
GenerateRelatedSerializer, get_embedding_model_by_knowledge_id, list_paragraph, write_image, zip_dir, \
@@ -877,3 +878,50 @@ def list(self):
877878
})
878879

879880
return result
881+
882+
883+
class KnowledgeBatchOperateSerializer(serializers.Serializer):
884+
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
885+
886+
def is_valid(self, *, raise_exception=False):
887+
super().is_valid(raise_exception=True)
888+
889+
@transaction.atomic
890+
def batch_delete(self, instance: Dict, with_valid=True):
891+
if with_valid:
892+
BatchSerializer(data=instance).is_valid(model=Knowledge, raise_exception=True)
893+
self.is_valid(raise_exception=True)
894+
id_list = instance.get('id_list')
895+
workspace_id = self.data.get('workspace_id')
896+
knowledge_query_set = QuerySet(Knowledge).filter(id__in=id_list,workspace_id=workspace_id)
897+
898+
# 删除所有关联
899+
QuerySet(Document).filter(knowledge__in=knowledge_query_set).delete()
900+
QuerySet(ProblemParagraphMapping).filter(knowledge__in=knowledge_query_set).delete()
901+
QuerySet(Paragraph).filter(knowledge__in=knowledge_query_set).delete()
902+
QuerySet(Problem).filter(knowledge__in=knowledge_query_set).delete()
903+
QuerySet(WorkspaceUserResourcePermission).filter(target__in=id_list).delete()
904+
905+
for k_id in id_list:
906+
drop_knowledge_index(knowledge_id=k_id)
907+
delete_embedding_by_knowledge(k_id)
908+
909+
File.objects.filter(source_id__in=id_list).delete()
910+
QuerySet(ResourceMapping).filter(
911+
Q(target_id__in=id_list) | Q(source_id__in=id_list)
912+
).delete()
913+
914+
knowledge_query_set.delete()
915+
return True
916+
917+
def batch_move(self, instance: Dict, with_valid=True):
918+
if with_valid:
919+
BatchMoveSerializer(data=instance).is_valid(model=Knowledge, raise_exception=True)
920+
self.is_valid(raise_exception=True)
921+
id_list = instance.get('id_list')
922+
folder_id = instance.get('folder_id')
923+
workspace_id = self.data.get('workspace_id')
924+
925+
QuerySet(Knowledge).filter(id__in=id_list, workspace_id=workspace_id).update(folder_id=folder_id)
926+
return True
927+

apps/knowledge/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
path('workspace/<str:workspace_id>/knowledge/model', views.KnowledgeView.Model.as_view()),
1616
path('workspace/<str:workspace_id>/knowledge/embedding_model', views.KnowledgeView.EmbeddingModel.as_view()),
1717
path('workspace/<str:workspace_id>/knowledge/tags', views.KnowledgeView.Tags.as_view()),
18+
path('workspace/<str:workspace_id>/knowledge/batch_delete', views.KnowledgeView.BatchDelete.as_view()),
19+
path('workspace/<str:workspace_id>/knowledge/batch_move', views.KnowledgeView.BatchMove.as_view()),
1820
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>', views.KnowledgeView.Operate.as_view()),
1921
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/sync', views.KnowledgeView.SyncWeb.as_view()),
2022
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow', views.KnowledgeWorkflowView.Operate.as_view()),

apps/knowledge/views/knowledge.py

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,29 @@
44
from rest_framework.views import APIView
55

66
from common.auth import TokenAuth
7-
from common.auth.authentication import has_permissions
7+
from common.auth.authentication import has_permissions, check_batch_permissions
88
from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
99
from common.log.log import log
10-
from common.result import result
10+
from common import result
1111
from knowledge.api.knowledge import KnowledgeBaseCreateAPI, KnowledgeWebCreateAPI, KnowledgeTreeReadAPI, \
1212
KnowledgeEditAPI, KnowledgeReadAPI, KnowledgePageAPI, SyncWebAPI, GenerateRelatedAPI, HitTestAPI, EmbeddingAPI, \
13-
GetModelAPI, KnowledgeExportAPI
13+
GetModelAPI, KnowledgeExportAPI, KnowledgeBatchOperateAPI
1414
from knowledge.models import KnowledgeScope
1515
from knowledge.serializers.common import get_knowledge_operation_object
16-
from knowledge.serializers.knowledge import KnowledgeSerializer
16+
from knowledge.serializers.knowledge import KnowledgeSerializer, KnowledgeBatchOperateSerializer
1717
from models_provider.serializers.model_serializer import ModelSerializer
1818
from tools.api.tool import GetInternalToolAPI
19-
19+
from django.db.models import QuerySet
20+
from knowledge.models import Knowledge
21+
22+
def get_knowledge_operation_object_batch(knowledge_id_list):
23+
knowledge_model_list = QuerySet(model=Knowledge).filter(id__in=knowledge_id_list)
24+
if knowledge_model_list is not None:
25+
return {
26+
"name": f'[{",".join([app.name for app in knowledge_model_list])}]',
27+
'knowledge_list': [{'name': app.name} for app in knowledge_model_list]
28+
}
29+
return {}
2030

2131
class KnowledgeView(APIView):
2232
authentication_classes = [TokenAuth]
@@ -124,6 +134,83 @@ def get(self, request: Request, workspace_id: str, knowledge_id: str):
124134
data={'user_id': request.user.id, 'workspace_id': workspace_id, 'knowledge_id': knowledge_id}
125135
).one())
126136

137+
class BatchDelete(APIView):
138+
authentication_classes = [TokenAuth]
139+
140+
@extend_schema(
141+
methods=['PUT'],
142+
description=_("Batch delete knowledge"),
143+
summary=_("Batch delete knowledge"),
144+
operation_id=_("Batch delete knowledge"),
145+
parameters=KnowledgeBatchOperateAPI.get_parameters(),
146+
request=KnowledgeBatchOperateAPI.get_request(),
147+
responses=result.DefaultResultSerializer,
148+
tags=[_('Knowledge Base')]
149+
)
150+
@has_permissions(PermissionConstants.KNOWLEDGE_BATCH_DELETE.get_workspace_permission(),
151+
RoleConstants.USER.get_workspace_role(),
152+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
153+
)
154+
def put(self, request: Request, workspace_id: str):
155+
id_list = request.data.get('id_list', [])
156+
permitted_ids = check_batch_permissions(
157+
request, id_list, 'knowledge_id',
158+
(PermissionConstants.KNOWLEDGE_DELETE.get_workspace_knowledge_permission(),
159+
PermissionConstants.KNOWLEDGE_DELETE.get_workspace_permission_workspace_manage_role(),
160+
ViewPermission([RoleConstants.USER.get_workspace_role()],
161+
[PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()],
162+
CompareConstants.AND),
163+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()), workspace_id=workspace_id
164+
)
165+
166+
@log(menu='Knowledge Base', operate='Batch delete knowledge',
167+
get_operation_object=lambda r, k: get_knowledge_operation_object_batch(permitted_ids))
168+
def inner(view, r, **kwargs):
169+
return KnowledgeBatchOperateSerializer(
170+
data={'workspace_id': workspace_id, 'user_id': request.user.id}
171+
).batch_delete({'id_list': permitted_ids})
172+
173+
return result.success(inner(self, request, workspace_id=workspace_id))
174+
175+
class BatchMove(APIView):
176+
authentication_classes = [TokenAuth]
177+
178+
@extend_schema(
179+
methods=['PUT'],
180+
description=_("Batch move knowledge"),
181+
summary=_("Batch move knowledge"),
182+
operation_id=_("Batch move knowledge"),
183+
parameters=KnowledgeBatchOperateAPI.get_parameters(),
184+
request=KnowledgeBatchOperateAPI.get_move_request(),
185+
responses=result.DefaultResultSerializer,
186+
tags=[_('Knowledge Base')]
187+
)
188+
@has_permissions(PermissionConstants.KNOWLEDGE_BATCH_MOVE.get_workspace_permission(),
189+
RoleConstants.USER.get_workspace_role(),
190+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()
191+
)
192+
def put(self, request: Request, workspace_id: str):
193+
id_list = request.data.get('id_list', [])
194+
permitted_ids = check_batch_permissions(
195+
request, id_list, 'knowledge_id',
196+
(PermissionConstants.KNOWLEDGE_EDIT.get_workspace_knowledge_permission(),
197+
PermissionConstants.KNOWLEDGE_EDIT.get_workspace_permission_workspace_manage_role(),
198+
ViewPermission([RoleConstants.USER.get_workspace_role()],
199+
[PermissionConstants.KNOWLEDGE.get_workspace_knowledge_permission()],
200+
CompareConstants.AND),
201+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role()),
202+
workspace_id=workspace_id
203+
)
204+
205+
@log(menu='Knowledge Base', operate='Batch move knowledge',
206+
get_operation_object=lambda r, k: get_knowledge_operation_object_batch(permitted_ids))
207+
def inner(view, r, **kwargs):
208+
return KnowledgeBatchOperateSerializer(
209+
data={'workspace_id': workspace_id, 'user_id': request.user.id}
210+
).batch_move({'id_list': permitted_ids, 'folder_id': request.data.get('folder_id')})
211+
212+
return result.success(inner(self, request, workspace_id=workspace_id))
213+
127214
class Page(APIView):
128215
authentication_classes = [TokenAuth]
129216

apps/locales/en_US/LC_MESSAGES/django.po

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9175,3 +9175,16 @@ msgstr "Batch delete applications"
91759175

91769176
msgid "Batch move applications"
91779177
msgstr "Batch move applications"
9178+
9179+
msgid "Batch delete knowledge"
9180+
msgstr "Batch delete knowledge"
9181+
9182+
msgid "Batch move knowledge"
9183+
msgstr "Batch move knowledge"
9184+
9185+
msgid "Batch delete tools"
9186+
msgstr "Batch delete tools"
9187+
9188+
msgid "Batch move tools"
9189+
msgstr "Batch move tools"
9190+

apps/locales/zh_CN/LC_MESSAGES/django.po

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9298,3 +9298,16 @@ msgstr "批量删除应用"
92989298

92999299
msgid "Batch move applications"
93009300
msgstr "批量移动应用"
9301+
9302+
msgid "Batch delete knowledge"
9303+
msgstr "批量删除知识库"
9304+
9305+
msgid "Batch move knowledge"
9306+
msgstr "批量移动知识库"
9307+
9308+
msgid "Batch delete tools"
9309+
msgstr "批量删除工具"
9310+
9311+
msgid "Batch move tools"
9312+
msgstr "批量移动工具"
9313+

apps/locales/zh_Hant/LC_MESSAGES/django.po

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9295,3 +9295,16 @@ msgstr "批量刪除應用"
92959295

92969296
msgid "Batch move applications"
92979297
msgstr "批量移動應用"
9298+
9299+
msgid "Batch delete knowledge"
9300+
msgstr "批量刪除知識庫"
9301+
9302+
msgid "Batch move knowledge"
9303+
msgstr "批量移動知識庫"
9304+
9305+
msgid "Batch delete tools"
9306+
msgstr "批量刪除工具"
9307+
9308+
msgid "Batch move tools"
9309+
msgstr "批量移動工具"
9310+

0 commit comments

Comments
 (0)