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:
@@ -61,7 +61,9 @@ func InitializeApp() (*App, error) {
|
|||||||
dataChangeLogService := wire.ProvideDataChangeLogService(asyncLogManager, dataChangeLogRepository)
|
dataChangeLogService := wire.ProvideDataChangeLogService(asyncLogManager, dataChangeLogRepository)
|
||||||
logService := wire.ProvideLogService(operationLogService, loginLogService, dataChangeLogService)
|
logService := wire.ProvideLogService(operationLogService, loginLogService, dataChangeLogService)
|
||||||
userHandler := wire.ProvideUserHandler(userService, userActivityService, postService, commentService, logService)
|
userHandler := wire.ProvideUserHandler(userService, userActivityService, postService, commentService, logService)
|
||||||
postHandler := wire.ProvidePostHandler(postService, userService, logService)
|
channelRepository := repository.NewChannelRepository(db)
|
||||||
|
channelService := wire.ProvideChannelService(channelRepository)
|
||||||
|
postHandler := wire.ProvidePostHandler(postService, userService, channelService, logService)
|
||||||
commentHandler := handler.NewCommentHandler(commentService)
|
commentHandler := handler.NewCommentHandler(commentService)
|
||||||
chatService := wire.ProvideChatService(db, messageRepository, userRepository, hub, cache)
|
chatService := wire.ProvideChatService(db, messageRepository, userRepository, hub, cache)
|
||||||
messageService := wire.ProvideMessageService(db, messageRepository, cache)
|
messageService := wire.ProvideMessageService(db, messageRepository, cache)
|
||||||
@@ -87,8 +89,6 @@ func InitializeApp() (*App, error) {
|
|||||||
voteRepository := repository.NewVoteRepository(db)
|
voteRepository := repository.NewVoteRepository(db)
|
||||||
voteService := wire.ProvideVoteService(voteRepository, postRepository, cache, postAIService, systemMessageService)
|
voteService := wire.ProvideVoteService(voteRepository, postRepository, cache, postAIService, systemMessageService)
|
||||||
voteHandler := handler.NewVoteHandler(voteService, postService)
|
voteHandler := handler.NewVoteHandler(voteService, postService)
|
||||||
channelRepository := repository.NewChannelRepository(db)
|
|
||||||
channelService := wire.ProvideChannelService(channelRepository)
|
|
||||||
channelHandler := handler.NewChannelHandler(channelService)
|
channelHandler := handler.NewChannelHandler(channelService)
|
||||||
scheduleRepository := repository.NewScheduleRepository(db)
|
scheduleRepository := repository.NewScheduleRepository(db)
|
||||||
scheduleService := wire.ProvideScheduleService(scheduleRepository)
|
scheduleService := wire.ProvideScheduleService(scheduleRepository)
|
||||||
|
|||||||
@@ -120,6 +120,12 @@ type AdminUpdateUserStatusRequest struct {
|
|||||||
|
|
||||||
// ==================== Post DTOs ====================
|
// ==================== Post DTOs ====================
|
||||||
|
|
||||||
|
// PostChannelBrief 帖子所属频道(列表/详情卡片展示)
|
||||||
|
type PostChannelBrief struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
// PostImageResponse 帖子图片响应
|
// PostImageResponse 帖子图片响应
|
||||||
type PostImageResponse struct {
|
type PostImageResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
@@ -154,6 +160,7 @@ type PostResponse struct {
|
|||||||
Author *UserResponse `json:"author"`
|
Author *UserResponse `json:"author"`
|
||||||
IsLiked bool `json:"is_liked"`
|
IsLiked bool `json:"is_liked"`
|
||||||
IsFavorited bool `json:"is_favorited"`
|
IsFavorited bool `json:"is_favorited"`
|
||||||
|
Channel *PostChannelBrief `json:"channel,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostDetailResponse 帖子详情响应
|
// PostDetailResponse 帖子详情响应
|
||||||
@@ -179,6 +186,7 @@ type PostDetailResponse struct {
|
|||||||
Author *UserResponse `json:"author"`
|
Author *UserResponse `json:"author"`
|
||||||
IsLiked bool `json:"is_liked"`
|
IsLiked bool `json:"is_liked"`
|
||||||
IsFavorited bool `json:"is_favorited"`
|
IsFavorited bool `json:"is_favorited"`
|
||||||
|
Channel *PostChannelBrief `json:"channel,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Comment DTOs ====================
|
// ==================== Comment DTOs ====================
|
||||||
|
|||||||
@@ -31,8 +31,42 @@ func ConvertPostImagesToResponse(images []model.PostImage) []PostImageResponse {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertPostToResponse 将Post转换为PostResponse(列表用)
|
func postChannelBrief(post *model.Post, channelByID map[string]*model.Channel) *PostChannelBrief {
|
||||||
func ConvertPostToResponse(post *model.Post, isLiked, isFavorited bool) *PostResponse {
|
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 {
|
if post == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -69,11 +103,12 @@ func ConvertPostToResponse(post *model.Post, isLiked, isFavorited bool) *PostRes
|
|||||||
Author: author,
|
Author: author,
|
||||||
IsLiked: isLiked,
|
IsLiked: isLiked,
|
||||||
IsFavorited: isFavorited,
|
IsFavorited: isFavorited,
|
||||||
|
Channel: postChannelBrief(post, channelByID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertPostToDetailResponse 将Post转换为PostDetailResponse
|
// ConvertPostToDetailResponse 将Post转换为PostDetailResponse;channelByID 可为 nil
|
||||||
func ConvertPostToDetailResponse(post *model.Post, isLiked, isFavorited bool) *PostDetailResponse {
|
func ConvertPostToDetailResponse(post *model.Post, channelByID map[string]*model.Channel, isLiked, isFavorited bool) *PostDetailResponse {
|
||||||
if post == nil {
|
if post == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -110,11 +145,12 @@ func ConvertPostToDetailResponse(post *model.Post, isLiked, isFavorited bool) *P
|
|||||||
Author: author,
|
Author: author,
|
||||||
IsLiked: isLiked,
|
IsLiked: isLiked,
|
||||||
IsFavorited: isFavorited,
|
IsFavorited: isFavorited,
|
||||||
|
Channel: postChannelBrief(post, channelByID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertPostsToResponse 将Post列表转换为响应列表(每个帖子独立检查点赞/收藏状态)
|
// ConvertPostsToResponse 将Post列表转换为响应列表(每个帖子独立检查点赞/收藏状态);channelByID 可为 nil
|
||||||
func ConvertPostsToResponse(posts []*model.Post, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
|
func ConvertPostsToResponse(posts []*model.Post, channelByID map[string]*model.Channel, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
|
||||||
result := make([]*PostResponse, 0, len(posts))
|
result := make([]*PostResponse, 0, len(posts))
|
||||||
for _, post := range posts {
|
for _, post := range posts {
|
||||||
isLiked := false
|
isLiked := false
|
||||||
@@ -125,21 +161,21 @@ func ConvertPostsToResponse(posts []*model.Post, isLikedMap, isFavoritedMap map[
|
|||||||
if isFavoritedMap != nil {
|
if isFavoritedMap != nil {
|
||||||
isFavorited = isFavoritedMap[post.ID]
|
isFavorited = isFavoritedMap[post.ID]
|
||||||
}
|
}
|
||||||
result = append(result, ConvertPostToResponse(post, isLiked, isFavorited))
|
result = append(result, ConvertPostToResponse(post, channelByID, isLiked, isFavorited))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildPostResponse 构建单个帖子响应(包含交互状态)
|
// BuildPostResponse 构建单个帖子响应(包含交互状态)
|
||||||
// 这是一个语义化的辅助函数,便于 Handler 层调用
|
// 这是一个语义化的辅助函数,便于 Handler 层调用
|
||||||
func BuildPostResponse(post *model.Post, isLiked, isFavorited bool) *PostResponse {
|
func BuildPostResponse(post *model.Post, channelByID map[string]*model.Channel, isLiked, isFavorited bool) *PostResponse {
|
||||||
return ConvertPostToResponse(post, isLiked, isFavorited)
|
return ConvertPostToResponse(post, channelByID, isLiked, isFavorited)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildPostsWithInteractionResponse 批量构建帖子响应(包含交互状态)
|
// BuildPostsWithInteractionResponse 批量构建帖子响应(包含交互状态)
|
||||||
// 这是一个语义化的辅助函数,便于 Handler 层调用
|
// 这是一个语义化的辅助函数,便于 Handler 层调用
|
||||||
func BuildPostsWithInteractionResponse(posts []*model.Post, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
|
func BuildPostsWithInteractionResponse(posts []*model.Post, channelByID map[string]*model.Channel, isLikedMap, isFavoritedMap map[string]bool) []*PostResponse {
|
||||||
return ConvertPostsToResponse(posts, isLikedMap, isFavoritedMap)
|
return ConvertPostsToResponse(posts, channelByID, isLikedMap, isFavoritedMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== Comment 转换 ====================
|
// ==================== Comment 转换 ====================
|
||||||
|
|||||||
@@ -17,18 +17,33 @@ import (
|
|||||||
|
|
||||||
// PostHandler 帖子处理器
|
// PostHandler 帖子处理器
|
||||||
type PostHandler struct {
|
type PostHandler struct {
|
||||||
postService service.PostService
|
postService service.PostService
|
||||||
userService service.UserService
|
userService service.UserService
|
||||||
|
channelService service.ChannelService
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPostHandler 创建帖子处理器
|
// NewPostHandler 创建帖子处理器
|
||||||
func NewPostHandler(postService service.PostService, userService service.UserService) *PostHandler {
|
func NewPostHandler(postService service.PostService, userService service.UserService, channelService service.ChannelService) *PostHandler {
|
||||||
return &PostHandler{
|
return &PostHandler{
|
||||||
postService: postService,
|
postService: postService,
|
||||||
userService: userService,
|
userService: userService,
|
||||||
|
channelService: channelService,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// channelMapForPosts 批量解析帖子中的频道 ID,用于填充响应里的 channel 名称
|
||||||
|
func (h *PostHandler) channelMapForPosts(posts []*model.Post) map[string]*model.Channel {
|
||||||
|
ids := dto.CollectPostChannelIDs(posts)
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m, err := h.channelService.MapByIDs(ids)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
// Create 创建帖子
|
// Create 创建帖子
|
||||||
func (h *PostHandler) Create(c *gin.Context) {
|
func (h *PostHandler) Create(c *gin.Context) {
|
||||||
userID := c.GetString("user_id")
|
userID := c.GetString("user_id")
|
||||||
@@ -61,7 +76,8 @@ func (h *PostHandler) Create(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Success(c, dto.ConvertPostToResponse(post, false, false))
|
chMap := h.channelMapForPosts([]*model.Post{post})
|
||||||
|
response.Success(c, dto.ConvertPostToResponse(post, chMap, false, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetByID 获取帖子(不增加浏览量)
|
// GetByID 获取帖子(不增加浏览量)
|
||||||
@@ -123,6 +139,9 @@ func (h *PostHandler) GetByID(c *gin.Context) {
|
|||||||
IsFavorited: isFavorited,
|
IsFavorited: isFavorited,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chMap := h.channelMapForPosts([]*model.Post{post})
|
||||||
|
responseData.Channel = dto.PostChannelBriefForPost(post, chMap)
|
||||||
|
|
||||||
response.Success(c, responseData)
|
response.Success(c, responseData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +270,8 @@ func (h *PostHandler) List(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
||||||
|
|
||||||
// 转换为响应结构
|
chMap := h.channelMapForPosts(posts)
|
||||||
postResponses := dto.BuildPostsWithInteractionResponse(posts, isLikedMap, isFavoritedMap)
|
postResponses := dto.BuildPostsWithInteractionResponse(posts, chMap, isLikedMap, isFavoritedMap)
|
||||||
|
|
||||||
response.Paginated(c, postResponses, total, page, pageSize)
|
response.Paginated(c, postResponses, total, page, pageSize)
|
||||||
}
|
}
|
||||||
@@ -308,8 +327,8 @@ func (h *PostHandler) ListByCursor(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
||||||
|
|
||||||
// 转换为响应结构
|
chMap := h.channelMapForPosts(result.Items)
|
||||||
postResponses := dto.BuildPostsWithInteractionResponse(result.Items, isLikedMap, isFavoritedMap)
|
postResponses := dto.BuildPostsWithInteractionResponse(result.Items, chMap, isLikedMap, isFavoritedMap)
|
||||||
|
|
||||||
// 构建游标分页响应
|
// 构建游标分页响应
|
||||||
cursorResp := &dto.PostCursorPageResponse{
|
cursorResp := &dto.PostCursorPageResponse{
|
||||||
@@ -378,7 +397,8 @@ func (h *PostHandler) Update(c *gin.Context) {
|
|||||||
currentUserID := c.GetString("user_id")
|
currentUserID := c.GetString("user_id")
|
||||||
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), post.ID, currentUserID)
|
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), post.ID, currentUserID)
|
||||||
|
|
||||||
response.Success(c, dto.BuildPostResponse(post, isLiked, isFavorited))
|
chMap := h.channelMapForPosts([]*model.Post{post})
|
||||||
|
response.Success(c, dto.BuildPostResponse(post, chMap, isLiked, isFavorited))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete 删除帖子
|
// Delete 删除帖子
|
||||||
@@ -437,7 +457,8 @@ func (h *PostHandler) Like(c *gin.Context) {
|
|||||||
// 获取交互状态
|
// 获取交互状态
|
||||||
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
||||||
|
|
||||||
response.Success(c, dto.BuildPostResponse(post, isLiked, isFavorited))
|
chMap := h.channelMapForPosts([]*model.Post{post})
|
||||||
|
response.Success(c, dto.BuildPostResponse(post, chMap, isLiked, isFavorited))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unlike 取消点赞
|
// Unlike 取消点赞
|
||||||
@@ -466,7 +487,8 @@ func (h *PostHandler) Unlike(c *gin.Context) {
|
|||||||
// 获取交互状态
|
// 获取交互状态
|
||||||
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
||||||
|
|
||||||
response.Success(c, dto.BuildPostResponse(post, isLiked, isFavorited))
|
chMap := h.channelMapForPosts([]*model.Post{post})
|
||||||
|
response.Success(c, dto.BuildPostResponse(post, chMap, isLiked, isFavorited))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Favorite 收藏帖子
|
// Favorite 收藏帖子
|
||||||
@@ -495,7 +517,8 @@ func (h *PostHandler) Favorite(c *gin.Context) {
|
|||||||
// 获取交互状态
|
// 获取交互状态
|
||||||
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
||||||
|
|
||||||
response.Success(c, dto.BuildPostResponse(post, isLiked, isFavorited))
|
chMap := h.channelMapForPosts([]*model.Post{post})
|
||||||
|
response.Success(c, dto.BuildPostResponse(post, chMap, isLiked, isFavorited))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unfavorite 取消收藏
|
// Unfavorite 取消收藏
|
||||||
@@ -524,7 +547,8 @@ func (h *PostHandler) Unfavorite(c *gin.Context) {
|
|||||||
// 获取交互状态
|
// 获取交互状态
|
||||||
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
isLiked, isFavorited := h.postService.GetPostInteractionStatusSingle(c.Request.Context(), id, userID)
|
||||||
|
|
||||||
response.Success(c, dto.BuildPostResponse(post, isLiked, isFavorited))
|
chMap := h.channelMapForPosts([]*model.Post{post})
|
||||||
|
response.Success(c, dto.BuildPostResponse(post, chMap, isLiked, isFavorited))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserPosts 获取用户帖子列表(支持游标分页和偏移分页)
|
// GetUserPosts 获取用户帖子列表(支持游标分页和偏移分页)
|
||||||
@@ -557,8 +581,8 @@ func (h *PostHandler) GetUserPosts(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
||||||
|
|
||||||
// 转换为响应结构
|
chMap := h.channelMapForPosts(posts)
|
||||||
postResponses := dto.BuildPostsWithInteractionResponse(posts, isLikedMap, isFavoritedMap)
|
postResponses := dto.BuildPostsWithInteractionResponse(posts, chMap, isLikedMap, isFavoritedMap)
|
||||||
|
|
||||||
response.Paginated(c, postResponses, total, page, pageSize)
|
response.Paginated(c, postResponses, total, page, pageSize)
|
||||||
}
|
}
|
||||||
@@ -588,8 +612,8 @@ func (h *PostHandler) GetUserPostsByCursor(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
||||||
|
|
||||||
// 转换为响应结构
|
chMap := h.channelMapForPosts(result.Items)
|
||||||
postResponses := dto.BuildPostsWithInteractionResponse(result.Items, isLikedMap, isFavoritedMap)
|
postResponses := dto.BuildPostsWithInteractionResponse(result.Items, chMap, isLikedMap, isFavoritedMap)
|
||||||
|
|
||||||
// 构建游标分页响应
|
// 构建游标分页响应
|
||||||
cursorResp := &dto.PostCursorPageResponse{
|
cursorResp := &dto.PostCursorPageResponse{
|
||||||
@@ -623,8 +647,8 @@ func (h *PostHandler) GetFavorites(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
||||||
|
|
||||||
// 转换为响应结构
|
chMap := h.channelMapForPosts(posts)
|
||||||
postResponses := dto.BuildPostsWithInteractionResponse(posts, isLikedMap, isFavoritedMap)
|
postResponses := dto.BuildPostsWithInteractionResponse(posts, chMap, isLikedMap, isFavoritedMap)
|
||||||
|
|
||||||
response.Paginated(c, postResponses, total, page, pageSize)
|
response.Paginated(c, postResponses, total, page, pageSize)
|
||||||
}
|
}
|
||||||
@@ -659,8 +683,8 @@ func (h *PostHandler) Search(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
||||||
|
|
||||||
// 转换为响应结构
|
chMap := h.channelMapForPosts(posts)
|
||||||
postResponses := dto.BuildPostsWithInteractionResponse(posts, isLikedMap, isFavoritedMap)
|
postResponses := dto.BuildPostsWithInteractionResponse(posts, chMap, isLikedMap, isFavoritedMap)
|
||||||
|
|
||||||
response.Paginated(c, postResponses, total, page, pageSize)
|
response.Paginated(c, postResponses, total, page, pageSize)
|
||||||
}
|
}
|
||||||
@@ -687,8 +711,8 @@ func (h *PostHandler) SearchByCursor(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
isLikedMap, isFavoritedMap, _ := h.postService.GetPostInteractionStatus(c.Request.Context(), postIDs, currentUserID)
|
||||||
|
|
||||||
// 转换为响应结构
|
chMap := h.channelMapForPosts(result.Items)
|
||||||
postResponses := dto.BuildPostsWithInteractionResponse(result.Items, isLikedMap, isFavoritedMap)
|
postResponses := dto.BuildPostsWithInteractionResponse(result.Items, chMap, isLikedMap, isFavoritedMap)
|
||||||
|
|
||||||
// 构建游标分页响应
|
// 构建游标分页响应
|
||||||
cursorResp := &dto.PostCursorPageResponse{
|
cursorResp := &dto.PostCursorPageResponse{
|
||||||
|
|||||||
@@ -48,6 +48,19 @@ func (r *ChannelRepository) GetByID(id string) (*model.Channel, error) {
|
|||||||
return &channel, nil
|
return &channel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListByIDs 按 ID 列表查询频道(用于帖子列表批量填充 channel 名称)
|
||||||
|
func (r *ChannelRepository) ListByIDs(ids []string) ([]*model.Channel, error) {
|
||||||
|
if len(ids) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
var list []*model.Channel
|
||||||
|
err := r.db.Where("id IN ?", ids).Find(&list).Error
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ChannelRepository) Delete(id string) error {
|
func (r *ChannelRepository) Delete(id string) error {
|
||||||
return r.db.Delete(&model.Channel{}, "id = ?", id).Error
|
return r.db.Delete(&model.Channel{}, "id = ?", id).Error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
type ChannelService interface {
|
type ChannelService interface {
|
||||||
ListActive() ([]*model.Channel, error)
|
ListActive() ([]*model.Channel, error)
|
||||||
ListAll() ([]*model.Channel, error)
|
ListAll() ([]*model.Channel, error)
|
||||||
|
MapByIDs(ids []string) (map[string]*model.Channel, error)
|
||||||
Create(name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error)
|
Create(name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error)
|
||||||
Update(id, name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error)
|
Update(id, name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error)
|
||||||
Delete(id string) error
|
Delete(id string) error
|
||||||
@@ -29,6 +30,20 @@ func (s *channelServiceImpl) ListAll() ([]*model.Channel, error) {
|
|||||||
return s.channelRepo.ListAll()
|
return s.channelRepo.ListAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *channelServiceImpl) MapByIDs(ids []string) (map[string]*model.Channel, error) {
|
||||||
|
list, err := s.channelRepo.ListByIDs(ids)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
m := make(map[string]*model.Channel, len(list))
|
||||||
|
for _, ch := range list {
|
||||||
|
if ch != nil {
|
||||||
|
m[ch.ID] = ch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *channelServiceImpl) Create(name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error) {
|
func (s *channelServiceImpl) Create(name, slug, description string, sortOrder int, isActive bool) (*model.Channel, error) {
|
||||||
channel := &model.Channel{
|
channel := &model.Channel{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|||||||
@@ -64,9 +64,10 @@ func ProvideUserHandler(
|
|||||||
func ProvidePostHandler(
|
func ProvidePostHandler(
|
||||||
postService service.PostService,
|
postService service.PostService,
|
||||||
userService service.UserService,
|
userService service.UserService,
|
||||||
|
channelService service.ChannelService,
|
||||||
logService *service.LogService,
|
logService *service.LogService,
|
||||||
) *handler.PostHandler {
|
) *handler.PostHandler {
|
||||||
h := handler.NewPostHandler(postService, userService)
|
h := handler.NewPostHandler(postService, userService, channelService)
|
||||||
if ps, ok := postService.(interface{ SetLogService(*service.LogService) }); ok {
|
if ps, ok := postService.(interface{ SetLogService(*service.LogService) }); ok {
|
||||||
ps.SetLogService(logService)
|
ps.SetLogService(logService)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user