feat(post): enhance post handling with channel integration

- Updated PostHandler to include channel information in post responses.
- Introduced PostChannelBrief DTO to represent channel details associated with posts.
- Modified post conversion functions to support channel data, ensuring proper mapping of channel IDs to channel names.
- Enhanced ChannelRepository and ChannelService to facilitate batch retrieval of channels by IDs.
- Updated wire generation to inject channel service into post handler for improved functionality.
This commit is contained in:
lafay
2026-03-25 00:58:41 +08:00
parent fc0d6ff19d
commit 7c14cf5bab
7 changed files with 137 additions and 40 deletions

View File

@@ -120,6 +120,12 @@ type AdminUpdateUserStatusRequest struct {
// ==================== Post DTOs ====================
// PostChannelBrief 帖子所属频道(列表/详情卡片展示)
type PostChannelBrief struct {
ID string `json:"id"`
Name string `json:"name"`
}
// PostImageResponse 帖子图片响应
type PostImageResponse struct {
ID string `json:"id"`
@@ -154,6 +160,7 @@ type PostResponse struct {
Author *UserResponse `json:"author"`
IsLiked bool `json:"is_liked"`
IsFavorited bool `json:"is_favorited"`
Channel *PostChannelBrief `json:"channel,omitempty"`
}
// PostDetailResponse 帖子详情响应
@@ -179,6 +186,7 @@ type PostDetailResponse struct {
Author *UserResponse `json:"author"`
IsLiked bool `json:"is_liked"`
IsFavorited bool `json:"is_favorited"`
Channel *PostChannelBrief `json:"channel,omitempty"`
}
// ==================== Comment DTOs ====================

View File

@@ -31,8 +31,42 @@ func ConvertPostImagesToResponse(images []model.PostImage) []PostImageResponse {
return result
}
// ConvertPostToResponse 将Post转换为PostResponse列表用
func ConvertPostToResponse(post *model.Post, isLiked, isFavorited bool) *PostResponse {
func postChannelBrief(post *model.Post, channelByID map[string]*model.Channel) *PostChannelBrief {
if post == nil || post.ChannelID == nil || *post.ChannelID == "" || channelByID == nil {
return nil
}
ch := channelByID[*post.ChannelID]
if ch == nil {
return nil
}
return &PostChannelBrief{ID: ch.ID, Name: ch.Name}
}
// CollectPostChannelIDs 从帖子列表收集去重后的频道 ID用于批量查库填充 channel 名称)
func CollectPostChannelIDs(posts []*model.Post) []string {
seen := make(map[string]struct{})
out := make([]string, 0)
for _, p := range posts {
if p == nil || p.ChannelID == nil || *p.ChannelID == "" {
continue
}
id := *p.ChannelID
if _, ok := seen[id]; ok {
continue
}
seen[id] = struct{}{}
out = append(out, id)
}
return out
}
// PostChannelBriefForPost 根据帖子与频道映射生成频道摘要(供 Handler 手动组装响应)
func PostChannelBriefForPost(post *model.Post, channelByID map[string]*model.Channel) *PostChannelBrief {
return postChannelBrief(post, channelByID)
}
// ConvertPostToResponse 将Post转换为PostResponse列表用channelByID 可为 nil
func ConvertPostToResponse(post *model.Post, channelByID map[string]*model.Channel, isLiked, isFavorited bool) *PostResponse {
if post == nil {
return nil
}
@@ -69,11 +103,12 @@ func ConvertPostToResponse(post *model.Post, isLiked, isFavorited bool) *PostRes
Author: author,
IsLiked: isLiked,
IsFavorited: isFavorited,
Channel: postChannelBrief(post, channelByID),
}
}
// ConvertPostToDetailResponse 将Post转换为PostDetailResponse
func ConvertPostToDetailResponse(post *model.Post, isLiked, isFavorited bool) *PostDetailResponse {
// ConvertPostToDetailResponse 将Post转换为PostDetailResponsechannelByID 可为 nil
func ConvertPostToDetailResponse(post *model.Post, channelByID map[string]*model.Channel, isLiked, isFavorited bool) *PostDetailResponse {
if post == nil {
return nil
}
@@ -110,11 +145,12 @@ func ConvertPostToDetailResponse(post *model.Post, isLiked, isFavorited bool) *P
Author: author,
IsLiked: isLiked,
IsFavorited: isFavorited,
Channel: postChannelBrief(post, channelByID),
}
}
// ConvertPostsToResponse 将Post列表转换为响应列表每个帖子独立检查点赞/收藏状态)
func ConvertPostsToResponse(posts []*model.Post, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
// ConvertPostsToResponse 将Post列表转换为响应列表每个帖子独立检查点赞/收藏状态)channelByID 可为 nil
func ConvertPostsToResponse(posts []*model.Post, channelByID map[string]*model.Channel, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
result := make([]*PostResponse, 0, len(posts))
for _, post := range posts {
isLiked := false
@@ -125,21 +161,21 @@ func ConvertPostsToResponse(posts []*model.Post, isLikedMap, isFavoritedMap map[
if isFavoritedMap != nil {
isFavorited = isFavoritedMap[post.ID]
}
result = append(result, ConvertPostToResponse(post, isLiked, isFavorited))
result = append(result, ConvertPostToResponse(post, channelByID, isLiked, isFavorited))
}
return result
}
// BuildPostResponse 构建单个帖子响应(包含交互状态)
// 这是一个语义化的辅助函数,便于 Handler 层调用
func BuildPostResponse(post *model.Post, isLiked, isFavorited bool) *PostResponse {
return ConvertPostToResponse(post, isLiked, isFavorited)
func BuildPostResponse(post *model.Post, channelByID map[string]*model.Channel, isLiked, isFavorited bool) *PostResponse {
return ConvertPostToResponse(post, channelByID, isLiked, isFavorited)
}
// BuildPostsWithInteractionResponse 批量构建帖子响应(包含交互状态)
// 这是一个语义化的辅助函数,便于 Handler 层调用
func BuildPostsWithInteractionResponse(posts []*model.Post, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
return ConvertPostsToResponse(posts, isLikedMap, isFavoritedMap)
func BuildPostsWithInteractionResponse(posts []*model.Post, channelByID map[string]*model.Channel, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
return ConvertPostsToResponse(posts, channelByID, isLikedMap, isFavoritedMap)
}
// ==================== Comment 转换 ====================