完善角色与消息权限:收紧板管内容处置,彻底删除仅站长,并统一管理删帖/评弹窗。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -15,6 +15,25 @@ var (
|
||||
ErrContentNotFound = errors.New("内容不存在")
|
||||
)
|
||||
|
||||
func (s *ModerationService) authorRole(userID uint) (model.Role, error) {
|
||||
var u model.User
|
||||
if err := s.db.Select("role").First(&u, userID).Error; err != nil {
|
||||
return model.RoleUser, err
|
||||
}
|
||||
return u.Role, nil
|
||||
}
|
||||
|
||||
func (s *ModerationService) assertCanModerateAuthor(actor *Actor, authorID uint) error {
|
||||
role, err := s.authorRole(authorID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !actor.CanModerateAuthor(role) {
|
||||
return ErrAuthorProtected
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const adminContentPageSize = 15
|
||||
|
||||
// AdminContentStatus 列表筛选:live=未删除全部状态;其余为具体状态或已删除
|
||||
@@ -303,12 +322,15 @@ func (s *ModerationService) loadCommentUnscoped(actor *Actor, id uint) (*model.C
|
||||
return &cm, post.BoardID, nil
|
||||
}
|
||||
|
||||
// SoftDeletePost 软删帖子(未删除时);须填写删除类型与理由,并通知作者
|
||||
// SoftDeletePost 软删帖子(未删除时);须选类型,「其他」才须填理由,并通知作者
|
||||
func (s *ModerationService) SoftDeletePost(actor *Actor, id uint, deleteType, deleteReason string) (authorID uint, err error) {
|
||||
post, err := s.loadPostUnscoped(actor, id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := s.assertCanModerateAuthor(actor, post.UserID); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if post.DeletedAt.Valid {
|
||||
return 0, errors.New("帖子已在回收站")
|
||||
}
|
||||
@@ -317,11 +339,15 @@ func (s *ModerationService) SoftDeletePost(actor *Actor, id uint, deleteType, de
|
||||
if !model.ValidPostDeleteType(deleteType) {
|
||||
return 0, errors.New("无效的删除类型")
|
||||
}
|
||||
if deleteReason == "" {
|
||||
return 0, errors.New("请填写删除理由")
|
||||
}
|
||||
if len([]rune(deleteReason)) > 200 {
|
||||
return 0, errors.New("删除理由不能超过 200 字")
|
||||
if deleteType == model.PostDeleteTypeOther {
|
||||
if deleteReason == "" {
|
||||
return 0, errors.New("请填写删除理由")
|
||||
}
|
||||
if len([]rune(deleteReason)) > 200 {
|
||||
return 0, errors.New("删除理由不能超过 200 字")
|
||||
}
|
||||
} else {
|
||||
deleteReason = ""
|
||||
}
|
||||
updates := map[string]interface{}{
|
||||
"delete_type": deleteType,
|
||||
@@ -343,14 +369,20 @@ func (s *ModerationService) RestorePost(actor *Actor, id uint) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.assertCanModerateAuthor(actor, post.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
if !post.DeletedAt.Valid {
|
||||
return errors.New("帖子未被删除")
|
||||
}
|
||||
return s.db.Unscoped().Model(&model.Post{}).Where("id = ?", id).Update("deleted_at", nil).Error
|
||||
}
|
||||
|
||||
// PurgePost 彻底删除已软删帖子及其评论
|
||||
// PurgePost 彻底删除已软删帖子及其评论(仅站长)
|
||||
func (s *ModerationService) PurgePost(actor *Actor, id uint) error {
|
||||
if !actor.CanPurgeContent() {
|
||||
return ErrPurgeOwnerOnly
|
||||
}
|
||||
post, err := s.loadPostUnscoped(actor, id)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -372,6 +404,9 @@ func (s *ModerationService) SoftDeleteComment(actor *Actor, id uint, deleteType,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.assertCanModerateAuthor(actor, cm.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
if cm.DeletedAt.Valid {
|
||||
return errors.New("评论已在回收站")
|
||||
}
|
||||
@@ -414,6 +449,9 @@ func (s *ModerationService) RestoreComment(actor *Actor, id uint) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.assertCanModerateAuthor(actor, cm.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
if !cm.DeletedAt.Valid {
|
||||
return errors.New("评论未被删除")
|
||||
}
|
||||
@@ -433,8 +471,11 @@ func (s *ModerationService) RestoreComment(actor *Actor, id uint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PurgeComment 彻底删除已软删评论
|
||||
// PurgeComment 彻底删除已软删评论(仅站长)
|
||||
func (s *ModerationService) PurgeComment(actor *Actor, id uint) error {
|
||||
if !actor.CanPurgeContent() {
|
||||
return ErrPurgeOwnerOnly
|
||||
}
|
||||
cm, _, err := s.loadCommentUnscoped(actor, id)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user