feat: 评论/帖子编辑历史与编辑标记,内容锁定
- 新增 smartDiff 差异计算与 EditHistoryModal 编辑历史弹窗,替换原 CommentEditHistoryModal - 新增 PostEditedMark 编辑标记展示 - 新增内容锁定机制(content_lock)防止并发编辑冲突 - 审核与通知服务适配
This commit is contained in:
@@ -81,6 +81,7 @@ type AdminContentComment struct {
|
||||
BoardID uint `json:"board_id"`
|
||||
Content string `json:"content"`
|
||||
Status string `json:"status"`
|
||||
Edited bool `json:"edited"` // 相对创建已编辑(同评论侧规则),用于隐藏无修订的历史入口
|
||||
Deleted bool `json:"deleted"`
|
||||
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
@@ -223,13 +224,14 @@ func (s *ModerationService) ListAdminComments(actor *Actor, status, keyword stri
|
||||
Content string
|
||||
Status string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
DeletedAt gorm.DeletedAt
|
||||
BoardID uint
|
||||
PostTitle string
|
||||
UserID uint
|
||||
}
|
||||
var rows []row
|
||||
if err := q.Select("comments.id, comments.post_id, comments.content, comments.status, comments.created_at, comments.deleted_at, posts.board_id, posts.title AS post_title, comments.user_id").
|
||||
if err := q.Select("comments.id, comments.post_id, comments.content, comments.status, comments.created_at, comments.updated_at, comments.deleted_at, posts.board_id, posts.title AS post_title, comments.user_id").
|
||||
Order("comments.id DESC").
|
||||
Offset((page - 1) * adminContentPageSize).Limit(adminContentPageSize).
|
||||
Scan(&rows).Error; err != nil {
|
||||
@@ -276,6 +278,7 @@ func (s *ModerationService) ListAdminComments(actor *Actor, status, keyword stri
|
||||
BoardID: r.BoardID,
|
||||
Content: r.Content,
|
||||
Status: r.Status,
|
||||
Edited: r.UpdatedAt.Sub(r.CreatedAt) > time.Minute,
|
||||
CreatedAt: r.CreatedAt,
|
||||
Board: boards[r.BoardID],
|
||||
User: users[r.UserID],
|
||||
@@ -354,7 +357,8 @@ func (s *ModerationService) SoftDeletePost(actor *Actor, id uint, deleteType, de
|
||||
"delete_reason": deleteReason,
|
||||
"deleted_by": actor.ID,
|
||||
}
|
||||
if err := s.db.Model(post).Updates(updates).Error; err != nil {
|
||||
// UpdateColumns:删除元数据非内容编辑,不刷新 updated_at(详情页「更新于」由该字段推导)
|
||||
if err := s.db.Model(post).UpdateColumns(updates).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := s.db.Delete(post).Error; err != nil {
|
||||
@@ -375,7 +379,8 @@ func (s *ModerationService) RestorePost(actor *Actor, id uint) error {
|
||||
if !post.DeletedAt.Valid {
|
||||
return errors.New("帖子未被删除")
|
||||
}
|
||||
return s.db.Unscoped().Model(&model.Post{}).Where("id = ?", id).Update("deleted_at", nil).Error
|
||||
// UpdateColumn:恢复非内容编辑,不刷新 updated_at
|
||||
return s.db.Unscoped().Model(&model.Post{}).Where("id = ?", id).UpdateColumn("deleted_at", nil).Error
|
||||
}
|
||||
|
||||
// PurgePost 彻底删除已软删帖子及其评论(仅站长)
|
||||
@@ -391,6 +396,9 @@ func (s *ModerationService) PurgePost(actor *Actor, id uint) error {
|
||||
return ErrContentNotDeleted
|
||||
}
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Unscoped().Where("post_id = ?", id).Delete(&model.PostEditHistory{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Unscoped().Where("post_id = ?", id).Delete(&model.Comment{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -430,7 +438,8 @@ func (s *ModerationService) SoftDeleteComment(actor *Actor, id uint, deleteType,
|
||||
"delete_reason": deleteReason,
|
||||
"deleted_by": actor.ID,
|
||||
}
|
||||
if err := s.db.Model(cm).Updates(updates).Error; err != nil {
|
||||
// UpdateColumns:删除元数据非内容编辑,不刷新 updated_at(该字段用于 edited 判定)
|
||||
if err := s.db.Model(cm).UpdateColumns(updates).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.db.Delete(cm).Error; err != nil {
|
||||
@@ -461,7 +470,8 @@ func (s *ModerationService) RestoreComment(actor *Actor, id uint) error {
|
||||
"delete_reason": "",
|
||||
"deleted_by": 0,
|
||||
}
|
||||
if err := s.db.Unscoped().Model(&model.Comment{}).Where("id = ?", id).Updates(updates).Error; err != nil {
|
||||
// UpdateColumns:恢复非内容编辑,不刷新 updated_at(该字段用于 edited 判定)
|
||||
if err := s.db.Unscoped().Model(&model.Comment{}).Where("id = ?", id).UpdateColumns(updates).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if cm.Status == model.ContentStatusPublished {
|
||||
|
||||
Reference in New Issue
Block a user