feat: 评论/帖子编辑历史与编辑标记,内容锁定

- 新增 smartDiff 差异计算与 EditHistoryModal 编辑历史弹窗,替换原 CommentEditHistoryModal
- 新增 PostEditedMark 编辑标记展示
- 新增内容锁定机制(content_lock)防止并发编辑冲突
- 审核与通知服务适配
This commit is contained in:
2026-09-25 23:41:45 +08:00
parent cab8230803
commit 5270fee2b7
40 changed files with 2521 additions and 350 deletions

View File

@@ -180,7 +180,8 @@ func (s *ModerationService) ApprovePost(actor *Actor, id uint) (boardID uint, er
if raw, ok := EnsureDeadlineOnPublish(post.TypeMeta, post.PostType, time.Now().UTC()); ok {
updates["type_meta"] = raw
}
if err := tx.Model(&post).Updates(updates).Error; err != nil {
// UpdateColumns:审核非内容编辑,不刷新 updated_at(详情页「更新于」由该字段推导)
if err := tx.Model(&post).UpdateColumns(updates).Error; err != nil {
return err
}
boardID = post.BoardID
@@ -204,7 +205,8 @@ func (s *ModerationService) RejectPost(actor *Actor, id uint) error {
if post.Status != model.ContentStatusPending {
return ErrNotPending
}
if err := tx.Model(&post).Update("status", model.ContentStatusRejected).Error; err != nil {
// UpdateColumn:审核非内容编辑,不刷新 updated_at
if err := tx.Model(&post).UpdateColumn("status", model.ContentStatusRejected).Error; err != nil {
return err
}
s.notif.Create(post.UserID, actor.ID, model.NotificationTypeRejected, post.ID, 0,
@@ -230,7 +232,8 @@ func (s *ModerationService) ApproveComment(actor *Actor, id uint) (postID, board
if cm.Status != model.ContentStatusPending {
return ErrNotPending
}
if err := tx.Model(&cm).Update("status", model.ContentStatusPublished).Error; err != nil {
// UpdateColumn:审核非内容编辑,不刷新评论 updated_at(该字段用于 edited 判定)
if err := tx.Model(&cm).UpdateColumn("status", model.ContentStatusPublished).Error; err != nil {
return err
}
if err := tx.Model(&model.Post{}).Where("id = ?", cm.PostID).
@@ -273,7 +276,8 @@ func (s *ModerationService) RejectComment(actor *Actor, id uint) error {
if cm.Status != model.ContentStatusPending {
return ErrNotPending
}
if err := tx.Model(&cm).Update("status", model.ContentStatusRejected).Error; err != nil {
// UpdateColumn:审核非内容编辑,不刷新评论 updated_at(该字段用于 edited 判定)
if err := tx.Model(&cm).UpdateColumn("status", model.ContentStatusRejected).Error; err != nil {
return err
}
s.notif.Create(cm.UserID, actor.ID, model.NotificationTypeRejected, cm.PostID, cm.ID,