package controllers import ( "net/http" "strconv" "strings" "time" "NetworkAuth/database" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // ============================================================================ // 结构体定义 // ============================================================================ // BaseController 基础控制器结构体 // 提供通用的数据库访问和响应处理方法 type BaseController struct{} // ============================================================================ // 构造函数 // ============================================================================ // NewBaseController 创建基础控制器实例 func NewBaseController() *BaseController { return &BaseController{} } // ============================================================================ // 数据库相关方法 // ============================================================================ // GetDB 获取数据库连接,统一错误处理 func (bc *BaseController) GetDB(c *gin.Context) (*gorm.DB, bool) { db, err := database.GetDB() if err != nil { bc.HandleDatabaseError(c, err) return nil, false } return db, true } // ============================================================================ // 错误处理方法 // ============================================================================ // HandleDatabaseError 统一处理数据库连接错误 func (bc *BaseController) HandleDatabaseError(c *gin.Context, err error) { c.JSON(http.StatusInternalServerError, gin.H{ "code": 1, "msg": "数据库连接失败", "data": nil, }) } // HandleValidationError 统一处理验证错误 func (bc *BaseController) HandleValidationError(c *gin.Context, message string) { c.JSON(http.StatusBadRequest, gin.H{ "code": 1, "msg": message, "data": nil, }) } // HandleNotFoundError 统一处理资源未找到错误 func (bc *BaseController) HandleNotFoundError(c *gin.Context, resource string) { c.JSON(http.StatusNotFound, gin.H{ "code": 1, "msg": resource + "不存在", "data": nil, }) } // HandleInternalError 统一处理内部服务器错误 func (bc *BaseController) HandleInternalError(c *gin.Context, message string, err error) { c.JSON(http.StatusInternalServerError, gin.H{ "code": 1, "msg": message, "data": nil, }) } // ============================================================================ // 成功响应方法 // ============================================================================ // HandleSuccess 统一处理成功响应 func (bc *BaseController) HandleSuccess(c *gin.Context, message string, data interface{}) { resp := gin.H{ "code": 0, "msg": message, "data": data, } // 检查是否有刷新的Token if newToken, exists := c.Get("new_token"); exists { resp["token"] = newToken } c.JSON(http.StatusOK, resp) } // HandleCreated 统一处理创建成功响应 func (bc *BaseController) HandleCreated(c *gin.Context, message string, data interface{}) { c.JSON(http.StatusCreated, gin.H{ "code": 0, "msg": message, "data": data, }) } // ============================================================================ // 辅助方法 // ============================================================================ // ValidateRequired 验证必填字段 func (bc *BaseController) ValidateRequired(c *gin.Context, fields map[string]interface{}) bool { for fieldName, fieldValue := range fields { if fieldValue == nil || fieldValue == "" { bc.HandleValidationError(c, fieldName+"不能为空") return false } } return true } // GetPaginationParams 获取分页参数 func (bc *BaseController) GetPaginationParams(c *gin.Context) (int, int) { page := 1 limit := 10 if p := c.Query("page"); p != "" { if pageInt, err := strconv.Atoi(p); err == nil && pageInt > 0 { page = pageInt } } // 兼容 layui 的 limit 和 其他的 page_size if l := c.Query("limit"); l != "" { if limitInt, err := strconv.Atoi(l); err == nil && limitInt > 0 { limit = limitInt } } else if ps := c.Query("page_size"); ps != "" { if pageSizeInt, err := strconv.Atoi(ps); err == nil && pageSizeInt > 0 { limit = pageSizeInt } } return page, limit } // CalculateOffset 计算数据库查询偏移量 func (bc *BaseController) CalculateOffset(page, pageSize int) int { return (page - 1) * pageSize } // ApplyTimeRangeQuery 应用通用时间范围查询 func (bc *BaseController) ApplyTimeRangeQuery(c *gin.Context, query *gorm.DB, field string) *gorm.DB { // 获取可能的时间参数名 startTimes := []string{"start_time", "login_start_time", "operation_start_time"} endTimes := []string{"end_time", "login_end_time", "operation_end_time"} var startTimeStr, endTimeStr string for _, k := range startTimes { if v := strings.TrimSpace(c.Query(k)); v != "" { startTimeStr = v break } } for _, k := range endTimes { if v := strings.TrimSpace(c.Query(k)); v != "" { endTimeStr = v break } } if startTimeStr != "" { if t, err := time.ParseInLocation("2006-01-02", startTimeStr, time.Local); err == nil { query = query.Where(field+" >= ?", t) } else if t, err := time.ParseInLocation("2006-01-02 15:04:05", startTimeStr, time.Local); err == nil { query = query.Where(field+" >= ?", t) } else { query = query.Where(field+" >= ?", startTimeStr) } } if endTimeStr != "" { if t, err := time.ParseInLocation("2006-01-02", endTimeStr, time.Local); err == nil { t = t.Add(24*time.Hour - time.Nanosecond) query = query.Where(field+" <= ?", t) } else if t, err := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local); err == nil { query = query.Where(field+" <= ?", t) } else { if len(endTimeStr) == 10 { // yyyy-MM-dd endTimeStr += " 23:59:59" } query = query.Where(field+" <= ?", endTimeStr) } } return query } // BindJSON 绑定JSON数据并处理错误 func (bc *BaseController) BindJSON(c *gin.Context, obj interface{}) bool { if err := c.ShouldBindJSON(obj); err != nil { bc.HandleValidationError(c, "请求参数错误: "+err.Error()) return false } return true } // BindQuery 绑定查询参数并处理错误 func (bc *BaseController) BindQuery(c *gin.Context, obj interface{}) bool { if err := c.ShouldBindQuery(obj); err != nil { bc.HandleValidationError(c, "查询参数错误: "+err.Error()) return false } return true } // BindURI 绑定URI参数并处理错误 func (bc *BaseController) BindURI(c *gin.Context, obj interface{}) bool { if err := c.ShouldBindUri(obj); err != nil { bc.HandleValidationError(c, "URI参数绑定失败: "+err.Error()) return false } return true } // GetDefaultTemplateData 获取默认模板数据 // 返回包含系统基础信息的数据映射,包括站点标题、页脚文本、备案信息等 func (bc *BaseController) GetDefaultTemplateData() gin.H { return gin.H{ "Title": "NetworkAuth", "SystemName": "NetworkAuth", "FooterText": "© 2026 NetworkAuth 保留所有权利", "ICPRecord": "", "ICPRecordLink": "https://beian.miit.gov.cn", "PSBRecord": "", "PSBRecordLink": "https://www.beian.gov.cn", } }