diff --git a/internal/feed/repo.go b/internal/feed/repo.go new file mode 100644 index 0000000..c27b11b --- /dev/null +++ b/internal/feed/repo.go @@ -0,0 +1,30 @@ +package feed + +import ( + "context" + "feedsystem_video_go/internal/video" // 引入视频实体 + "time" + + "gorm.io/gorm" +) + +type FeedRepository struct { + db *gorm.DB +} + +func NewFeedRepository(db *gorm.DB) *FeedRepository { + return &FeedRepository{db: db} +} + +func (repo *FeedRepository) ListLatest(ctx context.Context, limit int, latestBefore time.Time) ([]video.Video, error) { + var videos []video.Video + query := repo.db.WithContext(ctx).Model(&video.Video{}). + Order("create_time DESC") + if !latestBefore.IsZero() { + query = query.Where("create_time < ?", latestBefore) + } + 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 new file mode 100644 index 0000000..28a2949 --- /dev/null +++ b/internal/feed/service.go @@ -0,0 +1,41 @@ +package feed + +import ( + "context" + "feedsystem_video_go/internal/video" + "time" +) + +type FeedService struct { + repo *FeedRepository +} + +type FeedResponse struct { + VideoList []video.Video `json:"video_list"` + NextTime time.Time `json:"next_time"` + HasMore bool `json:"has_more"` +} + +func NewFeedService(repo *FeedRepository) *FeedService { + return &FeedService{repo: repo} +} + +func (f *FeedService) ListLatest(ctx context.Context, limit int, latestBefore time.Time) (FeedResponse, error) { + videos, err := f.repo.ListLatest(ctx, limit, latestBefore) + if err != nil { + return FeedResponse{}, err + } + var nextTime time.Time + if len(videos) > 0 { + nextTime = videos[len(videos)-1].CreateTime + } else { + nextTime = time.Time{} + } + hasMore := len(videos) == limit + resp := FeedResponse{ + VideoList: videos, + NextTime: nextTime, + HasMore: hasMore, + } + return resp, nil +} diff --git a/internal/http/feed_handler.go b/internal/http/feed_handler.go new file mode 100644 index 0000000..ef6a56d --- /dev/null +++ b/internal/http/feed_handler.go @@ -0,0 +1,43 @@ +package http + +import ( + "feedsystem_video_go/internal/feed" + "time" + + "github.com/gin-gonic/gin" +) + +type ListLatestRequest struct { + Limit int `json:"limit"` + LatestTime int64 `json:"latest_time"` +} + +type FeedHandler struct { + service *feed.FeedService +} + +func NewFeedHandler(service *feed.FeedService) *FeedHandler { + return &FeedHandler{service: service} +} + +func (f *FeedHandler) ListLatest(c *gin.Context) { + var req ListLatestRequest + 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 + } + ctx := c.Request.Context() + var latestTime time.Time + if req.LatestTime > 0 { + latestTime = time.Unix(req.LatestTime, 0) + } + feeds, err := f.service.ListLatest(ctx, req.Limit, latestTime) + if err != nil { + c.JSON(500, gin.H{"error": err.Error()}) + return + } + c.JSON(200, feeds) +} diff --git a/internal/http/router.go b/internal/http/router.go index 7b58e9e..3dc9aab 100644 --- a/internal/http/router.go +++ b/internal/http/router.go @@ -2,6 +2,7 @@ package http import ( "feedsystem_video_go/internal/account" + "feedsystem_video_go/internal/feed" "feedsystem_video_go/internal/middleware" "feedsystem_video_go/internal/video" @@ -44,5 +45,13 @@ func SetRouter(db *gorm.DB) *gin.Engine { protectedVideoGroup.POST("/publish", videoHandler.PublishVideo) } + // feed + feedRepository := feed.NewFeedRepository(db) + feedService := feed.NewFeedService(feedRepository) + feedHandler := NewFeedHandler(feedService) + feedGroup := r.Group("/feed") + { + feedGroup.POST("/listLatest", feedHandler.ListLatest) + } return r }