fix: speed up chat detail pagination
This commit is contained in:
@@ -53,6 +53,7 @@ const previewKnowledgeId = ref<number | null>(null);
|
||||
const chatDetail = ref<ChatDetail | null>(null);
|
||||
const chatDetailOpen = ref(false);
|
||||
const chatDetailLoading = ref(false);
|
||||
const chatMessagesLoading = ref(false);
|
||||
const chatDetailSessionId = ref<number | null>(null);
|
||||
const selectedAiLog = ref<AiLogRecord | null>(null);
|
||||
const aiLogDetailOpen = ref(false);
|
||||
@@ -773,7 +774,21 @@ async function loadChatDetail(sessionId = chatDetailSessionId.value, page = chat
|
||||
}
|
||||
|
||||
async function changeChatDetailMessagePage(page: number, pageSize: number) {
|
||||
await loadChatDetail(chatDetailSessionId.value, page, pageSize);
|
||||
if (!chatDetailSessionId.value || !chatDetail.value) return;
|
||||
chatMessagesLoading.value = true;
|
||||
try {
|
||||
const result = await api.chatMessages(chatDetailSessionId.value, { page, pageSize });
|
||||
chatDetail.value = {
|
||||
...chatDetail.value,
|
||||
messages: result.items,
|
||||
messagesPage: result,
|
||||
};
|
||||
Object.assign(chatDetailMessagePager, { page: result.page, pageSize: result.pageSize, total: result.total });
|
||||
} catch (error) {
|
||||
ElMessage.error(error instanceof Error ? error.message : "聊天消息加载失败");
|
||||
} finally {
|
||||
chatMessagesLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function openAiLogDetail(row: AiLogRecord) {
|
||||
@@ -1244,7 +1259,7 @@ function formatRecordDateTime(value: string, boundary: "start" | "end") {
|
||||
</section>
|
||||
|
||||
<h3 class="detail-title">完整对话</h3>
|
||||
<section class="conversation-list">
|
||||
<section v-loading="chatMessagesLoading" class="conversation-list">
|
||||
<article
|
||||
v-for="message in chatDetail.messages"
|
||||
:key="message.id"
|
||||
|
||||
@@ -8,6 +8,7 @@ import type {
|
||||
AiLogRecord,
|
||||
ApiResponse,
|
||||
ChatDetail,
|
||||
ChatMessageRecord,
|
||||
ChatRecord,
|
||||
ChatRecordQuery,
|
||||
DashboardStats,
|
||||
@@ -203,6 +204,8 @@ export const api = {
|
||||
chats: (query: ChatRecordQuery = {}) => request<PageResult<ChatRecord>>(`/admin/chat/list${queryString(query)}`),
|
||||
chatDetail: (sessionId: number, query: { messagePage?: number; messagePageSize?: number } = {}) =>
|
||||
request<ChatDetail>(`/admin/chat/${sessionId}${queryString(query)}`),
|
||||
chatMessages: (sessionId: number, query: { page?: number; pageSize?: number } = {}) =>
|
||||
request<PageResult<ChatMessageRecord>>(`/admin/chat/${sessionId}/messages${queryString(query)}`),
|
||||
exportChats: (query: ChatRecordQuery = {}) => download(`/admin/chat/export${queryString(query)}`, "chat_records.csv"),
|
||||
aiLogs: (query: { sessionId?: number; userId?: number; status?: string; page?: number; pageSize?: number } = {}) =>
|
||||
request<PageResult<AiLogRecord>>(`/admin/ai-log/list${queryString(query)}`),
|
||||
|
||||
@@ -80,6 +80,28 @@ def export_chats(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/chat/{session_id}/messages")
|
||||
def chat_messages(
|
||||
session_id: int,
|
||||
page: int = Query(default=1, ge=1),
|
||||
pageSize: int = Query(default=20, ge=10, le=100),
|
||||
db: Session = Depends(get_db),
|
||||
current_admin: Admin = Depends(get_current_admin),
|
||||
) -> dict:
|
||||
exists_session = db.scalar(select(ChatSession.id).where(ChatSession.id == session_id))
|
||||
if exists_session is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="会话不存在")
|
||||
message_query = select(ChatMessage).where(ChatMessage.session_id == session_id)
|
||||
total = db.scalar(select(func.count()).select_from(message_query.subquery())) or 0
|
||||
messages = db.scalars(
|
||||
message_query
|
||||
.order_by(ChatMessage.created_at.asc(), ChatMessage.id.asc())
|
||||
.offset((page - 1) * pageSize)
|
||||
.limit(pageSize)
|
||||
).all()
|
||||
return api_success(page_result([_message_dict(item) for item in messages], total=total, page=page, page_size=pageSize))
|
||||
|
||||
|
||||
@router.get("/chat/{session_id}")
|
||||
def chat_detail(
|
||||
session_id: int,
|
||||
|
||||
@@ -3,7 +3,7 @@ from sqlalchemy.orm import Session
|
||||
from sqlalchemy.pool import StaticPool
|
||||
|
||||
from app.api.admin_agent_records import attention_list, retrieval_logs
|
||||
from app.api.admin_records import ai_logs, chat_detail
|
||||
from app.api.admin_records import ai_logs, chat_detail, chat_messages
|
||||
from app.api.admin_users import list_users
|
||||
from app.models import Base
|
||||
from app.models.chat import ChatMessage, ChatSession
|
||||
@@ -65,6 +65,27 @@ def test_chat_detail_messages_are_paginated():
|
||||
assert data["messages"][0]["content"] == "消息11"
|
||||
|
||||
|
||||
def test_chat_messages_endpoint_returns_only_message_page():
|
||||
with _database() as db:
|
||||
user = User(id=1, phone="13800000000", name="学员", daily_chat_limit=10)
|
||||
session = ChatSession(id=1, user_id=1, title="长会话", message_count=12)
|
||||
db.add_all([user, session])
|
||||
db.add_all([
|
||||
ChatMessage(id=index + 1, session_id=1, user_id=1, role="user", content=f"消息{index + 1}")
|
||||
for index in range(12)
|
||||
])
|
||||
db.add(AiRequestLog(session_id=1, status="success", prompt="p" * 5000, retrieved_chunks='[{"content":"large"}]'))
|
||||
db.commit()
|
||||
|
||||
response = chat_messages(1, page=2, pageSize=10, db=db, current_admin=object())
|
||||
|
||||
data = response["data"]
|
||||
assert data["total"] == 12
|
||||
assert len(data["items"]) == 2
|
||||
assert data["items"][0]["content"] == "消息11"
|
||||
assert "aiLogs" not in data
|
||||
|
||||
|
||||
def test_retrieval_and_attention_lists_are_paginated():
|
||||
with _database() as db:
|
||||
for index in range(21):
|
||||
|
||||
Reference in New Issue
Block a user