feat(posts): filter posts by blocked users
Add functionality to filter out posts from blocked users in post listing endpoints. Includes a new `IsBlockedBatch` method for efficient batch checking of blocked relationships and `is_blocked` field in API responses when viewing a blocked user's posts.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -31,6 +32,41 @@ func NewPostHandler(postService service.PostService, userService service.UserSer
|
||||
}
|
||||
}
|
||||
|
||||
// collectAuthorIDs 从帖子列表中收集去重的作者ID
|
||||
func collectAuthorIDs(posts []*model.Post) []string {
|
||||
seen := make(map[string]struct{})
|
||||
ids := make([]string, 0, len(posts))
|
||||
for _, p := range posts {
|
||||
if _, ok := seen[p.UserID]; !ok {
|
||||
seen[p.UserID] = struct{}{}
|
||||
ids = append(ids, p.UserID)
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// filterBlockedPosts 过滤掉被当前用户拉黑的作者发布的帖子
|
||||
func (h *PostHandler) filterBlockedPosts(ctx context.Context, posts []*model.Post, currentUserID string) []*model.Post {
|
||||
if currentUserID == "" || len(posts) == 0 {
|
||||
return posts
|
||||
}
|
||||
|
||||
authorIDs := collectAuthorIDs(posts)
|
||||
blockedMap, err := h.userService.IsBlockedBatch(ctx, currentUserID, authorIDs)
|
||||
if err != nil {
|
||||
return posts
|
||||
}
|
||||
|
||||
filtered := make([]*model.Post, 0, len(posts))
|
||||
for _, p := range posts {
|
||||
if blockedMap[p.UserID] {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, p)
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
// channelMapForPosts 批量解析帖子中的频道 ID,用于填充响应里的 channel 名称
|
||||
func (h *PostHandler) channelMapForPosts(posts []*model.Post) map[string]*model.Channel {
|
||||
ids := dto.CollectPostChannelIDs(posts)
|
||||
@@ -267,6 +303,8 @@ func (h *PostHandler) List(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
posts = h.filterBlockedPosts(c.Request.Context(), posts, currentUserID)
|
||||
|
||||
// 批量获取交互状态
|
||||
postIDs := make([]string, len(posts))
|
||||
for i, post := range posts {
|
||||
@@ -324,6 +362,8 @@ func (h *PostHandler) ListByCursor(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
result.Items = h.filterBlockedPosts(c.Request.Context(), result.Items, currentUserID)
|
||||
|
||||
// 批量获取交互状态
|
||||
postIDs := make([]string, len(result.Items))
|
||||
for i, post := range result.Items {
|
||||
@@ -577,6 +617,32 @@ func (h *PostHandler) GetUserPosts(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否拉黑了对方
|
||||
if currentUserID != "" && currentUserID != userID {
|
||||
isBlocked, _ := h.userService.IsBlocked(c.Request.Context(), currentUserID, userID)
|
||||
if isBlocked {
|
||||
// 检查是否使用游标分页
|
||||
cursorStr := c.Query("cursor")
|
||||
if cursorStr != "" {
|
||||
response.Success(c, &dto.PostCursorPageResponse{
|
||||
Items: []*dto.PostResponse{},
|
||||
HasMore: false,
|
||||
IsBlocked: true,
|
||||
})
|
||||
} else {
|
||||
response.Success(c, gin.H{
|
||||
"list": []*dto.PostResponse{},
|
||||
"total": 0,
|
||||
"page": 1,
|
||||
"page_size": 20,
|
||||
"total_pages": 0,
|
||||
"is_blocked": true,
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否使用游标分页
|
||||
cursorStr := c.Query("cursor")
|
||||
if cursorStr != "" {
|
||||
@@ -709,6 +775,9 @@ func (h *PostHandler) Search(c *gin.Context) {
|
||||
|
||||
// 批量获取交互状态
|
||||
currentUserID := c.GetString("user_id")
|
||||
|
||||
posts = h.filterBlockedPosts(c.Request.Context(), posts, currentUserID)
|
||||
|
||||
postIDs := make([]string, len(posts))
|
||||
for i, post := range posts {
|
||||
postIDs[i] = post.ID
|
||||
@@ -736,6 +805,8 @@ func (h *PostHandler) SearchByCursor(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
result.Items = h.filterBlockedPosts(c.Request.Context(), result.Items, currentUserID)
|
||||
|
||||
// 批量获取交互状态
|
||||
postIDs := make([]string, len(result.Items))
|
||||
for i, post := range result.Items {
|
||||
|
||||
Reference in New Issue
Block a user