Skip to content

Commit fd233ae

Browse files
committed
feat: optimize chat list sorting
1 parent 2fefef0 commit fd233ae

5 files changed

Lines changed: 61 additions & 9 deletions

File tree

backend/apps/chat/api/chat.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
format_json_data, format_json_list_data, get_chart_config, list_recent_questions, rename_chat_with_user, \
1717
get_chat_log_history, get_chart_data_with_user_live
1818
from apps.chat.models.chat_model import CreateChat, ChatRecord, RenameChat, ChatQuestion, AxisObj, QuickCommand, \
19-
ChatInfo, Chat, ChatFinishStep, ChatQuestionBase, SimpleChat
19+
ChatInfo, Chat, ChatFinishStep, ChatQuestionBase, SimpleChat, ChatItem
2020
from apps.chat.task.llm import LLMService
2121
from apps.swagger.i18n import PLACEHOLDER_PREFIX
2222
from apps.system.schemas.permission import SqlbotPermission, require_permissions
@@ -29,7 +29,7 @@
2929
router = APIRouter(tags=["Data Q&A"], prefix="/chat")
3030

3131

32-
@router.get("/list", response_model=List[Chat], summary=f"{PLACEHOLDER_PREFIX}get_chat_list")
32+
@router.get("/list", response_model=List[ChatItem], summary=f"{PLACEHOLDER_PREFIX}get_chat_list")
3333
async def chats(session: SessionDep, current_user: CurrentUser):
3434
return list_chats(session, current_user)
3535

backend/apps/chat/curd/chat.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from sqlalchemy.orm import aliased
1010

1111
from apps.chat.models.chat_model import Chat, ChatRecord, CreateChat, ChatInfo, RenameChat, ChatQuestion, ChatLog, \
12-
TypeEnum, OperationEnum, ChatRecordResult, ChatLogHistory, ChatLogHistoryItem
12+
TypeEnum, OperationEnum, ChatRecordResult, ChatLogHistory, ChatLogHistoryItem, ChatItem
1313
from apps.datasource.crud.datasource import get_ds
1414
from apps.datasource.crud.recommended_problem import get_datasource_recommended_chart
1515
from apps.datasource.models.datasource import CoreDatasource
@@ -41,10 +41,31 @@ def get_chat(session: SessionDep, chat_id: int) -> Chat:
4141
return chat
4242

4343

44-
def list_chats(session: SessionDep, current_user: CurrentUser) -> List[Chat]:
44+
def list_chats(session: SessionDep, current_user: CurrentUser) -> List[ChatItem]:
4545
oid = current_user.oid if current_user.oid is not None else 1
46-
chart_list = session.query(Chat).filter(and_(Chat.create_by == current_user.id, Chat.oid == oid)).order_by(
47-
Chat.create_time.desc()).all()
46+
# 子查询:获取每个chat对应的最新chat_record的create_time
47+
latest_record_subq = (
48+
session.query(
49+
ChatRecord.chat_id,
50+
func.max(ChatRecord.create_time).label('latest_record_time')
51+
)
52+
.group_by(ChatRecord.chat_id)
53+
.subquery()
54+
)
55+
# 按最新chat_record的create_time排序,如果没有chat_record则使用chat自身的create_time
56+
sort_time = func.coalesce(latest_record_subq.c.latest_record_time, Chat.create_time)
57+
results = (
58+
session.query(Chat, sort_time.label('latest_record_time'))
59+
.outerjoin(latest_record_subq, Chat.id == latest_record_subq.c.chat_id)
60+
.filter(and_(Chat.create_by == current_user.id, Chat.oid == oid))
61+
.order_by(sort_time.desc())
62+
.all()
63+
)
64+
chart_list = []
65+
for chat, latest_record_time in results:
66+
item = ChatItem(**chat.model_dump())
67+
item.latest_record_time = latest_record_time
68+
chart_list.append(item)
4869
return chart_list
4970

5071

@@ -476,6 +497,11 @@ def get_chat_with_records(session: SessionDep, chart_id: int, current_user: Curr
476497

477498
chat_info.records = result
478499

500+
# 从已查出的records中取最新的create_time
501+
record_times = [r.get('create_time') for r in result if r.get('create_time') is not None]
502+
if record_times:
503+
chat_info.latest_record_time = max(record_times)
504+
479505
return chat_info
480506

481507

backend/apps/chat/models/chat_model.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,22 @@ class SimpleChat(BaseModel):
179179
id: int = None
180180
brief: str = ''
181181

182+
class ChatItem(BaseModel):
183+
id: Optional[int] = None
184+
oid: Optional[int] = None
185+
create_time: Optional[datetime] = None
186+
create_by: Optional[int] = None
187+
brief: Optional[str] = None
188+
chat_type: Optional[str] = "chat"
189+
datasource: Optional[int] = None
190+
engine_type: Optional[str] = None
191+
origin: Optional[int] = 0
192+
brief_generate: Optional[bool] = False
193+
recommended_question_answer: Optional[str] = None
194+
recommended_question: Optional[str] = None
195+
recommended_generate: Optional[bool] = False
196+
latest_record_time: Optional[datetime] = None
197+
182198
class ChatInfo(BaseModel):
183199
id: Optional[int] = None
184200
create_time: datetime = None
@@ -192,6 +208,7 @@ class ChatInfo(BaseModel):
192208
datasource_exists: bool = True
193209
recommended_question: Optional[str] = None
194210
recommended_generate: Optional[bool] = False
211+
latest_record_time: Optional[datetime] = None
195212
records: List[ChatRecord | dict] = []
196213

197214

frontend/src/api/chat.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ export class ChatRecord {
148148
export class Chat {
149149
id?: number
150150
create_time?: Date | string
151+
latest_record_time?: Date | string
151152
create_by?: number
152153
brief?: string
153154
chat_type?: string
@@ -161,6 +162,7 @@ export class Chat {
161162
constructor(
162163
id: number,
163164
create_time: Date | string,
165+
latest_record_time: Date | string,
164166
create_by: number,
165167
brief: string,
166168
chat_type: string,
@@ -170,6 +172,7 @@ export class Chat {
170172
constructor(
171173
id?: number,
172174
create_time?: Date | string,
175+
latest_record_time?: Date | string,
173176
create_by?: number,
174177
brief?: string,
175178
chat_type?: string,
@@ -178,6 +181,7 @@ export class Chat {
178181
) {
179182
this.id = id
180183
this.create_time = getDate(create_time)
184+
this.latest_record_time = getDate(latest_record_time ?? create_time)
181185
this.create_by = create_by
182186
this.brief = brief
183187
this.chat_type = chat_type
@@ -196,6 +200,7 @@ export class ChatInfo extends Chat {
196200
constructor(
197201
id: number,
198202
create_time: Date | string,
203+
latest_record_time: Date | string,
199204
create_by: number,
200205
brief: string,
201206
chat_type: string,
@@ -211,6 +216,7 @@ export class ChatInfo extends Chat {
211216
constructor(
212217
param1?: number | Chat,
213218
create_time?: Date | string,
219+
latest_record_time?: Date | string,
214220
create_by?: number,
215221
brief?: string,
216222
chat_type?: string,
@@ -228,6 +234,7 @@ export class ChatInfo extends Chat {
228234
if (param1 instanceof Chat) {
229235
this.id = param1.id
230236
this.create_time = getDate(param1.create_time)
237+
this.latest_record_time = getDate(param1.latest_record_time ?? param1.create_time)
231238
this.create_by = param1.create_by
232239
this.brief = param1.brief
233240
this.chat_type = param1.chat_type
@@ -239,6 +246,7 @@ export class ChatInfo extends Chat {
239246
} else {
240247
this.id = param1
241248
this.create_time = getDate(create_time)
249+
this.latest_record_time = getDate(latest_record_time ?? create_time)
242250
this.create_by = create_by
243251
this.brief = brief
244252
this.chat_type = chat_type
@@ -408,6 +416,7 @@ export const chatApi = {
408416
return new ChatInfo(
409417
data.id,
410418
data.create_time,
419+
data.latest_record_time,
411420
data.create_by,
412421
data.brief,
413422
data.chat_type,

frontend/src/views/chat/ChatList.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import icon_more_outlined from '@/assets/svg/icon_more_outlined.svg'
33
import icon_expand_down_filled from '@/assets/embedded/icon_expand-down_filled.svg'
44
import rename from '@/assets/svg/icon_rename_outlined.svg'
55
import delIcon from '@/assets/svg/icon_delete.svg'
6-
import { type Chat, chatApi } from '@/api/chat.ts'
6+
import { type Chat, chatApi, ChatInfo } from '@/api/chat.ts'
77
import { computed, reactive, ref } from 'vue'
88
import dayjs from 'dayjs'
99
import { getDate } from '@/utils/utils.ts'
@@ -13,7 +13,7 @@ import { useI18n } from 'vue-i18n'
1313
const props = withDefaults(
1414
defineProps<{
1515
currentChatId?: number
16-
chatList: Array<Chat>
16+
chatList: Array<ChatInfo>
1717
loading?: boolean
1818
}>(),
1919
{
@@ -30,7 +30,7 @@ function groupByDate(chat: Chat) {
3030
const todayEnd = dayjs(dayjs().format('YYYY-MM-DD') + ' 23:59:59').toDate()
3131
const weekStart = dayjs(dayjs().subtract(7, 'day').format('YYYY-MM-DD') + ' 00:00:00').toDate()
3232
33-
const time = getDate(chat.create_time)
33+
const time = getDate(chat.latest_record_time ?? chat.create_time)
3434
3535
if (time) {
3636
if (time >= todayStart && time <= todayEnd) {

0 commit comments

Comments
 (0)