Files
responsex/response.go
T

169 lines
4.0 KiB
Go
Raw Permalink Normal View History

2024-06-30 17:42:27 +08:00
package responsex
// Author: Yun
// Version: 2023年6月12日19:25:54
import (
"context"
"encoding/json"
"math"
"net/http"
2025-10-26 21:17:00 +08:00
"github.com/yuninks/errorx"
2025-12-06 22:57:01 +08:00
"github.com/yuninks/langx"
2024-06-30 17:42:27 +08:00
"github.com/zeromicro/go-zero/core/trace"
)
2025-12-07 11:21:00 +08:00
type response struct {
Code int `json:"code"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
2026-07-22 01:17:07 +08:00
Pagination *Pagination `json:"pagination,omitempty"`
2025-12-07 11:21:00 +08:00
TraceId string `json:"trace_id,omitempty"`
}
2026-07-22 01:17:07 +08:00
type Pagination struct {
2024-06-30 17:42:27 +08:00
Page int64 `json:"page"`
Size int64 `json:"size"`
TotalPage int64 `json:"total_page"`
TotalCount int64 `json:"total_count"`
}
// 计算DB分页偏移量
func GetOffset(page, size int) (offset int, limit int) {
if page <= 0 {
page = 1
}
offset = (page - 1) * size
limit = size
if limit == 0 {
// 默认查10条
limit = 10
}
return
}
// 计算响应分页
2026-07-22 01:17:07 +08:00
func GetPage(page, size, totalCount int64) Pagination {
pa := Pagination{}
2024-06-30 17:42:27 +08:00
totalPage := 0
if size != 0 {
totalPage = int(math.Ceil(float64(totalCount) / float64(size)))
}
pa.Page = page
pa.Size = size
pa.TotalPage = int64(totalPage)
pa.TotalCount = totalCount
return pa
}
// Msg格式化响应
2026-07-22 01:17:07 +08:00
func FormatMessage(ctx context.Context, w http.ResponseWriter, msgKey string, format map[string]string, data interface{}, ops ...Option) {
2025-12-07 01:51:01 +08:00
code, msg := langx.GetTransFormatCtx(ctx, msgKey, format)
2026-07-22 01:17:07 +08:00
baseOps := []Option{SetCode(code), SetMessage(msg), SetData(data)}
baseOps = append(baseOps, ops...)
ResponseCtx(ctx, w, baseOps...)
2024-06-30 17:42:27 +08:00
}
// 成功的响应
2026-07-22 01:17:07 +08:00
func Success(ctx context.Context, w http.ResponseWriter, data any, ops ...Option) {
baseOps := []Option{SetCode(op.defaultSuccessCode), SetMessage("请求成功"), SetData(data)}
baseOps = append(baseOps, ops...)
ResponseCtx(ctx, w, baseOps...)
2024-06-30 17:42:27 +08:00
}
2026-07-22 01:17:07 +08:00
func SuccessWithPage(ctx context.Context, w http.ResponseWriter, data any, page *Pagination, ops ...Option) {
baseOps := []Option{SetCode(op.defaultSuccessCode), SetMessage("请求成功"), SetData(data), SetPage(page)}
baseOps = append(baseOps, ops...)
ResponseCtx(ctx, w, baseOps...)
2024-06-30 17:42:27 +08:00
}
// 失败的响应
2026-07-22 01:17:07 +08:00
func Error(ctx context.Context, w http.ResponseWriter, err error, ops ...Option) {
ErrorWithData(ctx, w, err, "", ops...)
2025-12-06 22:57:01 +08:00
}
2026-07-22 01:17:07 +08:00
func ErrorWithData(ctx context.Context, w http.ResponseWriter, err error, data interface{}, ops ...Option) {
2024-07-10 17:32:12 +08:00
code := op.defaultErrorCode
2024-06-30 17:42:27 +08:00
msg := "请求失败"
if err != nil {
2026-07-22 01:17:07 +08:00
val,ok := errorx.As(err)
2024-06-30 17:42:27 +08:00
if ok {
2026-07-22 01:17:07 +08:00
if langx.GetDefaultCode() != val.Code() {
code = val.Code()
2024-07-10 17:32:12 +08:00
}
2024-06-30 17:42:27 +08:00
}
2024-07-10 17:32:12 +08:00
msg = err.Error()
2024-06-30 17:42:27 +08:00
}
2026-07-22 01:17:07 +08:00
baseOps := []Option{SetCode(code), SetMessage(msg), SetData(data)}
baseOps = append(baseOps, ops...)
ResponseCtx(ctx, w, baseOps...)
2024-06-30 17:42:27 +08:00
}
2026-07-22 01:17:07 +08:00
func ErrorStr(ctx context.Context, w http.ResponseWriter, msg string, ops ...Option) {
2024-07-10 17:32:12 +08:00
msg = langx.GetMsgCtx(ctx, msg)
code := langx.GetCode(msg)
if code == langx.GetDefaultCode() {
code = op.defaultErrorCode
}
2026-07-22 01:17:07 +08:00
baseOps := []Option{SetCode(code), SetMessage(msg)}
baseOps = append(baseOps, ops...)
ResponseCtx(ctx, w, baseOps...)
2024-06-30 17:42:27 +08:00
}
// 基础的响应
2025-12-07 01:51:01 +08:00
func ResponseCtx(ctx context.Context, w http.ResponseWriter, ops ...Option) {
def := defaultOptions() // 默认值
for _, o := range ops {
o(def)
}
2024-06-30 17:42:27 +08:00
2025-12-07 11:21:00 +08:00
resp := response{}
resp.Code = def.code
resp.Message = def.message
resp.Data = def.data
resp.Pagination = def.pagination
2024-06-30 17:42:27 +08:00
// 获取trace_id
2025-12-07 01:51:01 +08:00
if def.traceId != "" {
t := ctx.Value(def.traceId)
2024-06-30 17:42:27 +08:00
if t != nil {
2025-12-07 11:21:00 +08:00
val, ok := t.(string)
if ok {
resp.TraceId = val
}
2024-06-30 17:42:27 +08:00
} else {
// go-zero
2025-12-07 11:21:00 +08:00
resp.TraceId = trace.TraceIDFromContext(ctx)
2024-06-30 17:42:27 +08:00
}
}
2025-12-07 12:07:21 +08:00
bs, _ := json.Marshal(resp)
2025-12-07 01:51:01 +08:00
if !def.ignoreLog {
2024-06-30 17:42:27 +08:00
// 记录日志
2025-12-07 12:07:21 +08:00
def.logger.Info(ctx, "response:", string(bs))
2024-06-30 17:42:27 +08:00
}
2026-07-22 01:17:07 +08:00
// 写入自定义响应头
for k, v := range def.headers {
w.Header().Set(k, v)
}
2024-06-30 17:42:27 +08:00
w.Header().Set("Content-Type", "application/json; charset=utf-8")
2026-07-22 01:17:07 +08:00
// 确定HTTP状态码
httpStatus := def.httpStatusCode
if httpStatus == 0 {
httpStatus = 200
}
w.WriteHeader(httpStatus)
2024-06-30 17:42:27 +08:00
n, err := w.Write(bs)
if err != nil || n != len(bs) {
op.logger.Error(ctx, "write response failed err:%+v", err)
}
}