feat: 对接稿件审核通知系统 + 消息页面系统消息区域
- 新增通知类型 post_approved / post_rejected
- PostService.Approve/Reject 完成后通知作者(通知失败不影响主流程)
- NotificationService 新增 NotifyPostApproved/NotifyPostRejected 方法
- 消息页面顶部增加系统消息标识和分隔线,之下为全部消息列表
- 稿件审核通过通知卡片点击跳转到 /posts/{id} 页面
- 稿件审核拒绝通知卡片点击跳转到 /studio/posts 创作中心
- 新增 postNotifier 接口遵循 ISP 原则
This commit is contained in:
@ -110,3 +110,20 @@ func (s *NotificationService) NotifyAuditRejected(userID uint, auditType, reason
|
||||
content,
|
||||
&relatedID)
|
||||
}
|
||||
|
||||
// NotifyPostApproved 稿件审核通过通知
|
||||
func (s *NotificationService) NotifyPostApproved(userID uint, postTitle string, postID uint) {
|
||||
title := "稿件审核通过"
|
||||
content := "你的稿件《" + postTitle + "》已通过审核,现已公开发布"
|
||||
_ = s.Create(userID, model.NotifyPostApproved, title, content, &postID)
|
||||
}
|
||||
|
||||
// NotifyPostRejected 稿件审核拒绝通知
|
||||
func (s *NotificationService) NotifyPostRejected(userID uint, postTitle, reason string, postID uint) {
|
||||
title := "稿件审核未通过"
|
||||
content := "你的稿件《" + postTitle + "》未通过审核"
|
||||
if reason != "" {
|
||||
content += ",理由:" + reason
|
||||
}
|
||||
_ = s.Create(userID, model.NotifyPostRejected, title, content, &postID)
|
||||
}
|
||||
|
||||
@ -75,15 +75,17 @@ func generateExcerpt(md string) string {
|
||||
|
||||
// PostService 帖子业务逻辑
|
||||
type PostService struct {
|
||||
repo postStore
|
||||
ss *config.SiteSettings
|
||||
repo postStore
|
||||
ss *config.SiteSettings
|
||||
notifier postNotifier
|
||||
}
|
||||
|
||||
// NewPostService 构造函数
|
||||
func NewPostService(repo postStore, ss *config.SiteSettings) *PostService {
|
||||
func NewPostService(repo postStore, ss *config.SiteSettings, notifier postNotifier) *PostService {
|
||||
return &PostService{
|
||||
repo: repo,
|
||||
ss: ss,
|
||||
repo: repo,
|
||||
ss: ss,
|
||||
notifier: notifier,
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,8 +265,10 @@ func (s *PostService) Approve(postID uint) error {
|
||||
return err
|
||||
}
|
||||
|
||||
wasRevision := post.PendingBody != ""
|
||||
|
||||
// 修订审核:将待审内容覆盖到正式字段
|
||||
if post.PendingBody != "" {
|
||||
if wasRevision {
|
||||
post.Title = post.PendingTitle
|
||||
post.Body = post.PendingBody
|
||||
post.Excerpt = generateExcerpt(post.PendingBody)
|
||||
@ -272,7 +276,14 @@ func (s *PostService) Approve(postID uint) error {
|
||||
post.PendingBody = ""
|
||||
post.Status = model.PostStatusApproved
|
||||
post.RejectReason = ""
|
||||
return s.repo.Update(post)
|
||||
if err := s.repo.Update(post); err != nil {
|
||||
return err
|
||||
}
|
||||
// 通知作者修订审核通过
|
||||
if s.notifier != nil {
|
||||
s.notifier.NotifyPostApproved(post.UserID, post.Title, post.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 首次审核通过
|
||||
@ -281,7 +292,14 @@ func (s *PostService) Approve(postID uint) error {
|
||||
}
|
||||
post.Status = model.PostStatusApproved
|
||||
post.RejectReason = ""
|
||||
return s.repo.Update(post)
|
||||
if err := s.repo.Update(post); err != nil {
|
||||
return err
|
||||
}
|
||||
// 通知作者审核通过
|
||||
if s.notifier != nil {
|
||||
s.notifier.NotifyPostApproved(post.UserID, post.Title, post.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Reject 退回:pending/approved → rejected;修订退回则清空 Pending 保持 approved
|
||||
@ -299,13 +317,27 @@ func (s *PostService) Reject(postID uint, reason string) error {
|
||||
post.PendingTitle = ""
|
||||
post.PendingBody = ""
|
||||
post.RejectReason = reason
|
||||
return s.repo.Update(post)
|
||||
if err := s.repo.Update(post); err != nil {
|
||||
return err
|
||||
}
|
||||
// 通知作者修订被退回
|
||||
if s.notifier != nil {
|
||||
s.notifier.NotifyPostRejected(post.UserID, post.Title, reason, post.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 普通退回(首次审核)
|
||||
post.Status = model.PostStatusRejected
|
||||
post.RejectReason = reason
|
||||
return s.repo.Update(post)
|
||||
if err := s.repo.Update(post); err != nil {
|
||||
return err
|
||||
}
|
||||
// 通知作者审核被退回
|
||||
if s.notifier != nil {
|
||||
s.notifier.NotifyPostRejected(post.UserID, post.Title, reason, post.ID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lock 锁定:设置 IsLocked 标志,禁止编辑,不改变帖子发布状态
|
||||
|
||||
@ -53,4 +53,10 @@ type spaceUserStore interface {
|
||||
// spacePostStore SpaceService 所需的最小帖子仓储接口(ISP:1 个方法)
|
||||
type spacePostStore interface {
|
||||
FindByUserID(userID uint, offset, limit int) ([]model.Post, int64, error)
|
||||
}
|
||||
|
||||
// postNotifier PostService 所需的通知服务接口(ISP:2 个方法)
|
||||
type postNotifier interface {
|
||||
NotifyPostApproved(userID uint, postTitle string, postID uint)
|
||||
NotifyPostRejected(userID uint, postTitle, reason string, postID uint)
|
||||
}
|
||||
Reference in New Issue
Block a user