diff --git a/internal/feed/entity.go b/internal/feed/entity.go index 35ea613..43d0730 100644 --- a/internal/feed/entity.go +++ b/internal/feed/entity.go @@ -38,3 +38,13 @@ type ListLikesCountResponse struct { NextLikesCountBefore int64 `json:"next_likes_count_before"` HasMore bool `json:"has_more"` } + +type ListByFollowingRequest struct { + Limit int `json:"limit"` +} + +type ListByFollowingResponse struct { + VideoList []FeedVideoItem `json:"video_list"` + NextTime int64 `json:"next_time"` + HasMore bool `json:"has_more"` +} diff --git a/internal/feed/handler.go b/internal/feed/handler.go index 84b6a4d..b541aec 100644 --- a/internal/feed/handler.go +++ b/internal/feed/handler.go @@ -60,3 +60,24 @@ func (f *FeedHandler) ListLikesCount(c *gin.Context) { } c.JSON(200, feedItems) } + +func (f *FeedHandler) ListByFollowing(c *gin.Context) { + var req ListByFollowingRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(400, gin.H{"error": err.Error()}) + return + } + if req.Limit <= 0 || req.Limit > 50 { + req.Limit = 10 + } + viewerAccountID, err := middleware.GetAccountID(c) + if err != nil { + viewerAccountID = 0 + } + feedItems, err := f.service.ListByFollowing(c.Request.Context(), req.Limit, viewerAccountID) + if err != nil { + c.JSON(500, gin.H{"error": err.Error()}) + return + } + c.JSON(200, feedItems) +} diff --git a/internal/feed/repo.go b/internal/feed/repo.go index e5c636f..a57e939 100644 --- a/internal/feed/repo.go +++ b/internal/feed/repo.go @@ -2,6 +2,7 @@ package feed import ( "context" + "feedsystem_video_go/internal/social" "feedsystem_video_go/internal/video" "time" @@ -41,3 +42,20 @@ func (repo *FeedRepository) ListLikesCount(ctx context.Context, limit int, likes } return videos, nil } + +func (repo *FeedRepository) ListByFollowing(ctx context.Context, limit int, viewerAccountID uint) ([]video.Video, error) { + var videos []video.Video + query := repo.db.WithContext(ctx).Model(&video.Video{}). + Order("create_time DESC") + if viewerAccountID > 0 { + followingSubQuery := repo.db.WithContext(ctx). + Model(&social.Social{}). + Select("vlogger_id"). + Where("follower_id = ?", viewerAccountID) + query = query.Where("author_id IN (?)", followingSubQuery) + } + if err := query.Limit(limit).Find(&videos).Error; err != nil { + return nil, err + } + return videos, nil +} diff --git a/internal/feed/service.go b/internal/feed/service.go index 9831536..1a3adfe 100644 --- a/internal/feed/service.go +++ b/internal/feed/service.go @@ -99,3 +99,45 @@ func (f *FeedService) ListLikesCount(ctx context.Context, limit int, likesCountB } return resp, nil } + +func (f *FeedService) ListByFollowing(ctx context.Context, limit int, viewerAccountID uint) (ListByFollowingResponse, error) { + videos, err := f.repo.ListByFollowing(ctx, limit, viewerAccountID) + if err != nil { + return ListByFollowingResponse{}, err + } + var nextTime int64 + if len(videos) > 0 { + nextTime = videos[len(videos)-1].CreateTime.Unix() + } else { + nextTime = 0 + } + hasMore := len(videos) == limit + feedVideos := make([]FeedVideoItem, 0, len(videos)) + for _, video := range videos { + var isLiked bool + if viewerAccountID == 0 { + isLiked = false + } else { + isLiked, err = f.likeRepo.IsLiked(ctx, video.ID, viewerAccountID) + if err != nil { + return ListByFollowingResponse{}, err + } + } + feedVideos = append(feedVideos, FeedVideoItem{ + ID: video.ID, + Author: FeedAuthor{ID: video.AuthorID, Username: video.Username}, + Title: video.Title, + Description: video.Description, + PlayURL: video.PlayURL, + CoverURL: video.CoverURL, + LikesCount: video.LikesCount, + IsLiked: isLiked, + }) + } + resp := ListByFollowingResponse{ + VideoList: feedVideos, + NextTime: nextTime, + HasMore: hasMore, + } + return resp, nil +} diff --git a/internal/http/router.go b/internal/http/router.go index d4614a4..4ca8cc2 100644 --- a/internal/http/router.go +++ b/internal/http/router.go @@ -97,5 +97,10 @@ func SetRouter(db *gorm.DB) *gin.Engine { feedGroup.POST("/listLatest", feedHandler.ListLatest) feedGroup.POST("/listLikesCount", feedHandler.ListLikesCount) } + protectedFeedGroup := feedGroup.Group("") + protectedFeedGroup.Use(middleware.JWTAuth(accountRepository)) + { + protectedFeedGroup.POST("/listByFollowing", feedHandler.ListByFollowing) + } return r }