response.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Package response 响应处理工具
  2. package response
  3. import (
  4. "errors"
  5. "net/http"
  6. "github.com/gin-gonic/gin"
  7. "gorm.io/gorm"
  8. "github.com/runningwater/gohub/pkg/logger"
  9. )
  10. // JSON 响应 200 和 JSON 数据
  11. func JSON(c *gin.Context, data any) {
  12. c.JSON(http.StatusOK, data)
  13. }
  14. // Success 响应 200 和预设『操作成功!』的 JSON 数据
  15. // 执行某个『没有具体返回数据』的『变更』操作成功后调用,例如删除、修改密码、修改手机号
  16. func Success(c *gin.Context) {
  17. JSON(c, gin.H{
  18. "success": true,
  19. "message": "操作成功!",
  20. })
  21. }
  22. // Data 响应 200 和带 data 键的 JSON 数据
  23. // 执行『更新操作』成功后调用,例如更新话题,成功后返回已更新的话题
  24. func Data(c *gin.Context, data any) {
  25. JSON(c, gin.H{
  26. "success": true,
  27. "data": data,
  28. })
  29. }
  30. // Created 响应 201 和带 data 键的 JSON 数据
  31. // 执行『更新操作』成功后调用,例如更新话题,成功后返回已更新的话题
  32. func Created(c *gin.Context, data any) {
  33. c.JSON(http.StatusCreated, gin.H{
  34. "success": true,
  35. "data": data,
  36. })
  37. }
  38. // CreatedJSON 响应 201 和 JSON 数据
  39. func CreatedJSON(c *gin.Context, data any) {
  40. c.JSON(http.StatusCreated, data)
  41. }
  42. // Abort404 响应 404,未传参 msg 时使用默认消息
  43. func Abort404(c *gin.Context, msg ...string) {
  44. c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
  45. "message": defaultMessage("数据不存在,请确定请求正确", msg...),
  46. })
  47. }
  48. // Abort403 响应 403,未传参 msg 时使用默认消息
  49. func Abort403(c *gin.Context, msg ...string) {
  50. c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
  51. "message": defaultMessage("权限不足,请确定您有对应的权限", msg...),
  52. })
  53. }
  54. // Abort500 响应 500,未传参 msg 时使用默认消息
  55. func Abort500(c *gin.Context, msg ...string) {
  56. c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
  57. "message": defaultMessage("服务器内部错误,请稍后再试", msg...),
  58. })
  59. }
  60. // BadRequest 响应 400,传参 err 对象,未传参 msg 时使用默认消息
  61. // 在解析用户请求,请求的格式或者方法不符合预期时调用
  62. func BadRequest(c *gin.Context, err error, msg ...string) {
  63. logger.LogIf(err)
  64. c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
  65. "message": defaultMessage("请求解析错误,请确认请求格式是否正确。上传文件请使用 multipart 标头,参数请使用 JSON 格式。", msg...),
  66. "error": err.Error(),
  67. })
  68. }
  69. // Error 响应 404 或 422,未传参 msg 时使用默认消息
  70. // 处理请求时出现错误 err,会附带返回 error 信息,如登录错误、找不到 ID 对应的 Model
  71. func Error(c *gin.Context, err error, msg ...string) {
  72. logger.LogIf(err)
  73. // error 类型为『数据库未找到内容』
  74. if errors.Is(err, gorm.ErrRecordNotFound) {
  75. Abort404(c)
  76. return
  77. }
  78. c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
  79. "message": defaultMessage("请求处理失败,请查看 error 的值", msg...),
  80. "error": err.Error(),
  81. })
  82. }
  83. // ValidationError 处理表单验证不通过的错误,返回的 JSON 示例:
  84. //
  85. // {
  86. // "errors": {
  87. // "phone": [
  88. // "手机号为必填项,参数名称 phone",
  89. // "手机号长度必须为 11 位的数字"
  90. // ]
  91. // },
  92. // "message": "请求验证不通过,具体请查看 errors"
  93. // }
  94. func ValidationError(c *gin.Context, errors map[string][]string) {
  95. c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
  96. "message": "请求验证不通过,具体请查看 errors",
  97. "errors": errors,
  98. })
  99. }
  100. // Unauthorized 响应 401,未传参 msg 时使用默认消息
  101. // 登录失败、jwt 解析失败时调用
  102. func Unauthorized(c *gin.Context, msg ...string) {
  103. c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
  104. "message": defaultMessage("请求解析错误,请确认请求格式是否正确。上传文件请使用 multipart 标头,参数请使用 JSON 格式。", msg...),
  105. })
  106. }
  107. // defaultMessage 内用的辅助函数,用以支持默认参数默认值
  108. // Go 不支持参数默认值,只能使用多变参数来实现类似效果
  109. func defaultMessage(defaultMsg string, msg ...string) (message string) {
  110. if len(msg) > 0 {
  111. message = msg[0]
  112. } else {
  113. message = defaultMsg
  114. }
  115. return
  116. }