调整项目结构,factory只负责暴露方法,不实现业务细节

This commit is contained in:
2025-12-07 00:04:01 +08:00
parent b66f345281
commit 339920a940
23 changed files with 2165 additions and 1231 deletions

View File

@@ -1,279 +0,0 @@
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)
}
}

View File

@@ -1,8 +1,12 @@
package http
import (
"encoding/json"
"io"
"net/http"
"strconv"
"git.toowon.com/jimmy/go-common/middleware"
)
// getQueryInt 获取整数查询参数内部方法供ParsePaginationRequest使用
@@ -114,3 +118,192 @@ func ParsePaginationRequest(r *http.Request) *PaginationRequest {
return req
}
// ========== 请求解析公共方法 ==========
// ParseJSON 解析JSON请求体公共方法
// r: HTTP请求
// v: 目标结构体指针
func ParseJSON(r *http.Request, v interface{}) error {
body, err := io.ReadAll(r.Body)
if err != nil {
return err
}
defer r.Body.Close()
if len(body) == 0 {
return nil
}
return json.Unmarshal(body, v)
}
// GetQuery 获取查询参数(公共方法)
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetQuery(r *http.Request, key, defaultValue string) string {
value := r.URL.Query().Get(key)
if value == "" {
return defaultValue
}
return value
}
// GetQueryInt 获取整数查询参数(公共方法)
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetQueryInt(r *http.Request, key string, defaultValue int) int {
value := r.URL.Query().Get(key)
if value == "" {
return defaultValue
}
intValue, err := strconv.Atoi(value)
if err != nil {
return defaultValue
}
return intValue
}
// GetQueryInt64 获取int64查询参数公共方法
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetQueryInt64(r *http.Request, key string, defaultValue int64) int64 {
value := r.URL.Query().Get(key)
if value == "" {
return defaultValue
}
intValue, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return defaultValue
}
return intValue
}
// GetQueryBool 获取布尔查询参数(公共方法)
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetQueryBool(r *http.Request, key string, defaultValue bool) bool {
value := r.URL.Query().Get(key)
if value == "" {
return defaultValue
}
boolValue, err := strconv.ParseBool(value)
if err != nil {
return defaultValue
}
return boolValue
}
// GetQueryFloat64 获取float64查询参数公共方法
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetQueryFloat64(r *http.Request, key string, defaultValue float64) float64 {
value := r.URL.Query().Get(key)
if value == "" {
return defaultValue
}
floatValue, err := strconv.ParseFloat(value, 64)
if err != nil {
return defaultValue
}
return floatValue
}
// GetFormValue 获取表单值(公共方法)
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetFormValue(r *http.Request, key, defaultValue string) string {
value := r.FormValue(key)
if value == "" {
return defaultValue
}
return value
}
// GetFormInt 获取表单整数(公共方法)
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetFormInt(r *http.Request, key string, defaultValue int) int {
value := r.FormValue(key)
if value == "" {
return defaultValue
}
intValue, err := strconv.Atoi(value)
if err != nil {
return defaultValue
}
return intValue
}
// GetFormInt64 获取表单int64公共方法
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetFormInt64(r *http.Request, key string, defaultValue int64) int64 {
value := r.FormValue(key)
if value == "" {
return defaultValue
}
intValue, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return defaultValue
}
return intValue
}
// GetFormBool 获取表单布尔值(公共方法)
// r: HTTP请求
// key: 参数名
// defaultValue: 默认值
func GetFormBool(r *http.Request, key string, defaultValue bool) bool {
value := r.FormValue(key)
if value == "" {
return defaultValue
}
boolValue, err := strconv.ParseBool(value)
if err != nil {
return defaultValue
}
return boolValue
}
// GetHeader 获取请求头(公共方法)
// r: HTTP请求
// key: 请求头名称
// defaultValue: 默认值
func GetHeader(r *http.Request, key, defaultValue string) string {
value := r.Header.Get(key)
if value == "" {
return defaultValue
}
return value
}
// GetTimezone 从请求的context中获取时区公共方法
// r: HTTP请求
// 如果使用了middleware.Timezone中间件可以从context中获取时区信息
// 如果未设置,返回默认时区 AsiaShanghai
func GetTimezone(r *http.Request) string {
return middleware.GetTimezoneFromContext(r.Context())
}

View File

@@ -30,7 +30,7 @@ type PageData struct {
PageSize int `json:"pageSize"` // 每页大小
}
// writeJSON 写入JSON响应内部方法)
// writeJSON 写入JSON响应公共方法)
// httpCode: HTTP状态码200表示正常500表示系统错误等
// code: 业务状态码0表示成功非0表示业务错误
// message: 响应消息
@@ -48,3 +48,58 @@ func writeJSON(w http.ResponseWriter, httpCode, code int, message string, data i
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)
}