Files
jiang13-bbs/backend/service/like.go
freefire 0c2b0d2d6a 首次提交:姜十三论坛
后端 Go+Gin:认证/CSRF/限流、板块、帖子、评论、点赞、通知、用户资料、置顶推荐;前端 Next.js 16:发帖/编辑/删除、搜索、分页、点赞、通知中心、设置;基础设施 docker-compose 与配置模板;添加 .gitignore 与专有许可证(保留所有权利)
2026-09-12 01:11:05 +08:00

78 lines
2.0 KiB
Go

package service
import (
"errors"
"github.com/freefire/jiang13-bbs/model"
"gorm.io/gorm"
)
// LikeService 点赞服务
type LikeService struct {
db *gorm.DB
}
func NewLikeService(db *gorm.DB) *LikeService {
return &LikeService{db: db}
}
// Toggle 切换点赞状态:已点赞则取消,未点赞则点赞
// 返回 (liked, likeCount, error)
func (s *LikeService) Toggle(postID, userID uint) (bool, int, error) {
// 检查帖子是否存在
var post model.Post
if err := s.db.First(&post, postID).Error; err != nil {
return false, 0, errors.New("帖子不存在")
}
var like model.Like
err := s.db.Where("post_id = ? AND user_id = ?", postID, userID).First(&like).Error
if err == nil {
// 已点赞 → 取消点赞
if err := s.db.Delete(&like).Error; err != nil {
return false, post.LikeCount, err
}
newCount := post.LikeCount - 1
if newCount < 0 {
newCount = 0
}
s.db.Model(&post).UpdateColumn("like_count", newCount)
return false, newCount, nil
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
return false, post.LikeCount, err
}
// 未点赞 → 点赞
newLike := model.Like{PostID: postID, UserID: userID}
if err := s.db.Create(&newLike).Error; err != nil {
return false, post.LikeCount, err
}
newCount := post.LikeCount + 1
s.db.Model(&post).UpdateColumn("like_count", newCount)
return true, newCount, nil
}
// HasLiked 判断用户是否已点赞某帖子
func (s *LikeService) HasLiked(postID, userID uint) bool {
var count int64
s.db.Model(&model.Like{}).Where("post_id = ? AND user_id = ?", postID, userID).Count(&count)
return count > 0
}
// BatchHasLiked 批量查询用户对多个帖子的点赞状态,返回 postID -> bool
func (s *LikeService) BatchHasLiked(postIDs []uint, userID uint) map[uint]bool {
result := make(map[uint]bool)
if len(postIDs) == 0 || userID == 0 {
return result
}
var likes []model.Like
s.db.Where("post_id IN ? AND user_id = ?", postIDs, userID).Find(&likes)
for _, l := range likes {
result[l.PostID] = true
}
return result
}