feat: 定时发布系统 — Phase 5 完成

- Post ScheduledAt 字段
- Scheduler goroutine 每分钟扫描到期文章
- Create/Update 校验最短 30min 定时
- Approve 审核晚于定时则即时发布
- public 列表+空间页过滤未到期文章
- 写文章页 datetime-local 选择器(min=now+30min)
- AutoMigrate 追加新表
This commit is contained in:
2026-06-22 00:39:04 +08:00
parent 0b8f6f890d
commit e9b7401dc9
14 changed files with 132 additions and 15 deletions

View File

@ -2,13 +2,14 @@ package service
import (
"strconv"
"time"
"metazone.cc/mce/internal/common"
"metazone.cc/mce/internal/model"
)
// Update 编辑帖子(权限在 controller 层检查)
func (s *PostService) Update(postID uint, title, body string, visibility, postType, reprintSource, declaration string, reprintProhibited bool, categoryID string) error {
func (s *PostService) Update(postID uint, title, body string, visibility, postType, reprintSource, declaration string, reprintProhibited bool, categoryID, scheduledAt string) error {
post, err := s.findPost(postID)
if err != nil {
return err
@ -31,6 +32,13 @@ func (s *PostService) Update(postID uint, title, body string, visibility, postTy
} else {
post.CategoryID = nil
}
// 定时发布
if t, err := parseScheduledAt(scheduledAt); err == nil {
if time.Until(t) < 30*time.Minute {
return common.ErrScheduledTooSoon
}
post.ScheduledAt = &t
}
// 已通过帖子:编辑内容保存为待审修订,不影响当前展示
if post.Status == model.PostStatusApproved {
@ -121,6 +129,10 @@ func (s *PostService) Approve(postID uint) error {
}
post.Status = model.PostStatusApproved
post.RejectReason = ""
// 审核晚于定时时间 → 即时发布
if post.ScheduledAt != nil && !post.ScheduledAt.After(time.Now()) {
post.ScheduledAt = nil
}
if err := s.repo.Update(post); err != nil {
return err
}