重构项目的实现,优化使用方法与使用逻辑
This commit is contained in:
95
http/handler.go
Normal file
95
http/handler.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.toowon.com/jimmy/go-common/i18n"
|
||||
)
|
||||
|
||||
// Handler HTTP 出参处理器(唯一对外出参方式)
|
||||
type Handler struct {
|
||||
w http.ResponseWriter
|
||||
r *http.Request
|
||||
i18n *i18n.I18n
|
||||
pagination *PaginationRequest
|
||||
}
|
||||
|
||||
// HandlerOption Handler 配置项
|
||||
type HandlerOption func(*Handler)
|
||||
|
||||
// WithI18n 注入 i18n
|
||||
func WithI18n(i *i18n.I18n) HandlerOption {
|
||||
return func(h *Handler) {
|
||||
h.i18n = i
|
||||
}
|
||||
}
|
||||
|
||||
// NewHandler 创建 HTTP 出参处理器
|
||||
func NewHandler(w http.ResponseWriter, r *http.Request, opts ...HandlerOption) *Handler {
|
||||
h := &Handler{w: w, r: r}
|
||||
for _, opt := range opts {
|
||||
opt(h)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// ParseJSON 解析 JSON 请求体
|
||||
func (h *Handler) ParseJSON(v interface{}) error {
|
||||
return ParseJSON(h.r, v)
|
||||
}
|
||||
|
||||
// Pagination 解析并缓存分页参数
|
||||
func (h *Handler) Pagination() *PaginationRequest {
|
||||
if h.pagination == nil {
|
||||
h.pagination = ParsePaginationRequest(h.r)
|
||||
}
|
||||
return h.pagination
|
||||
}
|
||||
|
||||
// GetLanguage 从 context 获取语言
|
||||
func (h *Handler) GetLanguage() string {
|
||||
return GetLanguage(h.r)
|
||||
}
|
||||
|
||||
// GetTimezone 从 context 获取时区
|
||||
func (h *Handler) GetTimezone() string {
|
||||
return GetTimezone(h.r)
|
||||
}
|
||||
|
||||
// Success 成功响应
|
||||
func (h *Handler) Success(data interface{}) {
|
||||
message := "success"
|
||||
code := 0
|
||||
if h.i18n != nil {
|
||||
info := h.i18n.GetMessageInfo(h.GetLanguage(), "common.success")
|
||||
if info.Message != "common.success" {
|
||||
message = info.Message
|
||||
code = info.Code
|
||||
}
|
||||
}
|
||||
writeResponse(h.w, code, message, data)
|
||||
}
|
||||
|
||||
// SuccessPage 分页成功响应
|
||||
func (h *Handler) SuccessPage(list interface{}, total int64) {
|
||||
p := h.Pagination()
|
||||
pageData := &PageData{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: p.GetPage(),
|
||||
PageSize: p.GetPageSize(),
|
||||
}
|
||||
h.Success(pageData)
|
||||
}
|
||||
|
||||
// Error 失败响应(messageCode 为 i18n 消息码)
|
||||
func (h *Handler) Error(messageCode string, args ...interface{}) {
|
||||
code := 0
|
||||
message := messageCode
|
||||
if h.i18n != nil {
|
||||
info := h.i18n.GetMessageInfo(h.GetLanguage(), messageCode, args...)
|
||||
code = info.Code
|
||||
message = info.Message
|
||||
}
|
||||
writeResponse(h.w, code, message, nil)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"git.toowon.com/jimmy/go-common/middleware"
|
||||
"git.toowon.com/jimmy/go-common/requestctx"
|
||||
"git.toowon.com/jimmy/go-common/tools"
|
||||
)
|
||||
|
||||
@@ -97,18 +97,12 @@ func ParseJSON(r *http.Request, v interface{}) error {
|
||||
return json.Unmarshal(body, v)
|
||||
}
|
||||
|
||||
// GetTimezone 从请求的context中获取时区(公共方法)
|
||||
// r: HTTP请求
|
||||
// 如果使用了middleware.Timezone中间件,可以从context中获取时区信息
|
||||
// 如果未设置,返回默认时区 AsiaShanghai
|
||||
// GetTimezone 从请求的 context 中获取时区
|
||||
func GetTimezone(r *http.Request) string {
|
||||
return middleware.GetTimezoneFromContext(r.Context())
|
||||
return requestctx.Timezone(r.Context())
|
||||
}
|
||||
|
||||
// GetLanguage 从请求的context中获取语言(公共方法)
|
||||
// r: HTTP请求
|
||||
// 如果使用了middleware.Language中间件,可以从context中获取语言信息
|
||||
// 如果未设置,返回默认语言 zh-CN
|
||||
// GetLanguage 从请求的 context 中获取语言
|
||||
func GetLanguage(r *http.Request) string {
|
||||
return middleware.GetLanguageFromContext(r.Context())
|
||||
return requestctx.Language(r.Context())
|
||||
}
|
||||
|
||||
@@ -8,36 +8,24 @@ import (
|
||||
|
||||
// Response 标准响应结构
|
||||
type Response struct {
|
||||
Code int `json:"code"` // 业务状态码,0表示成功
|
||||
Message string `json:"message"` // 响应消息
|
||||
Timestamp int64 `json:"timestamp"` // 时间戳
|
||||
Data interface{} `json:"data"` // 响应数据
|
||||
}
|
||||
|
||||
// PageResponse 分页响应结构
|
||||
type PageResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Data *PageData `json:"data"`
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
// PageData 分页数据
|
||||
type PageData struct {
|
||||
List interface{} `json:"list"` // 数据列表
|
||||
Total int64 `json:"total"` // 总记录数
|
||||
Page int `json:"page"` // 当前页码
|
||||
PageSize int `json:"pageSize"` // 每页大小
|
||||
List interface{} `json:"list"`
|
||||
Total int64 `json:"total"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"pageSize"`
|
||||
}
|
||||
|
||||
// writeJSON 写入JSON响应(公共方法)
|
||||
// httpCode: HTTP状态码(200表示正常,500表示系统错误等)
|
||||
// code: 业务状态码(0表示成功,非0表示业务错误)
|
||||
// message: 响应消息
|
||||
// data: 响应数据
|
||||
func writeJSON(w http.ResponseWriter, httpCode, code int, message string, data interface{}) {
|
||||
// writeResponse 统一 JSON 出参(HTTP 恒 200)
|
||||
func writeResponse(w http.ResponseWriter, code int, message string, data interface{}) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(httpCode)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
response := Response{
|
||||
Code: code,
|
||||
@@ -46,60 +34,5 @@ func writeJSON(w http.ResponseWriter, httpCode, code int, message string, data i
|
||||
Data: data,
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
// Success 成功响应(公共方法)
|
||||
// w: ResponseWriter
|
||||
// data: 响应数据,可以为nil
|
||||
// message: 响应消息(可选),如果为空则使用默认消息 "success"
|
||||
//
|
||||
// 使用方式:
|
||||
//
|
||||
// Success(w, data) // 只有数据,使用默认消息 "success"
|
||||
// Success(w, data, "查询成功") // 数据+消息
|
||||
func Success(w http.ResponseWriter, data interface{}, message ...string) {
|
||||
msg := "success"
|
||||
if len(message) > 0 && message[0] != "" {
|
||||
msg = message[0]
|
||||
}
|
||||
writeJSON(w, http.StatusOK, 0, msg, data)
|
||||
}
|
||||
|
||||
// SuccessPage 分页成功响应(公共方法)
|
||||
// w: ResponseWriter
|
||||
// list: 数据列表
|
||||
// total: 总记录数
|
||||
// page: 当前页码
|
||||
// pageSize: 每页大小
|
||||
// message: 响应消息(可选),如果为空则使用默认消息 "success"
|
||||
func SuccessPage(w http.ResponseWriter, list interface{}, total int64, page, pageSize int, message ...string) {
|
||||
msg := "success"
|
||||
if len(message) > 0 && message[0] != "" {
|
||||
msg = message[0]
|
||||
}
|
||||
|
||||
pageData := &PageData{
|
||||
List: list,
|
||||
Total: total,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, 0, msg, pageData)
|
||||
}
|
||||
|
||||
// Error 错误响应(公共方法)
|
||||
// w: ResponseWriter
|
||||
// code: 业务错误码,非0表示业务错误
|
||||
// message: 错误消息
|
||||
func Error(w http.ResponseWriter, code int, message string) {
|
||||
writeJSON(w, http.StatusOK, code, message, nil)
|
||||
}
|
||||
|
||||
// SystemError 系统错误响应(返回HTTP 500)(公共方法)
|
||||
// w: ResponseWriter
|
||||
// message: 错误消息
|
||||
func SystemError(w http.ResponseWriter, message string) {
|
||||
writeJSON(w, http.StatusInternalServerError, 500, message, nil)
|
||||
_ = json.NewEncoder(w).Encode(response)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user