feat(api): add cursor-based pagination for posts, comments, messages, groups, and notifications
Implement cursor-based pagination across multiple API endpoints to improve performance and enable efficient infinite scrolling. This replaces traditional offset-based pagination for high-volume data retrieval. Changes: - Add cursor pagination DTOs for all entity types (Post, Comment, Message, Conversation, Group, Notification, GroupMember, GroupAnnouncement) - Implement cursor pagination methods in repositories with support for various sort orders (created_at, updated_at, join_time, seq) - Add cursor pagination handlers that maintain backward compatibility with existing offset pagination - Add new API routes for cursor-based endpoints (/cursor suffix) - Add helper converter functions for pointer slice types in DTO conversions
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"carrot_bbs/internal/dto"
|
||||
"carrot_bbs/internal/pkg/cursor"
|
||||
"carrot_bbs/internal/pkg/response"
|
||||
"carrot_bbs/internal/service"
|
||||
)
|
||||
@@ -251,3 +252,70 @@ func (h *CommentHandler) Unlike(c *gin.Context) {
|
||||
|
||||
response.SuccessWithMessage(c, "unliked", nil)
|
||||
}
|
||||
|
||||
// GetByPostIDByCursor 游标分页获取帖子评论
|
||||
func (h *CommentHandler) GetByPostIDByCursor(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
postID := c.Param("id")
|
||||
|
||||
// 解析游标分页请求
|
||||
req := h.parseCursorRequest(c)
|
||||
|
||||
// 调用游标分页服务
|
||||
result, err := h.commentService.GetCommentsByCursor(c.Request.Context(), postID, req)
|
||||
if err != nil {
|
||||
response.InternalServerError(c, "failed to get comments")
|
||||
return
|
||||
}
|
||||
|
||||
// 转换为响应结构,检查每个评论的点赞状态
|
||||
commentResponses := dto.ConvertCommentsToResponseWithUser(result.Items, userID, h.commentService)
|
||||
|
||||
// 构建游标分页响应
|
||||
cursorResp := &dto.CommentCursorPageResponse{
|
||||
Items: commentResponses,
|
||||
NextCursor: result.NextCursor,
|
||||
PrevCursor: result.PrevCursor,
|
||||
HasMore: result.HasMore,
|
||||
}
|
||||
|
||||
response.Success(c, cursorResp)
|
||||
}
|
||||
|
||||
// GetRepliesByRootIDByCursor 游标分页获取根评论的回复
|
||||
func (h *CommentHandler) GetRepliesByRootIDByCursor(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
rootID := c.Param("id")
|
||||
|
||||
// 解析游标分页请求
|
||||
req := h.parseCursorRequest(c)
|
||||
|
||||
// 调用游标分页服务
|
||||
result, err := h.commentService.GetRepliesByCursor(c.Request.Context(), rootID, req)
|
||||
if err != nil {
|
||||
response.InternalServerError(c, "failed to get replies")
|
||||
return
|
||||
}
|
||||
|
||||
// 转换为响应结构,检查每个回复的点赞状态
|
||||
replyResponses := dto.ConvertCommentsToResponseWithUser(result.Items, userID, h.commentService)
|
||||
|
||||
// 构建游标分页响应
|
||||
cursorResp := &dto.CommentCursorPageResponse{
|
||||
Items: replyResponses,
|
||||
NextCursor: result.NextCursor,
|
||||
PrevCursor: result.PrevCursor,
|
||||
HasMore: result.HasMore,
|
||||
}
|
||||
|
||||
response.Success(c, cursorResp)
|
||||
}
|
||||
|
||||
// parseCursorRequest 解析游标分页请求参数
|
||||
func (h *CommentHandler) parseCursorRequest(c *gin.Context) *cursor.PageRequest {
|
||||
cursorStr := c.Query("cursor")
|
||||
direction := cursor.Direction(c.DefaultQuery("direction", "forward"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
|
||||
|
||||
return cursor.NewPageRequest(cursorStr, direction, pageSize)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user