- 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.
131 lines
3.5 KiB
Go
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})
|
|
}
|