feat: SSR 评论编辑与作者删除
帖详情提供时限内编辑与软删入口,作者删除与管理员共用回收站子树语义。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -369,12 +369,52 @@ func (s *CommentService) ListPending(page, size int) ([]models.Comment, int64, e
|
||||
}
|
||||
|
||||
func (s *CommentService) Delete(userID, commentID uint, isAdmin bool) error {
|
||||
if !isAdmin {
|
||||
var comment models.Comment
|
||||
if err := models.DB.First(&comment, commentID).Error; err != nil {
|
||||
return ErrCommentNotFound
|
||||
}
|
||||
if !isAdmin && (comment.UserID == 0 || comment.UserID != userID) {
|
||||
return ErrPermissionDenied
|
||||
}
|
||||
return s.AdminDelete(commentID)
|
||||
}
|
||||
|
||||
// CanUserEditComment 作者在编辑时限内,或管理员
|
||||
func (s *CommentService) CanUserEditComment(comment *models.Comment, userID uint, isAdmin bool) bool {
|
||||
window := 3
|
||||
if s != nil && s.settings != nil {
|
||||
window = s.settings.CommentEditWindowMinutes()
|
||||
}
|
||||
return canEditComment(comment, userID, isAdmin, window)
|
||||
}
|
||||
|
||||
// CanUserDeleteComment 作者或管理员可软删
|
||||
func (s *CommentService) CanUserDeleteComment(comment *models.Comment, userID uint, isAdmin bool) bool {
|
||||
if comment == nil || userID == 0 {
|
||||
return false
|
||||
}
|
||||
if isAdmin {
|
||||
return true
|
||||
}
|
||||
return comment.UserID > 0 && comment.UserID == userID
|
||||
}
|
||||
|
||||
func canEditComment(comment *models.Comment, userID uint, isAdmin bool, windowMin int) bool {
|
||||
if comment == nil || userID == 0 {
|
||||
return false
|
||||
}
|
||||
if isAdmin {
|
||||
return true
|
||||
}
|
||||
if comment.UserID == 0 || comment.UserID != userID {
|
||||
return false
|
||||
}
|
||||
if windowMin > 0 && time.Since(comment.CreatedAt) > time.Duration(windowMin)*time.Minute {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *CommentService) Update(userID, commentID uint, isAdmin, skipModeration bool, content string) (string, bool, error) {
|
||||
var comment models.Comment
|
||||
if err := models.DB.First(&comment, commentID).Error; err != nil {
|
||||
|
||||
47
services/comment_edit_test.go
Normal file
47
services/comment_edit_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.iioio.com/freefire/jiang13-forum/models"
|
||||
)
|
||||
|
||||
func TestCanEditComment(t *testing.T) {
|
||||
now := time.Now()
|
||||
c := &models.Comment{UserID: 7, CreatedAt: now}
|
||||
if !canEditComment(c, 7, false, 3) {
|
||||
t.Fatal("author within window")
|
||||
}
|
||||
if canEditComment(c, 8, false, 3) {
|
||||
t.Fatal("other user")
|
||||
}
|
||||
if !canEditComment(c, 1, true, 3) {
|
||||
t.Fatal("admin always")
|
||||
}
|
||||
old := &models.Comment{UserID: 7, CreatedAt: now.Add(-10 * time.Minute)}
|
||||
if canEditComment(old, 7, false, 3) {
|
||||
t.Fatal("expired")
|
||||
}
|
||||
if !canEditComment(old, 7, true, 3) {
|
||||
t.Fatal("admin ignores window")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanUserDeleteComment(t *testing.T) {
|
||||
s := &CommentService{}
|
||||
c := &models.Comment{UserID: 3}
|
||||
if !s.CanUserDeleteComment(c, 3, false) {
|
||||
t.Fatal("author")
|
||||
}
|
||||
if s.CanUserDeleteComment(c, 4, false) {
|
||||
t.Fatal("other")
|
||||
}
|
||||
if !s.CanUserDeleteComment(c, 1, true) {
|
||||
t.Fatal("admin")
|
||||
}
|
||||
guest := &models.Comment{UserID: 0}
|
||||
if s.CanUserDeleteComment(guest, 1, false) {
|
||||
t.Fatal("guest author id 0")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user