feat: 实现赞/踩系统(P2)

- 新增 PostLike/PostDislike 模型,复合主键 (user_id, post_id)
- Post 表新增 LikesCount/DislikesCount 冗余计数器
- Repository 层:reaction_repo.go,含 WithTx 事务支持
- Service 层:reaction_service.go,赞踩互斥逻辑(6 态切换),事务包裹
- Controller 层:reaction_controller.go,3 个 API(ToggleLike/ToggleDislike/GetReaction)
- 接口定义:controller/interfaces.go 新增 reactionUseCase,service/repository.go 新增 ReactionStore
- 路由注册 + 依赖注入 + AutoMigrate
- 前端:文章详情页赞踩按钮 + 状态查询 + 401 跳转登录
- 样式:posts.css 新增赞踩按钮样式
This commit is contained in:
2026-06-01 15:48:18 +08:00
parent 4815060839
commit 2b47380ac5
14 changed files with 557 additions and 2 deletions

View File

@ -0,0 +1,77 @@
package repository
import (
"metazone.cc/metalab/internal/model"
"metazone.cc/metalab/internal/service"
"gorm.io/gorm"
)
// ReactionRepo 赞/踩数据访问
type ReactionRepo struct {
db *gorm.DB
}
// NewReactionRepo 构造函数
func NewReactionRepo(db *gorm.DB) *ReactionRepo {
return &ReactionRepo{db: db}
}
// WithTx 基于给定事务连接创建新的 ReactionRepo
func (r *ReactionRepo) WithTx(tx *gorm.DB) service.ReactionStore {
return &ReactionRepo{db: tx}
}
// FindLike 查找点赞记录
func (r *ReactionRepo) FindLike(userID, postID uint) (*model.PostLike, error) {
var like model.PostLike
err := r.db.Where("user_id = ? AND post_id = ?", userID, postID).First(&like).Error
if err != nil {
return nil, err
}
return &like, nil
}
// CreateLike 创建点赞记录
func (r *ReactionRepo) CreateLike(like *model.PostLike) error {
return r.db.Create(like).Error
}
// DeleteLike 删除点赞记录
func (r *ReactionRepo) DeleteLike(userID, postID uint) error {
return r.db.Where("user_id = ? AND post_id = ?", userID, postID).Delete(&model.PostLike{}).Error
}
// FindDislike 查找踩记录
func (r *ReactionRepo) FindDislike(userID, postID uint) (*model.PostDislike, error) {
var dislike model.PostDislike
err := r.db.Where("user_id = ? AND post_id = ?", userID, postID).First(&dislike).Error
if err != nil {
return nil, err
}
return &dislike, nil
}
// CreateDislike 创建踩记录
func (r *ReactionRepo) CreateDislike(dislike *model.PostDislike) error {
return r.db.Create(dislike).Error
}
// DeleteDislike 删除踩记录
func (r *ReactionRepo) DeleteDislike(userID, postID uint) error {
return r.db.Where("user_id = ? AND post_id = ?", userID, postID).Delete(&model.PostDislike{}).Error
}
// IncrPostLikes 原子增加文章点赞数
func (r *ReactionRepo) IncrPostLikes(postID uint, delta int) error {
return r.db.Model(&model.Post{}).
Where("id = ?", postID).
UpdateColumn("likes_count", gorm.Expr("likes_count + ?", delta)).Error
}
// IncrPostDislikes 原子增加文章踩数
func (r *ReactionRepo) IncrPostDislikes(postID uint, delta int) error {
return r.db.Model(&model.Post{}).
Where("id = ?", postID).
UpdateColumn("dislikes_count", gorm.Expr("dislikes_count + ?", delta)).Error
}