From 61cefdbbbf8b318f5114fec7129ff04c9f315293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Mon, 11 Nov 2024 17:35:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=9F=E6=A0=B7=E6=90=AC=E8=BF=81=E7=8E=B0?= =?UTF-8?q?=E6=9C=89=E9=85=8D=E7=BD=AE=E5=AE=9E=E7=8E=B0,=20=E5=BE=85?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- define/context.go | 287 ++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 23 ++++ go.sum | 42 +++++++ 3 files changed, 352 insertions(+) create mode 100644 define/context.go create mode 100644 go.sum diff --git a/define/context.go b/define/context.go new file mode 100644 index 0000000..ab4261a --- /dev/null +++ b/define/context.go @@ -0,0 +1,287 @@ +// Package define ... +// +// Description : 自定义请求context +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2024-11-11 17:17 +package define + +import ( + "context" + httpclientDefine "git.zhangdeman.cn/gateway/httpclient/define" + "git.zhangdeman.cn/zhangdeman/trace" + "sync" + "time" +) + +// RequestContext 请求配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:19 2024/11/11 +type RequestContext struct { + GinCtx *context.Context `json:"-"` // gin 上下文 + RuntimeInstance *trace.Runtime `json:"-"` // 链路统一追踪实例 + GatewayUrlConfig *GatewayApiConfig `json:"gateway_url_config"` // 网关接口的配置 + GatewayApiInfo *GatewayApi `json:"gateway_api_info"` // 网关接口信息 + GatewayRequest *GatewayRequestInfo `json:"gateway_request"` // 网关请求信息 + BackendApiResultTable map[string]*httpclientDefine.Response `json:"backend_api_result_table"` // 后端接口返回数据详细信息: 接口别名 => 请求结果 + AppCode string `json:"app_code"` // 传入的APP Code + Sign string `json:"sign"` // 网关接口的签名 + AppApiPermission *AppApiPermission `json:"app_api_permission"` // 应用接口权限 + AppApiResultPermissionList []*AppApiResultPermission `json:"app_api_result_permission_list"` // 应用接口返回值权限 + Lock *sync.RWMutex `json:"-"` // 数据锁 + AppRateBehavior RateBehavior `json:"app_rate_behavior"` // 应用没有配置流控限制的行为 + ProjectRateLimit map[string]*RateLimitConfig `json:"project_rate_behavior"` // 项目流控行为 + ResponseData *ResponseData `json:"response_data"` // 网关响应数据 +} + +type GatewayApiConfig struct { + RateLimit *RateLimit `json:"rate_limit"` // 网关接口流控规则 + GatewayApiID int64 `json:"gateway_api_id"` // 网关接口ID + Uri string `json:"uri"` // 网关接口ID + ContentType string `json:"content_type"` // 请求类型 + Method string `json:"method"` // 请求方法 + Version string `json:"version"` // 接口版本 + Name string `json:"name"` // 接口名称 + Status string `json:"status"` // 状态 + ParamList []*GatewayApiDetailParamItem `json:"param_list"` // 参数列表 + ResultList []*GatewayApiDetailResultItem `json:"result_list"` // 返回值列表 + ProjectApiTable map[int64]*GatewayApiDetailProjectApiItem `json:"project_api_table"` // 项目接口列表 + RequestGroup [][]*GatewayApiDetailRequestGroupItem `json:"request_group"` // 请求分组 + RequestRewriteTable map[string][]*GatewayApiDetailRequestRewriteItem `json:"request_rewrite_table"` // 请求重写规则, 项目接口别名ID => 重写规则列表 +} + +type RateLimit struct { + ProjectTable map[int64]*RateLimitCfg `json:"project_table"` // 项目流控 + ProjectApiTable map[int64]*RateLimitCfg `json:"project_api_table"` // 项目接口流控 + Gateway *RateLimitCfg `json:"gateway"` // 网关接口本身流控 +} + +// GatewayApiDetailProjectApiParamItem 项目接口参数 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:51 2024/5/13 +type GatewayApiDetailProjectApiParamItem struct { + ID int64 `json:"id"` // 参数ID + Location string `json:"location"` // 参数位置 + Name string `json:"name"` // 参数名称 + ParamType string `json:"param_type"` // 参数类型 + DefaultValue string `json:"default_value"` // 默认值 +} + +// GatewayApiDetailProjectApiResultItem 项目接口返回值 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:51 2024/5/13 +type GatewayApiDetailProjectApiResultItem struct { + ID int64 `json:"id"` // 返回值ID + Location string `json:"location"` // 返回值位置 + Path string `json:"path"` // 返回值路径 + ResultType string `json:"result_type"` // 返回值类型 +} + +// GatewayApiDetailRequestGroupItem ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:58 2024/5/13 +type GatewayApiDetailRequestGroupItem struct { + ProjectID int64 `json:"project_id"` // 项目ID + ProjectFlag string `json:"project_flag"` // 项目标识 + ProjectApiID int64 `json:"project_api_id"` // 项目接口ID + ProjectApiAlias string `json:"project_api_alias"` // 项目接口别名 + ProjectApiAliasID int64 `json:"project_api_alias_id"` // 项目接口别名ID +} + +// GatewayApiDetailRequestRewriteItem 请求重写参数信息表 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:02 2024/5/13 +type GatewayApiDetailRequestRewriteItem struct { + SourceProjectApiAlias string `json:"source_project_api_alias"` // 数据源项目接口别名 __GATEWAY__ 代表从网关读取 + SourceProjectID int64 `json:"source_project_id"` // 数据源项目ID + SourceProjectApiID int64 `json:"source_project_api_id"` // 数据源项目接口ID + SourceProjectApiResultID int64 `json:"source_project_api_result_id"` // 数据源接口返回值ID, SourceProjectApiAlias = __GATEWAY__ 代表从网关读取 + TargetProjectApiAlias string `json:"target_project_api_alias"` // 目标接口接口别名 + TargetProjectID int64 `json:"target_project_id"` // 目标项目ID + TargetProjectApiID int64 `json:"target_project_api_id"` // 目标项目接口ID + TargetProjectApiParamID int64 `json:"target_project_api_param_id"` // 目标项目接口参数ID +} + +// GatewayApiDetailResultItem 网关响应信息表 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 18:03 2024/5/13 +type GatewayApiDetailResultItem struct { + ID int64 `json:"id"` // 网关接口返回值ID + SourceProjectApiAlias string `json:"source_project_api_alias"` // 数据源项目接口别名 __GATEWAY__ 代表从网关读取 + SourceDataLocation string `json:"source_data_location"` // 数据源数据位置 + SourceDataPath string `json:"source_data_path"` // 数据源数据路径 + SourceDataType string `json:"source_data_type"` // 数据源数据类型 + OutputLocation string `json:"output_location"` // 网关输出位置 + OutputPath string `json:"output_path"` // 网关输出路径 + OutputDataType string `json:"output_data_type"` // 网关输出数据类型 +} + +type GatewayApiDetailParamItem struct { + ID int64 `json:"id"` // 参数ID + Location string `json:"location"` // 参数位置 + Path string `json:"path"` // 参数名称 + ParamType string `json:"param_type"` // 参数类型 + DefaultValue string `json:"default_value"` // 默认值 + IsRequired bool `json:"is_required"` // 是否必传 + AllowEmpty bool `json:"allow_empty"` // 空字符串是否为有效参数 + AllowZero bool `json:"allow_zero"` // 数字类型, 0 是否为有效参数 + AllowNil bool `json:"allow_nil"` // nil 是否为有效参数 +} + +// GatewayApiDetailProjectApiItem 项目接口规则 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 17:44 2024/5/13 +type GatewayApiDetailProjectApiItem struct { + ProjectFlag string `json:"project_flag"` // 项目标识 + ProjectID int64 `json:"project_id"` // 项目ID + ProjectApiID int64 `json:"project_api_id"` // 项目接口ID + CacheEnable bool `json:"cache_enable"` // 缓存是否可用 + CacheInstanceID int64 `json:"cache_instance_id"` // 缓存可用的情况下, 缓存实例ID + CacheConfig *ApiCacheConfig `json:"cache_config"` // 缓存配置 + FullUrl string `json:"full_url"` // 项目接口完整Url + CodeField string `json:"code_field"` // 状态码字段 + MessageField string `json:"message_field"` // 状态码描述字段 + DataField string `json:"data_field"` // 数据字段 + SuccessCodeList []string `json:"success_code_list"` // 成功状态码列表 + Method string `json:"method"` // 请求方法 + ContentType string `json:"content_type"` // 请求类型 + ParamList []*GatewayApiDetailProjectApiParamItem `json:"param_list"` // 项目接口参数列表 + ResultList []*GatewayApiDetailProjectApiResultItem `json:"result_list"` // 项目接口返回值列表 +} + +type RateLimitCfg struct { + Day int `json:"day"` // 每天限制 + Hour int `json:"hour"` // 每小时限制 + Minute int `json:"minute"` // 每分钟限制 + Second int `json:"second"` // 每秒限制 +} + +type ApiCacheConfig struct { + PreHeatEnable bool `json:"pre_heat_enable"` // 启用预热 + ForcePreHeat bool `json:"force_pre_heat"` // 强制预热 + PreHeatMinPercent int64 `json:"pre_heat_min_percent"` // 预热最小剩余百分比 + PreHeatMinTTL int64 `json:"pre_heat_min_ttl"` // 预热最小剩余时长 + CacheTime int64 `json:"cache_time"` // 缓存时长, 单位 : s +} + +type GatewayApiDetail struct { + RateLimit *RateLimit `json:"rate_limit"` // 网关接口流控规则 + GatewayApiID int64 `json:"gateway_api_id"` // 网关接口ID + Uri string `json:"uri"` // 网关接口ID + ContentType string `json:"content_type"` // 请求类型 + Method string `json:"method"` // 请求方法 + Version string `json:"version"` // 接口版本 + Name string `json:"name"` // 接口名称 + Status string `json:"status"` // 状态 + ParamList []*GatewayApiDetailParamItem `json:"param_list"` // 参数列表 + ResultList []*GatewayApiDetailResultItem `json:"result_list"` // 返回值列表 + ProjectApiTable map[int64]*GatewayApiDetailProjectApiItem `json:"project_api_table"` // 项目接口列表 + RequestGroup [][]*GatewayApiDetailRequestGroupItem `json:"request_group"` // 请求分组 + RequestRewriteTable map[string][]*GatewayApiDetailRequestRewriteItem `json:"request_rewrite_table"` // 请求重写规则, 项目接口别名ID => 重写规则列表 +} + +type GatewayApi struct { + ID int64 `json:"id" gorm:"column:id;default:;NOT NULL"` // 主键ID + GroupID int64 `json:"group_id" gorm:"column:group_id;default:0;NOT NULL"` // 接口分组ID + Version string `json:"version" gorm:"column:version;default:v1;NOT NULL"` // 接口版本 + Uri string `json:"uri" gorm:"column:uri;default:;NOT NULL"` // 网关对外暴露的URI + MethodID int64 `json:"method_id" gorm:"column:method_id;default:0;NOT NULL"` // 请求方法ID + ContentTypeID int64 `json:"content_type_id" gorm:"column:content_type_id;default:0;NOT NULL"` // 请求类型ID + Name string `json:"name" gorm:"column:name;default:;NOT NULL"` // 网关API名称 + ExtendRule string `json:"extend_rule" gorm:"column:extend_rule;default:[];NOT NULL"` // 同名请求参数不存在时的参数规则 + Description string `json:"description" gorm:"column:description;default:;NOT NULL"` // 网关API描述 + Status string `json:"status" gorm:"column:status;default:INIT;NOT NULL"` // 状态 INIT - 待启用 NORMAL - 可用中 FORBIDDEN - 禁用 OFFLINE - 下线 DELETE - 删除 + Importance int64 `json:"importance" gorm:"column:importance;default:0;NOT NULL"` // 数据重要等级, 0 - 10 之间的数字 + CreateUserID string `json:"create_user_id" gorm:"column:create_user_id;default:0;NOT NULL"` // 创建人ID + ModifyUserID string `json:"modify_user_id" gorm:"column:modify_user_id;default:0;NOT NULL"` // 修改人ID + CreateTime time.Time `json:"create_time" gorm:"column:create_time;default:current_timestamp;NOT NULL"` // 创建时间 + ModifyTime time.Time `json:"modify_time" gorm:"column:modify_time;default:current_timestamp;NOT NULL"` // 修改时间 +} + +type GatewayRequestInfo struct { + Header map[string]string `json:"header"` // header信息 + Cookie map[string]string `json:"cookie"` // cookie信息 + Query map[string]string `json:"query"` // cookie信息 + Body map[string]any `json:"body"` // body信息 + Method string `json:"method"` // 请求方法 + Domain string `json:"domain"` // 域名 + ContentType string `json:"content_type"` // 请求类型 + Scheme string `json:"scheme"` // scheme + Uri string `json:"uri"` // 接口uri + Filter any `json:"filter_request"` // 过滤之后的请求信息 +} + +type AppApiPermission struct { + ID int64 `json:"id" gorm:"column:id;default:;NOT NULL"` // 主键ID + AppID int64 `json:"app_id" gorm:"column:app_id;default:0;NOT NULL"` // 应用ID + GatewayApiID int64 `json:"gateway_api_id" gorm:"column:gateway_api_id;default:0;NOT NULL"` // 网关接口ID + PerSecond int `json:"per_second" gorm:"column:per_second;default:0;NOT NULL"` // 全局每秒访问限制, 默认为 0 - 不限制 + PerMinute int `json:"per_minute" gorm:"column:per_minute;default:0;NOT NULL"` // 全局每分钟访问限制, 默认为 0 - 不限制 + PerHour int `json:"per_hour" gorm:"column:per_hour;default:0;NOT NULL"` // 全局每小时访问限制, 默认为 0 - 不限制 + PerDay int `json:"per_day" gorm:"column:per_day;default:0;NOT NULL"` // 全局每天访问限制, 默认为 0 - 不限制 + ItemTokenCount int `json:"item_token_count" gorm:"column:item_token_count;default:1;NOT NULL"` // 每次访问消耗的令牌数 + Status string `json:"status" gorm:"column:status;default:INIT;NOT NULL"` // 状态 INIT - 待启用 USING - 可用中 FORBIDDEN - 禁用 OFFLINE - 下线 DELETE - 删除 + Importance int64 `json:"importance" gorm:"column:importance;default:0;NOT NULL"` // 数据重要等级, 0 - 10 之间的数字 + CreateUserID string `json:"create_user_id" gorm:"column:create_user_id;default:0;NOT NULL"` // 创建人ID + ModifyUserID string `json:"modify_user_id" gorm:"column:modify_user_id;default:0;NOT NULL"` // 修改人ID + CreateTime time.Time `json:"create_time" gorm:"column:create_time;default:current_timestamp;NOT NULL"` // 创建时间 + ModifyTime time.Time `json:"modify_time" gorm:"column:modify_time;default:current_timestamp;NOT NULL"` // 修改时间 +} + +type AppApiResultPermission struct { + ID int64 `json:"id" gorm:"column:id;default:;NOT NULL"` // 主键ID + AppID int64 `json:"app_id" gorm:"column:app_id;default:0;NOT NULL"` // 应用ID + AppApiPermissionID int64 `json:"app_api_permission_id" gorm:"column:app_api_permission_id;default:0;NOT NULL"` // 接口授权ID + GatewayApiResultID int64 `json:"gateway_api_result_id" gorm:"column:gateway_api_result_id;default:0;NOT NULL"` // 网关接口返回值ID + Status string `json:"status" gorm:"column:status;default:INIT;NOT NULL"` // 状态 INIT - 待启用 USING - 可用中 FORBIDDEN - 禁用 OFFLINE - 下线 DELETE - 删除 + Importance int64 `json:"importance" gorm:"column:importance;default:0;NOT NULL"` // 数据重要等级, 0 - 10 之间的数字 + CreateUserID string `json:"create_user_id" gorm:"column:create_user_id;default:0;NOT NULL"` // 创建人ID + ModifyUserID string `json:"modify_user_id" gorm:"column:modify_user_id;default:0;NOT NULL"` // 修改人ID + CreateTime time.Time `json:"create_time" gorm:"column:create_time;default:current_timestamp;NOT NULL"` // 创建时间 + ModifyTime time.Time `json:"modify_time" gorm:"column:modify_time;default:current_timestamp;NOT NULL"` // 修改时间 +} + +type RateBehavior struct { + Day string `json:"day"` // 每天的处理 + Hour string `json:"hour"` // 每小时的处理 + Minute string `json:"minute"` // 每分钟的处理 + Second string `json:"second"` // 每秒中的处理 + SetRateLimitFail string `json:"set_rate_limit_fail"` // 设置流控失败的行为 +} + +type RateLimitConfig struct { + DayTotal int64 `json:"day_total"` // 每天总次数 + Day int64 `json:"day"` // 每天的次数 + DayZeroRateLimitBehavior string `json:"day_zero_rate_limit_behavior"` // 天未配置流控行为 + HourTotal int64 `json:"hour_total"` // 每小时总次数 + Hour int64 `json:"hour"` // 每小时的次数 + HourZeroRateLimitBehavior string `json:"hour_zero_rate_limit_behavior"` // 小时未配置流控行为 + MinuteTotal int64 `json:"minute_total"` // 每分钟总次数 + Minute int64 `json:"minute"` // 每分钟的次数 + MinuteZeroRateLimitBehavior string `json:"minute_zero_rate_limit_behavior"` // 分钟未配置流控行为 + SecondTotal int64 `json:"second_total"` // 每秒钟总次数 + Second int64 `json:"second"` // 每秒中的次数 + SecondZeroRateLimitBehavior string `json:"second_zero_rate_limit_behavior"` // 未配置流控行为 + SetRateLimitFail string `json:"set_rate_limit_fail"` // 流控失败的行为 +} + +type ResponseData struct { + Body map[string]any `json:"body"` // body数据 + Header map[string]string `json:"header"` // header数据 + Cookie map[string]string `json:"cookie"` // cookie数据 +} diff --git a/go.mod b/go.mod index 10be16b..705d043 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,26 @@ module git.zhangdeman.cn/gateway/core go 1.23.3 + +require ( + git.zhangdeman.cn/gateway/httpclient v0.0.0-20241024134801-faef35748763 // indirect + git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3 // 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/serialize v0.0.0-20241108082010-42ae8fe5ebdc // indirect + git.zhangdeman.cn/zhangdeman/trace v0.0.0-20231220041950-807f3d74a6fa // indirect + git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect + git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241106102517-46cd353dd617 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect + github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect + github.com/go-ini/ini v1.67.0 // indirect + github.com/go-resty/resty/v2 v2.16.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mozillazg/go-pinyin v0.20.0 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + golang.org/x/net v0.31.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..271ad6e --- /dev/null +++ b/go.sum @@ -0,0 +1,42 @@ +git.zhangdeman.cn/gateway/httpclient v0.0.0-20241024134801-faef35748763 h1:g0njPNnh1BDilE1YHYEykAkc/NXHIphRE8jCnN0pT/0= +git.zhangdeman.cn/gateway/httpclient v0.0.0-20241024134801-faef35748763/go.mod h1:+zqRzmRb5m7RlmKyYUeONJYj4z9Ftytf5yMD59w+ziM= +git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3 h1:BiAlBJ+DuRs/xD7nDQD2JT8Oc+V+0Uwt36qZwdXGvzI= +git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= +git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw= +git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4/go.mod h1:V4Dfg1v/JVIZGEKCm6/aehs8hK+Xow1dkL1yiQymXlQ= +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/serialize v0.0.0-20241108082010-42ae8fe5ebdc h1:jtdEMr/xNchJDEoCnvMr4JXT9+biYQu625Cj+dz025w= +git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241108082010-42ae8fe5ebdc/go.mod h1:XqgER4jDYwskFgj2riJ9XptIjzgYWubY+Zq8iB2WkY0= +git.zhangdeman.cn/zhangdeman/trace v0.0.0-20231220041950-807f3d74a6fa h1:2bZ9VmQF0pIZ+scnN3UuGoXjjKhccnwfIL779QGZArY= +git.zhangdeman.cn/zhangdeman/trace v0.0.0-20231220041950-807f3d74a6fa/go.mod h1:Bta0kzamTWqBIcc6robGAl/iRuyCFbzy45VGbG8L+7Y= +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/wrapper v0.0.0-20241106102517-46cd353dd617 h1:4rwv7bYKA4+IQgQiT8yNeM92t+fGd2tR5zD2ixpP6i8= +git.zhangdeman.cn/zhangdeman/wrapper v0.0.0-20241106102517-46cd353dd617/go.mod h1:uEuMBRzTlUJ9k3H+PymZWPn1b48U9lJPQ+ZBWmP+O/c= +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= +github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-resty/resty/v2 v2.16.0 h1:qpKalHWI2bpp9BIKlyT8TYWEJXOk1NuKbfiT3RRnzWc= +github.com/go-resty/resty/v2 v2.16.0/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= +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/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+GnMFQ= +github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +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/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=