package http import ( "context" "encoding/json" "io" "net/http" "strconv" "git.toowon.com/jimmy/go-common/middleware" ) // Handler HTTP处理器包装器,封装ResponseWriter和Request,提供简洁的API type Handler struct { w http.ResponseWriter r *http.Request } // NewHandler 创建Handler实例 func NewHandler(w http.ResponseWriter, r *http.Request) *Handler { return &Handler{ w: w, r: r, } } // ResponseWriter 获取原始的ResponseWriter(需要时使用) func (h *Handler) ResponseWriter() http.ResponseWriter { return h.w } // Request 获取原始的Request(需要时使用) func (h *Handler) Request() *http.Request { return h.r } // Context 获取请求的Context func (h *Handler) Context() context.Context { return h.r.Context() } // ========== 响应方法(黑盒模式) ========== // Success 成功响应 // data: 响应数据,可以为nil func (h *Handler) Success(data interface{}) { writeJSON(h.w, http.StatusOK, 0, "success", data) } // SuccessWithMessage 带消息的成功响应 func (h *Handler) SuccessWithMessage(message string, data interface{}) { writeJSON(h.w, http.StatusOK, 0, message, data) } // Error 错误响应 // code: 业务错误码,非0表示业务错误 // message: 错误消息 func (h *Handler) Error(code int, message string) { writeJSON(h.w, http.StatusOK, code, message, nil) } // SystemError 系统错误响应(返回HTTP 500) // message: 错误消息 func (h *Handler) SystemError(message string) { writeJSON(h.w, http.StatusInternalServerError, 500, message, nil) } // WriteJSON 写入JSON响应(自定义HTTP状态码和业务状态码) // httpCode: HTTP状态码(200表示正常,500表示系统错误等) // code: 业务状态码(0表示成功,非0表示业务错误) // message: 响应消息 // data: 响应数据 func (h *Handler) WriteJSON(httpCode, code int, message string, data interface{}) { writeJSON(h.w, httpCode, code, message, data) } // SuccessPage 分页成功响应 // list: 数据列表 // total: 总记录数 // page: 当前页码 // pageSize: 每页大小 // message: 响应消息(可选,如果为空则使用默认消息 "success") func (h *Handler) SuccessPage(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(h.w, http.StatusOK, 0, msg, pageData) } // ========== 请求解析方法(黑盒模式) ========== // ParseJSON 解析JSON请求体 // v: 目标结构体指针 func (h *Handler) ParseJSON(v interface{}) error { body, err := io.ReadAll(h.r.Body) if err != nil { return err } defer h.r.Body.Close() if len(body) == 0 { return nil } return json.Unmarshal(body, v) } // GetQuery 获取查询参数 // key: 参数名 // defaultValue: 默认值 func (h *Handler) GetQuery(key, defaultValue string) string { value := h.r.URL.Query().Get(key) if value == "" { return defaultValue } return value } // GetQueryInt 获取整数查询参数 // key: 参数名 // defaultValue: 默认值 func (h *Handler) GetQueryInt(key string, defaultValue int) int { value := h.r.URL.Query().Get(key) if value == "" { return defaultValue } intValue, err := strconv.Atoi(value) if err != nil { return defaultValue } return intValue } // GetQueryInt64 获取int64查询参数 func (h *Handler) GetQueryInt64(key string, defaultValue int64) int64 { value := h.r.URL.Query().Get(key) if value == "" { return defaultValue } intValue, err := strconv.ParseInt(value, 10, 64) if err != nil { return defaultValue } return intValue } // GetQueryBool 获取布尔查询参数 func (h *Handler) GetQueryBool(key string, defaultValue bool) bool { value := h.r.URL.Query().Get(key) if value == "" { return defaultValue } boolValue, err := strconv.ParseBool(value) if err != nil { return defaultValue } return boolValue } // GetQueryFloat64 获取float64查询参数 func (h *Handler) GetQueryFloat64(key string, defaultValue float64) float64 { value := h.r.URL.Query().Get(key) if value == "" { return defaultValue } floatValue, err := strconv.ParseFloat(value, 64) if err != nil { return defaultValue } return floatValue } // GetFormValue 获取表单值 func (h *Handler) GetFormValue(key, defaultValue string) string { value := h.r.FormValue(key) if value == "" { return defaultValue } return value } // GetFormInt 获取表单整数 func (h *Handler) GetFormInt(key string, defaultValue int) int { value := h.r.FormValue(key) if value == "" { return defaultValue } intValue, err := strconv.Atoi(value) if err != nil { return defaultValue } return intValue } // GetFormInt64 获取表单int64 func (h *Handler) GetFormInt64(key string, defaultValue int64) int64 { value := h.r.FormValue(key) if value == "" { return defaultValue } intValue, err := strconv.ParseInt(value, 10, 64) if err != nil { return defaultValue } return intValue } // GetFormBool 获取表单布尔值 func (h *Handler) GetFormBool(key string, defaultValue bool) bool { value := h.r.FormValue(key) if value == "" { return defaultValue } boolValue, err := strconv.ParseBool(value) if err != nil { return defaultValue } return boolValue } // GetHeader 获取请求头 func (h *Handler) GetHeader(key, defaultValue string) string { value := h.r.Header.Get(key) if value == "" { return defaultValue } return value } // ParsePaginationRequest 从请求中解析分页参数 // 支持从查询参数和form表单中解析 // 优先级:查询参数 > form表单 func (h *Handler) ParsePaginationRequest() *PaginationRequest { return ParsePaginationRequest(h.r) } // GetTimezone 从请求的context中获取时区 // 如果使用了middleware.Timezone中间件,可以从context中获取时区信息 // 如果未设置,返回默认时区 AsiaShanghai func (h *Handler) GetTimezone() string { return middleware.GetTimezoneFromContext(h.r.Context()) } // HandleFunc 将Handler函数转换为标准的http.HandlerFunc // 这样可以将Handler函数直接用于http.HandleFunc // 示例: // // http.HandleFunc("/users", http.HandleFunc(func(h *http.Handler) { // h.Success(data) // })) func HandleFunc(fn func(*Handler)) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { h := NewHandler(w, r) fn(h) } }