feat: optimize chat list sorting

This commit is contained in:
ulleo
2026-07-30 16:52:46 +08:00
committed by ulleo
parent 2fefef0a37
commit e58d1822dc
5 changed files with 61 additions and 9 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ from apps.chat.curd.chat import delete_chat_with_user, get_chart_data_with_user,
format_json_data, format_json_list_data, get_chart_config, list_recent_questions, rename_chat_with_user, \
get_chat_log_history, get_chart_data_with_user_live
from apps.chat.models.chat_model import CreateChat, ChatRecord, RenameChat, ChatQuestion, AxisObj, QuickCommand, \
ChatInfo, Chat, ChatFinishStep, ChatQuestionBase, SimpleChat
ChatInfo, Chat, ChatFinishStep, ChatQuestionBase, SimpleChat, ChatItem
from apps.chat.task.llm import LLMService
from apps.swagger.i18n import PLACEHOLDER_PREFIX
from apps.system.schemas.permission import SqlbotPermission, require_permissions
@@ -29,7 +29,7 @@ from common.utils.data_format import DataFormat
router = APIRouter(tags=["Data Q&A"], prefix="/chat")
@router.get("/list", response_model=List[Chat], summary=f"{PLACEHOLDER_PREFIX}get_chat_list")
@router.get("/list", response_model=List[ChatItem], summary=f"{PLACEHOLDER_PREFIX}get_chat_list")
async def chats(session: SessionDep, current_user: CurrentUser):
return list_chats(session, current_user)
+30 -4
View File
@@ -9,7 +9,7 @@ from sqlalchemy import desc, func
from sqlalchemy.orm import aliased
from apps.chat.models.chat_model import Chat, ChatRecord, CreateChat, ChatInfo, RenameChat, ChatQuestion, ChatLog, \
TypeEnum, OperationEnum, ChatRecordResult, ChatLogHistory, ChatLogHistoryItem
TypeEnum, OperationEnum, ChatRecordResult, ChatLogHistory, ChatLogHistoryItem, ChatItem
from apps.datasource.crud.datasource import get_ds
from apps.datasource.crud.recommended_problem import get_datasource_recommended_chart
from apps.datasource.models.datasource import CoreDatasource
@@ -41,10 +41,31 @@ def get_chat(session: SessionDep, chat_id: int) -> Chat:
return chat
def list_chats(session: SessionDep, current_user: CurrentUser) -> List[Chat]:
def list_chats(session: SessionDep, current_user: CurrentUser) -> List[ChatItem]:
oid = current_user.oid if current_user.oid is not None else 1
chart_list = session.query(Chat).filter(and_(Chat.create_by == current_user.id, Chat.oid == oid)).order_by(
Chat.create_time.desc()).all()
# 子查询:获取每个chat对应的最新chat_record的create_time
latest_record_subq = (
session.query(
ChatRecord.chat_id,
func.max(ChatRecord.create_time).label('latest_record_time')
)
.group_by(ChatRecord.chat_id)
.subquery()
)
# 按最新chat_record的create_time排序,如果没有chat_record则使用chat自身的create_time
sort_time = func.coalesce(latest_record_subq.c.latest_record_time, Chat.create_time)
results = (
session.query(Chat, sort_time.label('latest_record_time'))
.outerjoin(latest_record_subq, Chat.id == latest_record_subq.c.chat_id)
.filter(and_(Chat.create_by == current_user.id, Chat.oid == oid))
.order_by(sort_time.desc())
.all()
)
chart_list = []
for chat, latest_record_time in results:
item = ChatItem(**chat.model_dump())
item.latest_record_time = latest_record_time
chart_list.append(item)
return chart_list
@@ -476,6 +497,11 @@ def get_chat_with_records(session: SessionDep, chart_id: int, current_user: Curr
chat_info.records = result
# 从已查出的records中取最新的create_time
record_times = [r.get('create_time') for r in result if r.get('create_time') is not None]
if record_times:
chat_info.latest_record_time = max(record_times)
return chat_info
+17
View File
@@ -179,6 +179,22 @@ class SimpleChat(BaseModel):
id: int = None
brief: str = ''
class ChatItem(BaseModel):
id: Optional[int] = None
oid: Optional[int] = None
create_time: Optional[datetime] = None
create_by: Optional[int] = None
brief: Optional[str] = None
chat_type: Optional[str] = "chat"
datasource: Optional[int] = None
engine_type: Optional[str] = None
origin: Optional[int] = 0
brief_generate: Optional[bool] = False
recommended_question_answer: Optional[str] = None
recommended_question: Optional[str] = None
recommended_generate: Optional[bool] = False
latest_record_time: Optional[datetime] = None
class ChatInfo(BaseModel):
id: Optional[int] = None
create_time: datetime = None
@@ -192,6 +208,7 @@ class ChatInfo(BaseModel):
datasource_exists: bool = True
recommended_question: Optional[str] = None
recommended_generate: Optional[bool] = False
latest_record_time: Optional[datetime] = None
records: List[ChatRecord | dict] = []
+9
View File
@@ -148,6 +148,7 @@ export class ChatRecord {
export class Chat {
id?: number
create_time?: Date | string
latest_record_time?: Date | string
create_by?: number
brief?: string
chat_type?: string
@@ -161,6 +162,7 @@ export class Chat {
constructor(
id: number,
create_time: Date | string,
latest_record_time: Date | string,
create_by: number,
brief: string,
chat_type: string,
@@ -170,6 +172,7 @@ export class Chat {
constructor(
id?: number,
create_time?: Date | string,
latest_record_time?: Date | string,
create_by?: number,
brief?: string,
chat_type?: string,
@@ -178,6 +181,7 @@ export class Chat {
) {
this.id = id
this.create_time = getDate(create_time)
this.latest_record_time = getDate(latest_record_time ?? create_time)
this.create_by = create_by
this.brief = brief
this.chat_type = chat_type
@@ -196,6 +200,7 @@ export class ChatInfo extends Chat {
constructor(
id: number,
create_time: Date | string,
latest_record_time: Date | string,
create_by: number,
brief: string,
chat_type: string,
@@ -211,6 +216,7 @@ export class ChatInfo extends Chat {
constructor(
param1?: number | Chat,
create_time?: Date | string,
latest_record_time?: Date | string,
create_by?: number,
brief?: string,
chat_type?: string,
@@ -228,6 +234,7 @@ export class ChatInfo extends Chat {
if (param1 instanceof Chat) {
this.id = param1.id
this.create_time = getDate(param1.create_time)
this.latest_record_time = getDate(param1.latest_record_time ?? param1.create_time)
this.create_by = param1.create_by
this.brief = param1.brief
this.chat_type = param1.chat_type
@@ -239,6 +246,7 @@ export class ChatInfo extends Chat {
} else {
this.id = param1
this.create_time = getDate(create_time)
this.latest_record_time = getDate(latest_record_time ?? create_time)
this.create_by = create_by
this.brief = brief
this.chat_type = chat_type
@@ -408,6 +416,7 @@ export const chatApi = {
return new ChatInfo(
data.id,
data.create_time,
data.latest_record_time,
data.create_by,
data.brief,
data.chat_type,
+3 -3
View File
@@ -3,7 +3,7 @@ import icon_more_outlined from '@/assets/svg/icon_more_outlined.svg'
import icon_expand_down_filled from '@/assets/embedded/icon_expand-down_filled.svg'
import rename from '@/assets/svg/icon_rename_outlined.svg'
import delIcon from '@/assets/svg/icon_delete.svg'
import { type Chat, chatApi } from '@/api/chat.ts'
import { type Chat, chatApi, ChatInfo } from '@/api/chat.ts'
import { computed, reactive, ref } from 'vue'
import dayjs from 'dayjs'
import { getDate } from '@/utils/utils.ts'
@@ -13,7 +13,7 @@ import { useI18n } from 'vue-i18n'
const props = withDefaults(
defineProps<{
currentChatId?: number
chatList: Array<Chat>
chatList: Array<ChatInfo>
loading?: boolean
}>(),
{
@@ -30,7 +30,7 @@ function groupByDate(chat: Chat) {
const todayEnd = dayjs(dayjs().format('YYYY-MM-DD') + ' 23:59:59').toDate()
const weekStart = dayjs(dayjs().subtract(7, 'day').format('YYYY-MM-DD') + ' 00:00:00').toDate()
const time = getDate(chat.create_time)
const time = getDate(chat.latest_record_time ?? chat.create_time)
if (time) {
if (time >= todayStart && time <= todayEnd) {