Files
backend/internal/handler/admin_profile_audit_handler.go

130 lines
3.6 KiB
Go
Raw Normal View History

package handler
import (
"strconv"
"carrot_bbs/internal/model"
"carrot_bbs/internal/pkg/response"
"carrot_bbs/internal/service"
"github.com/gin-gonic/gin"
)
type AdminProfileAuditHandler struct {
profileAuditService service.UserProfileAuditService
}
func NewAdminProfileAuditHandler(profileAuditService service.UserProfileAuditService) *AdminProfileAuditHandler {
return &AdminProfileAuditHandler{
profileAuditService: profileAuditService,
}
}
func (h *AdminProfileAuditHandler) GetPendingList(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
if page <= 0 {
page = 1
}
if pageSize <= 0 || pageSize > 100 {
pageSize = 20
}
contentType := c.Query("content_type")
var ct model.UserProfileContentType
switch contentType {
case "avatar":
ct = model.UserProfileContentTypeAvatar
case "cover":
ct = model.UserProfileContentTypeCover
case "bio":
ct = model.UserProfileContentTypeBio
default:
ct = ""
}
audits, total, err := h.profileAuditService.GetPendingList(c.Request.Context(), ct, page, pageSize)
if err != nil {
response.InternalServerError(c, "failed to get pending profile audits")
return
}
items := make([]map[string]any, 0, len(audits))
for _, audit := range audits {
item := map[string]any{
"id": audit.ID,
"user_id": audit.UserID,
"content_type": audit.ContentType,
"content": audit.Content,
"status": audit.Status,
"created_at": audit.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
}
if audit.User != nil {
item["user"] = map[string]any{
"id": audit.User.ID,
"username": audit.User.Username,
"nickname": audit.User.Nickname,
"avatar": audit.User.Avatar,
}
}
items = append(items, item)
}
response.Paginated(c, items, total, page, pageSize)
}
func (h *AdminProfileAuditHandler) ModerateAudit(c *gin.Context) {
auditID := c.Param("id")
if auditID == "" {
response.BadRequest(c, "audit id is required")
return
}
var req struct {
Status string `json:"status" binding:"required"`
Reason string `json:"reason"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, err.Error())
return
}
if req.Status != string(model.UserProfileAuditStatusApproved) && req.Status != string(model.UserProfileAuditStatusRejected) {
response.BadRequest(c, "invalid status, must be 'approved' or 'rejected'")
return
}
reviewedBy := c.GetString("user_id")
if err := h.profileAuditService.ModerateAudit(c.Request.Context(), auditID, model.UserProfileAuditStatus(req.Status), req.Reason, reviewedBy); err != nil {
response.HandleError(c, err, "failed to moderate profile audit")
return
}
response.Success(c, map[string]any{"success": true})
}
func (h *AdminProfileAuditHandler) BatchModerate(c *gin.Context) {
var req struct {
IDs []string `json:"ids" binding:"required"`
Status string `json:"status" binding:"required"`
Reason string `json:"reason"`
}
if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, err.Error())
return
}
if req.Status != string(model.UserProfileAuditStatusApproved) && req.Status != string(model.UserProfileAuditStatusRejected) {
response.BadRequest(c, "invalid status, must be 'approved' or 'rejected'")
return
}
reviewedBy := c.GetString("user_id")
if err := h.profileAuditService.BatchModerateAudits(c.Request.Context(), req.IDs, model.UserProfileAuditStatus(req.Status), req.Reason, reviewedBy); err != nil {
response.InternalServerError(c, "failed to batch moderate profile audits")
return
}
response.Success(c, map[string]any{"success": true})
}