fix: Social GetAllFollowers/Vloggers + Like ListLikedVideos 加 Limit(200) 防海量数据

This commit is contained in:
Sisyphus
2026-04-25 17:45:33 +08:00
parent 48a7eea0f9
commit 1cadc95863
2 changed files with 195 additions and 192 deletions

View File

@@ -1,91 +1,93 @@
package social package social
import ( import (
"context" "context"
"feedsystem_video_go/internal/account" "feedsystem_video_go/internal/account"
"gorm.io/gorm" "gorm.io/gorm"
) )
type SocialRepository struct { type SocialRepository struct {
db *gorm.DB db *gorm.DB
} }
func NewSocialRepository(db *gorm.DB) *SocialRepository { func NewSocialRepository(db *gorm.DB) *SocialRepository {
return &SocialRepository{db: db} return &SocialRepository{db: db}
} }
func (r *SocialRepository) Follow(ctx context.Context, social *Social) error { func (r *SocialRepository) Follow(ctx context.Context, social *Social) error {
return r.db.WithContext(ctx).Create(social).Error return r.db.WithContext(ctx).Create(social).Error
} }
func (r *SocialRepository) Unfollow(ctx context.Context, social *Social) error { func (r *SocialRepository) Unfollow(ctx context.Context, social *Social) error {
return r.db.WithContext(ctx). return r.db.WithContext(ctx).
Where("follower_id = ? AND vlogger_id = ?", social.FollowerID, social.VloggerID). Where("follower_id = ? AND vlogger_id = ?", social.FollowerID, social.VloggerID).
Delete(&Social{}).Error Delete(&Social{}).Error
} }
func (r *SocialRepository) GetAllFollowers(ctx context.Context, VloggerID uint) ([]*account.Account, error) { func (r *SocialRepository) GetAllFollowers(ctx context.Context, VloggerID uint) ([]*account.Account, error) {
var relations []Social var relations []Social
if err := r.db.WithContext(ctx). if err := r.db.WithContext(ctx).
Model(&Social{}). Model(&Social{}).
Where("vlogger_id = ?", VloggerID). Where("vlogger_id = ?", VloggerID).
Find(&relations).Error; err != nil { Limit(200).
return nil, err Find(&relations).Error; err != nil {
} return nil, err
}
followerIDs := make([]uint, 0, len(relations))
for _, rel := range relations { followerIDs := make([]uint, 0, len(relations))
followerIDs = append(followerIDs, rel.FollowerID) for _, rel := range relations {
} followerIDs = append(followerIDs, rel.FollowerID)
if len(followerIDs) == 0 { }
return []*account.Account{}, nil if len(followerIDs) == 0 {
} return []*account.Account{}, nil
}
var followers []*account.Account
if err := r.db.WithContext(ctx). var followers []*account.Account
Model(&account.Account{}). if err := r.db.WithContext(ctx).
Where("id IN ?", followerIDs). Model(&account.Account{}).
Find(&followers).Error; err != nil { Where("id IN ?", followerIDs).
return nil, err Find(&followers).Error; err != nil {
} return nil, err
return followers, nil }
} return followers, nil
}
func (r *SocialRepository) GetAllVloggers(ctx context.Context, FollowerID uint) ([]*account.Account, error) {
var relations []Social func (r *SocialRepository) GetAllVloggers(ctx context.Context, FollowerID uint) ([]*account.Account, error) {
if err := r.db.WithContext(ctx). var relations []Social
Model(&Social{}). if err := r.db.WithContext(ctx).
Where("follower_id = ?", FollowerID). Model(&Social{}).
Find(&relations).Error; err != nil { Where("follower_id = ?", FollowerID).
return nil, err Limit(200).
} Find(&relations).Error; err != nil {
return nil, err
vloggerIDs := make([]uint, 0, len(relations)) }
for _, rel := range relations {
vloggerIDs = append(vloggerIDs, rel.VloggerID) vloggerIDs := make([]uint, 0, len(relations))
} for _, rel := range relations {
if len(vloggerIDs) == 0 { vloggerIDs = append(vloggerIDs, rel.VloggerID)
return []*account.Account{}, nil }
} if len(vloggerIDs) == 0 {
return []*account.Account{}, nil
var vloggers []*account.Account }
if err := r.db.WithContext(ctx).
Model(&account.Account{}). var vloggers []*account.Account
Where("id IN ?", vloggerIDs). if err := r.db.WithContext(ctx).
Find(&vloggers).Error; err != nil { Model(&account.Account{}).
return nil, err Where("id IN ?", vloggerIDs).
} Find(&vloggers).Error; err != nil {
return vloggers, nil return nil, err
} }
return vloggers, nil
func (r *SocialRepository) IsFollowed(ctx context.Context, social *Social) (bool, error) { }
var count int64
if err := r.db.WithContext(ctx). func (r *SocialRepository) IsFollowed(ctx context.Context, social *Social) (bool, error) {
Model(&Social{}). var count int64
Where("follower_id = ? AND vlogger_id = ?", social.FollowerID, social.VloggerID). if err := r.db.WithContext(ctx).
Count(&count).Error; err != nil { Model(&Social{}).
return false, err Where("follower_id = ? AND vlogger_id = ?", social.FollowerID, social.VloggerID).
} Count(&count).Error; err != nil {
return count > 0, nil return false, err
} }
return count > 0, nil
}

View File

@@ -1,101 +1,102 @@
package video package video
import ( import (
"context" "context"
"errors" "errors"
"github.com/go-sql-driver/mysql" "github.com/go-sql-driver/mysql"
"gorm.io/gorm" "gorm.io/gorm"
) )
type LikeRepository struct { type LikeRepository struct {
db *gorm.DB db *gorm.DB
} }
func NewLikeRepository(db *gorm.DB) *LikeRepository { func NewLikeRepository(db *gorm.DB) *LikeRepository {
return &LikeRepository{db: db} return &LikeRepository{db: db}
} }
func (r *LikeRepository) Like(ctx context.Context, like *Like) error { func (r *LikeRepository) Like(ctx context.Context, like *Like) error {
return r.db.WithContext(ctx).Create(like).Error return r.db.WithContext(ctx).Create(like).Error
} }
func (r *LikeRepository) Unlike(ctx context.Context, like *Like) error { func (r *LikeRepository) Unlike(ctx context.Context, like *Like) error {
return r.db.WithContext(ctx). return r.db.WithContext(ctx).
Where("video_id = ? AND account_id = ?", like.VideoID, like.AccountID). Where("video_id = ? AND account_id = ?", like.VideoID, like.AccountID).
Delete(&Like{}).Error Delete(&Like{}).Error
} }
func (r *LikeRepository) LikeIgnoreDuplicate(ctx context.Context, like *Like) (created bool, err error) { func (r *LikeRepository) LikeIgnoreDuplicate(ctx context.Context, like *Like) (created bool, err error) {
if like == nil || like.VideoID == 0 || like.AccountID == 0 { if like == nil || like.VideoID == 0 || like.AccountID == 0 {
return false, nil return false, nil
} }
err = r.db.WithContext(ctx).Create(like).Error err = r.db.WithContext(ctx).Create(like).Error
if err == nil { if err == nil {
return true, nil return true, nil
} }
var mysqlErr *mysql.MySQLError var mysqlErr *mysql.MySQLError
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 { if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {
return false, nil return false, nil
} }
return false, err return false, err
} }
func (r *LikeRepository) DeleteByVideoAndAccount(ctx context.Context, videoID, accountID uint) (deleted bool, err error) { func (r *LikeRepository) DeleteByVideoAndAccount(ctx context.Context, videoID, accountID uint) (deleted bool, err error) {
if videoID == 0 || accountID == 0 { if videoID == 0 || accountID == 0 {
return false, nil return false, nil
} }
res := r.db.WithContext(ctx). res := r.db.WithContext(ctx).
Where("video_id = ? AND account_id = ?", videoID, accountID). Where("video_id = ? AND account_id = ?", videoID, accountID).
Delete(&Like{}) Delete(&Like{})
return res.RowsAffected > 0, res.Error return res.RowsAffected > 0, res.Error
} }
func (r *LikeRepository) IsLiked(ctx context.Context, videoID, accountID uint) (bool, error) { func (r *LikeRepository) IsLiked(ctx context.Context, videoID, accountID uint) (bool, error) {
var count int64 var count int64
err := r.db.WithContext(ctx).Model(&Like{}). err := r.db.WithContext(ctx).Model(&Like{}).
Where("video_id = ? AND account_id = ?", videoID, accountID). Where("video_id = ? AND account_id = ?", videoID, accountID).
Count(&count).Error Count(&count).Error
if err != nil { if err != nil {
return false, err return false, err
} }
return count > 0, nil return count > 0, nil
} }
func (r *LikeRepository) BatchGetLiked(ctx context.Context, videoIDs []uint, accountID uint) (map[uint]bool, error) { func (r *LikeRepository) BatchGetLiked(ctx context.Context, videoIDs []uint, accountID uint) (map[uint]bool, error) {
likeMap := make(map[uint]bool) likeMap := make(map[uint]bool)
if len(videoIDs) == 0 { if len(videoIDs) == 0 {
return likeMap, nil return likeMap, nil
} }
if accountID == 0 { if accountID == 0 {
return likeMap, nil return likeMap, nil
} }
var likes []Like var likes []Like
err := r.db.WithContext(ctx).Model(&Like{}). err := r.db.WithContext(ctx).Model(&Like{}).
Where("video_id IN ? AND account_id = ?", videoIDs, accountID). Where("video_id IN ? AND account_id = ?", videoIDs, accountID).
Find(&likes).Error Find(&likes).Error
if err != nil { if err != nil {
return nil, err return nil, err
} }
for _, like := range likes { for _, like := range likes {
likeMap[like.VideoID] = true likeMap[like.VideoID] = true
} }
return likeMap, nil return likeMap, nil
} }
func (r *LikeRepository) ListLikedVideos(ctx context.Context, accountID uint) ([]Video, error) { func (r *LikeRepository) ListLikedVideos(ctx context.Context, accountID uint) ([]Video, error) {
var videos []Video var videos []Video
if accountID == 0 { if accountID == 0 {
return videos, nil return videos, nil
} }
err := r.db.WithContext(ctx). err := r.db.WithContext(ctx).
Model(&Video{}). Model(&Video{}).
Joins("JOIN likes ON likes.video_id = videos.id"). Joins("JOIN likes ON likes.video_id = videos.id").
Where("likes.account_id = ?", accountID). Where("likes.account_id = ?", accountID).
Order("likes.created_at desc"). Order("likes.created_at desc").
Find(&videos).Error Limit(200).
if err != nil { Find(&videos).Error
return nil, err if err != nil {
} return nil, err
return videos, nil }
} return videos, nil
}