response.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package handler
  2. import (
  3. "net/http"
  4. "github.com/gin-gonic/gin"
  5. )
  6. // Response is the unified response structure.
  7. type Response struct {
  8. Code int `json:"code"`
  9. Message string `json:"message"`
  10. Data interface{} `json:"data"`
  11. }
  12. // PageResponse wraps paginated results.
  13. type PageResponse struct {
  14. Items interface{} `json:"items"`
  15. Total int64 `json:"total"`
  16. Page int `json:"page"`
  17. PageSize int `json:"page_size"`
  18. }
  19. // OK sends a 200 response with data.
  20. func OK(c *gin.Context, data interface{}) {
  21. c.JSON(http.StatusOK, Response{
  22. Code: 0,
  23. Message: "ok",
  24. Data: data,
  25. })
  26. }
  27. // Fail sends an error response.
  28. func Fail(c *gin.Context, code int, msg string) {
  29. httpStatus := http.StatusBadRequest
  30. switch code {
  31. case 401:
  32. httpStatus = http.StatusUnauthorized
  33. case 403:
  34. httpStatus = http.StatusForbidden
  35. case 404:
  36. httpStatus = http.StatusNotFound
  37. case 409:
  38. httpStatus = http.StatusConflict
  39. case 429:
  40. httpStatus = http.StatusTooManyRequests
  41. case 500:
  42. httpStatus = http.StatusInternalServerError
  43. case 501:
  44. httpStatus = http.StatusNotImplemented
  45. }
  46. c.JSON(httpStatus, Response{
  47. Code: code,
  48. Message: msg,
  49. Data: nil,
  50. })
  51. }
  52. // PageOK sends a paginated 200 response.
  53. func PageOK(c *gin.Context, items interface{}, total int64, page, pageSize int) {
  54. c.JSON(http.StatusOK, Response{
  55. Code: 0,
  56. Message: "ok",
  57. Data: PageResponse{
  58. Items: items,
  59. Total: total,
  60. Page: page,
  61. PageSize: pageSize,
  62. },
  63. })
  64. }
  65. // parsePage extracts page and page_size from query params.
  66. // page defaults to 1, page_size defaults to 20, capped at 100.
  67. func parsePage(c *gin.Context) (page int, pageSize int, offset int) {
  68. page = 1
  69. pageSize = 20
  70. if p := c.Query("page"); p != "" {
  71. if v := parseInt(p, 1); v > 0 {
  72. page = v
  73. }
  74. }
  75. if ps := c.Query("page_size"); ps != "" {
  76. if v := parseInt(ps, 20); v > 0 {
  77. pageSize = v
  78. }
  79. }
  80. if pageSize > 100 {
  81. pageSize = 100
  82. }
  83. offset = (page - 1) * pageSize
  84. return
  85. }
  86. func parseInt(s string, def int) int {
  87. result := 0
  88. for _, ch := range s {
  89. if ch < '0' || ch > '9' {
  90. return def
  91. }
  92. result = result*10 + int(ch-'0')
  93. }
  94. if s == "" {
  95. return def
  96. }
  97. return result
  98. }