- 后端新增分站专属配置及审计接口(/api/distribution/invitation-config 等),基于分站管理员严格鉴权隔离 - 分销独立后台新增「邀请返利设置」页面(Invitations.tsx),支持分站管理员自主开启/调整返利比例并查看本站流水 - 主站后台邀请接口路径补齐 /admin 前缀,解决 404/401 鉴权作用域问题 - 验证方式:backend 单元测试全数通过,distribution-admin 类型与构建检查通过
93 lines
2.0 KiB
Go
93 lines
2.0 KiB
Go
package response
|
|
|
|
import (
|
|
"context"
|
|
"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 || errors.Is(err, context.Canceled) {
|
|
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 Forbidden(c *gin.Context, message string) {
|
|
Error(c, http.StatusForbidden, "forbidden", 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)
|
|
}
|