- Post ScheduledAt 字段 - Scheduler goroutine 每分钟扫描到期文章 - Create/Update 校验最短 30min 定时 - Approve 审核晚于定时则即时发布 - public 列表+空间页过滤未到期文章 - 写文章页 datetime-local 选择器(min=now+30min) - AutoMigrate 追加新表
93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package controller
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"metazone.cc/mce/internal/common"
|
||
"metazone.cc/mce/internal/model"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// Create 创建/发布帖子
|
||
func (ctrl *StudioController) Create(c *gin.Context) {
|
||
uid, _, ok := common.GetGinUser(c)
|
||
if !ok {
|
||
common.Error(c, http.StatusUnauthorized, "请先登录")
|
||
return
|
||
}
|
||
|
||
// LV0 用户不允许投稿
|
||
if !ctrl.postService.CanCreatePost(uid) {
|
||
common.Error(c, http.StatusForbidden, "经验不足,Lv1 解锁投稿")
|
||
return
|
||
}
|
||
|
||
var req model.PostCreateRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
common.Error(c, http.StatusBadRequest, "标题和正文不能为空")
|
||
return
|
||
}
|
||
|
||
post, err := ctrl.postService.Create(uid, req.Title, req.Body, req.Visibility, req.PostType, req.ReprintSource, req.Declaration, req.ReprintProhibited, req.CategoryID, req.ScheduledAt)
|
||
if err != nil {
|
||
if err == common.ErrScheduledTooSoon {
|
||
common.Error(c, http.StatusBadRequest, err.Error())
|
||
return
|
||
}
|
||
common.Error(c, http.StatusInternalServerError, "发布失败")
|
||
return
|
||
}
|
||
|
||
// 关联标签
|
||
if ctrl.tagSvc != nil && req.Tags != "" {
|
||
_ = ctrl.tagSvc.SetPostTags(post.ID, req.Tags)
|
||
}
|
||
|
||
common.OkWithMessage(c, post, "发布成功")
|
||
}
|
||
|
||
// Update 编辑帖子
|
||
func (ctrl *StudioController) Update(c *gin.Context) {
|
||
uid, role, ok := common.GetGinUser(c)
|
||
if !ok {
|
||
common.Error(c, http.StatusUnauthorized, "请先登录")
|
||
return
|
||
}
|
||
|
||
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||
if err != nil {
|
||
common.Error(c, http.StatusBadRequest, "无效的帖子 ID")
|
||
return
|
||
}
|
||
|
||
var req model.PostUpdateRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
common.Error(c, http.StatusBadRequest, "标题和正文不能为空")
|
||
return
|
||
}
|
||
|
||
post, getErr := ctrl.postService.GetByID(uint(id))
|
||
if getErr != nil {
|
||
common.Error(c, http.StatusNotFound, "帖子不存在")
|
||
return
|
||
}
|
||
if !ctrl.postService.IsPostAccessible(uid, role, post.UserID) {
|
||
common.Error(c, http.StatusForbidden, "无权操作此帖子")
|
||
return
|
||
}
|
||
|
||
if err := ctrl.postService.Update(uint(id), req.Title, req.Body, req.Visibility, req.PostType, req.ReprintSource, req.Declaration, req.ReprintProhibited, req.CategoryID, req.ScheduledAt); err != nil {
|
||
common.Error(c, http.StatusInternalServerError, "编辑失败")
|
||
return
|
||
}
|
||
|
||
// 更新标签
|
||
if ctrl.tagSvc != nil {
|
||
_ = ctrl.tagSvc.SetPostTags(uint(id), req.Tags)
|
||
}
|
||
|
||
common.OkMessage(c, "编辑成功")
|
||
}
|