feat(moderation): 帖评删除占位感知与硬删清场

管理删帖须填类型与理由并展示专用页;评论软删占位、版主可硬删不占楼。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 07:01:04 +08:00
parent 2b27703e6c
commit bcb4f6a603
15 changed files with 825 additions and 116 deletions

View File

@@ -361,7 +361,7 @@ func (h *Handlers) DownloadPostAttachment(c *gin.Context) {
_ = filepath.Base(path)
}
// DeletePost 删除帖子
// DeletePost 删除帖子(作者自删或 staff 软删;staff 须提交类型与理由)
func (h *Handlers) DeletePost(c *gin.Context) {
claims := middleware.CurrentUser(c)
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
@@ -369,10 +369,30 @@ func (h *Handlers) DeletePost(c *gin.Context) {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的帖子 ID"})
return
}
if err := h.Post.Delete(h.loadActor(claims.ID), uint(id), claims.ID); err != nil {
var body struct {
DeleteType string `json:"delete_type"`
DeleteReason string `json:"delete_reason"`
}
_ = c.ShouldBindJSON(&body)
staffDeleted, authorID, err := h.Post.Delete(
h.loadActor(claims.ID),
uint(id),
claims.ID,
service.DeletePostOpts{DeleteType: body.DeleteType, DeleteReason: body.DeleteReason},
)
if err != nil {
respondPostModError(c, err)
return
}
if staffDeleted {
label := model.PostDeleteTypeLabel(body.DeleteType)
preview := label
if body.DeleteReason != "" {
preview = label + ":" + body.DeleteReason
}
h.Notification.Create(authorID, claims.ID, model.NotificationTypeDeleted, uint(id), 0, preview)
}
c.JSON(http.StatusOK, gin.H{"message": "已删除"})
}