feat(comments): 软删占位、理由与恢复,管理删仅对访客打码
自删/管理删差异文案与理由可见性,评论者与管理员免马赛克,并支持恢复与处理人链接。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -106,7 +106,7 @@ func (h *Handlers) CreateComment(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"comment": comment})
|
||||
}
|
||||
|
||||
// DeleteComment 软删评论(占位)
|
||||
// DeleteComment 软删评论(占位;自删与管理删均须填理由,管理删另须类型)
|
||||
func (h *Handlers) DeleteComment(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
cid, err := strconv.ParseUint(c.Param("cid"), 10, 64)
|
||||
@@ -114,18 +114,58 @@ func (h *Handlers) DeleteComment(c *gin.Context) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的评论 ID"})
|
||||
return
|
||||
}
|
||||
if err := h.Comment.Delete(h.loadActor(claims.ID), uint(cid), claims.ID); err != nil {
|
||||
var body struct {
|
||||
DeleteType string `json:"delete_type"`
|
||||
DeleteReason string `json:"delete_reason"`
|
||||
}
|
||||
_ = c.ShouldBindJSON(&body)
|
||||
if err := h.Comment.Delete(h.loadActor(claims.ID), uint(cid), claims.ID, service.DeleteCommentOpts{
|
||||
DeleteType: body.DeleteType,
|
||||
DeleteReason: body.DeleteReason,
|
||||
}); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, service.ErrCommentNotFound):
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
case errors.Is(err, service.ErrCommentForbidden):
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": err.Error()})
|
||||
case errors.Is(err, service.ErrCommentDeleteMeta),
|
||||
errors.Is(err, service.ErrCommentInvalidType):
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
default:
|
||||
msg := err.Error()
|
||||
if msg == "删除理由不能超过 200 字" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": msg})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": msg})
|
||||
}
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": "已删除"})
|
||||
}
|
||||
|
||||
// RestoreComment 恢复软删评论(自删作者或版主)
|
||||
func (h *Handlers) RestoreComment(c *gin.Context) {
|
||||
claims := middleware.CurrentUser(c)
|
||||
cid, err := strconv.ParseUint(c.Param("cid"), 10, 64)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的评论 ID"})
|
||||
return
|
||||
}
|
||||
if err := h.Comment.Restore(h.loadActor(claims.ID), uint(cid), claims.ID); err != nil {
|
||||
switch {
|
||||
case errors.Is(err, service.ErrCommentNotFound):
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
case errors.Is(err, service.ErrCommentForbidden):
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "无权限恢复此评论"})
|
||||
case errors.Is(err, service.ErrCommentNotDeleted):
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
default:
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
}
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": "已删除"})
|
||||
c.JSON(http.StatusOK, gin.H{"message": "已恢复"})
|
||||
}
|
||||
|
||||
// PurgeComment 硬删评论及子树(仅版主;不占位)
|
||||
|
||||
@@ -157,7 +157,26 @@ func (h *Handlers) AdminPurgePost(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminSoftDeleteComment(c *gin.Context) {
|
||||
h.execContentAction(c, h.Moderation.SoftDeleteComment)
|
||||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
if err != nil || id == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的 ID"})
|
||||
return
|
||||
}
|
||||
var body struct {
|
||||
DeleteType string `json:"delete_type"`
|
||||
DeleteReason string `json:"delete_reason"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "请提交删除类型与理由"})
|
||||
return
|
||||
}
|
||||
actor := middleware.CurrentActor(c)
|
||||
if err := h.Moderation.SoftDeleteComment(actor, uint(id), body.DeleteType, body.DeleteReason); err != nil {
|
||||
h.writeModerationError(c, err)
|
||||
return
|
||||
}
|
||||
h.broadcastModerationChanged()
|
||||
c.JSON(http.StatusOK, gin.H{"message": "操作成功"})
|
||||
}
|
||||
|
||||
func (h *Handlers) AdminRestoreComment(c *gin.Context) {
|
||||
|
||||
Reference in New Issue
Block a user