Skip to content

Commit cd68e89

Browse files
committed
feat: add knowledge workflow and version models, serializers, and API views
1 parent de93d5d commit cd68e89

File tree

6 files changed

+155
-1
lines changed

6 files changed

+155
-1
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# coding=utf-8
2+
3+
from common.mixins.api_mixin import APIMixin
4+
5+
6+
class KnowledgeWorkflowApi(APIMixin):
7+
pass
8+
9+
10+
class KnowledgeWorkflowVersionApi(APIMixin):
11+
pass

apps/knowledge/models/knowledge.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class KnowledgeType(models.IntegerChoices):
2323
WEB = 1, 'web站点类型'
2424
LARK = 2, '飞书类型'
2525
YUQUE = 3, '语雀类型'
26+
WORKFLOW = 4, '工作流类型'
2627

2728

2829
class TaskType(Enum):
@@ -135,6 +136,40 @@ class Meta:
135136
db_table = "knowledge"
136137

137138

139+
class KnowledgeWorkflow(AppModelMixin):
140+
"""
141+
知识库工作流表
142+
"""
143+
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
144+
knowledge = models.OneToOneField(Knowledge, on_delete=models.CASCADE, verbose_name="知识库",
145+
db_constraint=False, related_name='workflow')
146+
workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True)
147+
work_flow = models.JSONField(verbose_name="工作流数据", default=dict)
148+
is_publish = models.BooleanField(verbose_name="是否发布", default=False, db_index=True)
149+
publish_time = models.DateTimeField(verbose_name="发布时间", null=True, blank=True)
150+
151+
class Meta:
152+
db_table = "knowledge_workflow"
153+
154+
155+
class KnowledgeWorkflowVersion(AppModelMixin):
156+
"""
157+
知识库工作流版本表 - 记录工作流历史版本
158+
"""
159+
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
160+
knowledge = models.ForeignKey(Knowledge, on_delete=models.CASCADE, verbose_name="知识库", db_constraint=False)
161+
workflow = models.ForeignKey(KnowledgeWorkflow, on_delete=models.CASCADE, verbose_name="工作流",
162+
db_constraint=False, related_name='versions')
163+
workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True)
164+
work_flow = models.JSONField(verbose_name="工作流数据", default=dict)
165+
publish_user_id = models.UUIDField(verbose_name="发布者id", max_length=128, default=None, null=True)
166+
publish_user_name = models.CharField(verbose_name="发布者名称", max_length=128, default="")
167+
168+
class Meta:
169+
db_table = "knowledge_workflow_version"
170+
unique_together = [['knowledge', 'version']] # 同一知识库的版本号唯一
171+
172+
138173
def get_default_status():
139174
return Status('').__str__()
140175

@@ -162,6 +197,7 @@ class Document(AppModelMixin):
162197
class Meta:
163198
db_table = "document"
164199

200+
165201
class Tag(AppModelMixin):
166202
"""
167203
标签表 - 存储标签的key-value定义
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# coding=utf-8
2+
3+
from typing import Dict
4+
5+
import uuid_utils.compat as uuid
6+
from django.db import transaction
7+
from django.db.models import QuerySet
8+
from django.utils.translation import gettext_lazy as _
9+
from rest_framework import serializers
10+
11+
from common.exception.app_exception import AppApiException
12+
from knowledge.models import KnowledgeScope, Knowledge, KnowledgeType, KnowledgeWorkflow
13+
from knowledge.serializers.knowledge import KnowledgeModelSerializer
14+
from system_manage.models import AuthTargetType
15+
from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer
16+
17+
18+
class KnowledgeWorkflowSerializer(serializers.Serializer):
19+
class Create(serializers.Serializer):
20+
user_id = serializers.UUIDField(required=True, label=_('user id'))
21+
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
22+
scope = serializers.ChoiceField(
23+
required=False, label=_('scope'), default=KnowledgeScope.WORKSPACE, choices=KnowledgeScope.choices
24+
)
25+
26+
@transaction.atomic
27+
def save_workflow(self, instance: Dict):
28+
self.is_valid(raise_exception=True)
29+
30+
folder_id = instance.get('folder_id', self.data.get('workspace_id'))
31+
if QuerySet(Knowledge).filter(
32+
workspace_id=self.data.get('workspace_id'), folder_id=folder_id, name=instance.get('name')
33+
).exists():
34+
raise AppApiException(500, _('Knowledge base name duplicate!'))
35+
36+
knowledge_id = uuid.uuid7()
37+
knowledge = Knowledge(
38+
id=knowledge_id,
39+
name=instance.get('name'),
40+
desc=instance.get('desc'),
41+
user_id=self.data.get('user_id'),
42+
type=instance.get('type', KnowledgeType.WORKFLOW),
43+
scope=self.data.get('scope', KnowledgeScope.WORKSPACE),
44+
folder_id=folder_id,
45+
workspace_id=self.data.get('workspace_id'),
46+
embedding_model_id=instance.get('embedding_model_id'),
47+
meta={},
48+
)
49+
knowledge.save()
50+
# 自动资源给授权当前用户
51+
UserResourcePermissionSerializer(data={
52+
'workspace_id': self.data.get('workspace_id'),
53+
'user_id': self.data.get('user_id'),
54+
'auth_target_type': AuthTargetType.KNOWLEDGE.value
55+
}).auth_resource(str(knowledge_id))
56+
57+
knowledge_workflow = KnowledgeWorkflow(
58+
id=uuid.uuid7(),
59+
knowledge_id=knowledge_id,
60+
workspace_id=self.data.get('workspace_id'),
61+
work_flow=instance.get('work_flow', {}),
62+
63+
)
64+
65+
knowledge_workflow.save()
66+
67+
return {**KnowledgeModelSerializer(knowledge).data, 'document_list': []}

apps/knowledge/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,5 +67,5 @@
6767
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/problem/<int:current_page>/<int:page_size>', views.ProblemView.Page.as_view()),
6868
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/document/<int:current_page>/<int:page_size>', views.DocumentView.Page.as_view()),
6969
path('workspace/<str:workspace_id>/knowledge/<int:current_page>/<int:page_size>', views.KnowledgeView.Page.as_view()),
70-
70+
path('workspace/<str:workspace_id>/knowledge/<str:knowledge_id>/workflow', views.KnowledgeWorkflowView.as_view()),
7171
]

apps/knowledge/views/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
from .paragraph import *
44
from .problem import *
55
from .tag import *
6+
from .knowledge_workflow import *
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# coding=utf-8
2+
3+
from django.utils.translation import gettext_lazy as _
4+
from drf_spectacular.utils import extend_schema
5+
from rest_framework.request import Request
6+
from rest_framework.views import APIView
7+
8+
from common.auth import TokenAuth
9+
from common.auth.authentication import has_permissions
10+
from common.constants.permission_constants import PermissionConstants, RoleConstants
11+
from common.result import result
12+
from knowledge.api.knowledge_workflow import KnowledgeWorkflowApi
13+
from knowledge.serializers.knowledge_workflow import KnowledgeWorkflowSerializer
14+
15+
16+
class KnowledgeWorkflowView(APIView):
17+
authentication_classes = [TokenAuth]
18+
19+
@extend_schema(
20+
methods=['GET'],
21+
description=_('Create knowledge workflow'),
22+
summary=_('Create knowledge workflow'),
23+
operation_id=_('Create knowledge workflow'), # type: ignore
24+
parameters=KnowledgeWorkflowApi.get_parameters(),
25+
responses=KnowledgeWorkflowApi.get_response(),
26+
tags=[_('Knowledge Base')] # type: ignore
27+
)
28+
@has_permissions(
29+
PermissionConstants.KNOWLEDGE_CREATE.get_workspace_permission(),
30+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(), RoleConstants.USER.get_workspace_role()
31+
)
32+
def post(self, request: Request, workspace_id: str):
33+
return result.success(KnowledgeWorkflowSerializer.Create(
34+
data={'user_id': request.user.id, 'workspace_id': workspace_id}
35+
).save_workflow(request.data))
36+
37+
38+
class KnowledgeWorkflowVersionView(APIView):
39+
pass

0 commit comments

Comments
 (0)