Files
Mycontent/soul-api/internal/handler/admin_super_articles.go
乘风 01f9e216da feat: enhance super article features and UI updates
- Integrated AI writing capabilities in the super article editor, allowing users to upload multiple reference files and generate drafts using prompts.
- Updated the reading page to unify the display of book chapters and super articles, improving user navigation and experience.
- Enhanced the "My" page with new UI elements, including gradient icons and improved layout for better visual appeal.
- Added backend support for new article management endpoints, ensuring seamless integration with the front end.

This update aims to streamline the article creation process and enhance the overall user interface across the application.
2026-05-11 15:43:10 +08:00

131 lines
3.5 KiB
Go

package handler
import (
"net/http"
"strconv"
"strings"
"soul-api/internal/database"
"soul-api/internal/model"
"github.com/gin-gonic/gin"
)
// AdminSuperArticlesList GET /api/admin/super-articles?status=pending|approved|rejected|all&page=&pageSize=
func AdminSuperArticlesList(c *gin.Context) {
status := strings.TrimSpace(strings.ToLower(c.Query("status")))
if status == "" {
status = "pending"
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "20"))
if page < 1 {
page = 1
}
if pageSize < 1 || pageSize > 100 {
pageSize = 20
}
db := database.DB()
q := db.Model(&model.SuperArticle{})
if status != "all" {
q = q.Where("audit_status = ?", status)
}
var total int64
if err := q.Count(&total).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
var rows []model.SuperArticle
if err := q.Order("updated_at DESC").
Offset((page - 1) * pageSize).
Limit(pageSize).
Find(&rows).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
idSet := map[string]bool{}
var uids []string
for _, r := range rows {
u := strings.TrimSpace(r.UserID)
if u == "" || idSet[u] {
continue
}
idSet[u] = true
uids = append(uids, u)
}
authorMap := loadSuperArticleAuthorMap(uids)
list := make([]gin.H, 0, len(rows))
for _, r := range rows {
a := authorMap[strings.TrimSpace(r.UserID)]
an, aa := resolveSuperArticleAuthorDisplay(a)
list = append(list, gin.H{
"id": r.ID,
"userId": r.UserID,
"title": r.Title,
"content": r.Content,
"images": parseSuperArticleImagesJSON(r.Images),
"auditStatus": strings.TrimSpace(r.AuditStatus),
"rejectReason": strings.TrimSpace(r.RejectReason),
"authorNickname": an,
"authorAvatar": aa,
"createdAt": r.CreatedAt,
"updatedAt": r.UpdatedAt,
})
}
c.JSON(http.StatusOK, gin.H{
"success": true,
"list": list,
"total": total,
"page": page,
"pageSize": pageSize,
})
}
// AdminSuperArticleReview PUT /api/admin/super-articles/:id/review
// body: { "action": "approve" | "reject", "rejectReason": "..." }
func AdminSuperArticleReview(c *gin.Context) {
idRaw := strings.TrimSpace(c.Param("id"))
id, err := strconv.ParseUint(idRaw, 10, 64)
if err != nil || id == 0 {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "参数错误"})
return
}
var req struct {
Action string `json:"action"`
RejectReason string `json:"rejectReason"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "参数错误"})
return
}
act := strings.TrimSpace(strings.ToLower(req.Action))
if act != "approve" && act != "reject" {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "action 须为 approve 或 reject"})
return
}
db := database.DB()
var row model.SuperArticle
if err := db.First(&row, id).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": "记录不存在"})
return
}
if act == "approve" {
row.AuditStatus = model.SuperArticleAuditApproved
row.RejectReason = ""
} else {
row.AuditStatus = model.SuperArticleAuditRejected
row.RejectReason = strings.TrimSpace(req.RejectReason)
if row.RejectReason == "" {
row.RejectReason = "未填写原因"
}
}
if err := db.Save(&row).Error; err != nil {
c.JSON(http.StatusOK, gin.H{"success": false, "error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"success": true})
}