package responsex // Author: Yun // Version: 2023年6月12日19:25:54 import ( "context" "encoding/json" "math" "net/http" "github.com/yuninks/errorx" "github.com/yuninks/langx" "github.com/zeromicro/go-zero/core/trace" ) type response struct { Code int `json:"code"` Message string `json:"message"` Data any `json:"data,omitempty"` Pagination *pagination `json:"pagination,omitempty"` TraceId string `json:"trace_id,omitempty"` } type pagination struct { 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 } // 计算响应分页 func GetPage(page, size, totalCount int64) pagination { pa := pagination{} 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格式化响应 func FormatMessage(ctx context.Context, w http.ResponseWriter, msgKey string, format map[string]string, data interface{}) { code, msg := langx.GetTransFormatCtx(ctx, msgKey, format) ResponseCtx(ctx, w, SetCode(code), SetMessage(msg), SetData(data)) } // 成功的响应 func Success(ctx context.Context, w http.ResponseWriter, data any) { ResponseCtx(ctx, w, SetCode(op.defaultSuccessCode), SetMessage("请求成功"), SetData(data)) } func SuccessWithPage(ctx context.Context, w http.ResponseWriter, data any, page *pagination) { ResponseCtx(ctx, w, SetCode(op.defaultSuccessCode), SetMessage("请求成功"), SetData(data), SetPage(page)) } // 失败的响应 func Error(ctx context.Context, w http.ResponseWriter, err error) { ErrorWithData(ctx, w, err, "") } func ErrorWithData(ctx context.Context, w http.ResponseWriter, err error, data interface{}) { code := op.defaultErrorCode msg := "请求失败" if err != nil { val, ok := err.(errorx.ErrorInterface) if ok { if langx.GetDefaultCode() != val.GetCode() { code = val.GetCode() } } msg = err.Error() } ResponseCtx(ctx, w, SetCode(code), SetMessage(msg), SetData(data)) } func ErrorStr(ctx context.Context, w http.ResponseWriter, msg string) { msg = langx.GetMsgCtx(ctx, msg) code := langx.GetCode(msg) if code == langx.GetDefaultCode() { code = op.defaultErrorCode } ResponseCtx(ctx, w, SetCode(code), SetMessage(msg)) } // 基础的响应 func ResponseCtx(ctx context.Context, w http.ResponseWriter, ops ...Option) { def := defaultOptions() // 默认值 for _, o := range ops { o(def) } resp := response{} resp.Code = def.code resp.Message = def.message resp.Data = def.data resp.Pagination = def.pagination // 获取trace_id if def.traceId != "" { t := ctx.Value(def.traceId) if t != nil { val, ok := t.(string) if ok { resp.TraceId = val } } else { // go-zero resp.TraceId = trace.TraceIDFromContext(ctx) } } if !def.ignoreLog { // 记录日志 def.logger.Info(ctx, "response:", resp) } bs, _ := json.Marshal(resp) w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(200) n, err := w.Write(bs) if err != nil || n != len(bs) { op.logger.Error(ctx, "write response failed err:%+v", err) } }