diff --git a/apps/chat/api/chat_api.py b/apps/chat/api/chat_api.py index 69b45da32..993d2b183 100644 --- a/apps/chat/api/chat_api.py +++ b/apps/chat/api/chat_api.py @@ -10,7 +10,9 @@ from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter from chat.serializers.chat import ChatMessageSerializers +from chat.serializers.chat_record import HistoryChatRecordModel from common.mixins.api_mixin import APIMixin +from common.result import ResultSerializer, ResultPageSerializer class ChatAPI(APIMixin): @@ -27,3 +29,33 @@ class ChatAPI(APIMixin): @staticmethod def get_request(): return ChatMessageSerializers + + +class ApplicationCreateResponse(ResultSerializer): + def get_data(self): + return HistoryChatRecordModel(many=True) + + +class PageApplicationCreateResponse(ResultPageSerializer): + def get_data(self): + return HistoryChatRecordModel(many=True) + + +class HistoricalConversationAPI(APIMixin): + @staticmethod + def get_parameters(): + return [] + + @staticmethod + def get_response(): + return ApplicationCreateResponse + + +class PageHistoricalConversationAPI(APIMixin): + @staticmethod + def get_parameters(): + return [] + + @staticmethod + def get_response(): + return PageApplicationCreateResponse diff --git a/apps/chat/serializers/chat_authentication.py b/apps/chat/serializers/chat_authentication.py index ec43b27c6..aae8d4eb6 100644 --- a/apps/chat/serializers/chat_authentication.py +++ b/apps/chat/serializers/chat_authentication.py @@ -33,7 +33,7 @@ class AnonymousAuthenticationSerializer(serializers.Serializer): try: # 校验token if token is not None: - token_details = signing.loads(token) + token_details = signing.loads(token[7:]) except Exception as e: pass if with_valid: diff --git a/apps/chat/serializers/chat_record.py b/apps/chat/serializers/chat_record.py index 8ff992d02..8436de4c5 100644 --- a/apps/chat/serializers/chat_record.py +++ b/apps/chat/serializers/chat_record.py @@ -13,7 +13,8 @@ from django.db.models import QuerySet from django.utils.translation import gettext_lazy as _, gettext from rest_framework import serializers -from application.models import VoteChoices, ChatRecord +from application.models import VoteChoices, ChatRecord, Chat +from common.db.search import page_search from common.exception.app_exception import AppApiException from common.utils.lock import try_lock, un_lock @@ -23,6 +24,16 @@ class VoteRequest(serializers.Serializer): label=_("Bidding Status")) +class HistoryChatRecordModel(serializers.ModelSerializer): + class Meta: + model = Chat + fields = ['id', + 'application_id', + 'abstract', + 'create_time', + 'update_time'] + + class VoteSerializer(serializers.Serializer): chat_id = serializers.UUIDField(required=True, label=_("Conversation ID")) @@ -63,3 +74,22 @@ class VoteSerializer(serializers.Serializer): finally: un_lock(self.data.get('chat_record_id')) return True + + +class ChatRecordSerializer(serializers.Serializer): + application_id = serializers.UUIDField(required=True, label=_('Application ID')) + chat_user_id = serializers.UUIDField(required=True, label=_('Chat User ID')) + + def get_queryset(self): + chat_user_id = self.data.get('chat_user_id') + application_id = self.data.get("application_id") + return QuerySet(Chat).filter(application_id=application_id, chat_user_id=chat_user_id, is_deleted=False) + + def list(self): + self.is_valid(raise_exception=True) + queryset = self.get_queryset() + return [HistoryChatRecordModel(r).data for r in queryset] + + def page(self, current_page, page_size): + self.is_valid(raise_exception=True) + return page_search(current_page, page_size, self.get_queryset(), lambda r: HistoryChatRecordModel(r).data) diff --git a/apps/chat/urls.py b/apps/chat/urls.py index 812a25b60..04d372ccf 100644 --- a/apps/chat/urls.py +++ b/apps/chat/urls.py @@ -13,4 +13,8 @@ urlpatterns = [ path('open', views.OpenView.as_view()), path('captcha', views.CaptchaView.as_view(), name='captcha'), path('vote/chat//chat_record/', views.VoteView.as_view(), name='vote'), + path('historical_conversation', views.HistoricalConversationView.as_view(), name='historical_conversation'), + path('historical_conversation//', + views.HistoricalConversationView.PageView.as_view(), + name='historical_conversation') ] diff --git a/apps/chat/views/chat_record.py b/apps/chat/views/chat_record.py index 9d1cabd02..43e74320f 100644 --- a/apps/chat/views/chat_record.py +++ b/apps/chat/views/chat_record.py @@ -6,13 +6,14 @@ @date:2025/6/23 10:42 @desc: """ +from django.utils.translation import gettext_lazy as _ from drf_spectacular.utils import extend_schema from rest_framework.request import Request from rest_framework.views import APIView -from django.utils.translation import gettext_lazy as _ +from chat.api.chat_api import HistoricalConversationAPI, PageHistoricalConversationAPI from chat.api.vote_api import VoteAPI -from chat.serializers.chat_record import VoteSerializer +from chat.serializers.chat_record import VoteSerializer, ChatRecordSerializer from common import result from common.auth import TokenAuth @@ -35,3 +36,42 @@ class VoteView(APIView): data={'chat_id': chat_id, 'chat_record_id': chat_record_id }).vote(request.data)) + + +class HistoricalConversationView(APIView): + authentication_classes = [TokenAuth] + + @extend_schema( + methods=['GET'], + description=_("Get historical conversation"), + summary=_("Get historical conversation"), + operation_id=_("Get historical conversation"), # type: ignore + parameters=HistoricalConversationAPI.get_parameters(), + responses=HistoricalConversationAPI.get_response(), + tags=[_('Chat')] # type: ignore + ) + def get(self, request: Request): + return result.success(ChatRecordSerializer( + data={ + 'application_id': request.auth.application_id, + 'chat_user_id': request.auth.chat_user_id, + }).list()) + + class PageView(APIView): + authentication_classes = [TokenAuth] + + @extend_schema( + methods=['GET'], + description=_("Get historical conversation by page"), + summary=_("Get historical conversation by page"), + operation_id=_("Get historical conversation by page"), # type: ignore + parameters=PageHistoricalConversationAPI.get_parameters(), + responses=PageHistoricalConversationAPI.get_response(), + tags=[_('Chat')] # type: ignore + ) + def get(self, request: Request, current_page: int, page_size: int): + return result.success(ChatRecordSerializer( + data={ + 'application_id': request.auth.application_id, + 'chat_user_id': request.auth.chat_user_id, + }).page(current_page, page_size)) diff --git a/ui/src/api/chat/chat.ts b/ui/src/api/chat/chat.ts index 4f1e630b5..9373be679 100644 --- a/ui/src/api/chat/chat.ts +++ b/ui/src/api/chat/chat.ts @@ -182,6 +182,13 @@ const vote: ( loading, ) } +const pageChat: ( + current_page: number, + page_size: number, + loading?: Ref, +) => Promise> = (current_page, page_size, loading) => { + return get(`/historical_conversation/${current_page}/${page_size}`, undefined, loading) +} export default { open, chat, @@ -200,4 +207,5 @@ export default { getAuthSetting, passwordAuthentication, vote, + pageChat, } diff --git a/ui/src/views/chat/pc/index.vue b/ui/src/views/chat/pc/index.vue index b60bcde86..22d615cfc 100644 --- a/ui/src/views/chat/pc/index.vue +++ b/ui/src/views/chat/pc/index.vue @@ -153,6 +153,7 @@ import { ref, onMounted, nextTick, computed } from 'vue' import { marked } from 'marked' import { saveAs } from 'file-saver' +import chatAPI from '@/api/chat/chat' import { isAppIcon } from '@/utils/common' import useStore from '@/stores' import useResize from '@/layout/hooks/useResize' @@ -278,7 +279,7 @@ function getChatLog(id: string, refresh?: boolean) { page_size: 20, } - chatLog.asyncGetChatLogClient(id, page, left_loading).then((res: any) => { + chatAPI.pageChat(page.current_page, page.page_size, left_loading).then((res: any) => { chatLogData.value = res.data.records if (refresh) { currentChatName.value = chatLogData.value?.[0]?.abstract