feat: 锁定文章需填写锁定理由,编辑器显示锁定理由
- Post 模型新增 LockReason 字段,锁定必填理由,解锁清空 - PostLockRequest DTO:reason 必填,1-500字 - Admin JS:锁定操作弹出 prompt 要求填写理由 - 编辑器锁定横幅显示"锁定理由:XXX",理由为空时不显示该行
This commit is contained in:
@ -116,7 +116,13 @@ func (ctrl *AdminPostController) Lock(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctrl.postService.Lock(uint(id)); err != nil {
|
||||
var req model.PostLockRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
common.Error(c, http.StatusBadRequest, "请填写锁定理由")
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctrl.postService.Lock(uint(id), req.Reason); err != nil {
|
||||
if errors.Is(err, common.ErrPostNotFound) || errors.Is(err, common.ErrPostCannotLock) {
|
||||
common.Error(c, http.StatusBadRequest, err.Error())
|
||||
} else {
|
||||
|
||||
@ -42,7 +42,7 @@ type adminPostUseCase interface {
|
||||
ListPendingRevisions(keyword string, page, pageSize int) ([]model.Post, int64, error)
|
||||
Approve(postID uint) error
|
||||
Reject(postID uint, reason string) error
|
||||
Lock(postID uint) error
|
||||
Lock(postID uint, reason string) error
|
||||
Unlock(postID uint) error
|
||||
Restore(postID uint) error
|
||||
}
|
||||
|
||||
@ -154,7 +154,6 @@ func (ctrl *StudioController) WritePage(c *gin.Context) {
|
||||
"Post": post,
|
||||
"ActiveTab": "write",
|
||||
"ExtraCSS": "/static/css/studio.css",
|
||||
"StatusNames": common.PostStatusDisplayNames,
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
@ -47,6 +47,11 @@ type PostRejectRequest struct {
|
||||
Reason string `json:"reason" binding:"required,min=1,max=500"`
|
||||
}
|
||||
|
||||
// PostLockRequest 锁定请求
|
||||
type PostLockRequest struct {
|
||||
Reason string `json:"reason" binding:"required,min=1,max=500"`
|
||||
}
|
||||
|
||||
// PostListQuery 列表查询参数
|
||||
type PostListQuery struct {
|
||||
Keyword string `form:"keyword"`
|
||||
|
||||
@ -15,6 +15,7 @@ type Post struct {
|
||||
UserID uint `gorm:"index;not null" json:"user_id"`
|
||||
Status string `gorm:"type:varchar(20);index;default:draft;not null" json:"status"`
|
||||
IsLocked bool `gorm:"default:false" json:"is_locked"`
|
||||
LockReason string `gorm:"type:varchar(500);default:''" json:"lock_reason,omitempty"`
|
||||
PendingTitle string `gorm:"type:varchar(200);default:''" json:"pending_title,omitempty"`
|
||||
PendingBody string `gorm:"type:text" json:"pending_body,omitempty"`
|
||||
RejectReason string `gorm:"type:varchar(500);default:''" json:"reject_reason,omitempty"`
|
||||
|
||||
@ -341,7 +341,7 @@ func (s *PostService) Reject(postID uint, reason string) error {
|
||||
}
|
||||
|
||||
// Lock 锁定:设置 IsLocked 标志,禁止编辑,不改变帖子发布状态
|
||||
func (s *PostService) Lock(postID uint) error {
|
||||
func (s *PostService) Lock(postID uint, reason string) error {
|
||||
post, err := s.findPost(postID)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -351,6 +351,7 @@ func (s *PostService) Lock(postID uint) error {
|
||||
return common.ErrPostCannotLock
|
||||
}
|
||||
post.IsLocked = true
|
||||
post.LockReason = reason
|
||||
return s.repo.Update(post)
|
||||
}
|
||||
|
||||
@ -364,6 +365,7 @@ func (s *PostService) Unlock(postID uint) error {
|
||||
return common.ErrPostCannotUnlock
|
||||
}
|
||||
post.IsLocked = false
|
||||
post.LockReason = ""
|
||||
return s.repo.Update(post)
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,9 @@
|
||||
<div class="locked-banner-icon">🔒</div>
|
||||
<div>
|
||||
<strong>这篇文章已被锁定,无法编辑。</strong>
|
||||
<p>如需解锁请联系管理员。当前状态:{{if $.StatusNames}}{{index $.StatusNames .Post.Status}}、已锁定{{end}}</p>
|
||||
{{if .Post.LockReason}}
|
||||
<p>锁定理由:{{.Post.LockReason}}</p>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
@ -47,7 +47,9 @@
|
||||
|
||||
// 锁定
|
||||
handleClick('.post-lock', function(id) {
|
||||
api('/api/admin/posts/' + id + '/lock', 'POST')
|
||||
var reason = prompt('请输入锁定理由(必填):');
|
||||
if (!reason || !reason.trim()) return;
|
||||
api('/api/admin/posts/' + id + '/lock', 'POST', { reason: reason.trim() })
|
||||
.then(function(d) { if (d.success) refreshPage(); else alert(d.message); })
|
||||
.catch(function() { alert('操作失败'); });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user