package response import ( "errors" "fmt" "net/http" "github.com/gin-gonic/gin" ) const contextResponseCode = "response_code" type Body struct { Code string `json:"code"` Message string `json:"message"` Data any `json:"data,omitempty"` } func OK(c *gin.Context, data any) { c.JSON(http.StatusOK, Body{ Code: "ok", Message: "ok", Data: data, }) } func Created(c *gin.Context, data any) { c.JSON(http.StatusCreated, Body{ Code: "ok", Message: "created", Data: data, }) } func Error(c *gin.Context, status int, code, message string) { if status >= http.StatusInternalServerError && len(c.Errors) == 0 { RecordError(c, fmt.Errorf("未记录原始错误: %s", code)) } c.Set(contextResponseCode, code) c.JSON(status, Body{ Code: code, Message: message, }) } // RecordError 保存原始错误,供统一请求日志记录服务端故障原因。 func RecordError(c *gin.Context, err error) { if c == nil || err == nil { return } for _, item := range c.Errors { if errors.Is(item.Err, err) { return } } _ = c.Error(err) } // CodeFromContext 返回已经写入响应的稳定业务错误码。 func CodeFromContext(c *gin.Context) string { value, ok := c.Get(contextResponseCode) if !ok { return "" } code, _ := value.(string) return code } func BadRequest(c *gin.Context, message string) { Error(c, http.StatusBadRequest, "bad_request", message) } func Unauthorized(c *gin.Context, message string) { Error(c, http.StatusUnauthorized, "unauthorized", message) } func ServiceUnavailable(c *gin.Context, message string) { Error(c, http.StatusServiceUnavailable, "service_unavailable", message) } func NotFound(c *gin.Context, message string) { Error(c, http.StatusNotFound, "not_found", message) } func InternalServerError(c *gin.Context, message string) { Error(c, http.StatusInternalServerError, "internal_server_error", message) }