支持通过controller自动解析注册接口路由 #2
47
go.mod
47
go.mod
@ -5,44 +5,41 @@ go 1.21.0
|
|||||||
toolchain go1.23.1
|
toolchain go1.23.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00
|
||||||
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465
|
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06
|
||||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240725055115-98eb52ae307a
|
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad
|
||||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442
|
git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241104092308-ecb02113459e
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241013112816-e3de2835a971
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
github.com/go-playground/validator/v10 v10.22.1
|
github.com/go-playground/validator/v10 v10.24.0
|
||||||
github.com/mcuadros/go-defaults v1.2.0
|
github.com/mcuadros/go-defaults v1.2.0
|
||||||
github.com/pkg/errors v0.9.1
|
|
||||||
github.com/sbabiv/xml2map v1.2.1
|
github.com/sbabiv/xml2map v1.2.1
|
||||||
github.com/stretchr/testify v1.9.0
|
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda // indirect
|
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 // indirect
|
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 // indirect
|
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e // indirect
|
||||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||||
github.com/bytedance/sonic v1.12.4 // indirect
|
github.com/bytedance/sonic v1.12.8 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.2.1 // indirect
|
github.com/bytedance/sonic/loader v0.2.3 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect
|
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.6 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v1.0.0 // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/goccy/go-json v0.10.3 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
|
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
|
||||||
github.com/lestrrat-go/strftime v1.1.0 // indirect
|
github.com/lestrrat-go/strftime v1.1.0 // indirect
|
||||||
@ -53,7 +50,7 @@ require (
|
|||||||
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
||||||
github.com/mssola/user_agent v0.6.0 // indirect
|
github.com/mssola/user_agent v0.6.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
github.com/tidwall/gjson v1.18.0 // indirect
|
github.com/tidwall/gjson v1.18.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
@ -61,12 +58,12 @@ require (
|
|||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/arch v0.11.0 // indirect
|
golang.org/x/arch v0.14.0 // indirect
|
||||||
golang.org/x/crypto v0.28.0 // indirect
|
golang.org/x/crypto v0.32.0 // indirect
|
||||||
golang.org/x/net v0.30.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.26.0 // indirect
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
golang.org/x/text v0.19.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
google.golang.org/protobuf v1.35.1 // indirect
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 // indirect
|
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
134
go.sum
134
go.sum
@ -1,55 +1,50 @@
|
|||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7 h1:tyCPCMK+68PZ0axZylQHitMVp1d5mzNr9/YqMHXqo+A=
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00 h1:obyJF0CXVR93TOnOtzN5xXxxSLpw1UFMBc4niWiyoQI=
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240924065029-c865046cd9e7/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241015035056-b6f4a6512763 h1:aG59AjZAn/Y+smWoa6l6HQB+yh/Rpml79EvmfjEb6Ks=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241015035056-b6f4a6512763/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241023090605-10cff9173059 h1:TPAYdTKKUjgxtCnK38d1Tb4teyQp1C7wYHPdR32yZtM=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241023090605-10cff9173059/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104081823-ab1d691f309d h1:LvQIKDKQ6NNgX/3l3A7tukOFcUeTzC1kEZSeq8eIdUU=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104081823-ab1d691f309d/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3 h1:BiAlBJ+DuRs/xD7nDQD2JT8Oc+V+0Uwt36qZwdXGvzI=
|
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
|
||||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda h1:bMD6r9gjRy7cO+T4zRQVYAesgIblBdTnhzT1vN5wjvI=
|
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda h1:bMD6r9gjRy7cO+T4zRQVYAesgIblBdTnhzT1vN5wjvI=
|
||||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda/go.mod h1:dT0rmHcJ9Z9IqWeMIt7YzR88nKkNV2V3dfG0j9Q6lK0=
|
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda/go.mod h1:dT0rmHcJ9Z9IqWeMIt7YzR88nKkNV2V3dfG0j9Q6lK0=
|
||||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0=
|
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw=
|
||||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211/go.mod h1:SrtvrQRdzt+8KfYzvosH++gWxo2ShPTzR1m3VQ6uX7U=
|
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4/go.mod h1:V4Dfg1v/JVIZGEKCm6/aehs8hK+Xow1dkL1yiQymXlQ=
|
||||||
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20231105153815-e8561a060cc8/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw=
|
|
||||||
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465 h1:j5EB0hamTMT5fY+xmjJ51oBvll+vS2inNPi+3/UBj60=
|
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465 h1:j5EB0hamTMT5fY+xmjJ51oBvll+vS2inNPi+3/UBj60=
|
||||||
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw=
|
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw=
|
||||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240725055115-98eb52ae307a h1:22VkxGmpS58zHA8tf75lPr/3S6hmHKP00w/jUa700Ps=
|
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091353-907c20662792 h1:BehqU7W+FF39xCcrbrlPBggbKVTIguDDXfABn8l5RB4=
|
||||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240725055115-98eb52ae307a/go.mod h1:phaF6LMebn7Fpp8J/mOzHRYGniKuCk78k4N53T2m8NI=
|
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091353-907c20662792/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw=
|
||||||
|
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06 h1:XsjGMkBCi93h56oCg5Lrz5zVpUxify/CQVhQU9+qLWM=
|
||||||
|
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250207091724-ca151fbc1f06/go.mod h1:Voc8J4ordx7nuMWpgACXXZULQy7ZIuBzcEIoS8VnDIw=
|
||||||
|
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad h1:6BI3QiDI64SlER1006UJbTJyOCXxB8KCmCK+Kr7FzQo=
|
||||||
|
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20241125083316-eab7bab9d7ad/go.mod h1:+jPQTyCEQqMWhq4p1LowQWq15emisON+++87ArTgwNA=
|
||||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 h1:1eBf0C0gdpBQOqjTK3UCw/mwzQ/SCodx3iTQtidx9eE=
|
git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442 h1:1eBf0C0gdpBQOqjTK3UCw/mwzQ/SCodx3iTQtidx9eE=
|
||||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442/go.mod h1:hFYWiS+ExIuJJJdwHWy4P3pVHbd/0mpv53qlbhDNdTI=
|
git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442/go.mod h1:hFYWiS+ExIuJJJdwHWy4P3pVHbd/0mpv53qlbhDNdTI=
|
||||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
|
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQMuJ4xNfP2Abl1Msmpa3fASLWYkNlqDFF/6GN0Y=
|
||||||
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
|
git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd h1:2Y37waOVCmVvx0Rp8VGEptE2/2JVMImtxB4dKKDk/3w=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240618035451-8d48a6bd39dd/go.mod h1:6+7whkCmb4sJDIfH3HxNuXRveaM0gCCNWd2uXZqNtIE=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241023104258-2e0a298aa558 h1:ZVJyyDKfYeA3TsN8UOi4IprkouK4wIIfCKe+F9byLWA=
|
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241023104258-2e0a298aa558/go.mod h1:/9eicss/Dt9tp2jwZ/4cXDqDKo/Dez+HuT5/NGdqW+s=
|
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241104092308-ecb02113459e h1:A045F67AMSqFKGD9kk2uLa+6c/zpmW8vjjSRmSsdjPs=
|
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241104092308-ecb02113459e/go.mod h1:XqgER4jDYwskFgj2riJ9XptIjzgYWubY+Zq8iB2WkY0=
|
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 h1:P2kuhU2TFWk9mPbJlZCK6FMDVS7S3NGafWKD4eNqKiI=
|
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 h1:P2kuhU2TFWk9mPbJlZCK6FMDVS7S3NGafWKD4eNqKiI=
|
||||||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2/go.mod h1:7KaMpQmWgiNLpEkaV7oDtep7geI1f/VoCoPVcyvMjAE=
|
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2/go.mod h1:7KaMpQmWgiNLpEkaV7oDtep7geI1f/VoCoPVcyvMjAE=
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1 h1:LYw8NJeWcOiyrGjH9weyxnaMit94MlIngL+uskbLjtw=
|
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e h1:YE2Gi+M03UDImIpWa3I7jzSesyfu2RL8x/4ONs5v0oE=
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240924063449-ef80c6cb79d1/go.mod h1:+2qNxuRsfyfOvXk9HNwn+CmyPmmhhrQm/eIi1FDU1jw=
|
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e/go.mod h1:L/7JugxKZL3JP9JP/XDvPAPz0FQXG1u181Su1+u/d1c=
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241013112816-e3de2835a971 h1:vCkhZliMy2H+OqhcIyhPYQcH13wFuYb9LUeAu71ToNA=
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9 h1:yF770WIDNwyiKL0nwmBGmjZvNCLXtHQL4xJyffPjTMU=
|
||||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241013112816-e3de2835a971/go.mod h1:+2qNxuRsfyfOvXk9HNwn+CmyPmmhhrQm/eIi1FDU1jw=
|
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9/go.mod h1:I76wxEsWq7KnMQ84elpwTjEqq4I49QFw60tp5h7iGBs=
|
||||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||||
github.com/bytedance/sonic v1.12.3 h1:W2MGa7RCU1QTeYRTPE3+88mVC0yXmsRQRChiyVocVjU=
|
github.com/bytedance/sonic v1.12.5 h1:hoZxY8uW+mT+OpkcUWw4k0fDINtOcVavEsGfzwzFU/w=
|
||||||
github.com/bytedance/sonic v1.12.3/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
github.com/bytedance/sonic v1.12.5/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||||
github.com/bytedance/sonic v1.12.4 h1:9Csb3c9ZJhfUWeMtpCDCq6BUoH5ogfDFLUgQ/jG+R0k=
|
github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q=
|
||||||
github.com/bytedance/sonic v1.12.4/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I=
|
||||||
|
github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs=
|
||||||
|
github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
|
|
||||||
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
|
||||||
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
|
github.com/bytedance/sonic/loader v0.2.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
|
||||||
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.2.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
|
github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0=
|
||||||
|
github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
|
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||||
|
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -58,12 +53,12 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU=
|
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1 h1:CaO/zOnF8VvUfEbhRatPcwKVWamvbYd8tQGRWacE9kU=
|
||||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
|
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc=
|
|
||||||
github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc=
|
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
|
github.com/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
|
||||||
|
github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=
|
||||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||||
@ -74,13 +69,19 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
|||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
|
github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
|
||||||
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
|
||||||
|
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
||||||
@ -88,8 +89,8 @@ github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUB
|
|||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
@ -135,15 +136,17 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
@ -161,34 +164,33 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
|||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
|
golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
|
||||||
golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/arch v0.11.0 h1:KXV8WWKCXm6tRpLirl2szsO5j/oOODwZf4hATmGVNs4=
|
golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA=
|
||||||
golang.org/x/arch v0.11.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
|
||||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
|
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||||
|
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/mcuadros/go-defaults"
|
"github.com/mcuadros/go-defaults"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -43,7 +42,7 @@ func (f *form) Parse(ctx *gin.Context, receiver interface{}) error {
|
|||||||
// 请求信息写入上下文
|
// 请求信息写入上下文
|
||||||
ctx.Set(handleConfig.RecordRequestDataField, string(requestBody))
|
ctx.Set(handleConfig.RecordRequestDataField, string(requestBody))
|
||||||
// 因为请求体被读一遍之后就没了,重新赋值 requestBody
|
// 因为请求体被读一遍之后就没了,重新赋值 requestBody
|
||||||
ctx.Request.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
|
ctx.Request.Body = io.NopCloser(bytes.NewReader(requestBody))
|
||||||
method := strings.ToUpper(ctx.Request.Method)
|
method := strings.ToUpper(ctx.Request.Method)
|
||||||
if method == http.MethodGet ||
|
if method == http.MethodGet ||
|
||||||
method == http.MethodPatch ||
|
method == http.MethodPatch ||
|
||||||
|
110
router/README.md
Normal file
110
router/README.md
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# 路由包使用说明
|
||||||
|
|
||||||
|
## 基础说明
|
||||||
|
|
||||||
|
- 基于 [web框架GIN](https://github.com/gin-gonic/gin) 的二次封装
|
||||||
|
|
||||||
|
## 为什么要二次封装
|
||||||
|
|
||||||
|
二次封装的想法来源于 [web框架GoFrame](https://github.com/gogf/gf)。gf框架本身内置集成了大量组件, 对于轻量应用开发, 相比较而言比较笨重, 但是启根据请求数据结构、响应数据结构自动生成表单的能力十分实用。
|
||||||
|
在采用gin开发时,一般接口文档有两种选择 :
|
||||||
|
- 在内部文档平台手搓文档, 并人工维护, 此方案最终演变方式大概率为文档主键滞后,与接口实现并不一致
|
||||||
|
- 利用golang的文档生成工具[swag]() 自动生成swagger文档, 此种方案需要在代码中引入大量swag工具解析时需要的注释, 且当输入/输出发生变化时需要维护相关注释
|
||||||
|
基于以上问题, 对gin的路由注册进行二次封装
|
||||||
|
|
||||||
|
## 二次封装解决哪些问题
|
||||||
|
|
||||||
|
- 文档维护的繁琐性 : 会通过反射自动基于 **`请求的数据结构 + 返回的数据结构`** , 生成接口文档, 专注于数据结构设计即可, 无需关注文档相关内容, 程序接管, 自动生成
|
||||||
|
- 做接口设计的统一性规范约束, 如 :
|
||||||
|
- 入参数据类型不能为 any
|
||||||
|
- 入参类型不能为 map , 但是特定字段特定场景, 可以强行禁用此规则等
|
||||||
|
- 返回值必须为结构体等
|
||||||
|
|
||||||
|
## 设计方案
|
||||||
|
|
||||||
|
### 【可选】路由组定义
|
||||||
|
|
||||||
|
路由组可以通过函数进行定义, 函数名必须需为 : **`RouterPrefix`** , 函数无任何参数, 返回路由组名称, 示例 :
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TestController struct{}
|
||||||
|
|
||||||
|
func (t *TestController) RouterPrefix() string {
|
||||||
|
return "/uri/prefix"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 【可选】路由组中间件定义
|
||||||
|
|
||||||
|
路由组中间件可以通过函数进行定义, 函数名必须需为 : **`RouterMiddleware`** , 函数无任何参数, 返回路由组中间件列表 **`[]gin.HandlerFunc`**, 示例 :
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TestController struct{}
|
||||||
|
|
||||||
|
func (t *TestController) RouterPrefix() string {
|
||||||
|
return "/uri/prefix"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestController) RouterMiddleware() []gin.HandlerFunc {
|
||||||
|
return []gin.HandlerFunc{
|
||||||
|
func(ctx *gin.Context) {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 接口逻辑处理定义
|
||||||
|
|
||||||
|
接口逻辑处理函数, 函数名称自定义, 必须是个 **`可导出函数`** , 函数接收两个参数, 分别是 :
|
||||||
|
|
||||||
|
- *gin.Context : gin框架的上下文信息
|
||||||
|
- any: 表单参数 **结构体指针** , 注意 : 类型必须为结构体指针
|
||||||
|
|
||||||
|
函数返回值有两个 :
|
||||||
|
- any : 返回的业务数据, 必须是个 **`结构体指针`**
|
||||||
|
- error : 可以是内置的 **error** , 也可以是 **exception.IException** , 建议使用 exception.IException , 可承载更多的异常信息
|
||||||
|
|
||||||
|
## 使用方式
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TestController struct{}
|
||||||
|
|
||||||
|
func (t *TestController) RouterPrefix() string {
|
||||||
|
return "/uri/prefix"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *TestController) RouterMiddleware() []gin.HandlerFunc {
|
||||||
|
return []gin.HandlerFunc{
|
||||||
|
func(ctx *gin.Context) {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (t *TestController) Uri(ctx *gin.Context, formData *TestForm) (any, error) {
|
||||||
|
return formData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestForm struct {
|
||||||
|
Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"`
|
||||||
|
Age int `json:"age" form:"age"`
|
||||||
|
Name string `json:"name" form:"name"`
|
||||||
|
Test *Test `json:"test" form:"test"`
|
||||||
|
Num *int64 `json:"num" form:"num"`
|
||||||
|
}
|
||||||
|
type Test struct {
|
||||||
|
L string `json:"l"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_parseController(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
controller any
|
||||||
|
}
|
||||||
|
Register(8080, &TestController{})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
注意事项:
|
||||||
|
|
||||||
|
- Register 方法第一个入参是监听的端口
|
||||||
|
- 后面若干个controller实例, 朱一必须以指针的方式传入
|
@ -1,35 +0,0 @@
|
|||||||
// Package router ...
|
|
||||||
//
|
|
||||||
// Description : 便捷的相关API处理
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 2021-03-26 2:06 下午
|
|
||||||
package router
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IApi 每一个接口的实现约束
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 2:08 下午 2021/3/26
|
|
||||||
type IApi interface {
|
|
||||||
// GetMethod 接口请求方法
|
|
||||||
GetMethod() string
|
|
||||||
// GetURI 接口URI
|
|
||||||
GetURI() string
|
|
||||||
// GetMiddleWareList 使用的中间件列表
|
|
||||||
GetMiddleWareList() []gin.HandlerFunc
|
|
||||||
// GetHandler 处理的handler
|
|
||||||
GetHandler() gin.HandlerFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterFunc 注册路由的函数
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 3:09 下午 2021/3/26
|
|
||||||
type RegisterFunc func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc)
|
|
160
router/controller.go
Normal file
160
router/controller.go
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-27 15:29
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// controller 解析controller有哪些方法要注册为接口
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:30 2025/1/27
|
||||||
|
type controller struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse 执行解析
|
||||||
|
//
|
||||||
|
// 符合注册为借口的方法具有如下特征:
|
||||||
|
//
|
||||||
|
// 1. 函数接受两个入参, 第一个参数为 gin.Context , 第二个参数为 任意结构体指针, 但是必须声明 Meta 相关信息, 否则会报错
|
||||||
|
//
|
||||||
|
// 2. 函数有两个返回值, 第一个返回值为任意结构体/结构体指针(限制死不能为map/slice, 方便后续统一标准化) , 第二个返回值为 error , 代表处理的异常, 会自动适配 exception.IException 类型
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:31 2025/1/27
|
||||||
|
func (c controller) Parse(inputController any) map[string]UriConfig {
|
||||||
|
parseRes := make(map[string]UriConfig)
|
||||||
|
if nil == inputController {
|
||||||
|
return parseRes
|
||||||
|
}
|
||||||
|
controllerType := reflect.TypeOf(inputController)
|
||||||
|
controllerValue := reflect.ValueOf(inputController)
|
||||||
|
/*if controllerType.Kind() == reflect.Func {
|
||||||
|
// 直接函数注册
|
||||||
|
cfg, isNeedRegister := c.methodConfig(controllerType)
|
||||||
|
if isNeedRegister {
|
||||||
|
parseRes[cfg.Path] = cfg
|
||||||
|
}
|
||||||
|
return parseRes
|
||||||
|
}*/
|
||||||
|
if controllerType.Kind() == reflect.Ptr {
|
||||||
|
controllerValue = controllerValue.Elem()
|
||||||
|
}
|
||||||
|
/*if controllerValue.IsNil() {
|
||||||
|
return parseRes
|
||||||
|
}*/
|
||||||
|
for methodIdx := 0; methodIdx < controllerType.NumMethod(); methodIdx++ {
|
||||||
|
uriCfg, needRegister := c.methodConfig(controllerType.Method(methodIdx))
|
||||||
|
if !needRegister {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
uriCfg.ApiStructValue = controllerValue
|
||||||
|
parseRes[uriCfg.Path] = uriCfg
|
||||||
|
}
|
||||||
|
return parseRes
|
||||||
|
}
|
||||||
|
|
||||||
|
// methodConfig 解析方法配置, 要求函数格式, 两个参数, 两个返回值, 格式 : func(ctx *gin.Context, formData anyStruct[组合Meta]) (anyStruct|map[response], error)
|
||||||
|
//
|
||||||
|
// 参数 : 方法反射结果
|
||||||
|
//
|
||||||
|
// 返回值 : 第一个 -> 解析出的接口配置 第二个 -> 是否要注册为接口
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 16:05 2025/1/27
|
||||||
|
func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, needRegister bool) {
|
||||||
|
methodType := reflectMethod.Type
|
||||||
|
// num0: 函数声明
|
||||||
|
// num1: 第一个参数
|
||||||
|
// num2: 第二个参数
|
||||||
|
if methodType.NumIn() != 3 {
|
||||||
|
needRegister = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 第一个参数必须是 *gin.Context
|
||||||
|
if methodType.In(1).String() != GinContextType {
|
||||||
|
needRegister = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 解析第二个参数是组合Meta的form表单
|
||||||
|
formType := methodType.In(2)
|
||||||
|
if formType.Kind() == reflect.Ptr {
|
||||||
|
formType = methodType.In(2).Elem()
|
||||||
|
}
|
||||||
|
cfg.FormDataType = formType
|
||||||
|
metaField, metaFieldExist := formType.FieldByName(FieldNameMeta)
|
||||||
|
if !metaFieldExist {
|
||||||
|
needRegister = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if methodType.Out(1).Kind().String() != ErrorType {
|
||||||
|
// 判断是否是实现 error接口的方法
|
||||||
|
outputErrParse := false
|
||||||
|
for j := 0; j < methodType.Out(1).NumMethod(); j++ {
|
||||||
|
if methodType.Out(1).Method(j).Name == ErrorInterfaceFuncName && // 实现Error方法
|
||||||
|
methodType.Out(1).Method(j).Type.NumIn() == 0 && // 没有任何参数
|
||||||
|
methodType.Out(1).Method(j).Type.NumOut() == 1 && // 一个返回值
|
||||||
|
methodType.Out(1).Method(j).Type.Out(0).Kind().String() == reflect.String.String() {
|
||||||
|
outputErrParse = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !outputErrParse {
|
||||||
|
needRegister = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 解析meta信息
|
||||||
|
cfg.Path = metaField.Tag.Get(TagNamePath)
|
||||||
|
cfg.RequestMethod = metaField.Tag.Get(TagNameMethod)
|
||||||
|
cfg.Desc = metaField.Tag.Get(TagNameDesc)
|
||||||
|
cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",")
|
||||||
|
// 解析第一个返回值, 要求必须是结构体或者是map
|
||||||
|
outputStrictModel := metaField.Tag.Get(TagNameOutputStrict)
|
||||||
|
cfg.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true"
|
||||||
|
if cfg.OutputStrict {
|
||||||
|
// 开启输出严格模式校验
|
||||||
|
if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map {
|
||||||
|
panic(cfg.Path + " : 接口配置输出严格校验, 输出数据类型必须为 struct 或 *struct 或 map, 实际返回数据类型 : " + methodType.Out(0).Kind().String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 解析参数配置
|
||||||
|
cfg.ParamList = c.parseParamConfig(formType)
|
||||||
|
cfg.ApiLogicFunc = reflectMethod
|
||||||
|
needRegister = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseParamConfig 解析参数配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 14:35 2025/2/7
|
||||||
|
func (c controller) parseParamConfig(formDataType reflect.Type) []UriParam {
|
||||||
|
res := make([]UriParam, 0)
|
||||||
|
for i := 0; i < formDataType.NumField(); i++ {
|
||||||
|
structField := formDataType.Field(i)
|
||||||
|
if structField.Name == FieldNameMeta {
|
||||||
|
// Meta 字段, 忽略
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
jsonTag := structField.Tag.Get("json")
|
||||||
|
if jsonTag == "" {
|
||||||
|
jsonTag = structField.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
65
router/define.go
Normal file
65
router/define.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2024-07-20 22:57
|
||||||
|
package router
|
||||||
|
|
||||||
|
import "reflect"
|
||||||
|
|
||||||
|
const (
|
||||||
|
PrefixFuncName = "RouterPrefix" // 路由前缀函数名称
|
||||||
|
MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称
|
||||||
|
GinContextType = "*gin.Context" // gin context 类型名称
|
||||||
|
ErrorType = "error" // error类型
|
||||||
|
ErrorInterfaceFuncName = "Error" // error接口需要实现的方法名称
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TagNamePath = "path" // 接口的请求路径
|
||||||
|
TagNameMethod = "method" // 接口的请求方法
|
||||||
|
TagNameUriTag = "tag" // 接口的tag
|
||||||
|
TagNameDesc = "desc" // 接口的描述
|
||||||
|
TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
||||||
|
TagNameBinding = "binding" // gin 内置的验证规则tag
|
||||||
|
TagNameValidate = "validate" // validator v10 默认的验证规则tag
|
||||||
|
TagNameErrMsg = "err" // 验证失败错误信息tag
|
||||||
|
)
|
||||||
|
|
||||||
|
// UriConfig 接口配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:41 2024/7/21
|
||||||
|
type UriConfig struct {
|
||||||
|
Path string `json:"path"` // 接口路由, 必须配置
|
||||||
|
RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置
|
||||||
|
TagList []string `json:"tag_list"` // 接口分组
|
||||||
|
Desc string `json:"desc"` // 接口描述
|
||||||
|
OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
|
||||||
|
ParamList []UriParam `json:"param_list"` // 参数信息表
|
||||||
|
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
||||||
|
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
|
||||||
|
ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑
|
||||||
|
}
|
||||||
|
|
||||||
|
// UriParam 接口参数配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:40 2025/1/27
|
||||||
|
type UriParam struct {
|
||||||
|
Field string `json:"field"` // 结构体字段
|
||||||
|
Name string `json:"name"` // 参数名称
|
||||||
|
Type string `json:"type"` // 参数类型
|
||||||
|
Validate string `json:"validate"` // 验证规则: validator/v10 库
|
||||||
|
ErrorMsg string `json:"error_msg"` // 验证失败的错误信息
|
||||||
|
DisableAutoType bool `json:"disable_auto_type"` // 禁用自动类型转换
|
||||||
|
Sort string `json:"sort"` // 参数读取顺序: 默认 POST : body > query > path GET : query > path > body
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
FieldNameMeta = "Meta" // 元信息字段
|
||||||
|
)
|
51
router/group.go
Normal file
51
router/group.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-27 19:33
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Group 注册接口路由
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 19:35 2025/1/27
|
||||||
|
func Group(router *gin.Engine, routerPrefix string, middlewareList []gin.HandlerFunc, cList ...any) error {
|
||||||
|
g := router.Group(routerPrefix)
|
||||||
|
g.Use(middlewareList...)
|
||||||
|
cParser := controller{}
|
||||||
|
for _, c := range cList {
|
||||||
|
urlTable := cParser.Parse(c)
|
||||||
|
for _, itemUriCfg := range urlTable {
|
||||||
|
method := strings.ToUpper(itemUriCfg.RequestMethod)
|
||||||
|
switch method {
|
||||||
|
case http.MethodGet:
|
||||||
|
g.GET(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
case http.MethodHead:
|
||||||
|
g.HEAD(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
case http.MethodPost:
|
||||||
|
g.POST(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
case http.MethodPut:
|
||||||
|
g.PUT(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
case http.MethodPatch:
|
||||||
|
g.PATCH(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
case http.MethodDelete:
|
||||||
|
g.DELETE(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
case http.MethodOptions:
|
||||||
|
g.OPTIONS(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
case http.MethodTrace:
|
||||||
|
return errors.New(`method Trace is not supported`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
61
router/handler.go
Normal file
61
router/handler.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2025-01-27 19:42
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.zhangdeman.cn/zhangdeman/exception"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/gin/request"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/gin/response"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RequestHandler 获取请求处理方法
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 19:44 2025/1/27
|
||||||
|
func RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
|
||||||
|
return func(ctx *gin.Context) {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
ok bool
|
||||||
|
e exception.IException
|
||||||
|
)
|
||||||
|
|
||||||
|
formData := reflect.New(uriCfg.FormDataType).Interface()
|
||||||
|
// 表单解析
|
||||||
|
if err = request.Form.Parse(ctx, formData); nil != err {
|
||||||
|
e = exception.NewFromError(400, err)
|
||||||
|
response.SendWithException(ctx, e, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 执行逻辑
|
||||||
|
resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, reflect.ValueOf(ctx), reflect.ValueOf(formData)})
|
||||||
|
if resList[1].IsNil() {
|
||||||
|
// 请求成功
|
||||||
|
response.Success(ctx, resList[0].Interface())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 请求失败
|
||||||
|
if e, ok = resList[1].Interface().(exception.IException); ok {
|
||||||
|
response.SendWithException(ctx, e, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err, ok = resList[1].Interface().(error); ok {
|
||||||
|
e = exception.NewFromError(-1, err)
|
||||||
|
response.SendWithException(ctx, e, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
e = exception.NewWithCodeAndData(-1, map[string]any{
|
||||||
|
"err": resList[1].Interface(),
|
||||||
|
})
|
||||||
|
response.SendWithException(ctx, e, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
19
router/meta.go
Normal file
19
router/meta.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2024-07-20 21:40
|
||||||
|
package router
|
||||||
|
|
||||||
|
// Meta 接口的元信息, 主要包含如下信息:
|
||||||
|
//
|
||||||
|
// uri: 接口路由(不包含group前缀)
|
||||||
|
//
|
||||||
|
// method: 请求方法: get/post 等
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 21:40 2024/7/20
|
||||||
|
type Meta struct{}
|
@ -1,115 +1,213 @@
|
|||||||
// Package router ...
|
// Package router ...
|
||||||
//
|
//
|
||||||
// Description : 注册路由
|
// Description : router ...
|
||||||
//
|
//
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 2021-03-26 2:13 下午
|
// Date : 2024-07-20 21:39
|
||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"fmt"
|
||||||
"reflect"
|
"git.zhangdeman.cn/zhangdeman/exception"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/gin/middleware"
|
||||||
"github.com/pkg/errors"
|
"git.zhangdeman.cn/zhangdeman/gin/request"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/gin/response"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// DebugLogEnable 默认打开debug日志
|
Debug = false // 是否开启DEBUG
|
||||||
DebugLogEnable = true
|
ginRouter = gin.Default()
|
||||||
)
|
)
|
||||||
|
|
||||||
// DisableDebugLog 禁用debug日志
|
func init() {
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 2:17 下午 2021/3/26
|
|
||||||
func DisableDebugLog() {
|
|
||||||
DebugLogEnable = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterRouter 注册一个路由
|
// Register 注册路由
|
||||||
//
|
//
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 2:14 下午 2021/3/26
|
// Date : 21:40 2024/7/20
|
||||||
func RegisterRouter(router *gin.Engine, apiInstanceList ...any) error {
|
func Register(port int, controllerList ...any) error {
|
||||||
for _, apiInstance := range apiInstanceList {
|
for _, controller := range controllerList {
|
||||||
if nil == apiInstance {
|
if nil == controller {
|
||||||
|
// 忽略空指针
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
val := reflect.ValueOf(apiInstance)
|
parseController(controller)
|
||||||
switch val.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
fallthrough
|
|
||||||
case reflect.Ptr:
|
|
||||||
api, ok := apiInstance.(IApi)
|
|
||||||
if ok {
|
|
||||||
if err := HandleRegisterRouter(router, api.GetMethod(), api.GetURI(), api.GetHandler(), api.GetMiddleWareList()); nil != err {
|
|
||||||
routerLog(err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
routerLog(val.String() + "结构体或者结构体指针, 自动识别函数是否包含RouterFunc")
|
|
||||||
// 不是IApi接口,自动识别函数列表 RouterFunc 函数自动注册
|
|
||||||
methodCnt := val.NumMethod()
|
|
||||||
for i := 0; i < methodCnt; i++ {
|
|
||||||
// TODO : 识别函数本身是不是 RouterFunc
|
|
||||||
af, o := val.Method(i).Interface().(func() (string, string, gin.HandlerFunc, []gin.HandlerFunc))
|
|
||||||
if o {
|
|
||||||
method, uri, handler, middlewareList := af()
|
|
||||||
if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err {
|
|
||||||
routerLog(err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
apiFuncList := val.Method(i).Call(nil)
|
|
||||||
for _, apiFuncVal := range apiFuncList {
|
|
||||||
apiFunc, ok := apiFuncVal.Interface().(RegisterFunc)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
method, uri, handler, middlewareList := apiFunc()
|
|
||||||
if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err {
|
|
||||||
routerLog(err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
case reflect.Func:
|
|
||||||
api, ok := apiInstance.(RegisterFunc)
|
|
||||||
if !ok {
|
|
||||||
err := errors.New("函数方式注册路由必须是 RouterFunc")
|
|
||||||
routerLog(err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
method, uri, handler, middlewareList := api()
|
|
||||||
if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err {
|
|
||||||
routerLog(err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
err := errors.New("注册的路由必须是 IApi 或者 RouterFunc 或者 包含 RouterFunc 的结构体")
|
|
||||||
routerLog(err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return ginRouter.Run(fmt.Sprintf(":%d", port))
|
||||||
}
|
}
|
||||||
|
|
||||||
// routerLog 记录日志
|
// parseController 解析controller
|
||||||
//
|
//
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 2:28 下午 2021/3/26
|
// Date : 22:10 2024/7/20
|
||||||
func routerLog(msg string) {
|
func parseController(controller any) {
|
||||||
if !DebugLogEnable || len(msg) == 0 {
|
controllerType := reflect.TypeOf(controller)
|
||||||
|
controllerValue := reflect.ValueOf(controller)
|
||||||
|
routerPrefix := "/"
|
||||||
|
// 解析路由前缀函数
|
||||||
|
// routerPrefix 不能有任何入参, 并且只能有一个返回值,
|
||||||
|
// 返回值类型为字符串, 为具体路由前缀
|
||||||
|
routerPrefixFunc, routerPrefixFuncExist := controllerType.MethodByName(PrefixFuncName)
|
||||||
|
if routerPrefixFuncExist {
|
||||||
|
routerPrefixFuncType := routerPrefixFunc.Type
|
||||||
|
if routerPrefixFuncType.NumIn() == 1 && // 无任何入参, 正在没有如何入参情况下, 第一个参数是结构体指针
|
||||||
|
routerPrefixFuncType.NumOut() == 1 && // 只能有一个返回值
|
||||||
|
routerPrefixFuncType.Out(0).Kind() == reflect.String { // 返回值必须是字符串
|
||||||
|
routerPrefix = routerPrefixFunc.Func.Call([]reflect.Value{controllerValue})[0].String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 请求组的中间件
|
||||||
|
middlewareList := make([]gin.HandlerFunc, 0)
|
||||||
|
routerMiddlewareFunc, routerMiddlewareFuncExist := controllerType.MethodByName(MiddlewareFuncName)
|
||||||
|
if routerMiddlewareFuncExist {
|
||||||
|
routerMiddlewareFuncType := routerMiddlewareFunc.Type
|
||||||
|
if routerMiddlewareFuncType.NumIn() == 1 && // 无需任何参数
|
||||||
|
routerMiddlewareFuncType.NumOut() == 1 && // 只能有一个返回值
|
||||||
|
routerMiddlewareFuncType.Out(0).String() == "[]gin.HandlerFunc" { // 返回值必须是gin.HandlerFunc
|
||||||
|
res := routerMiddlewareFunc.Func.Call([]reflect.Value{controllerValue})
|
||||||
|
if !res[0].IsNil() {
|
||||||
|
middlewareList = res[0].Interface().([]gin.HandlerFunc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for funcIdx := 0; funcIdx < controllerType.NumMethod(); funcIdx++ {
|
||||||
|
method := controllerType.Method(funcIdx)
|
||||||
|
if method.Name == PrefixFuncName || method.Name == MiddlewareFuncName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
methodType := method.Type
|
||||||
|
uriConfig, err := parseUriConfig(methodType, routerPrefix)
|
||||||
|
if nil != err {
|
||||||
|
debugLog("parseUriConfig error : %s -> %s", err.Error(), methodType.Kind().String())
|
||||||
|
}
|
||||||
|
if nil == uriConfig {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
registerUri(uriConfig, controllerValue.Method(funcIdx), middlewareList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseUriConfig 解析Uri配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 16:40 2024/7/21
|
||||||
|
func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, error) {
|
||||||
|
if methodType.NumIn() != 3 || // 结构体指针 + 两个参数
|
||||||
|
methodType.NumOut() != 2 { // 两个返回值
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
// 接口logic共计两个参数. 两个返回值, 格式 : func(ctx *gin.Context, formData any[组合Meta]) (any[response], error)
|
||||||
|
|
||||||
|
// 解析第一个参数是 *gin.Context
|
||||||
|
if methodType.In(1).String() != "*gin.Context" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
// 解析第二个参数是组合Meta的form表单
|
||||||
|
formType := methodType.In(2)
|
||||||
|
if formType.Kind() == reflect.Ptr {
|
||||||
|
formType = methodType.In(2).Elem()
|
||||||
|
}
|
||||||
|
metaField, metaFieldExist := formType.FieldByName(FieldNameMeta)
|
||||||
|
if !metaFieldExist {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
uriConfig := &UriConfig{
|
||||||
|
Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"),
|
||||||
|
RequestMethod: strings.ToUpper(metaField.Tag.Get(TagNameMethod)),
|
||||||
|
TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"),
|
||||||
|
Desc: metaField.Tag.Get(TagNameDesc),
|
||||||
|
OutputStrict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameOutputStrict))) >= 0,
|
||||||
|
FormDataType: methodType.In(2).Elem(),
|
||||||
|
}
|
||||||
|
// 校验 FormDataType
|
||||||
|
for fieldIdx := 0; fieldIdx < uriConfig.FormDataType.NumField(); fieldIdx++ {
|
||||||
|
if uriConfig.FormDataType.Field(fieldIdx).Type.Kind() == reflect.Interface {
|
||||||
|
panic("request param set type `interface` is not allowed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uriConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// registerUri 注册路由
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:00 2024/7/21
|
||||||
|
func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList []gin.HandlerFunc) {
|
||||||
|
if nil == middlewareList {
|
||||||
|
middlewareList = make([]gin.HandlerFunc, 0)
|
||||||
|
}
|
||||||
|
handlerFunc := func(ctx *gin.Context) {
|
||||||
|
formDataReceiver := reflect.New(uriConfig.FormDataType)
|
||||||
|
if err := request.Form.Parse(ctx, formDataReceiver.Interface()); nil != err {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
returnValue := methodValue.Call([]reflect.Value{reflect.ValueOf(ctx), formDataReceiver})
|
||||||
|
businessData := returnValue[0].Interface()
|
||||||
|
errData := returnValue[1]
|
||||||
|
if errData.IsNil() {
|
||||||
|
response.Success(ctx, businessData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := errData.Interface()
|
||||||
|
if e, ok := err.(exception.IException); ok {
|
||||||
|
response.SendWithException(ctx, e, map[string]any{"business_data": businessData})
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
response.SendWithException(ctx, exception.NewFromError(-1, errData.Interface().(error)), map[string]any{"business_data": businessData})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
middlewareList = append(middlewareList, handlerFunc)
|
||||||
|
middlewareList = append([]gin.HandlerFunc{
|
||||||
|
middleware.InitRequest(),
|
||||||
|
}, middlewareList...)
|
||||||
|
switch uriConfig.RequestMethod {
|
||||||
|
case http.MethodGet:
|
||||||
|
ginRouter.GET(uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodHead:
|
||||||
|
ginRouter.HEAD(uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodPost:
|
||||||
|
ginRouter.PUT(uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodPut:
|
||||||
|
ginRouter.PUT(uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodPatch:
|
||||||
|
ginRouter.PATCH(uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodDelete:
|
||||||
|
ginRouter.DELETE(uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodConnect:
|
||||||
|
ginRouter.Handle(http.MethodConnect, uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodOptions:
|
||||||
|
ginRouter.OPTIONS(uriConfig.Path, middlewareList...)
|
||||||
|
case http.MethodTrace:
|
||||||
|
ginRouter.Handle(http.MethodTrace, uriConfig.Path, middlewareList...)
|
||||||
|
case "ANY":
|
||||||
|
ginRouter.Any(uriConfig.Path, middlewareList...)
|
||||||
|
default:
|
||||||
|
panic(uriConfig.Path + " : " + uriConfig.RequestMethod + " is not support")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// debugLog ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 15:32 2024/7/21
|
||||||
|
func debugLog(format string, valList ...any) {
|
||||||
|
if !Debug {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Print(msg)
|
fmt.Printf("[DEBUG] "+format+"\n", valList...)
|
||||||
}
|
}
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
// Package router ...
|
|
||||||
//
|
|
||||||
// Description : 路由注册单元测试
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 2021-03-26 3:49 下午
|
|
||||||
package router
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TestRegisterRouter ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 3:50 下午 2021/3/26
|
|
||||||
func TestRegisterRouter(t *testing.T) {
|
|
||||||
r := gin.Default()
|
|
||||||
err := RegisterRouter(r, demoApiFunc(), &demoApi{}, &otherApi{}, nil)
|
|
||||||
assert.Nil(t, err, "路由注册异常 : %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func demoApiFunc() RegisterFunc {
|
|
||||||
return func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) {
|
|
||||||
return http.MethodGet, "/api/func/test", func(context *gin.Context) {
|
|
||||||
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type demoApi struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d demoApi) GetMethod() string {
|
|
||||||
return http.MethodGet
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d demoApi) GetURI() string {
|
|
||||||
return "/api/struct/test"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d demoApi) GetMiddleWareList() []gin.HandlerFunc {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d demoApi) GetHandler() gin.HandlerFunc {
|
|
||||||
return func(context *gin.Context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type otherApi struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (oa *otherApi) DemoApiFunc() RegisterFunc {
|
|
||||||
return func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) {
|
|
||||||
return http.MethodGet, "/api/other/test", func(context *gin.Context) {
|
|
||||||
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (oa *otherApi) Lala() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (oa *otherApi) SelfApi() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) {
|
|
||||||
return http.MethodGet, "/api/other/self/test", func(context *gin.Context) {
|
|
||||||
|
|
||||||
}, nil
|
|
||||||
}
|
|
37
router/register_test.go
Normal file
37
router/register_test.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Package router ...
|
||||||
|
//
|
||||||
|
// Description : router ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2024-07-20 23:24
|
||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestController struct{}
|
||||||
|
|
||||||
|
func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (any, error) {
|
||||||
|
return formData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestForm struct {
|
||||||
|
Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get"`
|
||||||
|
Age int `json:"age" form:"age" binding:"min=20"`
|
||||||
|
Name string `json:"name" form:"name"`
|
||||||
|
Test *Test `json:"test" form:"test"`
|
||||||
|
Num *int64 `json:"num" form:"num"`
|
||||||
|
}
|
||||||
|
type Test struct {
|
||||||
|
L string `json:"l"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_parseController(t *testing.T) {
|
||||||
|
r := gin.Default()
|
||||||
|
Group(r, "test", nil, TestController{})
|
||||||
|
r.Run(":8080")
|
||||||
|
}
|
@ -1,79 +0,0 @@
|
|||||||
// Package router ...
|
|
||||||
//
|
|
||||||
// Description : router ...
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 2023-03-03 16:48
|
|
||||||
package router
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HandleRegisterRouter 注册gin路由
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 8:36 下午 2021/3/9
|
|
||||||
func HandleRegisterRouter(router *gin.Engine, method string, uri string, handler gin.HandlerFunc, middlewareList []gin.HandlerFunc) error {
|
|
||||||
if nil == middlewareList {
|
|
||||||
middlewareList = make([]gin.HandlerFunc, 0)
|
|
||||||
}
|
|
||||||
switch strings.ToUpper(method) {
|
|
||||||
case http.MethodGet:
|
|
||||||
router.GET(uri, handler).Use(middlewareList...)
|
|
||||||
case http.MethodPost:
|
|
||||||
router.POST(uri, handler).Use(middlewareList...)
|
|
||||||
case http.MethodDelete:
|
|
||||||
router.DELETE(uri, handler).Use(middlewareList...)
|
|
||||||
case http.MethodHead:
|
|
||||||
router.HEAD(uri, handler).Use(middlewareList...)
|
|
||||||
case http.MethodOptions:
|
|
||||||
router.OPTIONS(uri, handler).Use(middlewareList...)
|
|
||||||
case http.MethodPatch:
|
|
||||||
router.PATCH(uri, handler).Use(middlewareList...)
|
|
||||||
case http.MethodPut:
|
|
||||||
router.PUT(uri, handler).Use(middlewareList...)
|
|
||||||
case "ANY": // 一次性注册全部请求方法的路由
|
|
||||||
router.Any(uri, handler).Use(middlewareList...)
|
|
||||||
default:
|
|
||||||
// 不是一个函数,数名method配置错误
|
|
||||||
return fmt.Errorf("uri=%s method=%s 请求方法配置错误", uri, method)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterRouterGroup 注册gin路由
|
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 8:36 下午 2021/3/9
|
|
||||||
func RegisterRouterGroup(router *gin.RouterGroup, method string, uri string, handler gin.HandlerFunc) error {
|
|
||||||
switch strings.ToUpper(method) {
|
|
||||||
case http.MethodGet:
|
|
||||||
router.GET(uri, handler)
|
|
||||||
case http.MethodPost:
|
|
||||||
router.POST(uri, handler)
|
|
||||||
case http.MethodDelete:
|
|
||||||
router.DELETE(uri, handler)
|
|
||||||
case http.MethodHead:
|
|
||||||
router.HEAD(uri, handler)
|
|
||||||
case http.MethodOptions:
|
|
||||||
router.OPTIONS(uri, handler)
|
|
||||||
case http.MethodPatch:
|
|
||||||
router.PATCH(uri, handler)
|
|
||||||
case http.MethodPut:
|
|
||||||
router.PUT(uri, handler)
|
|
||||||
case "ANY": // 一次性注册全部请求方法的路由
|
|
||||||
router.Any(uri, handler)
|
|
||||||
default:
|
|
||||||
// 不是一个函数,数名method配置错误
|
|
||||||
return fmt.Errorf("uri=%s method=%s 请求方法配置错误", uri, method)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user