mirror of
https://github.com/lkmio/gb-cms.git
synced 2025-09-27 03:56:08 +08:00
179 lines
4.4 KiB
Go
179 lines
4.4 KiB
Go
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)
|
||
}
|
||
}
|
||
}
|