fix: 修复帖子提交审核权限缺失 + 防重复提交 + 分页逻辑复用
- 修复 Submit API 缺少 uid 权限检查,任意登录用户可提交他人帖子审核 - 前端 handleSubmit 添加 submitting 锁和按钮禁用/恢复,防止重复提交 - 分页计算 TotalPages/PrevPage/NextPage 提取为 Pagination 方法,消除三处重复代码
This commit is contained in:
@ -23,5 +23,31 @@ func (p *Pagination) Offset() int {
|
||||
return (p.Page - 1) * p.PageSize
|
||||
}
|
||||
|
||||
// TotalPages 根据 total 计算总页数
|
||||
func (p *Pagination) TotalPages(total int64) int {
|
||||
if total == 0 {
|
||||
return 0
|
||||
}
|
||||
return int((total + int64(p.PageSize) - 1) / int64(p.PageSize))
|
||||
}
|
||||
|
||||
// PrevPage 上一页(最小为 1)
|
||||
func (p *Pagination) PrevPage() int {
|
||||
prev := p.Page - 1
|
||||
if prev < 1 {
|
||||
return 1
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
// NextPage 下一页(最大为 totalPages)
|
||||
func (p *Pagination) NextPage(totalPages int) int {
|
||||
next := p.Page + 1
|
||||
if next > totalPages {
|
||||
return totalPages
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
// 固定时间格式,前后端统一
|
||||
const TimeFormat = time.RFC3339
|
||||
|
||||
@ -43,11 +43,7 @@ func (ctrl *AdminPostController) PostsPage(c *gin.Context) {
|
||||
|
||||
p := common.Pagination{Page: page, PageSize: pageSize}
|
||||
p.DefaultPagination()
|
||||
totalPages := int((total + int64(p.PageSize) - 1) / int64(p.PageSize))
|
||||
prevPage := p.Page - 1
|
||||
if prevPage < 1 { prevPage = 1 }
|
||||
nextPage := p.Page + 1
|
||||
if nextPage > totalPages { nextPage = totalPages }
|
||||
totalPages := p.TotalPages(total)
|
||||
|
||||
c.HTML(http.StatusOK, "admin/posts/index.html", common.BuildAdminPageData(c, gin.H{
|
||||
"Title": "内容管理",
|
||||
@ -55,8 +51,8 @@ func (ctrl *AdminPostController) PostsPage(c *gin.Context) {
|
||||
"Total": total,
|
||||
"Page": p.Page,
|
||||
"TotalPages": totalPages,
|
||||
"PrevPage": prevPage,
|
||||
"NextPage": nextPage,
|
||||
"PrevPage": p.PrevPage(),
|
||||
"NextPage": p.NextPage(totalPages),
|
||||
"Keyword": keyword,
|
||||
"Status": status,
|
||||
"StatusNames": model.PostStatusDisplayNames,
|
||||
|
||||
@ -49,11 +49,7 @@ func (ctrl *PostController) ListPage(c *gin.Context) {
|
||||
|
||||
p := common.Pagination{Page: page, PageSize: pageSize}
|
||||
p.DefaultPagination()
|
||||
totalPages := int((total + int64(p.PageSize) - 1) / int64(p.PageSize))
|
||||
prevPage := p.Page - 1
|
||||
if prevPage < 1 { prevPage = 1 }
|
||||
nextPage := p.Page + 1
|
||||
if nextPage > totalPages { nextPage = totalPages }
|
||||
totalPages := p.TotalPages(total)
|
||||
|
||||
c.HTML(http.StatusOK, "posts/index.html", common.BuildPageData(c, gin.H{
|
||||
"Title": "社区帖子",
|
||||
@ -61,8 +57,8 @@ func (ctrl *PostController) ListPage(c *gin.Context) {
|
||||
"Total": total,
|
||||
"Page": p.Page,
|
||||
"TotalPages": totalPages,
|
||||
"PrevPage": prevPage,
|
||||
"NextPage": nextPage,
|
||||
"PrevPage": p.PrevPage(),
|
||||
"NextPage": p.NextPage(totalPages),
|
||||
"Keyword": keyword,
|
||||
"ExtraCSS": "/static/css/posts.css",
|
||||
}))
|
||||
@ -276,12 +272,30 @@ func (ctrl *PostController) Delete(c *gin.Context) {
|
||||
|
||||
// Submit API 提交审核
|
||||
func (ctrl *PostController) Submit(c *gin.Context) {
|
||||
uidObj, _ := c.Get("uid")
|
||||
uid, ok := uidObj.(uint)
|
||||
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
|
||||
}
|
||||
|
||||
// 权限检查:仅帖子作者可提交审核
|
||||
post, err := ctrl.postService.GetByID(uint(id))
|
||||
if err != nil {
|
||||
common.Error(c, http.StatusNotFound, "帖子不存在")
|
||||
return
|
||||
}
|
||||
if post.UserID != uid {
|
||||
common.Error(c, http.StatusForbidden, "无权操作此帖子")
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctrl.postService.SubmitForAudit(uint(id)); err != nil {
|
||||
if errors.Is(err, common.ErrPostCannotSubmit) || errors.Is(err, common.ErrPostNotFound) {
|
||||
common.Error(c, http.StatusBadRequest, err.Error())
|
||||
@ -312,13 +326,12 @@ func (ctrl *PostController) ListAPI(c *gin.Context) {
|
||||
|
||||
p := common.Pagination{Page: page, PageSize: pageSize}
|
||||
p.DefaultPagination()
|
||||
totalPages := int((total + int64(p.PageSize) - 1) / int64(p.PageSize))
|
||||
|
||||
common.Ok(c, model.PostListResult{
|
||||
Items: posts,
|
||||
Total: total,
|
||||
Page: p.Page,
|
||||
TotalPages: totalPages,
|
||||
TotalPages: p.TotalPages(total),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user