diff --git a/docs/README.md b/docs/README.md index 4481aea..eb4c1c0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -77,20 +77,26 @@ now := tools.Now() str := tools.FormatDateTime(now) ``` -#### HTTP响应(Handler黑盒模式) +#### HTTP响应(Factory黑盒模式,推荐) ```go import ( "net/http" - commonhttp "git.toowon.com/jimmy/go-common/http" + "git.toowon.com/jimmy/go-common/factory" + "git.toowon.com/jimmy/go-common/tools" ) -func GetUser(h *commonhttp.Handler) { - id := h.GetQueryInt64("id", 0) - h.Success(data) +func GetUser(w http.ResponseWriter, r *http.Request) { + fac, _ := factory.NewFactoryFromFile("config.json") + + // 获取查询参数(使用类型转换方法) + id := tools.ConvertInt64(r.URL.Query().Get("id"), 0) + + // 返回成功响应 + fac.Success(w, data) } -http.HandleFunc("/user", commonhttp.HandleFunc(GetUser)) +http.HandleFunc("/user", GetUser) ``` #### 中间件(生产级配置) diff --git a/docs/factory.md b/docs/factory.md index 0645384..28cb299 100644 --- a/docs/factory.md +++ b/docs/factory.md @@ -32,7 +32,7 @@ | **金额计算** | `YuanToCents()`, `CentsToYuan()`, `FormatYuan()` | `fac.YuanToCents(100.5)` | | **版本信息** | `GetVersion()` | `fac.GetVersion()` | | **HTTP响应** | `Success()`, `Error()`, `SuccessPage()` | `fac.Success(w, data)` | -| **HTTP请求** | `ParseJSON()`, `GetQuery()`, `GetTimezone()` 等 | `fac.ParseJSON(r, &req)` | +| **HTTP请求** | `ParseJSON()`, `ConvertInt()`, `GetTimezone()` 等 | `fac.ParseJSON(r, &req)` | ### 🔧 高级功能:Get方法(仅在必要时使用) @@ -286,11 +286,15 @@ import "net/http" var req UserRequest fac.ParseJSON(r, &req) -// 获取查询参数 -id := fac.GetQueryInt64(r, "id", 0) -uid := fac.GetQueryUint64(r, "uid", 0) -userId := fac.GetQueryUint32(r, "user_id", 0) -keyword := fac.GetQuery(r, "keyword", "") +// 获取查询参数(使用类型转换方法) +id := fac.ConvertInt64(r.URL.Query().Get("id"), 0) +uid := fac.ConvertUint64(r.URL.Query().Get("uid"), 0) +userId := fac.ConvertUint32(r.URL.Query().Get("user_id"), 0) +keyword := r.URL.Query().Get("keyword") // 字符串直接获取 + +// 获取表单参数 +age := fac.ConvertInt(r.FormValue("age"), 0) +isActive := fac.ConvertBool(r.FormValue("is_active"), false) // 获取时区(需要配合middleware.Timezone使用) timezone := fac.GetTimezone(r) @@ -657,34 +661,74 @@ fac.Success(w, user, "获取成功") // 自定义消息 - `r`: HTTP请求 - `v`: 目标结构体指针 -#### GetQuery(r *http.Request, key, defaultValue string) string - -获取查询参数。 - -#### GetQueryInt(r *http.Request, key string, defaultValue int) int - -获取查询整数参数。 - -#### GetQueryInt64(r *http.Request, key string, defaultValue int64) int64 - -获取查询64位整数参数。 - -#### GetQueryUint64(r *http.Request, key string, defaultValue uint64) uint64 - -获取查询64位无符号整数参数。 - -#### GetQueryUint32(r *http.Request, key string, defaultValue uint32) uint32 - -获取查询32位无符号整数参数。 - -#### GetFormValue(r *http.Request, key, defaultValue string) string - -获取表单值。 - #### GetTimezone(r *http.Request) string 从请求的context中获取时区(需要配合middleware.Timezone使用)。 +### 类型转换方法(黑盒模式) + +#### ConvertInt(value string, defaultValue int) int + +将字符串转换为int类型。 + +**参数:** +- `value`: 待转换的字符串 +- `defaultValue`: 转换失败或字符串为空时返回的默认值 + +**示例:** +```go +// 从查询参数获取整数 +id := fac.ConvertInt(r.URL.Query().Get("id"), 0) + +// 从表单获取整数 +age := fac.ConvertInt(r.FormValue("age"), 0) +``` + +#### ConvertInt64(value string, defaultValue int64) int64 + +将字符串转换为int64类型。 + +**示例:** +```go +id := fac.ConvertInt64(r.URL.Query().Get("id"), 0) +``` + +#### ConvertUint64(value string, defaultValue uint64) uint64 + +将字符串转换为uint64类型。 + +**示例:** +```go +uid := fac.ConvertUint64(r.URL.Query().Get("uid"), 0) +``` + +#### ConvertUint32(value string, defaultValue uint32) uint32 + +将字符串转换为uint32类型。 + +**示例:** +```go +userId := fac.ConvertUint32(r.URL.Query().Get("user_id"), 0) +``` + +#### ConvertBool(value string, defaultValue bool) bool + +将字符串转换为bool类型。 + +**示例:** +```go +isActive := fac.ConvertBool(r.URL.Query().Get("is_active"), false) +``` + +#### ConvertFloat64(value string, defaultValue float64) float64 + +将字符串转换为float64类型。 + +**示例:** +```go +price := fac.ConvertFloat64(r.URL.Query().Get("price"), 0.0) +``` + ### 日期时间工具方法(黑盒模式) #### Now(timezone ...string) time.Time diff --git a/docs/http.md b/docs/http.md index e99b1fa..6335c27 100644 --- a/docs/http.md +++ b/docs/http.md @@ -111,13 +111,14 @@ import ( "net/http" "git.toowon.com/jimmy/go-common/factory" commonhttp "git.toowon.com/jimmy/go-common/http" + "git.toowon.com/jimmy/go-common/tools" ) func GetUser(w http.ResponseWriter, r *http.Request) { fac, _ := factory.NewFactoryFromFile("config.json") - // 获取查询参数(使用公共方法) - id := commonhttp.GetQueryInt64(r, "id", 0) + // 获取查询参数(使用类型转换方法) + id := tools.ConvertInt64(r.URL.Query().Get("id"), 0) // 返回成功响应(使用factory方法) fac.Success(w, data) @@ -145,10 +146,10 @@ func GetUserList(w http.ResponseWriter, r *http.Request) { // 获取分页参数(使用factory方法,推荐) pagination := fac.ParsePaginationRequest(r) page := pagination.GetPage() - pageSize := pagination.GetSize() + pageSize := pagination.GetPageSize() - // 获取查询参数(使用factory方法,推荐) - keyword := fac.GetQuery(r, "keyword", "") + // 获取查询参数(直接使用HTTP原生方法) + keyword := r.URL.Query().Get("keyword") // 查询数据 list, total := getDataList(keyword, page, pageSize) @@ -170,11 +171,12 @@ http.HandleFunc("/users", GetUserList) import ( "net/http" commonhttp "git.toowon.com/jimmy/go-common/http" + "git.toowon.com/jimmy/go-common/tools" ) func GetUser(w http.ResponseWriter, r *http.Request) { // 获取查询参数 - id := commonhttp.GetQueryInt64(r, "id", 0) + id := tools.ConvertInt64(r.URL.Query().Get("id"), 0) // 返回成功响应 commonhttp.Success(w, data) @@ -252,30 +254,41 @@ if err := commonhttp.ParseJSON(r, &req); err != nil { #### 获取查询参数 ```go -// 使用公共方法 -name := commonhttp.GetQuery(r, "name", "") -id := commonhttp.GetQueryInt(r, "id", 0) -userId := commonhttp.GetQueryInt64(r, "userId", 0) -isActive := commonhttp.GetQueryBool(r, "isActive", false) -price := commonhttp.GetQueryFloat64(r, "price", 0.0) +import "git.toowon.com/jimmy/go-common/tools" + +// 字符串直接获取 +name := r.URL.Query().Get("name") + +// 使用类型转换方法 +id := tools.ConvertInt(r.URL.Query().Get("id"), 0) +userId := tools.ConvertInt64(r.URL.Query().Get("userId"), 0) +isActive := tools.ConvertBool(r.URL.Query().Get("isActive"), false) +price := tools.ConvertFloat64(r.URL.Query().Get("price"), 0.0) ``` #### 获取表单参数 ```go -// 使用公共方法 -name := commonhttp.GetFormValue(r, "name", "") -age := commonhttp.GetFormInt(r, "age", 0) -userId := commonhttp.GetFormInt64(r, "userId", 0) -isActive := commonhttp.GetFormBool(r, "isActive", false) +import "git.toowon.com/jimmy/go-common/tools" + +// 字符串直接获取 +name := r.FormValue("name") + +// 使用类型转换方法 +age := tools.ConvertInt(r.FormValue("age"), 0) +userId := tools.ConvertInt64(r.FormValue("userId"), 0) +isActive := tools.ConvertBool(r.FormValue("isActive"), false) ``` #### 获取请求头 ```go -// 使用公共方法 -token := commonhttp.GetHeader(r, "Authorization", "") -contentType := commonhttp.GetHeader(r, "Content-Type", "application/json") +// 直接使用HTTP原生方法 +token := r.Header.Get("Authorization") +contentType := r.Header.Get("Content-Type") +if contentType == "" { + contentType = "application/json" // 设置默认值 +} ``` #### 获取分页参数 @@ -297,9 +310,9 @@ if err := commonhttp.ParseJSON(r, &req); err != nil { } // 使用分页方法 -page := req.GetPage() // 获取页码(默认1) -size := req.GetSize() // 获取每页数量(默认20,最大100,优先使用page_size) -offset := req.GetOffset() // 计算偏移量 +page := req.GetPage() // 获取页码(默认1) +pageSize := req.GetPageSize() // 获取每页数量(默认20,最大100) +offset := req.GetOffset() // 计算偏移量 ``` **方式2:从查询参数/form解析分页** @@ -308,7 +321,7 @@ offset := req.GetOffset() // 计算偏移量 // 使用公共方法 pagination := commonhttp.ParsePaginationRequest(r) page := pagination.GetPage() -size := pagination.GetSize() +pageSize := pagination.GetPageSize() offset := pagination.GetOffset() ``` @@ -333,6 +346,7 @@ import ( "net/http" "git.toowon.com/jimmy/go-common/factory" commonhttp "git.toowon.com/jimmy/go-common/http" + "git.toowon.com/jimmy/go-common/tools" ) // 用户结构 @@ -349,10 +363,10 @@ func GetUserList(w http.ResponseWriter, r *http.Request) { // 获取分页参数(使用公共方法) pagination := commonhttp.ParsePaginationRequest(r) page := pagination.GetPage() - pageSize := pagination.GetSize() + pageSize := pagination.GetPageSize() - // 获取查询参数(使用公共方法) - keyword := commonhttp.GetQuery(r, "keyword", "") + // 获取查询参数(直接使用HTTP原生方法) + keyword := r.URL.Query().Get("keyword") // 查询数据 users, total := queryUsers(keyword, page, pageSize) @@ -397,8 +411,8 @@ func CreateUser(w http.ResponseWriter, r *http.Request) { func GetUser(w http.ResponseWriter, r *http.Request) { fac, _ := factory.NewFactoryFromFile("config.json") - // 获取查询参数(使用factory方法,推荐) - id := fac.GetQueryInt64(r, "id", 0) + // 获取查询参数(使用类型转换方法) + id := tools.ConvertInt64(r.URL.Query().Get("id"), 0) if id == 0 { commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "用户ID不能为空", nil) @@ -593,45 +607,45 @@ if err := commonhttp.ParseJSON(r, &req); err != nil { } ``` -#### GetQuery(r *http.Request, key, defaultValue string) string +#### 获取查询参数和表单参数 -获取查询参数(字符串)。 +**推荐方式:使用类型转换工具** -#### GetQueryInt(r *http.Request, key string, defaultValue int) int +```go +import "git.toowon.com/jimmy/go-common/tools" -获取查询参数(整数)。 +// 字符串直接使用HTTP原生方法 +name := r.URL.Query().Get("name") +if name == "" { + name = "default" // 设置默认值 +} -#### GetQueryInt64(r *http.Request, key string, defaultValue int64) int64 +// 类型转换使用tools包 +id := tools.ConvertInt(r.URL.Query().Get("id"), 0) +userId := tools.ConvertInt64(r.URL.Query().Get("userId"), 0) +isActive := tools.ConvertBool(r.URL.Query().Get("isActive"), false) +price := tools.ConvertFloat64(r.URL.Query().Get("price"), 0.0) -获取查询参数(int64)。 +// 表单参数类似 +age := tools.ConvertInt(r.FormValue("age"), 0) +``` -#### GetQueryBool(r *http.Request, key string, defaultValue bool) bool +**类型转换方法说明:** -获取查询参数(布尔值)。 +- `tools.ConvertInt(value string, defaultValue int) int` - 转换为int +- `tools.ConvertInt64(value string, defaultValue int64) int64` - 转换为int64 +- `tools.ConvertUint64(value string, defaultValue uint64) uint64` - 转换为uint64 +- `tools.ConvertUint32(value string, defaultValue uint32) uint32` - 转换为uint32 +- `tools.ConvertBool(value string, defaultValue bool) bool` - 转换为bool +- `tools.ConvertFloat64(value string, defaultValue float64) float64` - 转换为float64 -#### GetQueryFloat64(r *http.Request, key string, defaultValue float64) float64 +**获取请求头:** -获取查询参数(浮点数)。 - -#### GetFormValue(r *http.Request, key, defaultValue string) string - -获取表单值(字符串)。 - -#### GetFormInt(r *http.Request, key string, defaultValue int) int - -获取表单值(整数)。 - -#### GetFormInt64(r *http.Request, key string, defaultValue int64) int64 - -获取表单值(int64)。 - -#### GetFormBool(r *http.Request, key string, defaultValue bool) bool - -获取表单值(布尔值)。 - -#### GetHeader(r *http.Request, key, defaultValue string) string - -获取请求头。 +```go +// 直接使用HTTP原生方法 +token := r.Header.Get("Authorization") +contentType := r.Header.Get("Content-Type") +``` #### ParsePaginationRequest(r *http.Request) *PaginationRequest @@ -692,12 +706,11 @@ commonhttp.Success(w, data, "操作成功") // 数据+消息 **字段:** - `Page`: 页码(默认1) -- `Size`: 每页数量(兼容旧版本) -- `PageSize`: 每页数量(推荐使用,优先于Size) +- `PageSize`: 每页数量 **方法:** - `GetPage() int`: 获取页码,如果未设置则返回默认值1 -- `GetSize() int`: 获取每页数量,优先使用PageSize,如果未设置则使用Size,默认20,最大100 +- `GetPageSize() int`: 获取每页数量,如果未设置则返回默认值20,最大限制100 - `GetOffset() int`: 计算数据库查询的偏移量 #### ParsePaginationRequest(r *http.Request) *PaginationRequest diff --git a/examples/http_handler_example.go b/examples/http_handler_example.go index c589a1b..c754192 100644 --- a/examples/http_handler_example.go +++ b/examples/http_handler_example.go @@ -4,8 +4,9 @@ import ( "log" "net/http" - commonhttp "git.toowon.com/jimmy/go-common/http" "git.toowon.com/jimmy/go-common/factory" + commonhttp "git.toowon.com/jimmy/go-common/http" + "git.toowon.com/jimmy/go-common/tools" ) // 用户结构 @@ -18,14 +19,14 @@ type User struct { // 获取用户列表(使用公共方法和factory) func GetUserList(w http.ResponseWriter, r *http.Request) { fac, _ := factory.NewFactoryFromFile("config.json") - + // 获取分页参数(使用公共方法) pagination := commonhttp.ParsePaginationRequest(r) page := pagination.GetPage() - pageSize := pagination.GetSize() + pageSize := pagination.GetPageSize() // 获取查询参数(使用公共方法) - _ = commonhttp.GetQuery(r, "keyword", "") // 示例:获取查询参数 + _ = r.URL.Query().Get("keyword") // 示例:获取查询参数 // 模拟查询数据 users := []User{ @@ -41,7 +42,7 @@ func GetUserList(w http.ResponseWriter, r *http.Request) { // 创建用户(使用公共方法和factory) func CreateUser(w http.ResponseWriter, r *http.Request) { fac, _ := factory.NewFactoryFromFile("config.json") - + // 解析请求体(使用公共方法) var req struct { Name string `json:"name"` @@ -73,9 +74,9 @@ func CreateUser(w http.ResponseWriter, r *http.Request) { // 获取用户详情(使用公共方法和factory) func GetUser(w http.ResponseWriter, r *http.Request) { fac, _ := factory.NewFactoryFromFile("config.json") - + // 获取查询参数(使用公共方法) - id := commonhttp.GetQueryInt64(r, "id", 0) + id := tools.ConvertInt64(r.URL.Query().Get("id"), 0) if id == 0 { commonhttp.WriteJSON(w, http.StatusBadRequest, 400, "用户ID不能为空", nil) diff --git a/examples/http_pagination_example.go b/examples/http_pagination_example.go index 6c53026..ea127b1 100644 --- a/examples/http_pagination_example.go +++ b/examples/http_pagination_example.go @@ -4,14 +4,14 @@ import ( "log" "net/http" - commonhttp "git.toowon.com/jimmy/go-common/http" "git.toowon.com/jimmy/go-common/factory" + commonhttp "git.toowon.com/jimmy/go-common/http" ) // ListUserRequest 用户列表请求(包含分页字段) type ListUserRequest struct { - Keyword string `json:"keyword"` - commonhttp.PaginationRequest // 嵌入分页请求结构 + Keyword string `json:"keyword"` + commonhttp.PaginationRequest // 嵌入分页请求结构 } // User 用户结构 @@ -36,13 +36,13 @@ func GetUserList(w http.ResponseWriter, r *http.Request) { // 方式2:从查询参数解析分页 pagination := commonhttp.ParsePaginationRequest(r) req.PaginationRequest = *pagination - req.Keyword = commonhttp.GetQuery(r, "keyword", "") + req.Keyword = r.URL.Query().Get("keyword") } // 使用分页方法 - page := req.GetPage() // 获取页码(默认1) - size := req.GetSize() // 获取每页数量(默认20,最大100) - _ = req.GetOffset() // 计算偏移量 + page := req.GetPage() // 获取页码(默认1) + pageSize := req.GetPageSize() // 获取每页数量(默认20,最大100) + _ = req.GetOffset() // 计算偏移量 // 模拟查询数据 users := []User{ @@ -52,7 +52,7 @@ func GetUserList(w http.ResponseWriter, r *http.Request) { total := int64(100) // 返回分页响应(使用factory方法) - fac.SuccessPage(w, users, total, page, size) + fac.SuccessPage(w, users, total, page, pageSize) } func main() { diff --git a/factory/factory.go b/factory/factory.go index 7296768..710252c 100644 --- a/factory/factory.go +++ b/factory/factory.go @@ -927,7 +927,7 @@ func (f *Factory) SystemError(w http.ResponseWriter, message string) { // ========== HTTP请求解析方法(黑盒模式,推荐使用) ========== // // 这些方法直接调用 http 包的公共方法,保持低耦合。 -// 推荐直接使用 factory.ParseJSON()、factory.GetQuery() 等方法。 +// 推荐直接使用 factory.ParseJSON()、factory.ConvertInt() 等方法。 // ParseJSON 解析JSON请求体(黑盒模式,推荐使用) // r: HTTP请求 @@ -960,100 +960,46 @@ func (f *Factory) ParsePaginationRequest(r *http.Request) *PaginationRequest { return commonhttp.ParsePaginationRequest(r) } -// GetQuery 获取查询参数(字符串)(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetQuery(r *http.Request, key, defaultValue string) string { - return commonhttp.GetQuery(r, key, defaultValue) +// ConvertInt 将字符串转换为int类型(黑盒模式,推荐使用) +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func (f *Factory) ConvertInt(value string, defaultValue int) int { + return tools.ConvertInt(value, defaultValue) } -// GetQueryInt 获取整数查询参数(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetQueryInt(r *http.Request, key string, defaultValue int) int { - return commonhttp.GetQueryInt(r, key, defaultValue) +// ConvertInt64 将字符串转换为int64类型(黑盒模式,推荐使用) +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func (f *Factory) ConvertInt64(value string, defaultValue int64) int64 { + return tools.ConvertInt64(value, defaultValue) } -// GetQueryInt64 获取int64查询参数(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetQueryInt64(r *http.Request, key string, defaultValue int64) int64 { - return commonhttp.GetQueryInt64(r, key, defaultValue) +// ConvertUint64 将字符串转换为uint64类型(黑盒模式,推荐使用) +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func (f *Factory) ConvertUint64(value string, defaultValue uint64) uint64 { + return tools.ConvertUint64(value, defaultValue) } -// GetQueryUint64 获取uint64查询参数(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetQueryUint64(r *http.Request, key string, defaultValue uint64) uint64 { - return commonhttp.GetQueryUint64(r, key, defaultValue) +// ConvertUint32 将字符串转换为uint32类型(黑盒模式,推荐使用) +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func (f *Factory) ConvertUint32(value string, defaultValue uint32) uint32 { + return tools.ConvertUint32(value, defaultValue) } -// GetQueryUint32 获取uint32查询参数(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetQueryUint32(r *http.Request, key string, defaultValue uint32) uint32 { - return commonhttp.GetQueryUint32(r, key, defaultValue) +// ConvertBool 将字符串转换为bool类型(黑盒模式,推荐使用) +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func (f *Factory) ConvertBool(value string, defaultValue bool) bool { + return tools.ConvertBool(value, defaultValue) } -// GetQueryBool 获取布尔查询参数(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetQueryBool(r *http.Request, key string, defaultValue bool) bool { - return commonhttp.GetQueryBool(r, key, defaultValue) -} - -// GetQueryFloat64 获取float64查询参数(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetQueryFloat64(r *http.Request, key string, defaultValue float64) float64 { - return commonhttp.GetQueryFloat64(r, key, defaultValue) -} - -// GetFormValue 获取表单值(字符串)(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetFormValue(r *http.Request, key, defaultValue string) string { - return commonhttp.GetFormValue(r, key, defaultValue) -} - -// GetFormInt 获取表单整数(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetFormInt(r *http.Request, key string, defaultValue int) int { - return commonhttp.GetFormInt(r, key, defaultValue) -} - -// GetFormInt64 获取表单int64(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetFormInt64(r *http.Request, key string, defaultValue int64) int64 { - return commonhttp.GetFormInt64(r, key, defaultValue) -} - -// GetFormBool 获取表单布尔值(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 参数名 -// defaultValue: 默认值 -func (f *Factory) GetFormBool(r *http.Request, key string, defaultValue bool) bool { - return commonhttp.GetFormBool(r, key, defaultValue) -} - -// GetHeader 获取请求头(黑盒模式,推荐使用) -// r: HTTP请求 -// key: 请求头名称 -// defaultValue: 默认值 -func (f *Factory) GetHeader(r *http.Request, key, defaultValue string) string { - return commonhttp.GetHeader(r, key, defaultValue) +// ConvertFloat64 将字符串转换为float64类型(黑盒模式,推荐使用) +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func (f *Factory) ConvertFloat64(value string, defaultValue float64) float64 { + return tools.ConvertFloat64(value, defaultValue) } // GetTimezone 从请求的context中获取时区(黑盒模式,推荐使用) diff --git a/http/request.go b/http/request.go index fd8fe57..1b77816 100644 --- a/http/request.go +++ b/http/request.go @@ -4,47 +4,16 @@ import ( "encoding/json" "io" "net/http" - "strconv" "git.toowon.com/jimmy/go-common/middleware" + "git.toowon.com/jimmy/go-common/tools" ) -// getQueryInt 获取整数查询参数(内部方法,供ParsePaginationRequest使用) -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 -} - -// getFormInt 获取表单整数(内部方法,供ParsePaginationRequest使用) -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 -} - // PaginationRequest 分页请求结构 // 支持从JSON和form中解析分页参数 type PaginationRequest struct { Page int `json:"page" form:"page"` // 页码,默认1 - Size int `json:"size" form:"size"` // 每页数量(兼容旧版本) - PageSize int `json:"page_size" form:"page_size"` // 每页数量(推荐使用) + PageSize int `json:"page_size" form:"page_size"` // 每页数量 Keyword string `json:"keyword" form:"keyword"` // 关键字 } @@ -56,13 +25,9 @@ func (p *PaginationRequest) GetPage() int { return p.Page } -// GetSize 获取每页数量,如果未设置则返回默认值20,最大限制100 -// 优先使用 PageSize 字段,如果未设置则使用 Size 字段(兼容旧版本) -func (p *PaginationRequest) GetSize() int { +// GetPageSize 获取每页数量,如果未设置则返回默认值20,最大限制100 +func (p *PaginationRequest) GetPageSize() int { size := p.PageSize - if size <= 0 { - size = p.Size // 兼容旧版本的 Size 字段 - } if size <= 0 { return 20 // 默认20条 } @@ -74,22 +39,20 @@ func (p *PaginationRequest) GetSize() int { // GetOffset 计算数据库查询的偏移量 func (p *PaginationRequest) GetOffset() int { - return (p.GetPage() - 1) * p.GetSize() + return (p.GetPage() - 1) * p.GetPageSize() } // getPaginationFromQuery 从查询参数获取分页参数(内部辅助方法) -func getPaginationFromQuery(r *http.Request) (page, size, pageSize int) { - page = getQueryInt(r, "page", 0) - size = getQueryInt(r, "size", 0) - pageSize = getQueryInt(r, "page_size", 0) +func getPaginationFromQuery(r *http.Request) (page, pageSize int) { + page = tools.ConvertInt(r.URL.Query().Get("page"), 0) + pageSize = tools.ConvertInt(r.URL.Query().Get("page_size"), 0) return } // getPaginationFromForm 从form表单获取分页参数(内部辅助方法) -func getPaginationFromForm(r *http.Request) (page, size, pageSize int) { - page = getFormInt(r, "page", 0) - size = getFormInt(r, "size", 0) - pageSize = getFormInt(r, "page_size", 0) +func getPaginationFromForm(r *http.Request) (page, pageSize int) { + page = tools.ConvertInt(r.FormValue("page"), 0) + pageSize = tools.ConvertInt(r.FormValue("page_size"), 0) return } @@ -101,17 +64,14 @@ func ParsePaginationRequest(r *http.Request) *PaginationRequest { req := &PaginationRequest{} // 1. 从查询参数解析(优先级最高) - req.Page, req.Size, req.PageSize = getPaginationFromQuery(r) + req.Page, req.PageSize = getPaginationFromQuery(r) // 2. 如果查询参数中没有,尝试从form表单解析 - if req.Page == 0 || (req.Size == 0 && req.PageSize == 0) { - page, size, pageSize := getPaginationFromForm(r) + if req.Page == 0 || req.PageSize == 0 { + page, pageSize := getPaginationFromForm(r) if req.Page == 0 && page != 0 { req.Page = page } - if req.Size == 0 && size != 0 { - req.Size = size - } if req.PageSize == 0 && pageSize != 0 { req.PageSize = pageSize } @@ -120,8 +80,6 @@ func ParsePaginationRequest(r *http.Request) *PaginationRequest { return req } -// ========== 请求解析公共方法 ========== - // ParseJSON 解析JSON请求体(公共方法) // r: HTTP请求 // v: 目标结构体指针 @@ -139,196 +97,6 @@ func ParseJSON(r *http.Request, v interface{}) error { 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 -} - -func GetQueryUint64(r *http.Request, key string, defaultValue uint64) uint64 { - value := r.URL.Query().Get(key) - if value == "" { - return defaultValue - } - - uintValue, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return defaultValue - } - - return uintValue -} - -func GetQueryUint32(r *http.Request, key string, defaultValue uint32) uint32 { - value := r.URL.Query().Get(key) - if value == "" { - return defaultValue - } - - uintValue, err := strconv.ParseUint(value, 10, 32) - if err != nil { - return defaultValue - } - - return uint32(uintValue) -} - -// 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中获取时区信息 diff --git a/tools/convertor.go b/tools/convertor.go new file mode 100644 index 0000000..7ad75d5 --- /dev/null +++ b/tools/convertor.go @@ -0,0 +1,99 @@ +package tools + +import "strconv" + +// ConvertInt 将字符串转换为int类型 +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func ConvertInt(value string, defaultValue int) int { + if value == "" { + return defaultValue + } + + intValue, err := strconv.Atoi(value) + if err != nil { + return defaultValue + } + + return intValue +} + +// ConvertInt64 将字符串转换为int64类型 +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func ConvertInt64(value string, defaultValue int64) int64 { + if value == "" { + return defaultValue + } + + intValue, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return defaultValue + } + + return intValue +} + +// ConvertUint64 将字符串转换为uint64类型 +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func ConvertUint64(value string, defaultValue uint64) uint64 { + if value == "" { + return defaultValue + } + + uintValue, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return defaultValue + } + + return uintValue +} + +// ConvertUint32 将字符串转换为uint32类型 +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func ConvertUint32(value string, defaultValue uint32) uint32 { + if value == "" { + return defaultValue + } + + uintValue, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return defaultValue + } + + return uint32(uintValue) +} + +// ConvertBool 将字符串转换为bool类型 +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func ConvertBool(value string, defaultValue bool) bool { + if value == "" { + return defaultValue + } + + boolValue, err := strconv.ParseBool(value) + if err != nil { + return defaultValue + } + + return boolValue +} + +// ConvertFloat64 将字符串转换为float64类型 +// value: 待转换的字符串 +// defaultValue: 转换失败或字符串为空时返回的默认值 +func ConvertFloat64(value string, defaultValue float64) float64 { + if value == "" { + return defaultValue + } + + floatValue, err := strconv.ParseFloat(value, 64) + if err != nil { + return defaultValue + } + + return floatValue +}