|
| 1 | +# coding=utf-8 |
| 2 | +""" |
| 3 | +@project: MaxKB |
| 4 | +@Author:MaxKB |
| 5 | +@file: portal.py |
| 6 | +@date:2026/8/14 |
| 7 | +@desc: 门户配置序列化器 |
| 8 | +""" |
| 9 | + |
| 10 | +from django.db.models import Exists, OuterRef |
| 11 | +from django.utils.translation import gettext_lazy as _ |
| 12 | +from rest_framework import serializers |
| 13 | + |
| 14 | +from application.models import Application, Chat |
| 15 | +from application.models.application_access_token import ApplicationAccessToken |
| 16 | +from common.db.search import page_search |
| 17 | +from system_manage.models.chat_user import ( |
| 18 | + ChatUser, |
| 19 | + ResourceChatUserAuthorize, |
| 20 | + ResourceChatUserGroupAuthorize, |
| 21 | + ResourceType, |
| 22 | + UserGroupRelation, |
| 23 | +) |
| 24 | + |
| 25 | + |
| 26 | +class PortalApplicationAuthMixin: |
| 27 | + """门户应用授权过滤公共逻辑""" |
| 28 | + |
| 29 | + @staticmethod |
| 30 | + def get_authorized_application_queryset(user_id): |
| 31 | + public_apps = ApplicationAccessToken.objects.filter(application_id=OuterRef("id"), authentication=False) |
| 32 | + if not ChatUser.objects.filter(id=user_id).exists(): |
| 33 | + return Application.objects.filter(Exists(public_apps)) |
| 34 | + authed_token_exists = ApplicationAccessToken.objects.filter(application_id=OuterRef("id"), authentication=True) |
| 35 | + direct_auth = ResourceChatUserAuthorize.objects.filter( |
| 36 | + resource_id=OuterRef("id"), resource_type=ResourceType.APPLICATION.value, is_auth=True, user_id=user_id |
| 37 | + ) |
| 38 | + user_groups = UserGroupRelation.objects.filter(user_id=user_id).values_list("group_id", flat=True) |
| 39 | + group_auth = ResourceChatUserGroupAuthorize.objects.filter( |
| 40 | + resource_id=OuterRef("id"), |
| 41 | + resource_type=ResourceType.APPLICATION.value, |
| 42 | + is_auth=True, |
| 43 | + user_group_id__in=user_groups, |
| 44 | + ) |
| 45 | + return Application.objects.filter( |
| 46 | + Exists(public_apps) | (Exists(authed_token_exists) & (Exists(direct_auth) | Exists(group_auth))) |
| 47 | + ) |
| 48 | + |
| 49 | + |
| 50 | +class ApplicationResponseSerializer(serializers.Serializer): |
| 51 | + id = serializers.CharField(required=True) |
| 52 | + name = serializers.CharField(required=True) |
| 53 | + desc = serializers.CharField(required=True) |
| 54 | + icon = serializers.CharField(required=True) |
| 55 | + type = serializers.CharField(required=True) |
| 56 | + dialogue_number = serializers.IntegerField(required=True) |
| 57 | + prologue = serializers.CharField(required=True) |
| 58 | + is_publish = serializers.BooleanField(required=True) |
| 59 | + |
| 60 | + |
| 61 | +class PortalApplicationSerializer(serializers.Serializer): |
| 62 | + class Query(PortalApplicationAuthMixin, serializers.Serializer): |
| 63 | + name = serializers.CharField( |
| 64 | + required=False, allow_blank=True, label=_("Application Name"), help_text=_("Application name") |
| 65 | + ) |
| 66 | + |
| 67 | + def get_query_set(self): |
| 68 | + queryset = Application.objects.filter(is_publish=True) |
| 69 | + name = self.data.get("name") |
| 70 | + if name: |
| 71 | + queryset = queryset.filter(name__icontains=name) |
| 72 | + return queryset.order_by("-create_time") |
| 73 | + |
| 74 | + def page(self, current_page, page_size, user_id, with_valid=True): |
| 75 | + if with_valid: |
| 76 | + self.is_valid(raise_exception=True) |
| 77 | + queryset = self.get_query_set() |
| 78 | + queryset = queryset.filter(id__in=self.get_authorized_application_queryset(user_id).values("id")) |
| 79 | + return page_search( |
| 80 | + current_page, |
| 81 | + page_size, |
| 82 | + queryset, |
| 83 | + post_records_handler=lambda app: ApplicationResponseSerializer(app).data, |
| 84 | + ) |
| 85 | + |
| 86 | + |
| 87 | +class PortalHistoricalConversationResponseSerializer(serializers.Serializer): |
| 88 | + id = serializers.CharField(required=True) |
| 89 | + abstract = serializers.CharField(required=True) |
| 90 | + create_time = serializers.CharField(required=True) |
| 91 | + update_time = serializers.CharField(required=True) |
| 92 | + application = serializers.SerializerMethodField() |
| 93 | + |
| 94 | + def get_application(self, chat): |
| 95 | + return { |
| 96 | + "id": str(chat.application_id), |
| 97 | + "name": chat.application.name, |
| 98 | + "icon": chat.application.icon, |
| 99 | + } |
| 100 | + |
| 101 | + |
| 102 | +class PortalHistoricalConversationSerializer(serializers.Serializer): |
| 103 | + class Query(PortalApplicationAuthMixin, serializers.Serializer): |
| 104 | + name = serializers.CharField( |
| 105 | + required=False, allow_blank=True, label=_("Application Name"), help_text=_("Application name") |
| 106 | + ) |
| 107 | + |
| 108 | + def get_query_set(self, user_id): |
| 109 | + queryset = Chat.objects.filter( |
| 110 | + chat_user_id=user_id, |
| 111 | + is_deleted=False, |
| 112 | + application_id__in=self.get_authorized_application_queryset(user_id).values("id"), |
| 113 | + ) |
| 114 | + name = self.data.get("name") |
| 115 | + if name: |
| 116 | + queryset = queryset.filter(application__name__icontains=name) |
| 117 | + return queryset.select_related("application").order_by("-update_time", "id") |
| 118 | + |
| 119 | + def page(self, current_page, page_size, user_id, with_valid=True): |
| 120 | + if with_valid: |
| 121 | + self.is_valid(raise_exception=True) |
| 122 | + return page_search( |
| 123 | + current_page, |
| 124 | + page_size, |
| 125 | + self.get_query_set(user_id), |
| 126 | + post_records_handler=lambda chat: PortalHistoricalConversationResponseSerializer(chat).data, |
| 127 | + ) |
0 commit comments