diff --git a/Fabric.Backend.Guild/src/messaging/messaging.controller.ts b/Fabric.Backend.Guild/src/messaging/messaging.controller.ts index 8e73a39..cb5bb1e 100644 --- a/Fabric.Backend.Guild/src/messaging/messaging.controller.ts +++ b/Fabric.Backend.Guild/src/messaging/messaging.controller.ts @@ -16,6 +16,8 @@ type Message = { }; const EDIT_WINDOW_MS = 15 * 60 * 1000; +const DEFAULT_PAGE_LIMIT = 50; +const MAX_PAGE_LIMIT = 200; @Controller('channels/:id/messages') export class MessagingController { @@ -85,12 +87,28 @@ export class MessagingController { @Param('id') channelId: string, @Query('seq_from') seqFrom?: string, @Query('seq_to') seqTo?: string, + @Query('limit') limit?: string, ) { const from = seqFrom ? Number(seqFrom) : 1; const to = seqTo ? Number(seqTo) : Number.MAX_SAFE_INTEGER; + const requestedLimit = limit ? Number(limit) : DEFAULT_PAGE_LIMIT; + const safeLimit = + Number.isFinite(requestedLimit) && requestedLimit > 0 + ? Math.min(requestedLimit, MAX_PAGE_LIMIT) + : DEFAULT_PAGE_LIMIT; const arr = this.messagesByChannel.get(channelId) ?? []; + const filtered = arr.filter((m) => m.seq >= from && m.seq <= to); + const items = filtered.slice(0, safeLimit); + return { - items: arr.filter((m) => m.seq >= from && m.seq <= to), + items, + page: { + seqFrom: from, + seqTo: to, + limit: safeLimit, + returned: items.length, + hasMore: filtered.length > items.length, + }, }; } } diff --git a/docs/TODO-backend-center-guild.md b/docs/TODO-backend-center-guild.md index 5f93b0b..44f3931 100644 --- a/docs/TODO-backend-center-guild.md +++ b/docs/TODO-backend-center-guild.md @@ -47,7 +47,7 @@ - [x] 发送消息(content/reply/mentions/attachments 元数据) - [x] 编辑消息(可编辑窗口策略先简化) - [x] 删除消息(软删 vs 硬删,先定策略) -- [ ] `GET messages` 分页(seq 区间 + limit) +- [x] `GET messages` 分页(seq 区间 + limit) - [ ] seq 分配改为 DB 原子方案(避免并发冲突) ### 2.3 一致性与回补