Files
gb-cms/common/http_request.go
2025-09-14 21:41:03 +08:00

179 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package common
import (
"gb-cms/log"
"net/http"
"reflect"
"strconv"
)
// parseQueryParams 使用反射解析 URL 查询参数并填充到结构体中
func parseQueryParams(c func(key string) string, v interface{}) (interface{}, error) {
val := reflect.ValueOf(v)
if val.Kind() == reflect.Ptr {
if val.IsNil() {
// 如果指针为 nil创建一个新的实例
val = reflect.New(val.Type().Elem())
}
val = val.Elem()
}
if val.Kind() != reflect.Struct {
return nil, nil
}
typ := val.Type()
for i := 0; i < val.NumField(); i++ {
field := typ.Field(i)
fieldValue := val.Field(i)
// 处理组合字段
if field.Anonymous {
embedded := reflect.New(field.Type).Elem()
if _, err := parseQueryParams(c, embedded.Addr().Interface()); err != nil {
return nil, err
}
fieldValue.Set(embedded)
continue
}
// 获取字段名
fieldName := field.Tag.Get("json")
if fieldName == "" {
fieldName = field.Name
}
// 从 URL 参数中获取值
value := c(fieldName)
if value == "" {
continue
}
// 根据字段类型设置值
switch fieldValue.Kind() {
case reflect.String:
fieldValue.SetString(value)
break
case reflect.Int:
intValue, err := strconv.Atoi(value)
if err != nil {
return nil, err
}
fieldValue.SetInt(int64(intValue))
break
case reflect.Bool:
boolValue, err := strconv.ParseBool(value)
if err != nil {
return nil, err
}
fieldValue.SetBool(boolValue)
break
case reflect.Float64:
floatValue, err := strconv.ParseFloat(value, 64)
if err != nil {
return nil, err
}
fieldValue.SetFloat(floatValue)
break
case reflect.Float32:
floatValue, err := strconv.ParseFloat(value, 32)
if err != nil {
return nil, err
}
fieldValue.SetFloat(floatValue)
break
}
}
return val.Addr().Interface(), nil
}
func WithJsonParams[T any](f func(params T, w http.ResponseWriter, req *http.Request), params T) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
newParams := new(T)
if err := HttpDecodeJSONBody(w, req, newParams); err != nil {
log.Sugar.Errorf("解析请求体失败 err: %s path: %s", err.Error(), req.URL.Path)
_ = HttpResponseError(w, err.Error())
return
}
f(*newParams, w, req)
}
}
func WithJsonResponse[T any](f func(params T, w http.ResponseWriter, req *http.Request) (interface{}, error), params interface{}) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
newParams := new(T)
if err := HttpDecodeJSONBody(w, req, newParams); err != nil {
log.Sugar.Errorf("解析请求体失败 err: %s path: %s", err.Error(), req.URL.Path)
_ = HttpResponseError(w, err.Error())
return
}
responseBody, err := f(*newParams, w, req)
if err != nil {
_ = HttpResponseError(w, err.Error())
} else if responseBody != nil {
_ = HttpResponseOK(w, responseBody)
}
}
}
func WithQueryStringParams[T any](f func(params T, w http.ResponseWriter, req *http.Request) (interface{}, error), params interface{}) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
var newParams T
query := req.URL.Query()
result, err := parseQueryParams(func(key string) string {
if key == "token" {
cookie, err := req.Cookie("token")
if err != nil {
panic(err)
}
return cookie.Value
}
return query.Get(key)
}, newParams)
if err != nil {
_ = HttpResponseError(w, err.Error())
return
}
responseBody, err := f(result.(T), w, req)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
_ = HttpResponseJson(w, err.Error())
} else if responseBody != nil {
_ = HttpResponseJson(w, responseBody)
}
}
}
func WithFormDataParams[T any](f func(params T, w http.ResponseWriter, req *http.Request) (interface{}, error), params interface{}) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
var newParams T
result, err := parseQueryParams(func(key string) string {
if key == "token" {
cookie, err := req.Cookie("token")
if err != nil {
panic(err)
}
return cookie.Value
}
return req.FormValue(key)
}, newParams)
if err != nil {
_ = HttpResponseError(w, err.Error())
return
}
responseBody, err := f(result.(T), w, req)
if err != nil {
_ = HttpResponseJson(w, err.Error())
} else if responseBody != nil {
_ = HttpResponseJson(w, responseBody)
}
}
}