Compare commits
13 Commits
master
...
feature/ro
Author | SHA1 | Date |
---|---|---|
白茶清欢 | c420abfed9 | |
白茶清欢 | fce6043dca | |
白茶清欢 | df16e63e85 | |
白茶清欢 | 60ef099fdf | |
白茶清欢 | 8997577181 | |
白茶清欢 | cc98043aff | |
白茶清欢 | 0b7df330f7 | |
白茶清欢 | 8a6182d0de | |
白茶清欢 | deead87688 | |
白茶清欢 | f8f63691b7 | |
白茶清欢 | 455f74ad89 | |
白茶清欢 | f55dee577d | |
白茶清欢 | b14b1ef345 |
|
@ -33,7 +33,6 @@ type HttpHandleConfig struct {
|
|||
ResponseTraceIDField string
|
||||
StartRequestTimeField string
|
||||
FinishRequestTimeField string
|
||||
RequestIsSuccessField string // 请求处理是否成功的标识
|
||||
}
|
||||
|
||||
// ConvertDefaultConfig 覆盖默认配置
|
||||
|
@ -107,10 +106,5 @@ func GetHttpHandleConfig() *HttpHandleConfig {
|
|||
consts.GinRecordResponseDataField,
|
||||
wrapper.String(inputHttpHandleConfig.RecordResponseDataField),
|
||||
).Value(),
|
||||
RequestIsSuccessField: wrapper.TernaryOperator.String(
|
||||
nil == inputHttpHandleConfig || inputHttpHandleConfig.RequestIsSuccessField == "",
|
||||
consts.GinRequestIsSuccessField,
|
||||
wrapper.String(inputHttpHandleConfig.RecordResponseDataField),
|
||||
).Value(),
|
||||
}
|
||||
}
|
||||
|
|
32
go.mod
32
go.mod
|
@ -1,19 +1,17 @@
|
|||
module git.zhangdeman.cn/zhangdeman/gin
|
||||
|
||||
go 1.21.0
|
||||
go 1.21
|
||||
|
||||
toolchain go1.23.1
|
||||
toolchain go1.21.5
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240823041145-d4df71cf37e5
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240726024939-e424db29c5c4
|
||||
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20231105153815-e8561a060cc8
|
||||
git.zhangdeman.cn/zhangdeman/logger v0.0.0-20240725055115-98eb52ae307a
|
||||
git.zhangdeman.cn/zhangdeman/network v0.0.0-20230925112156-f0eb86dd2442
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240823103024-c38d16dc28d3
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240813083016-da44ae07ab9b
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/go-playground/validator/v10 v10.22.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
go.uber.org/zap v1.27.0
|
||||
)
|
||||
|
||||
|
@ -26,11 +24,10 @@ require (
|
|||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 // indirect
|
||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||
github.com/bytedance/sonic v1.12.2 // indirect
|
||||
github.com/bytedance/sonic v1.12.1 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // 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/gabriel-vasile/mimetype v1.4.5 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
|
@ -43,16 +40,15 @@ require (
|
|||
github.com/klauspost/cpuid/v2 v2.2.8 // 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/strftime v1.1.0 // indirect
|
||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mcuadros/go-defaults v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
||||
github.com/mssola/user_agent v0.6.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/tidwall/gjson v1.17.3 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
|
@ -60,11 +56,11 @@ require (
|
|||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.10.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
golang.org/x/net v0.29.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/arch v0.9.0 // indirect
|
||||
golang.org/x/crypto v0.26.0 // indirect
|
||||
golang.org/x/net v0.28.0 // indirect
|
||||
golang.org/x/sys v0.24.0 // indirect
|
||||
golang.org/x/text v0.17.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
|
44
go.sum
44
go.sum
|
@ -1,13 +1,5 @@
|
|||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240719075638-afb5d1d933ce h1:DH01rT/F/UNMqXm5HIv+Q2oKPSkg8rjy1TK8pE83rpU=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240719075638-afb5d1d933ce/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240723085016-ee0510753552 h1:SgxcaLXEXn3ImMOik9y3xDz82KwK/+9IhqV1kZbqIwQ=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240723085016-ee0510753552/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240726024939-e424db29c5c4 h1:mibnyzYbZullK0aTHVASHl3UeoVr8IgytQZsuyv+yEM=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240726024939-e424db29c5c4/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240817091513-491f455a23c0 h1:U12XDtyRrmsqb/wRvRZG9+SBKMCGFNADpiLogsp5POw=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240817091513-491f455a23c0/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240823041145-d4df71cf37e5 h1:pmIHln0gWW+5xAB762h3WDsRkZuYLUDndvJDsGMKoOY=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240823041145-d4df71cf37e5/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/go.mod h1:dT0rmHcJ9Z9IqWeMIt7YzR88nKkNV2V3dfG0j9Q6lK0=
|
||||
git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20240311030808-e2a2e6a3c211 h1:I/wOsRpCSRkU9vo1u703slQsmK0wnNeZzsWQOGtIAG0=
|
||||
|
@ -28,10 +20,10 @@ git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2 h1:P2k
|
|||
git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20240723075210-85feada512b2/go.mod h1:7KaMpQmWgiNLpEkaV7oDtep7geI1f/VoCoPVcyvMjAE=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50 h1:olo34i2Gq5gX7bYPv5TR4X5l5CrYFtu9UCElkYlmL2c=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd h1:zcmfmp/1srHldFpa7BCH6Cpp9iVNFM/7W7DoxHp48UU=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd/go.mod h1:gnaF3v9/om6gaxFKeNVuKeFTYM61gHyW7vign7vrwyo=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240813083016-da44ae07ab9b h1:CcO2t7ssBSZwE7BDTOkCSgOvTGATarOZ0tajZ00McEc=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240813083016-da44ae07ab9b/go.mod h1:gnaF3v9/om6gaxFKeNVuKeFTYM61gHyW7vign7vrwyo=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240823103024-c38d16dc28d3 h1:RcWNxrHmhZksZWrP/HLEwAM8uIIHYlPLQ20HnLzC+j0=
|
||||
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240823103024-c38d16dc28d3/go.mod h1:KcojKP22mv9/IZrQWlIBfa1EuBxtEOqfWMgN3SYK2N8=
|
||||
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/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||
|
@ -40,8 +32,6 @@ github.com/bytedance/sonic v1.11.9 h1:LFHENlIY/SLzDWverzdOvgMztTxcfcF+cqNsz9pK5z
|
|||
github.com/bytedance/sonic v1.11.9/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24=
|
||||
github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg=
|
||||
github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
|
||||
|
@ -54,7 +44,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
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/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
|
||||
|
@ -75,36 +64,31 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
|||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA=
|
||||
github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
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/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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/gofuzz v1.0.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/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
||||
github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
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/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.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
|
||||
github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
|
||||
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
|
||||
github.com/lestrrat-go/strftime v1.1.0 h1:gMESpZy44/4pXLO/m+sL0yBd1W6LjgjrrD4a68Gapyg=
|
||||
github.com/lestrrat-go/strftime v1.1.0/go.mod h1:uzeIB52CeUJenCo1syghlugshMysrqUT51HlxphXVeI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mcuadros/go-defaults v1.2.0 h1:FODb8WSf0uGaY8elWJAkoLL0Ri6AlZ1bFlenk56oZtc=
|
||||
github.com/mcuadros/go-defaults v1.2.0/go.mod h1:WEZtHEVIGYVDqkKSWBdWKUVdRyKlMfulPaGDWIVeCWY=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@ -116,11 +100,8 @@ github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+
|
|||
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
|
||||
github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4=
|
||||
github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
@ -163,41 +144,30 @@ golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
|||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k=
|
||||
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8=
|
||||
golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
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=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376 h1:sY2a+y0j4iDrajJcorb+a0hJIQ6uakU5gybjfLWHlXo=
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376/go.mod h1:BHKOc1m5wm8WwQkMqYBoo4vNxhmF7xg8+xhG8L+Cy3M=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/request"
|
||||
"go.uber.org/zap"
|
||||
"strings"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/gin/define"
|
||||
|
||||
|
@ -115,11 +114,7 @@ func LogRequest(cfg *AccessConfig) gin.HandlerFunc {
|
|||
"response_body": request.WrapperHandle.GetResponseBody(ctx, handleConfig.ResponseDataField, map[string]any{}), // 响应body
|
||||
"response_header": getLogResponseHeader(ctx, cfg), // 响应header
|
||||
})
|
||||
if ctx.GetBool(define.GetHttpHandleConfig().RequestIsSuccessField) {
|
||||
cfg.Logger.Info("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
|
||||
} else {
|
||||
cfg.Logger.Error("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,7 @@ package request
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/mcuadros/go-defaults"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
|
@ -43,34 +41,28 @@ func (f *form) Parse(ctx *gin.Context, receiver interface{}) error {
|
|||
// 请求信息写入上下文
|
||||
ctx.Set(handleConfig.RecordRequestDataField, string(requestBody))
|
||||
// 因为请求体被读一遍之后就没了,重新赋值 requestBody
|
||||
ctx.Request.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
|
||||
ctx.Request.Body = io.NopCloser(bytes.NewReader(requestBody))
|
||||
method := strings.ToUpper(ctx.Request.Method)
|
||||
if method == http.MethodGet ||
|
||||
method == http.MethodPatch ||
|
||||
method == http.MethodTrace ||
|
||||
method == http.MethodConnect ||
|
||||
method == http.MethodOptions {
|
||||
if err := ctx.ShouldBindQuery(receiver); nil != err {
|
||||
return err
|
||||
return ctx.ShouldBindQuery(receiver)
|
||||
}
|
||||
} else if method == http.MethodPost ||
|
||||
|
||||
if method == http.MethodPost ||
|
||||
method == http.MethodPut ||
|
||||
method == http.MethodDelete {
|
||||
if ContentType.IsJson(ctx) {
|
||||
if err := ctx.ShouldBindJSON(receiver); nil != err {
|
||||
return err
|
||||
return ctx.ShouldBindJSON(receiver)
|
||||
}
|
||||
} else if ContentType.IsFormURLEncoded(ctx) {
|
||||
if err := ctx.ShouldBind(receiver); nil != err {
|
||||
return err
|
||||
|
||||
if ContentType.IsFormURLEncoded(ctx) {
|
||||
return ctx.ShouldBind(receiver)
|
||||
}
|
||||
} else {
|
||||
|
||||
return errors.New(ctx.ContentType() + " is not support")
|
||||
}
|
||||
} else {
|
||||
return errors.New(method + " : request method is not support")
|
||||
}
|
||||
// 设置默认值
|
||||
defaults.SetDefaults(receiver)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -121,18 +121,6 @@ func (wh *wrapperHandle) GetContentType(ctx *gin.Context, defaultVal string) str
|
|||
return wrapper.TernaryOperator.String(len(contentType) > 0, wrapper.String(contentType), wrapper.String(defaultVal)).Value()
|
||||
}
|
||||
|
||||
// GetDomain 获取请求Domain
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:12 2024/9/19
|
||||
func (wh *wrapperHandle) GetDomain(ctx *gin.Context) string {
|
||||
if nil == ctx {
|
||||
return ""
|
||||
}
|
||||
return ctx.Request.Host
|
||||
}
|
||||
|
||||
// GetRequestBody 获取请求body
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -22,26 +21,12 @@ const (
|
|||
hasSendResponseFlag = "GIN_PKG_HAS_SEND_RESPONSE"
|
||||
)
|
||||
|
||||
var (
|
||||
// 成功的业务状态码
|
||||
successBusinessCode any = "200"
|
||||
)
|
||||
|
||||
// SetBusinessSuccessCode 设置成状态码
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 17:01 2024/8/17
|
||||
func SetBusinessSuccessCode(code any) {
|
||||
successBusinessCode = code
|
||||
}
|
||||
|
||||
// Success 成功的响应
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 22:37 2022/6/25
|
||||
func Success(ctx *gin.Context, data any) {
|
||||
func Success(ctx *gin.Context, data interface{}) {
|
||||
successException := exception.NewSuccess(data)
|
||||
Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData())
|
||||
}
|
||||
|
@ -51,23 +36,21 @@ func Success(ctx *gin.Context, data any) {
|
|||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 22:40 2022/6/25
|
||||
func Send(ctx *gin.Context, code any, httpCode int, data any) {
|
||||
// 设置请求是否成功的标识
|
||||
ctx.Set(define.GetHttpHandleConfig().RequestIsSuccessField, fmt.Sprintf("%v", code) == fmt.Sprintf("%v", successBusinessCode))
|
||||
func Send(ctx *gin.Context, code interface{}, httpCode int, data interface{}) {
|
||||
if ctx.GetBool(hasSendResponseFlag) {
|
||||
// 已经发送过数据, 后面在发送数据, 不执行
|
||||
return
|
||||
}
|
||||
finishRequestTime := time.Now().UnixMilli()
|
||||
// 设置数据已发送的标识
|
||||
defer ctx.Set(hasSendResponseFlag, true)
|
||||
responseConfig := define.GetHttpHandleConfig()
|
||||
responseData := map[string]any{
|
||||
finishRequestTime := time.Now().UnixMilli()
|
||||
responseData := map[string]interface{}{
|
||||
responseConfig.ResponseCodeField: code,
|
||||
responseConfig.ResponseMessageField: exception.GetMessage(code),
|
||||
responseConfig.ResponseTraceIDField: ctx.GetString(responseConfig.ResponseTraceIDField),
|
||||
responseConfig.ResponseDataField: data,
|
||||
responseConfig.HandleRequestCostField: finishRequestTime - ctx.GetInt64(responseConfig.StartRequestTimeField),
|
||||
responseConfig.HandleRequestCostField: finishRequestTime - ctx.GetTime(responseConfig.StartRequestTimeField).UnixMilli(),
|
||||
}
|
||||
// 记录完成时间
|
||||
ctx.Set(responseConfig.FinishRequestTimeField, finishRequestTime)
|
||||
|
@ -81,7 +64,7 @@ func Send(ctx *gin.Context, code any, httpCode int, data any) {
|
|||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 22:41 2022/6/25
|
||||
func SendWithStatusOK(ctx *gin.Context, code any, data any) {
|
||||
func SendWithStatusOK(ctx *gin.Context, code interface{}, data interface{}) {
|
||||
Send(ctx, code, http.StatusOK, data)
|
||||
}
|
||||
|
||||
|
@ -90,11 +73,11 @@ func SendWithStatusOK(ctx *gin.Context, code any, data any) {
|
|||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 13:08 2022/6/26
|
||||
func SendWithException(ctx *gin.Context, e exception.IException, data any) {
|
||||
func SendWithException(ctx *gin.Context, e exception.IException, data interface{}) {
|
||||
if nil == e {
|
||||
e = exception.NewSuccess(data)
|
||||
}
|
||||
outputData := map[string]any{
|
||||
outputData := map[string]interface{}{
|
||||
"e_data": e.GetData(),
|
||||
"u_e_data": data,
|
||||
}
|
||||
|
@ -106,7 +89,7 @@ func SendWithException(ctx *gin.Context, e exception.IException, data any) {
|
|||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 14:51 2023/2/15
|
||||
func JSON(ctx *gin.Context, httpCode int, data any) {
|
||||
func JSON(ctx *gin.Context, httpCode int, data interface{}) {
|
||||
if ctx.GetBool(hasSendResponseFlag) {
|
||||
// 已经发送过数据, 后面在发送数据, 不执行
|
||||
return
|
||||
|
|
|
@ -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)
|
|
@ -0,0 +1,37 @@
|
|||
// Package router ...
|
||||
//
|
||||
// Description : router ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-07-20 22:57
|
||||
package router
|
||||
|
||||
import "reflect"
|
||||
|
||||
const (
|
||||
PrefixFuncName = "RouterPrefix" // 路由前缀函数名称
|
||||
MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称
|
||||
)
|
||||
|
||||
const (
|
||||
TagNamePath = "path" // 接口的请求路径
|
||||
TagNameMethod = "method" // 接口的请求方法
|
||||
TagNameUriTag = "tag" // 接口的tag
|
||||
TagNameDesc = "desc" // 接口的描述
|
||||
TagNameStrict = "strict" // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY
|
||||
)
|
||||
|
||||
// UriConfig 接口配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:41 2024/7/21
|
||||
type UriConfig struct {
|
||||
Path string `json:"path"` // 接口路由, 必须配置
|
||||
Method string `json:"method"` // 接口请求方法, 必须配置
|
||||
TagList []string `json:"tag_list"` // 接口分组
|
||||
Desc string `json:"desc"` // 接口描述
|
||||
Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY
|
||||
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// Package router ...
|
||||
//
|
||||
// Description : router ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-07-20 21:40
|
||||
package router
|
||||
|
||||
// Meta 接口的元信息
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 21:40 2024/7/20
|
||||
type Meta struct{}
|
|
@ -1,115 +1,213 @@
|
|||
// Package router ...
|
||||
//
|
||||
// Description : 注册路由
|
||||
// Description : router ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2021-03-26 2:13 下午
|
||||
// Date : 2024-07-20 21:39
|
||||
package router
|
||||
|
||||
import (
|
||||
"log"
|
||||
"reflect"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"fmt"
|
||||
"git.zhangdeman.cn/zhangdeman/exception"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/middleware"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/request"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/response"
|
||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// DebugLogEnable 默认打开debug日志
|
||||
DebugLogEnable = true
|
||||
Debug = false // 是否开启DEBUG
|
||||
ginRouter = gin.Default()
|
||||
)
|
||||
|
||||
// DisableDebugLog 禁用debug日志
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2:17 下午 2021/3/26
|
||||
func DisableDebugLog() {
|
||||
DebugLogEnable = false
|
||||
func init() {
|
||||
|
||||
}
|
||||
|
||||
// RegisterRouter 注册一个路由
|
||||
// Register 注册路由
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2:14 下午 2021/3/26
|
||||
func RegisterRouter(router *gin.Engine, apiInstanceList ...any) error {
|
||||
for _, apiInstance := range apiInstanceList {
|
||||
if nil == apiInstance {
|
||||
// Date : 21:40 2024/7/20
|
||||
func Register(port int, controllerList ...any) error {
|
||||
for _, controller := range controllerList {
|
||||
if nil == controller {
|
||||
// 忽略空指针
|
||||
continue
|
||||
}
|
||||
val := reflect.ValueOf(apiInstance)
|
||||
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
|
||||
parseController(controller)
|
||||
}
|
||||
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<白茶清欢>
|
||||
//
|
||||
// Date : 2:28 下午 2021/3/26
|
||||
func routerLog(msg string) {
|
||||
if !DebugLogEnable || len(msg) == 0 {
|
||||
// Date : 22:10 2024/7/20
|
||||
func parseController(controller any) {
|
||||
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("Meta")
|
||||
if !metaFieldExist {
|
||||
return nil, nil
|
||||
}
|
||||
uriConfig := &UriConfig{
|
||||
Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"),
|
||||
Method: strings.ToUpper(metaField.Tag.Get(TagNameMethod)),
|
||||
TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"),
|
||||
Desc: metaField.Tag.Get(TagNameDesc),
|
||||
Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 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
|
||||
}
|
||||
log.Print(msg)
|
||||
err := errData.Interface()
|
||||
if e, ok := err.(exception.IException); ok {
|
||||
response.SendWithException(ctx, e, businessData)
|
||||
return
|
||||
} else {
|
||||
response.SendWithException(ctx, exception.NewFromError(-1, errData.Interface().(error)), businessData)
|
||||
return
|
||||
}
|
||||
}
|
||||
middlewareList = append(middlewareList, handlerFunc)
|
||||
middlewareList = append([]gin.HandlerFunc{
|
||||
middleware.InitRequest(),
|
||||
}, middlewareList...)
|
||||
switch uriConfig.Method {
|
||||
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.Method + " is not support")
|
||||
}
|
||||
}
|
||||
|
||||
// debugLog ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:32 2024/7/21
|
||||
func debugLog(format string, valList ...any) {
|
||||
if !Debug {
|
||||
return
|
||||
}
|
||||
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() RouterFunc {
|
||||
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() RouterFunc {
|
||||
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
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
// 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) 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{})
|
||||
}
|
|
@ -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…
Reference in New Issue