feat(moderation): add user profile content moderation for avatars, covers, and bios
All checks were successful
Build Backend / build (push) Successful in 4m24s
Build Backend / build-docker (push) Successful in 1m14s

This commit is contained in:
lafay
2026-04-15 11:50:47 +08:00
parent b6f2df87c4
commit 90495385cd
23 changed files with 1561 additions and 55 deletions

View File

@@ -32,13 +32,13 @@ func normalizePagination(page, pageSize int) (int, int) {
// UserHandler 用户处理器
type UserHandler struct {
userService service.UserService
activityService service.UserActivityService // 用户活跃统计服务
jwtService *service.JWTService
logService *service.LogService
userService service.UserService
activityService service.UserActivityService
profileAuditService service.UserProfileAuditService
jwtService *service.JWTService
logService *service.LogService
}
// NewUserHandler 创建用户处理器
func NewUserHandler(userService service.UserService, activityService service.UserActivityService, logService *service.LogService) *UserHandler {
return &UserHandler{
userService: userService,
@@ -47,6 +47,10 @@ func NewUserHandler(userService service.UserService, activityService service.Use
}
}
func (h *UserHandler) SetProfileAuditService(profileAuditService service.UserProfileAuditService) {
h.profileAuditService = profileAuditService
}
// SetJWTService 设置JWT服务
func (h *UserHandler) SetJWTService(jwtService *service.JWTService) {
h.jwtService = jwtService
@@ -318,6 +322,7 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
Website string `json:"website"`
Location string `json:"location"`
Avatar string `json:"avatar"`
CoverURL string `json:"cover_url"`
Phone *string `json:"phone"`
Email *string `json:"email"`
}
@@ -337,18 +342,12 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
if req.Nickname != "" {
user.Nickname = req.Nickname
}
if req.Bio != "" {
user.Bio = req.Bio
}
if req.Website != "" {
user.Website = req.Website
}
if req.Location != "" {
user.Location = req.Location
}
if req.Avatar != "" {
user.Avatar = req.Avatar
}
if req.Phone != nil {
user.Phone = req.Phone
}
@@ -359,20 +358,53 @@ func (h *UserHandler) UpdateUser(c *gin.Context) {
user.Email = req.Email
}
avatarNeedsAudit := req.Avatar != "" && req.Avatar != user.Avatar && h.profileAuditService != nil
coverNeedsAudit := req.CoverURL != "" && req.CoverURL != user.CoverURL && h.profileAuditService != nil
bioNeedsAudit := req.Bio != "" && req.Bio != user.Bio && h.profileAuditService != nil
if avatarNeedsAudit {
if _, err := h.profileAuditService.SubmitAvatarAudit(c.Request.Context(), userID, req.Avatar); err != nil {
avatarNeedsAudit = false
user.Avatar = req.Avatar
}
} else if req.Avatar != "" {
user.Avatar = req.Avatar
}
if coverNeedsAudit {
if _, err := h.profileAuditService.SubmitCoverAudit(c.Request.Context(), userID, req.CoverURL); err != nil {
coverNeedsAudit = false
user.CoverURL = req.CoverURL
}
} else if req.CoverURL != "" {
user.CoverURL = req.CoverURL
}
if bioNeedsAudit {
if _, err := h.profileAuditService.SubmitBioAudit(c.Request.Context(), userID, req.Bio); err != nil {
bioNeedsAudit = false
user.Bio = req.Bio
}
} else if req.Bio != "" {
user.Bio = req.Bio
}
err = h.userService.UpdateUser(c.Request.Context(), user)
if err != nil {
response.InternalServerError(c, "failed to update user")
return
}
// 实时计算帖子数量
postsCount, err := h.userService.GetUserPostCount(c.Request.Context(), userID)
if err != nil {
// 如果获取失败,使用数据库中的值
postsCount = int64(user.PostsCount)
}
response.Success(c, dto.ConvertUserToDetailResponseWithPostsCount(user, int(postsCount)))
resp := gin.H{"user": dto.ConvertUserToDetailResponseWithPostsCount(user, int(postsCount))}
if avatarNeedsAudit || coverNeedsAudit || bioNeedsAudit {
resp["audit_pending"] = true
}
response.Success(c, resp)
}
// SendEmailVerifyCode 发送当前用户邮箱验证码