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

@ -118,4 +118,17 @@ func setupAPIRoutes(r *gin.Engine, cfg *config.Config, d *dependencies) {
commentsAPI.GET("/users/search", d.commentCtrl.SearchUsers)
commentsAPI.POST("/comments/upload-image", d.commentCtrl.UploadImage)
}
// --- 赞/踩 API ---
// 公开:查询反应状态(未登录返回 none + 点赞数)
r.GET("/api/posts/:id/reaction", d.reactionCtrl.GetReaction)
// 需登录:切换赞/踩
reactionAPI := r.Group("/api/posts/:id")
reactionAPI.Use(d.authMdw.Required())
reactionAPI.Use(d.authMdw.BannedWriteGuard())
reactionAPI.Use(middleware.CSRF(cfg))
{
reactionAPI.POST("/like", d.reactionCtrl.ToggleLike)
reactionAPI.POST("/dislike", d.reactionCtrl.ToggleDislike)
}
}

View File

@ -37,6 +37,7 @@ type dependencies struct {
commentCtrl *controller.CommentController
commentService *service.CommentService
adminCommentCtrl *adminCtrl.AdminCommentController
reactionCtrl *controller.ReactionController
}
func buildDepsCore(db *gorm.DB, cfg *config.Config, siteSettings *config.SiteSettings, redisClient *redis.Client) (

View File

@ -69,6 +69,11 @@ func buildDeps(db *gorm.DB, cfg *config.Config, siteSettings *config.SiteSetting
// 后台评论管理
adminCommentCtrl := adminCtrl.NewAdminCommentController(commentService)
// 赞/踩系统
reactionRepo := repository.NewReactionRepo(db)
reactionService := service.NewReactionService(db, reactionRepo)
reactionCtrl := controller.NewReactionController(reactionService)
// 用户空间
spaceService := service.NewSpaceService(userRepo, postRepo)
spaceCtrl := controller.NewSpaceController(spaceService)
@ -90,5 +95,6 @@ func buildDeps(db *gorm.DB, cfg *config.Config, siteSettings *config.SiteSetting
commentCtrl: commentCtrl,
commentService: commentService,
adminCommentCtrl: adminCommentCtrl,
reactionCtrl: reactionCtrl,
}
}