feat: application list (#3160)

This commit is contained in:
shaohuzhang1 2025-05-28 18:57:09 +08:00 committed by GitHub
parent 743b04aebf
commit 345e588ef6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 273 additions and 8 deletions

View File

@ -11,9 +11,10 @@ from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter
from rest_framework import serializers
from application.serializers.application import ApplicationCreateSerializer
from application.serializers.application import ApplicationCreateSerializer, ApplicationListResponse, \
ApplicationQueryRequest
from common.mixins.api_mixin import APIMixin
from common.result import ResultSerializer
from common.result import ResultSerializer, ResultPageSerializer
class ApplicationCreateRequest(ApplicationCreateSerializer.SimplateRequest):
@ -25,6 +26,80 @@ class ApplicationCreateResponse(ResultSerializer):
return ApplicationCreateSerializer.ApplicationResponse()
class ApplicationListResult(ResultSerializer):
def get_data(self):
return ApplicationListResponse(many=True)
class ApplicationPageResult(ResultPageSerializer):
def get_data(self):
return ApplicationListResponse(many=True)
class ApplicationQueryAPI(APIMixin):
@staticmethod
def get_parameters():
return [
OpenApiParameter(
name="workspace_id",
description="工作空间id",
type=OpenApiTypes.STR,
location='path',
required=True,
),
OpenApiParameter(
name="current_page",
description=_("Current page"),
type=OpenApiTypes.INT,
location='path',
required=True,
),
OpenApiParameter(
name="page_size",
description=_("Page size"),
type=OpenApiTypes.INT,
location='path',
required=True,
),
OpenApiParameter(
name="folder_id",
description=_("folder id"),
type=OpenApiTypes.STR,
location='query',
required=False,
),
OpenApiParameter(
name="name",
description=_("Application Name"),
type=OpenApiTypes.STR,
location='query',
required=False,
),
OpenApiParameter(
name="desc",
description=_("Application Description"),
type=OpenApiTypes.STR,
location='query',
required=False,
),
OpenApiParameter(
name="user_id",
description=_("User ID"),
type=OpenApiTypes.STR,
location='query',
required=False,
)
]
@staticmethod
def get_response():
return ApplicationListResult
@staticmethod
def get_page_response():
return ApplicationPageResult
class ApplicationCreateAPI(APIMixin):
@staticmethod
def get_parameters():

View File

@ -7,6 +7,7 @@
@desc:
"""
import hashlib
import os
import re
from typing import Dict
@ -17,10 +18,15 @@ from django.db.models import QuerySet
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from application.models.application import Application, ApplicationTypeChoices, ApplicationKnowledgeMapping
from application.models.application import Application, ApplicationTypeChoices, ApplicationKnowledgeMapping, \
ApplicationFolder
from application.models.application_access_token import ApplicationAccessToken
from common.database_model_manage.database_model_manage import DatabaseModelManage
from common.db.search import native_search, native_page_search
from common.exception.app_exception import AppApiException
from common.utils.common import get_file_content
from knowledge.models import Knowledge
from maxkb.conf import PROJECT_DIR
from models_provider.models import Model
@ -227,11 +233,85 @@ class ApplicationCreateSerializer(serializers.Serializer):
)
class ApplicationQueryRequest(serializers.Serializer):
folder_id = serializers.CharField(required=False, label=_("folder id"))
name = serializers.CharField(required=False, label=_('Application Name'))
desc = serializers.CharField(required=False, label=_("Application Description"))
user_id = serializers.UUIDField(required=False, label=_("User ID"))
class ApplicationListResponse(serializers.Serializer):
id = serializers.CharField(required=True, label=_("Primary key id"), help_text=_("Primary key id"))
name = serializers.CharField(required=True, label=_("Application Name"), help_text=_("Application Name"))
desc = serializers.CharField(required=True, label=_("Application Description"),
help_text=_("Application Description"))
is_publish = serializers.BooleanField(required=True, label=_("Model id"), help_text=_("Model id"))
type = serializers.CharField(required=True, label=_("Application type"), help_text=_("Application type"))
resource_type = serializers.CharField(required=True, label=_("Resource type"), help_text=_("Resource type"))
user_id = serializers.CharField(required=True, label=_('Affiliation user'), help_text=_("Affiliation user"))
create_time = serializers.CharField(required=True, label=_('Creation time'), help_text=_("Creation time"))
update_time = serializers.CharField(required=True, label=_('Modification time'), help_text=_("Modification time"))
class Query(serializers.Serializer):
workspace_id = serializers.CharField(required=False, label=_('workspace id'))
def get_query_set(self, instance: Dict):
folder_query_set = QuerySet(ApplicationFolder)
application_query_set = QuerySet(Application)
workspace_id = self.data.get('workspace_id')
user_id = instance.get('user_id')
desc = instance.get('desc')
name = instance.get('name')
if workspace_id is not None:
folder_query_set = folder_query_set.filter(workspace_id=workspace_id)
application_query_set = application_query_set.filter(workspace_id=workspace_id)
if user_id is not None:
folder_query_set = folder_query_set.filter(user_id=user_id)
application_query_set = application_query_set.filter(user_id=user_id)
folder_id = instance.get('folder_id')
if folder_id is not None:
folder_query_set = folder_query_set.filter(parent=folder_id)
application_query_set = application_query_set.filter(folder_id=folder_id)
if name is not None:
folder_query_set = folder_query_set.filter(name__contains=name)
application_query_set = application_query_set.filter(name__contains=name)
if desc is not None:
folder_query_set = folder_query_set.filter(desc__contains=desc)
application_query_set = application_query_set.filter(desc__contains=desc)
application_query_set = application_query_set.order_by("-update_time")
return {
'folder_query_set': folder_query_set,
'application_query_set': application_query_set
}
@staticmethod
def is_x_pack_ee():
workspace_user_role_mapping_model = DatabaseModelManage.get_model("workspace_user_role_mapping")
role_permission_mapping_model = DatabaseModelManage.get_model("role_permission_mapping_model")
return workspace_user_role_mapping_model is not None and role_permission_mapping_model is not None
def list(self, instance: Dict):
self.is_valid(raise_exception=True)
ApplicationQueryRequest(data=instance).is_valid(raise_exception=True)
return native_search(self.get_query_set(instance), select_string=get_file_content(
os.path.join(PROJECT_DIR, "apps", "application", 'sql',
'list_application_ee.sql' if self.is_x_pack_ee() else 'list_application.sql')))
def page(self, current_page: int, page_size: int, instance: Dict):
self.is_valid(raise_exception=True)
ApplicationQueryRequest(data=instance).is_valid(raise_exception=True)
return native_page_search(current_page, page_size, self.get_query_set(instance), get_file_content(
os.path.join(PROJECT_DIR, "apps", "application", 'sql',
'list_application_ee.sql' if self.is_x_pack_ee() else 'list_application.sql')),
)
class ApplicationSerializer(serializers.Serializer):
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
user_id = serializers.UUIDField(required=True, label=_("User ID"))
def insert(self, instance: Dict, with_valid=True):
def insert(self, instance: Dict):
application_type = instance.get('type')
if 'WORK_FLOW' == application_type:
return self.insert_workflow(instance)

View File

@ -0,0 +1,31 @@
select *
from (select "id"::text,
"name",
"desc",
"is_publish",
"type",
'application' as "resource_type",
"workspace_id",
"folder_id",
"user_id",
"create_time",
"update_time"
from application
where id in (select target
from workspace_user_resource_permission
where auth_target_type = 'APPLICATION'
and 'VIEW' = any (permission_list))
UNION
select "id",
"name",
"desc",
true as "is_publish",
'folder' as "type",
'folder' as "resource_type",
"workspace_id",
"parent_id" as "folder_id",
"user_id",
"create_time",
"update_time"
from application_folder ${folder_query_set}) temp
${application_query_set}

View File

@ -0,0 +1,39 @@
select *
from (select "id"::text,
"name",
"desc",
"is_publish",
"type",
'application' as "resource_type",
"workspace_id",
"folder_id",
"user_id",
"create_time",
"update_time"
from application
where id in (select target
from workspace_user_resource_permission
where auth_target_type = 'APPLICATION'
and case
when auth_type = 'ROLE' then
'APPLICATION_READ' in (select permission_id
from role_permission
where role_id in (select role_id
from user_role_relation))
else
'VIEW' = any (permission_list)
end)
UNION
select "id",
"name",
"desc",
true as "is_publish",
'folder' as "type",
'folder' as "resource_type",
"workspace_id",
"parent_id" as "folder_id",
"user_id",
"create_time",
"update_time"
from application_folder ${folder_query_set}) temp
${application_query_set}

View File

@ -6,5 +6,7 @@ app_name = 'application'
urlpatterns = [
path('workspace/<str:workspace_id>/application', views.Application.as_view(), name='application'),
path('workspace/<str:workspace_id>/application/<int:current_page>/<int:page_size>',
views.Application.Page.as_view(), name='application_page'),
path('workspace/<str:workspace_id>/application/<str:application_id>/application_key',
views.ApplicationKey.as_view())]

View File

@ -11,10 +11,12 @@ from drf_spectacular.utils import extend_schema
from rest_framework.request import Request
from rest_framework.views import APIView
from application.api.application_api import ApplicationCreateAPI
from application.serializers.application import ApplicationSerializer
from application.api.application_api import ApplicationCreateAPI, ApplicationQueryAPI
from application.serializers.application import ApplicationSerializer, Query
from common import result
from common.auth import TokenAuth
from common.auth.authentication import has_permissions
from common.constants.permission_constants import PermissionConstants
class Application(APIView):
@ -30,6 +32,38 @@ class Application(APIView):
responses=ApplicationCreateAPI.get_response(),
tags=[_('Application')] # type: ignore
)
@has_permissions(PermissionConstants.APPLICATION_READ.get_workspace_permission())
def post(self, request: Request, workspace_id: str):
return result.success(
ApplicationSerializer(data={'workspace_id': workspace_id, 'user_id': request.user.id}).insert(request.data))
@extend_schema(
methods=['GET'],
description=_('Get the application list'),
summary=_('Get the application list'),
operation_id=_('Get the application list'), # type: ignore
parameters=ApplicationQueryAPI.get_parameters(),
responses=ApplicationQueryAPI.get_response(),
tags=[_('Application')] # type: ignore
)
@has_permissions(PermissionConstants.APPLICATION_READ.get_workspace_permission())
def get(self, request: Request, workspace_id: str):
return result.success(Query(data={'workspace_id': workspace_id, 'user_id': request.user.id}).list(request.data))
class Page(APIView):
authentication_classes = [TokenAuth]
@extend_schema(
methods=['GET'],
description=_('Get the application list by page'),
summary=_('Get the application list by page'),
operation_id=_('Get the application list by page'), # type: ignore
parameters=ApplicationQueryAPI.get_parameters(),
responses=ApplicationQueryAPI.get_page_response(),
tags=[_('Application')] # type: ignore
)
@has_permissions(PermissionConstants.APPLICATION_READ.get_workspace_permission())
def get(self, request: Request, workspace_id: str, current_page: int, page_size: int):
return result.success(
Query(data={'workspace_id': workspace_id, 'user_id': request.user.id}).page(current_page, page_size,
request.query_params))

View File

@ -58,6 +58,7 @@ class SystemGroup(Enum):
SYSTEM_SETTING = "SYSTEM_SETTING"
OPERATION_LOG = "OPERATION_LOG"
OTHER = "OTHER"
APPLICATION = "APPLICATION"
class WorkspaceGroup(Enum):
@ -514,8 +515,11 @@ class PermissionConstants(Enum):
group=Group.LOGIN_AUTH, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN],
parent_group=[SystemGroup.SYSTEM_SETTING]
)
APPLICATION_READ = Permission(group=Group.APPLICATION, operate=Operate.READ,
role_list=[RoleConstants.ADMIN, RoleConstants.USER],
parent_group=[SystemGroup.APPLICATION],
resource_permission_group_list=[ResourcePermissionGroup.VIEW],
)
def get_workspace_application_permission(self):
return lambda r, kwargs: Permission(group=self.value.group, operate=self.value.operate,