refactor:优化了like和unlike功能
This commit is contained in:
@@ -89,21 +89,3 @@ func (lh *LikeHandler) IsLiked(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
c.JSON(200, gin.H{"is_liked": isLiked})
|
c.JSON(200, gin.H{"is_liked": isLiked})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lh *LikeHandler) GetLikesCount(c *gin.Context) {
|
|
||||||
var req LikeRequest
|
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
|
||||||
c.JSON(400, gin.H{"error": err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if req.VideoID <= 0 {
|
|
||||||
c.JSON(400, gin.H{"error": "video_id is required"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
likesCount, err := lh.service.GetLikesCount(c.Request.Context(), req.VideoID)
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(500, gin.H{"error": err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.JSON(200, gin.H{"likes_count": likesCount})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -34,14 +34,3 @@ func (r *LikeRepository) IsLiked(ctx context.Context, videoID, accountID uint) (
|
|||||||
}
|
}
|
||||||
return count > 0, nil
|
return count > 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *LikeRepository) GetLikesCount(ctx context.Context, videoID uint) (int64, error) {
|
|
||||||
var count int64
|
|
||||||
err := r.db.WithContext(ctx).Model(&Like{}).
|
|
||||||
Where("video_id = ?", videoID).
|
|
||||||
Count(&count).Error
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return count, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-sql-driver/mysql"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LikeService struct {
|
type LikeService struct {
|
||||||
@@ -15,69 +18,49 @@ func NewLikeService(repo *LikeRepository, videoRepo *VideoRepository) *LikeServi
|
|||||||
return &LikeService{repo: repo, VideoRepo: videoRepo}
|
return &LikeService{repo: repo, VideoRepo: videoRepo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LikeService) Like(ctx context.Context, like *Like) error {
|
func isDupKey(err error) bool {
|
||||||
exists, err := s.VideoRepo.IsExist(ctx, like.VideoID)
|
var me *mysql.MySQLError
|
||||||
if err != nil {
|
return errors.As(err, &me) && me.Number == 1062
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
if !exists {
|
|
||||||
return errors.New("video not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
isLiked, err := s.IsLiked(ctx, like.VideoID, like.AccountID)
|
func (s *LikeService) Like(ctx context.Context, like *Like) error {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if isLiked {
|
|
||||||
return errors.New("user has liked this video")
|
|
||||||
}
|
|
||||||
like.CreatedAt = time.Now()
|
like.CreatedAt = time.Now()
|
||||||
if err := s.repo.Like(ctx, like); err != nil {
|
return s.repo.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
return err
|
if err := tx.Select("id").First(&Video{}, like.VideoID).Error; err != nil {
|
||||||
}
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
likesCount, err := s.GetLikesCount(ctx, like.VideoID)
|
return errors.New("video not found")
|
||||||
if err != nil {
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := s.VideoRepo.UpdateLikesCount(ctx, like.VideoID, likesCount); err != nil {
|
if err := tx.Create(like).Error; err != nil {
|
||||||
return err
|
if isDupKey(err) {
|
||||||
}
|
return errors.New("user has liked this video")
|
||||||
return nil
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Model(&Video{}).Where("id = ?", like.VideoID).
|
||||||
|
UpdateColumn("likes_count", gorm.Expr("likes_count + 1")).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LikeService) Unlike(ctx context.Context, like *Like) error {
|
func (s *LikeService) Unlike(ctx context.Context, like *Like) error {
|
||||||
exists, err := s.VideoRepo.IsExist(ctx, like.VideoID)
|
return s.repo.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
if err != nil {
|
del := tx.Where("video_id = ? AND account_id = ?", like.VideoID, like.AccountID).Delete(&Like{})
|
||||||
return err
|
if del.Error != nil {
|
||||||
}
|
return del.Error
|
||||||
if !exists {
|
}
|
||||||
return errors.New("video not found")
|
if del.RowsAffected == 0 {
|
||||||
}
|
return errors.New("user has not liked this video")
|
||||||
|
}
|
||||||
|
|
||||||
isLiked, err := s.IsLiked(ctx, like.VideoID, like.AccountID)
|
return tx.Model(&Video{}).Where("id = ?", like.VideoID).
|
||||||
if err != nil {
|
UpdateColumn("likes_count", gorm.Expr("GREATEST(likes_count - 1, 0)")).Error
|
||||||
return err
|
})
|
||||||
}
|
|
||||||
if !isLiked {
|
|
||||||
return errors.New("user has not liked this video")
|
|
||||||
}
|
|
||||||
if err := s.repo.Unlike(ctx, like); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
likesCount, err := s.GetLikesCount(ctx, like.VideoID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := s.VideoRepo.UpdateLikesCount(ctx, like.VideoID, likesCount); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LikeService) IsLiked(ctx context.Context, videoID, accountID uint) (bool, error) {
|
func (s *LikeService) IsLiked(ctx context.Context, videoID, accountID uint) (bool, error) {
|
||||||
return s.repo.IsLiked(ctx, videoID, accountID)
|
return s.repo.IsLiked(ctx, videoID, accountID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *LikeService) GetLikesCount(ctx context.Context, videoID uint) (int64, error) {
|
|
||||||
return s.repo.GetLikesCount(ctx, videoID)
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user