package handler import ( "net/http" "github.com/gin-gonic/gin" ) // Response is the unified response structure. type Response struct { Code int `json:"code"` Message string `json:"message"` Data interface{} `json:"data"` } // PageResponse wraps paginated results. type PageResponse struct { Items interface{} `json:"items"` Total int64 `json:"total"` Page int `json:"page"` PageSize int `json:"page_size"` } // OK sends a 200 response with data. func OK(c *gin.Context, data interface{}) { c.JSON(http.StatusOK, Response{ Code: 0, Message: "ok", Data: data, }) } // Fail sends an error response. func Fail(c *gin.Context, code int, msg string) { httpStatus := http.StatusBadRequest switch code { case 401: httpStatus = http.StatusUnauthorized case 403: httpStatus = http.StatusForbidden case 404: httpStatus = http.StatusNotFound case 409: httpStatus = http.StatusConflict case 429: httpStatus = http.StatusTooManyRequests case 500: httpStatus = http.StatusInternalServerError case 501: httpStatus = http.StatusNotImplemented } c.JSON(httpStatus, Response{ Code: code, Message: msg, Data: nil, }) } // PageOK sends a paginated 200 response. func PageOK(c *gin.Context, items interface{}, total int64, page, pageSize int) { c.JSON(http.StatusOK, Response{ Code: 0, Message: "ok", Data: PageResponse{ Items: items, Total: total, Page: page, PageSize: pageSize, }, }) } // parsePage extracts page and page_size from query params. // page defaults to 1, page_size defaults to 20, capped at 100. func parsePage(c *gin.Context) (page int, pageSize int, offset int) { page = 1 pageSize = 20 if p := c.Query("page"); p != "" { if v := parseInt(p, 1); v > 0 { page = v } } if ps := c.Query("page_size"); ps != "" { if v := parseInt(ps, 20); v > 0 { pageSize = v } } if pageSize > 100 { pageSize = 100 } offset = (page - 1) * pageSize return } func parseInt(s string, def int) int { result := 0 for _, ch := range s { if ch < '0' || ch > '9' { return def } result = result*10 + int(ch-'0') } if s == "" { return def } return result }