后端 Go+Gin:认证/CSRF/限流、板块、帖子、评论、点赞、通知、用户资料、置顶推荐;前端 Next.js 16:发帖/编辑/删除、搜索、分页、点赞、通知中心、设置;基础设施 docker-compose 与配置模板;添加 .gitignore 与专有许可证(保留所有权利)
78 lines
2.0 KiB
Go
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
|
|
}
|