Files
starter/internal/handler/helper.go
limitcool b7628c770b Refactor user handler and middleware for improved error handling and logging
- Consolidated user ID retrieval and permission checks into helper functions.
- Updated UserHandler to utilize BaseHandler for common database and configuration access.
- Enhanced logging for user-related operations, including login, registration, and password changes.
- Removed redundant context handling in middleware and improved readability.
- Introduced FileUtil for file URL generation and management, encapsulating file-related logic.
- Refactored FileRepo and UserRepo to streamline database operations and error handling.
- Deleted unused request_id middleware and integrated its functionality into request_logger.
- Removed legacy test runner script to simplify testing process.
2025-06-17 23:09:02 +08:00

158 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handler
import (
"github.com/gin-gonic/gin"
"github.com/limitcool/starter/internal/api/response"
"github.com/limitcool/starter/internal/pkg/errorx"
"github.com/limitcool/starter/internal/pkg/logger"
"github.com/spf13/cast"
)
// HandlerHelper 处理器辅助工具
type HandlerHelper struct{}
// NewHandlerHelper 创建处理器辅助工具
func NewHandlerHelper() *HandlerHelper {
return &HandlerHelper{}
}
// GetUserID 从上下文中获取用户ID如果不存在则返回错误响应
func (h *HandlerHelper) GetUserID(ctx *gin.Context) (int64, bool) {
reqCtx := ctx.Request.Context()
userID, exists := ctx.Get("user_id")
if !exists {
logger.WarnContext(reqCtx, "用户ID不存在")
response.Error(ctx, errorx.ErrUserNoLogin)
return 0, false
}
return cast.ToInt64(userID), true
}
// BindJSON 绑定JSON参数如果失败则返回错误响应
func (h *HandlerHelper) BindJSON(ctx *gin.Context, req interface{}, operation string) bool {
reqCtx := ctx.Request.Context()
if err := ctx.ShouldBindJSON(req); err != nil {
logger.WarnContext(reqCtx, operation+" request validation failed",
"error", err,
"client_ip", ctx.ClientIP())
response.Error(ctx, errorx.ErrInvalidParams.WithError(err))
return false
}
return true
}
// HandleDBError 处理数据库错误,统一日志记录和错误响应
func (h *HandlerHelper) HandleDBError(ctx *gin.Context, err error, operation string, fields ...interface{}) {
reqCtx := ctx.Request.Context()
// 构建日志字段
logFields := []interface{}{
"error", err,
"operation", operation,
}
logFields = append(logFields, fields...)
logger.ErrorContext(reqCtx, operation+" database operation failed", logFields...)
response.Error(ctx, err)
}
// HandleNotFoundError 处理资源不存在错误
func (h *HandlerHelper) HandleNotFoundError(ctx *gin.Context, err error, operation string, fields ...interface{}) {
reqCtx := ctx.Request.Context()
// 构建日志字段
logFields := []interface{}{
"operation", operation,
}
logFields = append(logFields, fields...)
logger.WarnContext(reqCtx, operation+" resource not found", logFields...)
response.Error(ctx, err)
}
// LogSuccess 记录成功操作日志
func (h *HandlerHelper) LogSuccess(ctx *gin.Context, operation string, fields ...interface{}) {
reqCtx := ctx.Request.Context()
// 构建日志字段
logFields := []interface{}{
"operation", operation,
}
logFields = append(logFields, fields...)
logger.InfoContext(reqCtx, operation+" successful", logFields...)
}
// LogWarning 记录警告日志
func (h *HandlerHelper) LogWarning(ctx *gin.Context, message string, fields ...interface{}) {
reqCtx := ctx.Request.Context()
logger.WarnContext(reqCtx, message, fields...)
}
// LogError 记录错误日志
func (h *HandlerHelper) LogError(ctx *gin.Context, message string, fields ...interface{}) {
reqCtx := ctx.Request.Context()
logger.ErrorContext(reqCtx, message, fields...)
}
// CheckPermission 检查用户权限(是否为管理员或资源所有者)
func (h *HandlerHelper) CheckPermission(ctx *gin.Context, userID int64, resourceOwnerID int64, operation string) bool {
reqCtx := ctx.Request.Context()
// 如果是资源所有者,直接允许
if userID == resourceOwnerID {
return true
}
// 检查是否是管理员
isAdmin, exists := ctx.Get("is_admin")
if exists && cast.ToBool(isAdmin) {
return true
}
// 权限不足
logger.WarnContext(reqCtx, operation+" permission denied",
"user_id", userID,
"resource_owner_id", resourceOwnerID,
"is_admin", isAdmin)
response.Error(ctx, errorx.ErrForbidden.WithMsg("无权限操作此资源"))
return false
}
// GetClientInfo 获取客户端信息
func (h *HandlerHelper) GetClientInfo(ctx *gin.Context) (string, string) {
return ctx.ClientIP(), ctx.Request.UserAgent()
}
// ValidateID 验证ID参数
func (h *HandlerHelper) ValidateID(ctx *gin.Context, idStr string, operation string) (uint, bool) {
reqCtx := ctx.Request.Context()
id := cast.ToUint(idStr)
if id == 0 {
logger.WarnContext(reqCtx, operation+" invalid ID", "id", idStr)
response.Error(ctx, errorx.ErrInvalidParams.WithMsg("ID无效"))
return 0, false
}
return id, true
}
// ValidateInt64ID 验证int64类型的ID参数
func (h *HandlerHelper) ValidateInt64ID(ctx *gin.Context, idStr string, operation string) (int64, bool) {
reqCtx := ctx.Request.Context()
id := cast.ToInt64(idStr)
if id == 0 {
logger.WarnContext(reqCtx, operation+" invalid ID", "id", idStr)
response.Error(ctx, errorx.ErrInvalidParams.WithMsg("ID无效"))
return 0, false
}
return id, true
}