feat: export RawEngine api
This commit is contained in:
parent
7336d0d9d2
commit
0b17bf0e71
|
@ -144,6 +144,11 @@ func (r *Register) PreRun(f func() error) error {
|
|||
return f()
|
||||
}
|
||||
|
||||
// RawEngine 获取gin路由引擎
|
||||
func (r *Register) RawEngine() *gin.Engine {
|
||||
return r.engine
|
||||
}
|
||||
|
||||
// Run 服务运行
|
||||
func (r *Register) Run() {
|
||||
if r.addr == "" {
|
||||
|
|
|
@ -26,14 +26,10 @@ func TestRegister_getCallFunc(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewRegister(t *testing.T) {
|
||||
var reg = NewRegister()
|
||||
reg.DefaultRouter(WithGinMode(gin.DebugMode))
|
||||
if err := reg.PreRun(func() error {
|
||||
return nil
|
||||
}); err != nil {
|
||||
// todo
|
||||
}
|
||||
var register = NewRegister()
|
||||
register.DefaultRouter(WithListenAddress(""), WithGinMode(gin.ReleaseMode), WithCors(), WithRecovery())
|
||||
register.PreRun(nil)
|
||||
// protoc core/file_module.proto --coco_out=core --go_out=core
|
||||
//reg.RegisterStruct(AutoGenFileRouterMap, &File{})
|
||||
reg.Run()
|
||||
//reg.RegisterStruct(AutoGenXXXRouterMap, &XXX{})
|
||||
register.Run()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package utils
|
||||
|
||||
import "math"
|
||||
|
||||
// DivisionRoundingUp 除法a/b向上取整
|
||||
func DivisionRoundingUp(a, b int64) int64 {
|
||||
fa := float64(a)
|
||||
fb := float64(b)
|
||||
return int64(math.Ceil(fa / fb))
|
||||
}
|
||||
|
||||
// DivisionRoundingDown 除法a/b向下取整
|
||||
func DivisionRoundingDown(a, b int64) int64 {
|
||||
fa := float64(a)
|
||||
fb := float64(b)
|
||||
return int64(math.Floor(fa / fb))
|
||||
}
|
||||
|
||||
// DivisionRounding 除法a/b四舍五入
|
||||
func DivisionRounding(a, b int64) int64 {
|
||||
fa := float64(a)
|
||||
fb := float64(b)
|
||||
return int64(math.Floor((fa / fb) + 0.5))
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDivisionRounding(t *testing.T) {
|
||||
fmt.Println(DivisionRounding(100, 9))
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// PluckUint64 从一个struct list 中 抽出某uint64字段的slice
|
||||
func PluckUint64(list interface{}, fieldName string) []uint64 {
|
||||
|
||||
var result []uint64
|
||||
|
||||
vo := reflect.ValueOf(list)
|
||||
|
||||
switch vo.Kind() {
|
||||
case reflect.Array, reflect.Slice:
|
||||
for i := 0; i < vo.Len(); i++ {
|
||||
elem := vo.Index(i)
|
||||
for elem.Kind() == reflect.Ptr {
|
||||
elem = elem.Elem()
|
||||
}
|
||||
if elem.Kind() != reflect.Struct {
|
||||
err := errors.New("element not struct")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f := elem.FieldByName(fieldName)
|
||||
if !f.IsValid() {
|
||||
err := fmt.Errorf("struct missed field %s", fieldName)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if f.Kind() != reflect.Uint64 {
|
||||
err := fmt.Errorf("struct element %s type required uint64", fieldName)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
result = append(result, f.Uint())
|
||||
}
|
||||
default:
|
||||
err := errors.New("required list of struct type")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// PluckUint64Map 从一个struct list 中 抽出某uint64字段的map
|
||||
func PluckUint64Map(list interface{}, fieldName string) map[uint64]bool {
|
||||
out := PluckUint64(list, fieldName)
|
||||
res := map[uint64]bool{}
|
||||
for _, v := range out {
|
||||
res[v] = true
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func PluckUint32(list interface{}, fieldName string) []uint32 {
|
||||
var result []uint32
|
||||
|
||||
vo := reflect.ValueOf(list)
|
||||
|
||||
switch vo.Kind() {
|
||||
case reflect.Array, reflect.Slice:
|
||||
for i := 0; i < vo.Len(); i++ {
|
||||
elem := vo.Index(i)
|
||||
for elem.Kind() == reflect.Ptr {
|
||||
elem = elem.Elem()
|
||||
}
|
||||
if elem.Kind() != reflect.Struct {
|
||||
err := errors.New("element not struct")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f := elem.FieldByName(fieldName)
|
||||
if !f.IsValid() {
|
||||
err := fmt.Errorf("struct missed field %s", fieldName)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if f.Kind() != reflect.Uint32 {
|
||||
err := fmt.Errorf("struct element %s type required uint32", fieldName)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
result = append(result, uint32(f.Uint()))
|
||||
}
|
||||
default:
|
||||
err := errors.New("required list of struct type")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func PluckUint32Map(list interface{}, fieldName string) map[uint32]bool {
|
||||
out := PluckUint32(list, fieldName)
|
||||
res := map[uint32]bool{}
|
||||
for _, v := range out {
|
||||
res[v] = true
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// PluckString 从一个struct list 中 抽出某string字段的slice
|
||||
func PluckString(list interface{}, fieldName string) []string {
|
||||
|
||||
var result []string
|
||||
|
||||
vo := reflect.ValueOf(list)
|
||||
|
||||
switch vo.Kind() {
|
||||
case reflect.Array, reflect.Slice:
|
||||
for i := 0; i < vo.Len(); i++ {
|
||||
elem := vo.Index(i)
|
||||
for elem.Kind() == reflect.Ptr {
|
||||
elem = elem.Elem()
|
||||
}
|
||||
if elem.Kind() != reflect.Struct {
|
||||
err := errors.New("element not struct")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
f := elem.FieldByName(fieldName)
|
||||
if !f.IsValid() {
|
||||
err := fmt.Errorf("struct missed field %s", fieldName)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if f.Kind() != reflect.String {
|
||||
err := fmt.Errorf("struct element %s type required string", fieldName)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
result = append(result, f.String())
|
||||
}
|
||||
default:
|
||||
err := errors.New("required list of struct type")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func PluckStringMap(list interface{}, fieldName string) map[string]bool {
|
||||
out := PluckString(list, fieldName)
|
||||
res := map[string]bool{}
|
||||
for _, v := range out {
|
||||
res[v] = true
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// KeyByMap 从一个struct list 中 根据某字段 转成一个以该字段为key的map
|
||||
// list 是 []StructType
|
||||
// res 是 *map[fieldType]StructType
|
||||
func KeyByMap(list interface{}, fieldName string, res interface{}) {
|
||||
// 取下 field type
|
||||
vo := EnsureIsSliceOrArray(list)
|
||||
elType := vo.Type().Elem()
|
||||
|
||||
t := elType
|
||||
for t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("slice or array element required struct type, but got %v", t))
|
||||
}
|
||||
|
||||
var keyType reflect.Type
|
||||
if sf, ok := t.FieldByName(fieldName); ok {
|
||||
keyType = sf.Type
|
||||
} else {
|
||||
panic(fmt.Sprintf("not found field %s", fieldName))
|
||||
}
|
||||
|
||||
m := reflect.MakeMap(reflect.MapOf(keyType, elType))
|
||||
|
||||
resVo := reflect.ValueOf(res)
|
||||
if resVo.Kind() != reflect.Ptr {
|
||||
panic(fmt.Sprintf("invalid res type %v, required *map[key]val", resVo.Type()))
|
||||
}
|
||||
resVo = resVo.Elem()
|
||||
EnsureIsMapType(resVo, keyType, elType)
|
||||
|
||||
l := vo.Len()
|
||||
for i := 0; i < l; i++ {
|
||||
el := vo.Index(i)
|
||||
elDef := el
|
||||
for elDef.Kind() == reflect.Ptr {
|
||||
elDef = elDef.Elem()
|
||||
}
|
||||
f := elDef.FieldByName(fieldName)
|
||||
if !f.IsValid() {
|
||||
continue
|
||||
}
|
||||
m.SetMapIndex(f, el)
|
||||
}
|
||||
|
||||
resVo.Set(m)
|
||||
}
|
||||
|
||||
// 基本数据类型的判断是否在数组内,是则返回true以及下标
|
||||
func BaseTypeInArray(val interface{}, array interface{}) (exists bool, index int) {
|
||||
exists = false
|
||||
index = -1
|
||||
switch reflect.TypeOf(array).Kind() {
|
||||
case reflect.Slice:
|
||||
s := reflect.ValueOf(array)
|
||||
length := s.Len()
|
||||
for i := 0; i < length; i++ {
|
||||
if reflect.DeepEqual(val, s.Index(i).Interface()) == true {
|
||||
index = i
|
||||
exists = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPluck(t *testing.T) {
|
||||
type S struct {
|
||||
Id uint64
|
||||
}
|
||||
|
||||
arr := []S{
|
||||
{
|
||||
Id: 1,
|
||||
},
|
||||
{
|
||||
Id: 2,
|
||||
},
|
||||
}
|
||||
|
||||
out := PluckUint64(arr, "Id")
|
||||
log.Infof("out %+v", out)
|
||||
|
||||
out = PluckUint64("", "Id")
|
||||
log.Infof("out %+v", out)
|
||||
}
|
||||
|
||||
func TestKeyBy(t *testing.T) {
|
||||
type T struct {
|
||||
Id uint32
|
||||
Name string
|
||||
}
|
||||
|
||||
list := []T{
|
||||
{
|
||||
Id: 1,
|
||||
Name: "hello",
|
||||
},
|
||||
{
|
||||
Id: 2,
|
||||
Name: "world",
|
||||
},
|
||||
}
|
||||
|
||||
var m map[uint32]T
|
||||
KeyByMap(list, "Id", &m)
|
||||
|
||||
log.Infof("m is %+v", m)
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ReflectGet(obj interface{}, path string, failHint *string) (res interface{}, success bool) {
|
||||
setFailHint := func(hint string) {
|
||||
if failHint != nil {
|
||||
*failHint = hint
|
||||
}
|
||||
}
|
||||
for obj != nil && path != "" {
|
||||
v := reflect.ValueOf(obj)
|
||||
for v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() != reflect.Struct {
|
||||
setFailHint("not struct type")
|
||||
break
|
||||
}
|
||||
|
||||
var fieldName string
|
||||
pos := strings.IndexByte(path, '.')
|
||||
if pos < 0 {
|
||||
fieldName = path
|
||||
path = ""
|
||||
} else {
|
||||
fieldName = path[:pos]
|
||||
path = path[pos+1:]
|
||||
}
|
||||
|
||||
f := v.FieldByName(fieldName)
|
||||
if !f.IsValid() {
|
||||
setFailHint(fmt.Sprintf("%s not found", fieldName))
|
||||
break
|
||||
}
|
||||
|
||||
if path == "" {
|
||||
res = f.Interface()
|
||||
success = true
|
||||
break
|
||||
}
|
||||
|
||||
obj = f.Interface()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ReflectGetInt(obj interface{}, path string, failHint *string) (res int, success bool) {
|
||||
setFailHint := func(hint string) {
|
||||
if failHint != nil {
|
||||
*failHint = hint
|
||||
}
|
||||
}
|
||||
|
||||
var i interface{}
|
||||
i, success = ReflectGet(obj, path, failHint)
|
||||
if !success {
|
||||
return
|
||||
}
|
||||
switch v := i.(type) {
|
||||
case int:
|
||||
res = v
|
||||
success = true
|
||||
case int32:
|
||||
res = int(v)
|
||||
success = true
|
||||
default:
|
||||
setFailHint(fmt.Sprintf("type not match: %s", reflect.TypeOf(i).String()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ReflectGetStr(obj interface{}, path string, failHint *string) (res string, success bool) {
|
||||
setFailHint := func(hint string) {
|
||||
if failHint != nil {
|
||||
*failHint = hint
|
||||
}
|
||||
}
|
||||
|
||||
var i interface{}
|
||||
i, success = ReflectGet(obj, path, failHint)
|
||||
if !success {
|
||||
return
|
||||
}
|
||||
switch v := i.(type) {
|
||||
case string:
|
||||
res = v
|
||||
success = true
|
||||
case []byte:
|
||||
res = string(v)
|
||||
success = true
|
||||
default:
|
||||
setFailHint(fmt.Sprintf("type not match: %s", reflect.TypeOf(i).String()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Interface2Int(i interface{}) int {
|
||||
vo := reflect.ValueOf(i)
|
||||
vk := vo.Kind()
|
||||
switch vk {
|
||||
case reflect.Uint, reflect.Uint32, reflect.Uint64, reflect.Uint8, reflect.Uint16:
|
||||
return int(vo.Uint())
|
||||
}
|
||||
return int(vo.Int())
|
||||
}
|
||||
|
||||
func Interface2String(i interface{}) string {
|
||||
vo := reflect.ValueOf(i)
|
||||
if vo.Kind() != reflect.String {
|
||||
log.Infof("expected string type, but got %v", vo.Type())
|
||||
panic("expected string type")
|
||||
}
|
||||
return vo.String()
|
||||
}
|
||||
|
||||
func EnsureIsSliceOrArray(obj interface{}) (res reflect.Value) {
|
||||
vo := reflect.ValueOf(obj)
|
||||
for vo.Kind() == reflect.Ptr || vo.Kind() == reflect.Interface {
|
||||
vo = vo.Elem()
|
||||
}
|
||||
k := vo.Kind()
|
||||
if k != reflect.Slice && k != reflect.Array {
|
||||
panic(fmt.Sprintf("obj required slice or array type, but got %v", vo.Type()))
|
||||
}
|
||||
res = vo
|
||||
return
|
||||
}
|
||||
|
||||
func EnsureIsMapType(m reflect.Value, keyType, valType reflect.Type) {
|
||||
if m.Kind() != reflect.Map {
|
||||
panic(fmt.Sprintf("required map type, but got %v", m.Type()))
|
||||
}
|
||||
|
||||
t := m.Type()
|
||||
if t.Key() != keyType {
|
||||
panic(fmt.Sprintf("map key type not equal, %v != %v", t.Key(), keyType))
|
||||
}
|
||||
|
||||
if t.Elem() != valType {
|
||||
panic(fmt.Sprintf("map val type not equal, %v != %v", t.Elem(), valType))
|
||||
}
|
||||
}
|
||||
|
||||
func ClearSlice(ptr interface{}) {
|
||||
vo := reflect.ValueOf(ptr)
|
||||
if vo.Kind() != reflect.Ptr {
|
||||
panic("required ptr to slice type")
|
||||
}
|
||||
for vo.Kind() == reflect.Ptr {
|
||||
vo = vo.Elem()
|
||||
}
|
||||
if vo.Kind() != reflect.Slice {
|
||||
panic("required ptr to slice type")
|
||||
}
|
||||
vo.Set(reflect.MakeSlice(vo.Type(), 0, 0))
|
||||
}
|
||||
|
||||
func GetSliceLen(i interface{}) int {
|
||||
vo := reflect.ValueOf(i)
|
||||
for vo.Kind() == reflect.Ptr {
|
||||
vo = vo.Elem()
|
||||
}
|
||||
if vo.Kind() != reflect.Slice && vo.Kind() != reflect.Array {
|
||||
panic("required slice or array type")
|
||||
}
|
||||
return vo.Len()
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type A struct {
|
||||
I int
|
||||
}
|
||||
|
||||
type B struct {
|
||||
AA *A
|
||||
}
|
||||
|
||||
func TestReflectGetInt(t *testing.T) {
|
||||
var b B
|
||||
b.AA = &A{}
|
||||
b.AA.I = 10
|
||||
var h string
|
||||
i, success := ReflectGetInt(&b, "AA.I", &h)
|
||||
if success {
|
||||
log.Infof("got %d", i)
|
||||
} else {
|
||||
log.Warnf("get fail %s", h)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterface2Int(t *testing.T) {
|
||||
i := Interface2Int(int64(-10))
|
||||
log.Infof("i %d", i)
|
||||
}
|
||||
|
||||
func TestReflectGetStr(t *testing.T) {
|
||||
|
||||
var typ = &struct {
|
||||
A string
|
||||
B uint64
|
||||
}{
|
||||
A: "hello",
|
||||
B: 100,
|
||||
}
|
||||
|
||||
var c interface{} = typ
|
||||
|
||||
res, _ := ReflectGetStr(c, "A", nil)
|
||||
log.Infof(res)
|
||||
}
|
||||
|
||||
func TestClearSlicePtr(t *testing.T) {
|
||||
l := []int{1, 2, 3}
|
||||
p := &l
|
||||
ClearSlice(&p)
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package utils
|
||||
|
||||
import "time"
|
||||
|
||||
// GetTimeNowUnix 获取当前时间的标准时间戳
|
||||
func GetTimeNowUnix() int64 {
|
||||
return time.Now().Unix()
|
||||
}
|
||||
|
||||
// GetTimeNowUnixMilli 获取当前时间的毫秒时间戳
|
||||
func GetTimeNowUnixMilli() int64 {
|
||||
return time.Now().UnixNano() / 1e6
|
||||
}
|
||||
|
||||
// UnixMilli2Time 毫秒时间戳转 time.Time 结构
|
||||
func UnixMilli2Time(u int64) time.Time {
|
||||
return time.Unix(u/1e3, 0)
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetTimeNowMillisecond(t *testing.T) {
|
||||
fmt.Println(GetTimeNowUnixMilli())
|
||||
}
|
||||
|
||||
func TestUnixMilli2Time(t *testing.T) {
|
||||
fmt.Println(UnixMilli2Time(1631693848445).Unix())
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Struct2UrlValues 将struct转为 url.Values 结构 只操作第一层 不嵌套
|
||||
// 如果有json标签 将依照json标签作为key 否则按照字段名做key
|
||||
// 如果struct字段为空 依然会将空值写入 url.Values 中
|
||||
func Struct2UrlValues(obj interface{}) url.Values {
|
||||
if obj == nil {
|
||||
panic("object is nil")
|
||||
}
|
||||
|
||||
var u = url.Values{}
|
||||
vo := reflect.ValueOf(obj)
|
||||
to := reflect.TypeOf(obj)
|
||||
|
||||
if vo.Kind() == reflect.Ptr {
|
||||
vo = vo.Elem()
|
||||
}
|
||||
if to.Kind() == reflect.Ptr {
|
||||
to = to.Elem()
|
||||
}
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fieldType := to.Field(i)
|
||||
|
||||
if fieldType.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldName := fieldType.Name
|
||||
fieldTag := fieldType.Tag.Get("json")
|
||||
if fieldTag != "" {
|
||||
fieldName = strings.Replace(fieldTag, ",omitempty", "", 1)
|
||||
}
|
||||
fieldValue := vo.Field(i)
|
||||
if fieldValue.Kind() == reflect.Ptr || fieldValue.Kind() == reflect.Struct ||
|
||||
fieldValue.Kind() == reflect.Map || fieldValue.Kind() == reflect.Slice ||
|
||||
fieldValue.Kind() == reflect.Array || fieldValue.Kind() == reflect.Chan ||
|
||||
fieldValue.Kind() == reflect.Func || fieldValue.Kind() == reflect.Interface ||
|
||||
fieldValue.Kind() == reflect.Complex64 || fieldValue.Kind() == reflect.Complex128 ||
|
||||
fieldValue.Kind() == reflect.Invalid || fieldValue.Kind() == reflect.Uintptr ||
|
||||
fieldValue.Kind() == reflect.UnsafePointer {
|
||||
continue
|
||||
}
|
||||
v := fmt.Sprintf("%+v", fieldValue.Interface())
|
||||
u.Set(fieldName, v)
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// Struct2UrlValuesOmitEmpty Struct2UrlValues 忽略空值字段
|
||||
func Struct2UrlValuesOmitEmpty(obj interface{}) url.Values {
|
||||
if obj == nil {
|
||||
panic("object is nil")
|
||||
}
|
||||
|
||||
var u = url.Values{}
|
||||
vo := reflect.ValueOf(obj)
|
||||
to := reflect.TypeOf(obj)
|
||||
|
||||
if vo.Kind() == reflect.Ptr {
|
||||
vo = vo.Elem()
|
||||
}
|
||||
if to.Kind() == reflect.Ptr {
|
||||
to = to.Elem()
|
||||
}
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fieldType := to.Field(i)
|
||||
|
||||
if fieldType.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
fieldName := fieldType.Name
|
||||
fieldTag := fieldType.Tag.Get("json")
|
||||
if fieldTag != "" {
|
||||
fieldName = strings.Replace(fieldTag, ",omitempty", "", 1)
|
||||
}
|
||||
fieldValue := vo.Field(i)
|
||||
if fieldValue.Kind() == reflect.Ptr || fieldValue.Kind() == reflect.Struct ||
|
||||
fieldValue.Kind() == reflect.Map || fieldValue.Kind() == reflect.Slice ||
|
||||
fieldValue.Kind() == reflect.Array || fieldValue.Kind() == reflect.Chan ||
|
||||
fieldValue.Kind() == reflect.Func || fieldValue.Kind() == reflect.Interface ||
|
||||
fieldValue.Kind() == reflect.Complex64 || fieldValue.Kind() == reflect.Complex128 ||
|
||||
fieldValue.Kind() == reflect.Invalid || fieldValue.Kind() == reflect.Uintptr ||
|
||||
fieldValue.Kind() == reflect.UnsafePointer {
|
||||
continue
|
||||
}
|
||||
|
||||
if fieldValue.IsZero() {
|
||||
continue
|
||||
}
|
||||
v := fmt.Sprintf("%+v", fieldValue.Interface())
|
||||
u.Set(fieldName, v)
|
||||
}
|
||||
return u
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStruct2UrlValues(t *testing.T) {
|
||||
type A struct {
|
||||
AccountType int32 `protobuf:"varint,1,opt,name=accountType,proto3" json:"accountType,omitempty"` // 用户账号类型 2:微信开放账号
|
||||
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` // 微信用户则填入对应的 openid/unionid
|
||||
UserIp string `protobuf:"bytes,3,opt,name=userIp,proto3" json:"userIp,omitempty"` // 用户领取奖励时的真实外网 IP
|
||||
PostTime int64 `protobuf:"varint,4,opt,name=postTime,proto3" json:"postTime,omitempty"` // 用户操作时间戳,单位秒(格林威治时间精确到秒,如1501590972)。
|
||||
WxSubType int32 `protobuf:"varint,5,opt,name=wxSubType,proto3" json:"wxSubType,omitempty"` // 1:微信公众号 2:微信小程序。
|
||||
WxToken string `protobuf:"bytes,6,opt,name=wxToken,proto3" json:"wxToken,omitempty"` // wxSubType = 1:微信公众号或第三方登录,则为授权的 access_token
|
||||
AppId string `protobuf:"bytes,7,opt,name=appId,proto3" json:"appId,omitempty"` // 天御appId
|
||||
RandNum string `protobuf:"bytes,8,opt,name=randNum,proto3" json:"randNum,omitempty"` // 随机数
|
||||
}
|
||||
|
||||
var a = A{}
|
||||
u := Struct2UrlValues(a)
|
||||
fmt.Println(u.Encode())
|
||||
}
|
||||
|
||||
func TestStruct2UrlValuesOmitEmpty(t *testing.T) {
|
||||
type A struct {
|
||||
AccountType int32 `protobuf:"varint,1,opt,name=accountType,proto3" json:"accountType,omitempty"` // 用户账号类型 2:微信开放账号
|
||||
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` // 微信用户则填入对应的 openid/unionid
|
||||
UserIp string `protobuf:"bytes,3,opt,name=userIp,proto3" json:"userIp,omitempty"` // 用户领取奖励时的真实外网 IP
|
||||
PostTime int64 `protobuf:"varint,4,opt,name=postTime,proto3" json:"postTime,omitempty"` // 用户操作时间戳,单位秒(格林威治时间精确到秒,如1501590972)。
|
||||
WxSubType int32 `protobuf:"varint,5,opt,name=wxSubType,proto3" json:"wxSubType,omitempty"` // 1:微信公众号 2:微信小程序。
|
||||
WxToken string `protobuf:"bytes,6,opt,name=wxToken,proto3" json:"wxToken,omitempty"` // wxSubType = 1:微信公众号或第三方登录,则为授权的 access_token
|
||||
AppId string `protobuf:"bytes,7,opt,name=appId,proto3" json:"appId,omitempty"` // 天御appId
|
||||
RandNum string `protobuf:"bytes,8,opt,name=randNum,proto3" json:"randNum,omitempty"` // 随机数
|
||||
}
|
||||
|
||||
var a = A{}
|
||||
u := Struct2UrlValuesOmitEmpty(a)
|
||||
fmt.Println(u.Encode())
|
||||
}
|
Loading…
Reference in New Issue