41 Commits

Author SHA1 Message Date
bd01c39fcc 参数解析增加解析标题 2025-02-07 18:16:34 +08:00
7ddd96bcb7 参数配置解析 2025-02-07 18:14:57 +08:00
5d19efa8cf Merge pull request '格式化验证失败的错误信息, 默认tag=err, 支持重置默认tag' (#3) from feature/format_validate_err into master
Reviewed-on: #3
2025-02-07 18:03:21 +08:00
7c67160c65 格式化验证失败的错误信息, 默认tag=err, 支持重置默认tag 2025-02-07 18:01:05 +08:00
a338713c77 Merge pull request '支持通过controller自动解析注册接口路由' (#2) from feature/router into master
Reviewed-on: #2
2025-02-07 17:32:34 +08:00
cb4718a269 接口逻辑函数返回值严格校验时, 校验不通过, 由忽略接口注册修改为panic 2025-02-07 17:25:25 +08:00
1b1964881f 返回数据支持是否严格模式的校验, 严格模式下, 必须返回结构体或者map 2025-02-07 17:19:25 +08:00
e95061a1a8 完成基础反射调用接口 + 数据响应 2025-02-07 16:57:15 +08:00
77ea723e86 完善 RequestHandler 逻辑 2025-02-07 16:10:33 +08:00
196c437cc5 update go mod 2025-02-07 10:33:39 +08:00
b408076fa7 保存路由统一注册方法 2025-01-27 19:46:34 +08:00
851de1b3ef save code 2025-01-27 15:07:58 +08:00
e40475cdb1 update go mod 2025-01-26 14:34:24 +08:00
ec04a023cd merge master && fix both modify 2025-01-26 14:32:59 +08:00
18988c4d46 Merge pull request '升级请求体解析' (#1) from feature/parse_body into master
Reviewed-on: #1
2024-11-05 17:32:44 +08:00
196c420fcc update go mod 2024-11-05 17:31:44 +08:00
6a917d338a 支持xml body解析 2024-11-04 17:06:51 +08:00
f6db9e8edb 升级 wrapperHandle -> ParseBody 2024-11-04 16:12:09 +08:00
a0b4cdb414 update go mod 2024-11-04 15:57:39 +08:00
cffb0c8779 增加form url encode解析 2024-10-22 17:20:30 +08:00
56441151cf 增加json的请求Body解析 2024-10-22 17:14:53 +08:00
2c99eb9656 涉及请求体解析适配器接口约束 2024-10-22 16:49:45 +08:00
a72733d81a update go mod 2024-10-22 16:37:13 +08:00
0636dd1b11 优化异常堆栈打印 2024-09-30 16:17:14 +08:00
e52d67cfe3 update 2024-09-30 15:54:20 +08:00
02cdc3c792 fix 2024-09-30 15:25:58 +08:00
36d4ca844a update debug strack 2024-09-30 15:25:17 +08:00
99ea9ba111 接口非成功打印异常堆栈
- 接口非成功打印异常堆栈
- 支持开关控制是否打印
2024-09-30 11:47:04 +08:00
8ceb818a24 fix 2024-09-26 17:40:09 +08:00
22bf77019a update method name 2024-09-26 17:33:27 +08:00
01c2fdf5a2 修复对外输出扩展数据 2024-09-24 15:10:37 +08:00
29b0eaa6b3 fix middleware 2024-09-24 15:05:02 +08:00
5ae2e3fae1 数据相应支持扩展数据 2024-09-24 14:56:03 +08:00
9d0f74b19a 增加解析header + 解析 cookie 2024-09-23 17:06:49 +08:00
c4d41a9d4e fix return value 2024-09-20 17:37:03 +08:00
5abd91f947 set defult支持get 2024-09-20 17:34:53 +08:00
4f1e0e2649 表单验证支持设置默认值 2024-09-20 17:31:23 +08:00
df5a20ea87 增加GetDomain方法 2024-09-19 15:13:25 +08:00
195e391235 修复响应完成时间未设置的问题 2024-08-17 20:21:34 +08:00
ce8feaa98b 修复响应完成时间未设置的问题 2024-08-17 20:07:48 +08:00
29bcf44ec9 相应日志区区成功和失败 2024-08-17 17:31:11 +08:00
25 changed files with 1006 additions and 197 deletions

View File

@ -33,6 +33,10 @@ type HttpHandleConfig struct {
ResponseTraceIDField string ResponseTraceIDField string
StartRequestTimeField string StartRequestTimeField string
FinishRequestTimeField string FinishRequestTimeField string
RequestIsSuccessField string // 请求处理是否成功的标识
ExtensionOutputField string // 扩展信息对外输出字段
EnableExtensionOutput bool
DisableDebugStackOutput bool // 禁用异常堆栈打印
} }
// ConvertDefaultConfig 覆盖默认配置 // ConvertDefaultConfig 覆盖默认配置
@ -51,6 +55,8 @@ func ConvertDefaultConfig(cfg *HttpHandleConfig) {
// Date : 16:55 2024/7/23 // Date : 16:55 2024/7/23
func GetHttpHandleConfig() *HttpHandleConfig { func GetHttpHandleConfig() *HttpHandleConfig {
return &HttpHandleConfig{ return &HttpHandleConfig{
EnableExtensionOutput: inputHttpHandleConfig.EnableExtensionOutput,
DisableDebugStackOutput: inputHttpHandleConfig.DisableDebugStackOutput,
RequestIDField: wrapper.TernaryOperator.String( RequestIDField: wrapper.TernaryOperator.String(
nil == inputHttpHandleConfig || inputHttpHandleConfig.RequestIDField == "", nil == inputHttpHandleConfig || inputHttpHandleConfig.RequestIDField == "",
consts.GinRequestIDField, consts.GinRequestIDField,
@ -106,5 +112,15 @@ func GetHttpHandleConfig() *HttpHandleConfig {
consts.GinRecordResponseDataField, consts.GinRecordResponseDataField,
wrapper.String(inputHttpHandleConfig.RecordResponseDataField), wrapper.String(inputHttpHandleConfig.RecordResponseDataField),
).Value(), ).Value(),
RequestIsSuccessField: wrapper.TernaryOperator.String(
nil == inputHttpHandleConfig || inputHttpHandleConfig.RequestIsSuccessField == "",
consts.GinRequestIsSuccessField,
wrapper.String(inputHttpHandleConfig.RecordResponseDataField),
).Value(),
ExtensionOutputField: wrapper.TernaryOperator.String(
nil == inputHttpHandleConfig || inputHttpHandleConfig.ExtensionOutputField == "",
consts.GinResponseExtensionField,
wrapper.String(inputHttpHandleConfig.RecordResponseDataField),
).Value(),
} }
} }

54
go.mod
View File

@ -1,67 +1,69 @@
module git.zhangdeman.cn/zhangdeman/gin module git.zhangdeman.cn/zhangdeman/gin
go 1.21 go 1.21.0
toolchain go1.21.5 toolchain go1.23.1
require ( require (
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240726024939-e424db29c5c4 git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20231105153815-e8561a060cc8 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/wrapper v0.0.0-20240813083016-da44ae07ab9b git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd
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.0 github.com/go-playground/validator/v10 v10.24.0
github.com/mcuadros/go-defaults v1.2.0
github.com/sbabiv/xml2map v1.2.1
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/serialize v0.0.0-20240618035451-8d48a6bd39dd // 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.1 // indirect github.com/bytedance/sonic v1.12.8 // indirect
github.com/bytedance/sonic/loader v0.2.0 // 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/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.5 // 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.0.6 // indirect github.com/lestrrat-go/strftime v1.1.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-homedir v1.1.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/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
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.2 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pkg/errors v0.9.1 // 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.17.3 // 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
github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect
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.9.0 // indirect golang.org/x/arch v0.14.0 // indirect
golang.org/x/crypto v0.26.0 // indirect golang.org/x/crypto v0.32.0 // indirect
golang.org/x/net v0.28.0 // indirect golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.24.0 // indirect golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.17.0 // indirect golang.org/x/text v0.22.0 // indirect
google.golang.org/protobuf v1.34.2 // 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
) )

155
go.sum
View File

@ -1,43 +1,50 @@
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240726024939-e424db29c5c4 h1:mibnyzYbZullK0aTHVASHl3UeoVr8IgytQZsuyv+yEM= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00 h1:obyJF0CXVR93TOnOtzN5xXxxSLpw1UFMBc4niWiyoQI=
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240726024939-e424db29c5c4/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20250122075709-5ecf3edb4a00/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 h1:q9pXs8ByVg/XwyDopIGyfEOi/LyHFR0r1rCnJ90uFxw= git.zhangdeman.cn/zhangdeman/exception v0.0.0-20240930081343-1e7f84ed8465 h1:j5EB0hamTMT5fY+xmjJ51oBvll+vS2inNPi+3/UBj60=
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20231105153815-e8561a060cc8/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/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-20240627031706-9ff1c213bb50 h1:olo34i2Gq5gX7bYPv5TR4X5l5CrYFtu9UCElkYlmL2c= git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e h1:YE2Gi+M03UDImIpWa3I7jzSesyfu2RL8x/4ONs5v0oE=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240627031706-9ff1c213bb50/go.mod h1:US/pcq2vstE3iyxIHf53w8IeXKkZys7bj/ozLWkRYeE= 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-20240806072320-3533617196fd h1:zcmfmp/1srHldFpa7BCH6Cpp9iVNFM/7W7DoxHp48UU= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9 h1:yF770WIDNwyiKL0nwmBGmjZvNCLXtHQL4xJyffPjTMU=
git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20240806072320-3533617196fd/go.mod h1:gnaF3v9/om6gaxFKeNVuKeFTYM61gHyW7vign7vrwyo= git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20250124091620-c757e551a8c9/go.mod h1:I76wxEsWq7KnMQ84elpwTjEqq4I49QFw60tp5h7iGBs=
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=
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.11.9 h1:LFHENlIY/SLzDWverzdOvgMztTxcfcF+cqNsz9pK5zg= github.com/bytedance/sonic v1.12.5 h1:hoZxY8uW+mT+OpkcUWw4k0fDINtOcVavEsGfzwzFU/w=
github.com/bytedance/sonic v1.11.9/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic v1.12.5/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk=
github.com/bytedance/sonic v1.12.1 h1:jWl5Qz1fy7X1ioY74WqO0KjAMtAGQs4sYnjiEBiyX24= github.com/bytedance/sonic v1.12.7 h1:CQU8pxOy9HToxhndH0Kx/S1qU/CuS9GnKYrGioDcU1Q=
github.com/bytedance/sonic v1.12.1/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= 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.1 h1:1GgorWTqf12TA8mma4DDSbaQigE2wOgQo7iCjjJv3+E=
github.com/bytedance/sonic/loader v0.2.0/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=
@ -46,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.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
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=
@ -62,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.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
github.com/go-playground/validator/v10 v10.22.0/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=
@ -76,21 +89,29 @@ 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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 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/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 h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= 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 h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= 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.1.0 h1:gMESpZy44/4pXLO/m+sL0yBd1W6LjgjrrD4a68Gapyg=
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw= 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 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 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 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -100,12 +121,16 @@ github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+
github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= 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 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4=
github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw= github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
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 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sbabiv/xml2map v1.2.1 h1:1lT7t0hhUvXZCkdxqtq4n8/ZCnwLWGq4rDuDv5XOoFE=
github.com/sbabiv/xml2map v1.2.1/go.mod h1:2TPoAfcaM7+Sd4iriPvzyntb2mx7GY+kkQpB/GQa/eo=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
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=
@ -120,10 +145,10 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.17.3/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=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
@ -139,39 +164,39 @@ 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.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA=
golang.org/x/arch v0.9.0 h1:ub9TgUInamJ8mrZIGlBG6/4TqWeMszd4N8lNorbrr6k= golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/arch v0.9.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
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/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.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.22.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.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.24.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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.17.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=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
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/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 h1:sY2a+y0j4iDrajJcorb+a0hJIQ6uakU5gybjfLWHlXo=
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376/go.mod h1:BHKOc1m5wm8WwQkMqYBoo4vNxhmF7xg8+xhG8L+Cy3M= 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= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

12
init.go Normal file
View File

@ -0,0 +1,12 @@
// Package gin ...
//
// Description : gin ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 17:01
package gin
import (
_ "git.zhangdeman.cn/zhangdeman/gin/request/parse_body"
)

View File

@ -8,10 +8,11 @@
package middleware package middleware
import ( import (
"strings"
"git.zhangdeman.cn/zhangdeman/consts" "git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/gin/request" "git.zhangdeman.cn/zhangdeman/gin/request"
"go.uber.org/zap" "go.uber.org/zap"
"strings"
"git.zhangdeman.cn/zhangdeman/gin/define" "git.zhangdeman.cn/zhangdeman/gin/define"
@ -97,10 +98,10 @@ func LogRequest(cfg *AccessConfig) gin.HandlerFunc {
startRequestTime := request.WrapperHandle.GetCtxIntData(ctx, handleConfig.StartRequestTimeField, 0) startRequestTime := request.WrapperHandle.GetCtxIntData(ctx, handleConfig.StartRequestTimeField, 0)
// 记录请求日志 // 记录请求日志
logData := logger.NewLogData(ctx, consts.LogTypeRequest, "", map[string]any{ logData := logger.NewLogData(ctx, consts.LogTypeRequest, "", map[string]any{
handleConfig.StartRequestTimeField: startRequestTime, // 开始请求时间 handleConfig.StartRequestTimeField: startRequestTime, // 开始请求时间
"request_header": getLogRequestHeader(ctx, cfg), // 请求header "request_header": getLogRequestHeader(ctx, cfg), // 请求header
"request_query": request.WrapperHandle.GetQuery(ctx), // 获取请求query "request_query": request.WrapperHandle.ParseQuery(ctx), // 获取请求query
"request_body": request.WrapperHandle.GetRequestBody(ctx), // 请求body "request_body": request.WrapperHandle.ParseBody(ctx), // 请求body
}) })
cfg.Logger.Info("接口请求日志记录", logger.ZapLogDataList(logData)...) cfg.Logger.Info("接口请求日志记录", logger.ZapLogDataList(logData)...)
ctx.Next() ctx.Next()
@ -114,7 +115,11 @@ func LogRequest(cfg *AccessConfig) gin.HandlerFunc {
"response_body": request.WrapperHandle.GetResponseBody(ctx, handleConfig.ResponseDataField, map[string]any{}), // 响应body "response_body": request.WrapperHandle.GetResponseBody(ctx, handleConfig.ResponseDataField, map[string]any{}), // 响应body
"response_header": getLogResponseHeader(ctx, cfg), // 响应header "response_header": getLogResponseHeader(ctx, cfg), // 响应header
}) })
cfg.Logger.Info("接口响应日志记录", logger.ZapLogDataList(logResponseData)...) if ctx.GetBool(define.GetHttpHandleConfig().RequestIsSuccessField) {
cfg.Logger.Info("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
} else {
cfg.Logger.Error("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
}
} }
} }

View File

@ -26,9 +26,12 @@ func ValidateBlackIPMiddleware(code interface{}, httpCode int, validateFunc defi
ctx.Next() ctx.Next()
return return
} }
if validateFunc(ctx, networkUtil.IP.GetRemoteIP(ctx.Request)) { remoteIp := networkUtil.IP.GetRemoteIP(ctx.Request)
if validateFunc(ctx, remoteIp) {
// 命中黑名单 // 命中黑名单
response.Send(ctx, code, httpCode, nil) response.Send(ctx, code, httpCode, map[string]any{
"remote_ip": remoteIp,
}, nil)
ctx.Abort() ctx.Abort()
return return
} }
@ -48,9 +51,12 @@ func ValidateWhiteIPMiddleware(code interface{}, httpCode int, validateFunc defi
ctx.Next() ctx.Next()
return return
} }
if !validateFunc(ctx, networkUtil.IP.GetRemoteIP(ctx.Request)) { remoteIp := networkUtil.IP.GetRemoteIP(ctx.Request)
if !validateFunc(ctx, remoteIp) {
// 非名单 // 非名单
response.Send(ctx, code, httpCode, nil) response.Send(ctx, code, httpCode, map[string]any{
"remote_ip": remoteIp,
}, nil)
ctx.Abort() ctx.Abort()
return return
} }

View File

@ -0,0 +1,26 @@
// Package abstract ...
//
// Description : abstract ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:38
package abstract
import (
"github.com/gin-gonic/gin"
)
// RequestBodyParseAdaptor 解析请求body的接口适配器约束
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:39 2024/10/22
type RequestBodyParseAdaptor interface {
// Parse 解析Body数据解析结果会反序列化至 receiver , 同时, 会以 map 结构返回
Parse(ctx *gin.Context, receiver any) ([]byte, error)
// Unmarshal 自定义反序列化的方法, 为 nil 则使用内置的序列化方式
Unmarshal() func(sourceData []byte, receiver any) error
// ContentType 当前适配器用与解析何种type
ContentType() string
}

View File

@ -10,6 +10,7 @@ package request
import ( import (
"bytes" "bytes"
"errors" "errors"
"github.com/mcuadros/go-defaults"
"io" "io"
"net/http" "net/http"
"strings" "strings"
@ -48,21 +49,27 @@ func (f *form) Parse(ctx *gin.Context, receiver interface{}) error {
method == http.MethodTrace || method == http.MethodTrace ||
method == http.MethodConnect || method == http.MethodConnect ||
method == http.MethodOptions { method == http.MethodOptions {
return ctx.ShouldBindQuery(receiver) if err := ctx.ShouldBindQuery(receiver); nil != err {
} return err
}
if method == http.MethodPost || } else if method == http.MethodPost ||
method == http.MethodPut || method == http.MethodPut ||
method == http.MethodDelete { method == http.MethodDelete {
if ContentType.IsJson(ctx) { if ContentType.IsJson(ctx) {
return ctx.ShouldBindJSON(receiver) if err := ctx.ShouldBindJSON(receiver); nil != err {
return err
}
} else if ContentType.IsFormURLEncoded(ctx) {
if err := ctx.ShouldBind(receiver); nil != err {
return err
}
} else {
return errors.New(ctx.ContentType() + " is not support")
} }
} else {
if ContentType.IsFormURLEncoded(ctx) { return errors.New(method + " : request method is not support")
return ctx.ShouldBind(receiver)
}
return errors.New(ctx.ContentType() + " is not support")
} }
return errors.New(method + " : request method is not support") // 设置默认值
defaults.SetDefaults(receiver)
return nil
} }

View File

@ -0,0 +1,46 @@
// Package parse_body ...
//
// Description : parse_body ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:51
package parse_body
import (
"bytes"
"github.com/gin-gonic/gin"
"io"
)
type base struct {
}
// Unmarshal 反序列化方法,可以不指定
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:54 2024/10/22
func (b base) Unmarshal() func(sourceData []byte, receiver any) error {
return nil
}
// DoParse 解析
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:08 2024/10/22
func (b base) DoParse(ctx *gin.Context, receiver any, unmarshalFunc func(sourceData []byte, receiver any) error) ([]byte, error) {
data, err := io.ReadAll(ctx.Request.Body)
if nil != err {
return nil, err
}
ctx.Request.Body = io.NopCloser(bytes.NewBuffer(data))
if nil == unmarshalFunc || nil == receiver {
return data, nil
}
if err := unmarshalFunc(data, receiver); nil != err {
return nil, err
}
return data, err
}

View File

@ -0,0 +1,70 @@
// Package parse_body ...
//
// Description : parse_body ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:43
package parse_body
import (
"errors"
"git.zhangdeman.cn/zhangdeman/gin/request/abstract"
"github.com/gin-gonic/gin"
"strings"
)
var (
requestBodyParseAdaptorTable = map[string]abstract.RequestBodyParseAdaptor{}
)
func init() {
adaptorList := []abstract.RequestBodyParseAdaptor{
JsonAdaptor{},
FormUrlEncode{},
XmlAdaptor{},
}
for _, itemAdaptor := range adaptorList {
Register(itemAdaptor)
}
}
// Register 注册适配器实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:45 2024/10/22
func Register(adaptor abstract.RequestBodyParseAdaptor) {
if nil == adaptor {
return
}
requestBodyParseAdaptorTable[adaptor.ContentType()] = adaptor
}
// Execute 解析请求BODY数据
func Execute(ctx *gin.Context, receiver any) ([]byte, error) {
contentType := strings.ToLower(strings.ReplaceAll(ctx.ContentType(), " ", ""))
// 裁剪出真实的类型,之所以截取,是因为 content_type 中可能还包含编码信息, 如 : application/json;charset=utf8
contentTypeArr := strings.Split(contentType, ";")
contentType = contentTypeArr[0]
if _, exist := requestBodyParseAdaptorTable[contentType]; !exist {
return nil, errors.New(contentType + " : adaptor not found")
}
if parseResult, err := requestBodyParseAdaptorTable[contentType].Parse(ctx, receiver); nil != err {
return nil, err
} else {
return parseResult, err
}
}
// ExecuteForMap 高层级包装表单解析为map
func ExecuteForMap(ctx *gin.Context) (map[string]any, error) {
var (
err error
result map[string]any
)
if _, err = Execute(ctx, &result); nil != err {
return nil, err
}
return result, nil
}

View File

@ -0,0 +1,44 @@
// Package parse_body ...
//
// Description : parse_body ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:43
package parse_body
import (
"encoding/json"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/serialize"
"github.com/gin-gonic/gin"
)
type FormUrlEncode struct {
base
}
func (f FormUrlEncode) Parse(ctx *gin.Context, receiver any) ([]byte, error) {
if err := ctx.Request.ParseForm(); nil != err {
return nil, err
}
body := map[string]string{}
for paramName, itemParam := range ctx.Request.PostForm {
if len(itemParam) > 0 {
body[paramName] = itemParam[0]
} else {
body[paramName] = ""
}
}
byteData, _ := json.Marshal(body)
if nil != receiver {
if err := serialize.JSON.UnmarshalWithNumber(byteData, receiver); nil != receiver {
return nil, err
}
}
return byteData, nil
}
func (f FormUrlEncode) ContentType() string {
return consts.MimeTypeXWWWFormUrlencoded
}

View File

@ -0,0 +1,49 @@
// Package parse_body ...
//
// Description : parse_body ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:42
package parse_body
import (
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/serialize"
"github.com/gin-gonic/gin"
)
type JsonAdaptor struct {
base
}
// Parse 解析json请求体
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:13 2024/10/22
func (j JsonAdaptor) Parse(ctx *gin.Context, receiver any) ([]byte, error) {
unmarshalFunc := j.Unmarshal()
if nil == unmarshalFunc {
unmarshalFunc = serialize.JSON.UnmarshalWithNumber
}
return j.DoParse(ctx, receiver, unmarshalFunc)
}
// Unmarshal 指定解析方法
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:56 2024/10/22
func (j JsonAdaptor) Unmarshal() func(sourceData []byte, receiver any) error {
return serialize.JSON.UnmarshalWithNumber
}
// ContentType 请求类型固定返回json
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:59 2024/10/22
func (j JsonAdaptor) ContentType() string {
return consts.MimeTypeJson
}

42
request/parse_body/xml.go Normal file
View File

@ -0,0 +1,42 @@
// Package parse_body ...
//
// Description : parse_body ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:42
package parse_body
import (
"bytes"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/serialize"
"github.com/gin-gonic/gin"
"github.com/sbabiv/xml2map"
)
type XmlAdaptor struct {
base
}
func (x XmlAdaptor) Parse(ctx *gin.Context, receiver any) ([]byte, error) {
unmarshalFunc := x.Unmarshal()
if nil == unmarshalFunc {
unmarshalFunc = serialize.Xml.UnmarshalWithNumber
}
return x.DoParse(ctx, receiver, unmarshalFunc)
}
func (x XmlAdaptor) Unmarshal() func(sourceData []byte, receiver any) error {
return func(sourceData []byte, receiver any) error {
res, err := xml2map.NewDecoder(bytes.NewReader(sourceData)).Decode()
if nil != err {
return err
}
return serialize.JSON.Transition(res, receiver)
}
}
func (x XmlAdaptor) ContentType() string {
return consts.MimeTypeXml
}

View File

@ -0,0 +1,8 @@
// Package parse_body ...
//
// Description : parse_body ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-10-22 16:43
package parse_body

View File

@ -8,11 +8,9 @@
package request package request
import ( import (
"bytes" "git.zhangdeman.cn/zhangdeman/gin/request/parse_body"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/wrapper" "git.zhangdeman.cn/zhangdeman/wrapper"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"io"
"strings" "strings"
) )
@ -76,12 +74,12 @@ func (wh *wrapperHandle) GetScheme(ctx *gin.Context, defaultVal string) string {
return defaultVal return defaultVal
} }
// GetQuery 获取query参数 // ParseQuery 获取query参数
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 16:03 2024/1/2 // Date : 16:03 2024/1/2
func (wh *wrapperHandle) GetQuery(ctx *gin.Context) map[string]string { func (wh *wrapperHandle) ParseQuery(ctx *gin.Context) map[string]string {
query := make(map[string]string) query := make(map[string]string)
if nil != ctx && nil != ctx.Request && nil != ctx.Request.URL { if nil != ctx && nil != ctx.Request && nil != ctx.Request.URL {
for paramName, valueList := range ctx.Request.URL.Query() { for paramName, valueList := range ctx.Request.URL.Query() {
@ -121,35 +119,27 @@ func (wh *wrapperHandle) GetContentType(ctx *gin.Context, defaultVal string) str
return wrapper.TernaryOperator.String(len(contentType) > 0, wrapper.String(contentType), wrapper.String(defaultVal)).Value() return wrapper.TernaryOperator.String(len(contentType) > 0, wrapper.String(contentType), wrapper.String(defaultVal)).Value()
} }
// GetRequestBody 获取请求body // 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
}
// ParseBody 获取请求body
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 11:25 2024/7/26 // Date : 11:25 2024/7/26
func (wh *wrapperHandle) GetRequestBody(ctx *gin.Context) map[string]any { func (wh *wrapperHandle) ParseBody(ctx *gin.Context) map[string]any {
body := map[string]any{} body := map[string]any{}
contentType := wh.GetContentType(ctx, "") if _, err := parse_body.Execute(ctx, &body); nil != err {
if strings.Contains(contentType, consts.MimeTypeXWWWFormUrlencoded) { // form请求 return map[string]any{}
if err := ctx.Request.ParseForm(); nil != err {
return body
}
for paramName, itemParam := range ctx.Request.PostForm {
if len(itemParam) > 0 {
body[paramName] = itemParam[0]
} else {
body[paramName] = ""
}
}
return body
}
if strings.Contains(contentType, consts.MimeTypeJson) || nil != ctx.Request.Body { // json请求 或者非 json请求 存在 body
data, err := io.ReadAll(ctx.Request.Body)
if nil != err {
return body
}
ctx.Request.Body = io.NopCloser(bytes.NewBuffer(data))
return body
} }
return body return body
@ -242,3 +232,39 @@ func (wh *wrapperHandle) GetCtxIntData(ctx *gin.Context, key string, defaultVal
} }
return ctx.GetInt64(key) return ctx.GetInt64(key)
} }
// ParseHeader 解析header数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:04 2024/9/23
func (wh *wrapperHandle) ParseHeader(ctx *gin.Context) map[string]string {
headerData := map[string]string{}
if nil == ctx || nil == ctx.Request {
return headerData
}
for headerName, headerVal := range ctx.Request.Header {
if len(headerVal) > 0 {
headerData[headerName] = headerVal[0]
} else {
headerData[headerName] = ""
}
}
return headerData
}
// ParseCookie 解析cookie数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:06 2024/9/23
func (wh *wrapperHandle) ParseCookie(ctx *gin.Context) map[string]string {
cookieData := map[string]string{}
if nil == ctx || nil == ctx.Request {
return cookieData
}
for _, itemCookie := range ctx.Request.Cookies() {
cookieData[itemCookie.Name] = itemCookie.Value
}
return cookieData
}

View File

@ -8,6 +8,7 @@
package response package response
import ( import (
"fmt"
"net/http" "net/http"
"time" "time"
@ -21,14 +22,38 @@ const (
hasSendResponseFlag = "GIN_PKG_HAS_SEND_RESPONSE" 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 成功的响应 // Success 成功的响应
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 22:37 2022/6/25 // Date : 22:37 2022/6/25
func Success(ctx *gin.Context, data interface{}) { func Success(ctx *gin.Context, data any) {
successException := exception.NewSuccess(data) successException := exception.NewSuccess(data)
Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData()) Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData(), nil)
}
// SuccessWithExtension 返回扩展数据
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:52 2024/9/24
func SuccessWithExtension(ctx *gin.Context, data any, extension map[string]any) {
successException := exception.NewSuccess(data)
Send(ctx, successException.GetCode(), successException.GetHttpCode(), successException.GetData(), extension)
} }
// Send 基础的发送数据 // Send 基础的发送数据
@ -36,21 +61,26 @@ func Success(ctx *gin.Context, data interface{}) {
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 22:40 2022/6/25 // Date : 22:40 2022/6/25
func Send(ctx *gin.Context, code interface{}, httpCode int, data interface{}) { func Send(ctx *gin.Context, code any, httpCode int, data any, extension map[string]any) {
// 设置请求是否成功的标识
ctx.Set(define.GetHttpHandleConfig().RequestIsSuccessField, fmt.Sprintf("%v", code) == fmt.Sprintf("%v", successBusinessCode))
if ctx.GetBool(hasSendResponseFlag) { if ctx.GetBool(hasSendResponseFlag) {
// 已经发送过数据, 后面在发送数据, 不执行 // 已经发送过数据, 后面在发送数据, 不执行
return return
} }
finishRequestTime := time.Now().UnixMilli()
// 设置数据已发送的标识 // 设置数据已发送的标识
defer ctx.Set(hasSendResponseFlag, true) defer ctx.Set(hasSendResponseFlag, true)
responseConfig := define.GetHttpHandleConfig() responseConfig := define.GetHttpHandleConfig()
finishRequestTime := time.Now().UnixMilli() responseData := map[string]any{
responseData := map[string]interface{}{
responseConfig.ResponseCodeField: code, responseConfig.ResponseCodeField: code,
responseConfig.ResponseMessageField: exception.GetMessage(code), responseConfig.ResponseMessageField: exception.GetMessage(code),
responseConfig.ResponseTraceIDField: ctx.GetString(responseConfig.ResponseTraceIDField), responseConfig.ResponseTraceIDField: ctx.GetString(responseConfig.ResponseTraceIDField),
responseConfig.ResponseDataField: data, responseConfig.ResponseDataField: data,
responseConfig.HandleRequestCostField: finishRequestTime - ctx.GetTime(responseConfig.StartRequestTimeField).UnixMilli(), responseConfig.HandleRequestCostField: finishRequestTime - ctx.GetInt64(responseConfig.StartRequestTimeField),
}
if responseConfig.EnableExtensionOutput && nil != extension {
responseData[responseConfig.ExtensionOutputField] = extension
} }
// 记录完成时间 // 记录完成时间
ctx.Set(responseConfig.FinishRequestTimeField, finishRequestTime) ctx.Set(responseConfig.FinishRequestTimeField, finishRequestTime)
@ -64,8 +94,8 @@ func Send(ctx *gin.Context, code interface{}, httpCode int, data interface{}) {
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 22:41 2022/6/25 // Date : 22:41 2022/6/25
func SendWithStatusOK(ctx *gin.Context, code interface{}, data interface{}) { func SendWithStatusOK(ctx *gin.Context, code any, data any) {
Send(ctx, code, http.StatusOK, data) Send(ctx, code, http.StatusOK, data, nil)
} }
// SendWithException 使用exception发送数据 // SendWithException 使用exception发送数据
@ -73,15 +103,21 @@ func SendWithStatusOK(ctx *gin.Context, code interface{}, data interface{}) {
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 13:08 2022/6/26 // Date : 13:08 2022/6/26
func SendWithException(ctx *gin.Context, e exception.IException, data interface{}) { func SendWithException(ctx *gin.Context, e exception.IException, data map[string]any) {
if nil == e { if nil == e {
e = exception.NewSuccess(data) e = exception.NewSuccess(data)
} }
outputData := map[string]interface{}{ if !define.GetHttpHandleConfig().DisableDebugStackOutput && nil != e {
stack := e.GetStack()
if len(stack) > 0 {
fmt.Println(stack)
}
}
outputData := map[string]any{
"e_data": e.GetData(), "e_data": e.GetData(),
"u_e_data": data, "u_e_data": data,
} }
Send(ctx, e.GetCode(), e.GetHttpCode(), outputData) Send(ctx, e.GetCode(), e.GetHttpCode(), outputData, nil)
} }
// JSON ctx.JSON 的平替, 增加了数据是否已相应的标识 // JSON ctx.JSON 的平替, 增加了数据是否已相应的标识
@ -89,7 +125,7 @@ func SendWithException(ctx *gin.Context, e exception.IException, data interface{
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 14:51 2023/2/15 // Date : 14:51 2023/2/15
func JSON(ctx *gin.Context, httpCode int, data interface{}) { func JSON(ctx *gin.Context, httpCode int, data any) {
if ctx.GetBool(hasSendResponseFlag) { if ctx.GetBool(hasSendResponseFlag) {
// 已经发送过数据, 后面在发送数据, 不执行 // 已经发送过数据, 后面在发送数据, 不执行
return return

25
router/config.go Normal file
View File

@ -0,0 +1,25 @@
// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-02-07 17:41
package router
import "strings"
var defaultValidateErrTag = "err"
// SetValidateErrTag 设置验证失败时, 获取错误信息的tag字段
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:42 2025/2/7
func SetValidateErrTag(tagName string) {
tagName = strings.TrimSpace(tagName)
if tagName == "" {
return
}
defaultValidateErrTag = tagName
}

175
router/controller.go Normal file
View File

@ -0,0 +1,175 @@
// 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
}
validate := strings.TrimSpace(structField.Tag.Get(TagNameBinding))
if len(validate) == 0 {
validate = strings.TrimSpace(structField.Tag.Get(TagNameValidate))
}
title := strings.TrimSpace(structField.Tag.Get(TagNameDesc))
if len(title) == 0 {
title = jsonTag
}
res = append(res, UriParam{
Field: structField.Name,
Name: jsonTag,
Title: title,
Type: structField.Type.String(),
Validate: validate,
ErrorMsg: "",
})
}
return res
}

View File

@ -10,16 +10,22 @@ package router
import "reflect" import "reflect"
const ( const (
PrefixFuncName = "RouterPrefix" // 路由前缀函数名称 PrefixFuncName = "RouterPrefix" // 路由前缀函数名称
MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称 MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称
GinContextType = "*gin.Context" // gin context 类型名称
ErrorType = "error" // error类型
ErrorInterfaceFuncName = "Error" // error接口需要实现的方法名称
) )
const ( const (
TagNamePath = "path" // 接口的请求路径 TagNamePath = "path" // 接口的请求路径
TagNameMethod = "method" // 接口的请求方法 TagNameMethod = "method" // 接口的请求方法
TagNameUriTag = "tag" // 接口的tag TagNameUriTag = "tag" // 接口的tag
TagNameDesc = "desc" // 接口的描述 TagNameDesc = "desc" // 接口/接口参数的描述
TagNameStrict = "strict" // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map非严格模式返回任意值
TagNameBinding = "binding" // gin 内置的验证规则tag
TagNameValidate = "validate" // validator v10 默认的验证规则tag
TagNameErrMsg = "err" // 验证失败错误信息tag
) )
// UriConfig 接口配置 // UriConfig 接口配置
@ -28,10 +34,31 @@ const (
// //
// Date : 15:41 2024/7/21 // Date : 15:41 2024/7/21
type UriConfig struct { type UriConfig struct {
Path string `json:"path"` // 接口路由, 必须配置 Path string `json:"path"` // 接口路由, 必须配置
Method string `json:"method"` // 接口请求方法, 必须配置 RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置
TagList []string `json:"tag_list"` // 接口分组 TagList []string `json:"tag_list"` // 接口分组
Desc string `json:"desc"` // 接口描述 Desc string `json:"desc"` // 接口描述
Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
FormDataType reflect.Type `json:"-"` // 表单数据类型 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"` // 参数名称
Title string `json:"title"` // 参数标题
Type string `json:"type"` // 参数类型
Validate string `json:"validate"` // 验证规则: validator/v10 库
ErrorMsg string `json:"error_msg"` // 验证失败的错误信息
}
const (
FieldNameMeta = "Meta" // 元信息字段
)

51
router/group.go Normal file
View 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
}

63
router/handler.go Normal file
View File

@ -0,0 +1,63 @@
// 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 {
// 格式化验证错误的信息
err = GetValidateErr(formData, 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
}
}

View File

@ -7,7 +7,11 @@
// Date : 2024-07-20 21:40 // Date : 2024-07-20 21:40
package router package router
// Meta 接口的元信息 // Meta 接口的元信息, 主要包含如下信息:
//
// uri: 接口路由(不包含group前缀)
//
// method: 请求方法: get/post 等
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //

View File

@ -118,17 +118,17 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e
if formType.Kind() == reflect.Ptr { if formType.Kind() == reflect.Ptr {
formType = methodType.In(2).Elem() formType = methodType.In(2).Elem()
} }
metaField, metaFieldExist := formType.FieldByName("Meta") metaField, metaFieldExist := formType.FieldByName(FieldNameMeta)
if !metaFieldExist { if !metaFieldExist {
return nil, nil return nil, nil
} }
uriConfig := &UriConfig{ uriConfig := &UriConfig{
Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"), Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"),
Method: strings.ToUpper(metaField.Tag.Get(TagNameMethod)), RequestMethod: strings.ToUpper(metaField.Tag.Get(TagNameMethod)),
TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"), TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"),
Desc: metaField.Tag.Get(TagNameDesc), Desc: metaField.Tag.Get(TagNameDesc),
Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0, OutputStrict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameOutputStrict))) >= 0,
FormDataType: methodType.In(2).Elem(), FormDataType: methodType.In(2).Elem(),
} }
// 校验 FormDataType // 校验 FormDataType
for fieldIdx := 0; fieldIdx < uriConfig.FormDataType.NumField(); fieldIdx++ { for fieldIdx := 0; fieldIdx < uriConfig.FormDataType.NumField(); fieldIdx++ {
@ -163,10 +163,10 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList
} }
err := errData.Interface() err := errData.Interface()
if e, ok := err.(exception.IException); ok { if e, ok := err.(exception.IException); ok {
response.SendWithException(ctx, e, businessData) response.SendWithException(ctx, e, map[string]any{"business_data": businessData})
return return
} else { } else {
response.SendWithException(ctx, exception.NewFromError(-1, errData.Interface().(error)), businessData) response.SendWithException(ctx, exception.NewFromError(-1, errData.Interface().(error)), map[string]any{"business_data": businessData})
return return
} }
} }
@ -174,7 +174,7 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList
middlewareList = append([]gin.HandlerFunc{ middlewareList = append([]gin.HandlerFunc{
middleware.InitRequest(), middleware.InitRequest(),
}, middlewareList...) }, middlewareList...)
switch uriConfig.Method { switch uriConfig.RequestMethod {
case http.MethodGet: case http.MethodGet:
ginRouter.GET(uriConfig.Path, middlewareList...) ginRouter.GET(uriConfig.Path, middlewareList...)
case http.MethodHead: case http.MethodHead:
@ -196,7 +196,7 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList
case "ANY": case "ANY":
ginRouter.Any(uriConfig.Path, middlewareList...) ginRouter.Any(uriConfig.Path, middlewareList...)
default: default:
panic(uriConfig.Path + " : " + uriConfig.Method + " is not support") panic(uriConfig.Path + " : " + uriConfig.RequestMethod + " is not support")
} }
} }

View File

@ -15,24 +15,13 @@ import (
type TestController struct{} type TestController struct{}
func (t *TestController) RouterPrefix() string { func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (any, error) {
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 return formData, nil
} }
type TestForm struct { type TestForm struct {
Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"` Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get"`
Age int `json:"age" form:"age"` Age int `json:"age" form:"age" binding:"min=20" err_msg:"年龄不能小于20"`
Name string `json:"name" form:"name"` Name string `json:"name" form:"name"`
Test *Test `json:"test" form:"test"` Test *Test `json:"test" form:"test"`
Num *int64 `json:"num" form:"num"` Num *int64 `json:"num" form:"num"`
@ -42,8 +31,8 @@ type Test struct {
} }
func Test_parseController(t *testing.T) { func Test_parseController(t *testing.T) {
type args struct { SetValidateErrTag("err_msg")
controller any r := gin.Default()
} Group(r, "test", nil, TestController{})
Register(8080, &TestController{}) r.Run(":8080")
} }

55
router/validator.go Normal file
View File

@ -0,0 +1,55 @@
// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-02-07 17:36
package router
import (
"errors"
"fmt"
"github.com/go-playground/validator/v10"
"reflect"
"strings"
)
// GetValidateErr 格式化错误信息
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 22:19 2025/1/15
func GetValidateErr(obj any, rawErr error) error {
if nil == rawErr {
return nil
}
if nil == obj {
return rawErr
}
var (
ok bool
validationErrs validator.ValidationErrors
errString []string
field reflect.StructField
)
if ok = errors.As(rawErr, &validationErrs); !ok {
return rawErr
}
objType := reflect.TypeOf(obj)
if objType.Kind() == reflect.Ptr {
objType = objType.Elem()
}
for _, validationErr := range validationErrs {
if field, ok = objType.FieldByName(validationErr.Field()); ok {
if e := field.Tag.Get(defaultValidateErrTag); e != "" {
errString = append(errString, fmt.Sprintf("%s: %s", field.Tag.Get("json"), e))
continue
} else {
errString = append(errString, fmt.Sprintf("%s: %v", field.Tag.Get("json"), validationErr.Value()))
}
}
errString = append(errString, validationErr.Error())
}
return errors.New(strings.Join(errString, "\n"))
}