From d6e256ef9e99c863614b794c254842cd666c1598 Mon Sep 17 00:00:00 2001 From: loser <1711788888@qq.com> Date: Thu, 27 Apr 2023 15:56:12 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E9=87=8D=E6=96=B0=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/login.go | 29 +++--- api/app/user.go | 12 ++- api/app/wine.go | 50 ++++++++++ api/base.go | 29 +----- client/mysql.go | 4 +- client/redis.go | 26 ++++++ common/constant/rds_key.go | 11 +-- common/constant/user.go | 88 +++++++++++++++++ common/default_keys.go | 8 ++ common/login_type.go | 16 ++++ common/types/model.go | 6 ++ config.yaml | 39 ++++---- config/aliyun.go | 7 ++ config/config.go | 3 +- config/redis.go | 15 +++ config/tencent.go | 17 ++++ core/response.go | 3 +- go.mod | 42 +++++++-- go.sum | 131 ++++++++++++++++++++------ initialize/clients.go | 1 - initialize/db_table.go | 6 +- initialize/init.go | 2 +- main.go | 59 ++++++++++++ middleware/cors.go | 21 +++++ model/cache/user.go | 5 +- model/entity/category.go | 8 -- model/entity/material.go | 14 +++ model/entity/user.go | 13 ++- model/entity/wine.go | 23 +++-- model/param/login.go | 14 ++- model/param/user.go | 22 +++-- model/param/wine.go | 21 +++-- model/resp/login.go | 22 ----- model/vo/user.go | 38 ++++++++ model/{resp => vo}/wine.go | 2 +- oauth2/handle/oauth2.go | 166 +++++++++++++++++++++++++++++++++ oauth2/handle/token_gen.go | 65 +++++++++++++ oauth2/handle/user.go | 68 ++++++++++++++ oauth2/server.go | 74 +++++++++++++++ repository/login.go | 9 ++ repository/oauth2_client.go | 23 +++++ repository/user.go | 49 +--------- repository/wine.go | 40 ++++++++ router/{app => }/login.go | 7 +- router/{app => }/route.go | 3 +- router/{app => }/user.go | 2 +- router/wine.go | 10 ++ utils/jwt.go | 71 -------------- utils/timer/timed_task.go | 104 +++++++++++++++++++++ utils/timer/timed_task_test.go | 61 ++++++++++++ 50 files changed, 1253 insertions(+), 306 deletions(-) create mode 100644 api/app/wine.go create mode 100644 client/redis.go create mode 100644 common/constant/user.go create mode 100644 common/default_keys.go create mode 100644 common/login_type.go create mode 100644 config/redis.go create mode 100644 main.go create mode 100644 middleware/cors.go delete mode 100644 model/entity/category.go create mode 100644 model/entity/material.go delete mode 100644 model/resp/login.go create mode 100644 model/vo/user.go rename model/{resp => vo}/wine.go (98%) create mode 100644 oauth2/handle/oauth2.go create mode 100644 oauth2/handle/token_gen.go create mode 100644 oauth2/handle/user.go create mode 100644 oauth2/server.go create mode 100644 repository/login.go create mode 100644 repository/oauth2_client.go create mode 100644 repository/wine.go rename router/{app => }/login.go (51%) rename router/{app => }/route.go (88%) rename router/{app => }/user.go (96%) create mode 100644 router/wine.go delete mode 100644 utils/jwt.go create mode 100644 utils/timer/timed_task.go create mode 100644 utils/timer/timed_task_test.go diff --git a/api/app/login.go b/api/app/login.go index 0e4f9ad..e2712ee 100644 --- a/api/app/login.go +++ b/api/app/login.go @@ -6,7 +6,6 @@ import ( "Lee-WineList/core" "Lee-WineList/model/param" "Lee-WineList/oauth2" - "Lee-WineList/repository" "context" "encoding/json" "fmt" @@ -30,7 +29,6 @@ func (l loginApi) Login(ctx *gin.Context) { core.R(ctx).FailWithMessage(err.Error()) return } - // 获取用户基础账号信息 userId, err := oauth2.OAuthServer.UserAuthorizationHandler(ctx.Writer, ctx.Request) if err != nil { @@ -40,10 +38,13 @@ func (l loginApi) Login(ctx *gin.Context) { } // 重新组装登录参数 ctx.Request.Form = url.Values{ - "username": {userId}, - "password": {p.Password}, - "scope": {"ALL"}, - "grant_type": {"password"}, + "username": {userId}, + "password": {p.Password}, + "scope": {"ALL"}, + "grant_type": {"password"}, + "invite_code": {p.InviteCode}, + "nickName": {p.NickName}, + "avatarUrl": {p.AvatarUrl}, } // 参数解析成功,进行登录 @@ -52,11 +53,7 @@ func (l loginApi) Login(ctx *gin.Context) { core.R(ctx).FailWithMessage("系统错误,登录失败") return } - // 登录成功才更新登录时间 - if ctx.Writer.Status() == http.StatusOK { - // 登录成功,更新登录时间和IP - go repository.Login().UpdateLastLoginInfo(userId, ctx.ClientIP(), p.UserIdentity) - } + } // Refresh 刷新登录Token @@ -107,3 +104,13 @@ func (loginApi) Logout(ctx *gin.Context) { r.Ok() } + +func (l loginApi) GetWeChatToken(c *gin.Context) { + wechaetToken, err := http.Get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx3d38ce1103a82225&secret=3c41ca428b4d0f43cfaef6f567a1cc06") + if err != nil { + log.Errorf("获取微信Token失败: %v", err) + core.R(c).FailWithMessage(err.Error()) + return + } + core.R(c).OkWithData(wechaetToken) +} diff --git a/api/app/user.go b/api/app/user.go index 8b2a6e1..b762e78 100644 --- a/api/app/user.go +++ b/api/app/user.go @@ -32,6 +32,7 @@ func (u userApi) GetUser(ctx *gin.Context) { // 转换为VO var v vo.UserVO v.ParseOrdinary(ue) + core.R(ctx).OkWithData(v) } @@ -56,11 +57,11 @@ func (u userApi) BindingWeChat(ctx *gin.Context) { core.R(ctx).FailWithMessage("系统错误,请稍后再试") return } - log.Debugf("用户[%v]的UnionId为[%v],OpenId为[%v]", loginUser.Id, unionId, openId) - if repository.User().CheckUnionIdIsExist(unionId, openId) { - core.R(ctx).FailWithMessage("该微信已绑定其他账号") - return - } + //log.Debugf("用户[%v]的UnionId为[%v],OpenId为[%v]", loginUser.Id, unionId, openId) + //if repository.User().CheckUnionIdIsExist(unionId, openId) { + // core.R(ctx).FailWithMessage("该微信已绑定其他账号") + // return + //} // 解析成功,修改用户信息 loginUser.WechatUnionId = &unionId loginUser.WechatOpenId = &openId @@ -100,5 +101,6 @@ func (u userApi) UpdateUser(ctx *gin.Context) { core.R(ctx).FailWithMessage("修改用户信息失败: " + err.Error()) return } + // 操作成功,更新头像和昵称 core.R(ctx).Ok() } diff --git a/api/app/wine.go b/api/app/wine.go new file mode 100644 index 0000000..1f57b70 --- /dev/null +++ b/api/app/wine.go @@ -0,0 +1,50 @@ +package app + +import ( + "Lee-WineList/core" + "Lee-WineList/model/param" + "Lee-WineList/repository" + "github.com/gin-gonic/gin" +) + +type wineApi struct { +} + +func WineApi() *wineApi { + return &wineApi{} +} + +// GetList 获取酒品列表 +func (w *wineApi) GetList(ctx *gin.Context) { + var p param.GetWineList + + if err := ctx.ShouldBind(&p); err != nil { + core.R(ctx).FailWithMessage(err.Error()) + return + } + + wines, err := repository.Wine().GetWineList(p) + if err != nil { + core.R(ctx).FailWithMessage(err.Error()) + return + } + + core.R(ctx).OkWithData(wines) +} + +// Add 添加酒单 +func (w *wineApi) Add(ctx *gin.Context) { + var p param.AddWine + + if err := ctx.ShouldBind(&p); err != nil { + core.R(ctx).FailWithMessage(err.Error()) + return + } + + if err := repository.Wine().Add(p); err != nil { + core.R(ctx).FailWithMessage(err.Error()) + return + } + + core.R(ctx).OkWithMessage("添加成功") +} diff --git a/api/base.go b/api/base.go index 8702f60..f4c0ff9 100644 --- a/api/base.go +++ b/api/base.go @@ -2,39 +2,14 @@ package api import ( "Lee-WineList/client" - "Lee-WineList/common/constant" "Lee-WineList/core" "Lee-WineList/model/entity" "git.echol.cn/loser/logger/log" "github.com/gin-gonic/gin" "net/http" + "strconv" ) -// GetAdminUser 获取登录的管理员信息 -func GetAdminUser(ctx *gin.Context, u *entity.AdminUser) { - userId := ctx.Request.Header.Get("userId") - if userId == "" { - ctx.Abort() - core.R(ctx).FailWithMessageAndCode("未授权操作", http.StatusUnauthorized) - return - } - u.Id = userId - // 查询用户信息 - err := client.MySQL.Where("id = ?", u.Id).First(&u).Error - if err != nil { - log.Errorf("获取用户信息失败:%s", err.Error()) - core.R(ctx).FailWithMessageAndCode("用户状态异常", http.StatusBadRequest) - ctx.Abort() - return - } - // 校验 - if u.Status != constant.UserStatusActive { - core.R(ctx).FailWithMessageAndCode("用户已被禁用", http.StatusBadRequest) - ctx.Abort() - return - } -} - // GetUser 获取登录的普通用户信息,dontResponse表示只获取用户信息,不论对错, dontCheck表示不检查微信绑定 func GetUser(ctx *gin.Context, u *entity.User, dontResponse, dontCheck bool) { userId := ctx.Request.Header.Get("userId") @@ -45,7 +20,7 @@ func GetUser(ctx *gin.Context, u *entity.User, dontResponse, dontCheck bool) { } return } - u.Id = userId + u.Id, _ = strconv.Atoi(userId) // 查询 err := client.MySQL.Take(&u).Error diff --git a/client/mysql.go b/client/mysql.go index 4302f89..a66a1e6 100644 --- a/client/mysql.go +++ b/client/mysql.go @@ -2,8 +2,10 @@ package client import ( "Lee-WineList/config" - "git.echol.cn/loser/logger" + "git.echol.cn/loser/logger/log" + + "git.echol.cn/loser/logger" "gorm.io/driver/mysql" "gorm.io/gorm" ) diff --git a/client/redis.go b/client/redis.go new file mode 100644 index 0000000..10efbe0 --- /dev/null +++ b/client/redis.go @@ -0,0 +1,26 @@ +package client + +import ( + "Lee-WineList/config" + "context" + "git.echol.cn/loser/logger/log" + "github.com/go-redis/redis/v8" +) + +var Redis *redis.Client + +func InitRedisClient() { + conf := config.Scd.Redis + // 初始化连接 + conn := redis.NewClient(&redis.Options{ + Addr: conf.GetDSN(), + Password: conf.Password, + DB: conf.Db, + }) + if err := conn.Ping(context.Background()).Err(); err != nil { + log.Panicf("Redis连接初始化失败: %v", err) + } else { + log.Debug("Redis连接初始化成功") + } + Redis = conn +} diff --git a/common/constant/rds_key.go b/common/constant/rds_key.go index e940123..cb798c6 100644 --- a/common/constant/rds_key.go +++ b/common/constant/rds_key.go @@ -1,11 +1,8 @@ package constant const ( - RdsCaptchaPrefix = "captcha:img:" // 验证码缓存前缀 - RdsSmsCaptchaPrefix = "captcha:sms:" // 短信验证码缓存前缀 - OAuth2RedisKey = "oauth:token:" // Token缓存前缀 - OAuth2UserCacheKey = "oauth:user:" // 用户缓存前缀 - ApiAntiShakeKey = "api:antishake:" // 防抖锁 - ReportGenTaskKey = "report:gen:task" // 任务生成计划待办队列 - WeChatSessionKey = "wechat:session:" // 小程序用户SessionKey前缀 + OAuth2RedisKey = "oauth:token:" // Token缓存前缀 + OAuth2UserCacheKey = "oauth:user:" // 用户缓存前缀 + ApiAntiShakeKey = "api:antishake:" // 防抖锁 + WeChatSessionKey = "wechat:session:" // 小程序用户SessionKey前缀 ) diff --git a/common/constant/user.go b/common/constant/user.go new file mode 100644 index 0000000..2484ad8 --- /dev/null +++ b/common/constant/user.go @@ -0,0 +1,88 @@ +package constant + +import ( + "fmt" +) + +// UserStatus 用户状态 +type UserStatus string + +const ( + UserStatusActive UserStatus = "NORMAL" // 用户状态正常 + UserStatusDisabled UserStatus = "DISABLE" // 已禁用用户 +) + +// 状态对应的描述 +var userStatusMap = map[UserStatus]string{ + UserStatusActive: "正常", + UserStatusDisabled: "已禁用", +} + +// 处理为看得懂的状态 +func (s UserStatus) String() string { + if str, ok := userStatusMap[s]; ok { + return str + } + return string(s) +} + +// ===================================================================================================================== + +// UserSex 性别 +type UserSex int + +const ( + UserSexNone UserSex = iota // 不知道是啥 + UserSexMale // 男 + UserSexFemale // 女 + UserSexOther // 其他性别 +) + +// 状态对应的描述 +var userSexMap = map[UserSex]string{ + UserSexNone: "无性别", + UserSexMale: "男", + UserSexFemale: "女", + UserSexOther: "其他", +} + +// FromString 中文取性别 +func (s UserSex) FromString(sex string) UserSex { + result := UserSexNone + for key, value := range userSexMap { + if sex == value { + result = key + break + } + } + return result +} + +// 处理为看得懂的状态 +func (s UserSex) String() string { + if str, ok := userSexMap[s]; ok { + return str + } + //return strconv.Itoa(int(s)) + return fmt.Sprintf("UserSex(%d)", int(s)) +} + +// MarshalJSON JSON序列化的时候转换为中文 +func (s UserSex) MarshalJSON() ([]byte, error) { + return []byte(`"` + s.String() + `"`), nil +} + +// ===================================================================================================================== + +// UserIdentity 用户身份 +type UserIdentity string + +const ( + UserIdentityAdmin UserIdentity = "admin" // 管理员 + UserIdentityUser UserIdentity = "user" // 普通用户 +) + +// String implements the Stringer interface. +func (t UserIdentity) String() string { + return string(t) +} diff --git a/common/default_keys.go b/common/default_keys.go new file mode 100644 index 0000000..4ca1fc5 --- /dev/null +++ b/common/default_keys.go @@ -0,0 +1,8 @@ +package common + +const ( + SmsSendKey = "sms:send:" // 短信发送缓存前缀 + Oauth2RedisKey = "oauth:token:" // Token缓存前缀 + WeChatSessionKey = "wechat:session:" // 小程序用户SessionKey前缀 + ImMessageKey = "im:message:" // IM消息缓存前缀 +) diff --git a/common/login_type.go b/common/login_type.go new file mode 100644 index 0000000..efa09d8 --- /dev/null +++ b/common/login_type.go @@ -0,0 +1,16 @@ +package common + +// LoginType 自定义登录类型 +type LoginType string + +// 登录类型 +const ( + Github LoginType = "github" // Github登录 + WeChatMiniApp LoginType = "wechat_mini_app" // 微信小程序登录 + Password LoginType = "password" // 密码登录 +) + +// String 转换为字符串 +func (t LoginType) String() string { + return string(t) +} diff --git a/common/types/model.go b/common/types/model.go index 8ab22a4..66930c7 100644 --- a/common/types/model.go +++ b/common/types/model.go @@ -11,3 +11,9 @@ type BaseDbModel struct { UpdatedAt DateTime `json:"updatedAt"` DeletedAt gorm.DeletedAt `json:"-" gorm:"index:deleted"` } + +type Model struct { + CreatedAt DateTime `json:"createdAt"` + UpdatedAt DateTime `json:"updatedAt"` + DeletedAt gorm.DeletedAt `json:"-" gorm:"index:deleted"` +} diff --git a/config.yaml b/config.yaml index 6e6e392..1145e64 100644 --- a/config.yaml +++ b/config.yaml @@ -5,31 +5,26 @@ api: prefix: /api/v1 mysql: - host: 127.0.0.1 - port: 49154 + host: 1.117.68.37 + port: 3307 user: root - password: mysqlpw - db: mini_app + password: loser765911. + db: lee_wine -#redis: -# host: 127.0.0.1 -# port: 49153 -# password: redispw -# db: 2 +redis: + host: 101.35.50.11 + port: 6379 + password: loser7659 + db: 10 -jwt: - AccessSecret: "leex" - AccessExpire: 604800 - RefreshAfter: 86400 +aliyun: + oss: + Endpoint: oss-cn-shanghai.aliyuncs.com + Bucket: workflow-zym + access-key: LTAI5tRFgH2mtJbtX8tuyeYY + access-key-secret: CW37ibDs9i8uvM08gKhkj12dEq2mOU tencent: mini-app: - app-id: xxxx - app-secret: xxxx - -aliyun: - oss: - endpoint: oss-cn-shanghai.aliyuncs.com - bucket: xxxx - access-key: xxxx - access-key-secret: xxxx \ No newline at end of file + app-id: wxcac07f5e3d0dedf0 + app-secret: 431d9dad0c96c2b7020da7d23c761196 \ No newline at end of file diff --git a/config/aliyun.go b/config/aliyun.go index 9c84faf..b10aafc 100644 --- a/config/aliyun.go +++ b/config/aliyun.go @@ -2,9 +2,16 @@ package config // 阿里云配置 type aliyunConfig struct { + Sms aliSmsConfig `mapstructure:"sms" yaml:"sms"` // 短信配置 Oss aliOssConfig `mapstructure:"oss" yaml:"oss"` // oss配置 } +// SmsConfig 阿里云短信配置 +type aliSmsConfig struct { + AccessKeyId string `mapstructure:"access-key" yaml:"access-key"` + AccessKeySecret string `mapstructure:"access-key-secret" yaml:"access-key-secret"` +} + // OSSConfig 阿里云OSS配置 type aliOssConfig struct { Endpoint string `mapstructure:"endpoint" yaml:"endpoint"` diff --git a/config/config.go b/config/config.go index 25988a7..74c84a6 100644 --- a/config/config.go +++ b/config/config.go @@ -1,14 +1,13 @@ package config var Scd systemConfigData -var Nacos nacosConfig // 配置信息 type systemConfigData struct { Admin appInfo `mapstructure:"admin" yaml:"admin"` // 系统配置-Admin Api appInfo `mapstructure:"api" yaml:"api"` // 系统配置-Api MySQL mysqlConfig `mapstructure:"mysql" yaml:"mysql"` // MySQL配置 + Redis redisConfig `mapstructure:"redis" yaml:"redis"` // Redis配置 Aliyun aliyunConfig `mapstructure:"aliyun" yaml:"aliyun"` // 阿里云配置 Tencent tencentConfig `mapstructure:"tencent" yaml:"tencent"` // 腾讯相关配置 - JWT JWT `mapstructure:"jwt" yaml:"jwt"` } diff --git a/config/redis.go b/config/redis.go new file mode 100644 index 0000000..a6150ba --- /dev/null +++ b/config/redis.go @@ -0,0 +1,15 @@ +package config + +import "fmt" + +// Redis配置 +type redisConfig struct { + Host string `mapstructure:"host" yaml:"host"` // 主机 + Port int `mapstructure:"port" yaml:"port"` // 端口 + Password string `mapstructure:"password" yaml:"password"` // 密码 + Db int `mapstructure:"db" yaml:"db"` // 数据库名称 +} + +func (r redisConfig) GetDSN() string { + return fmt.Sprintf("%s:%v", r.Host, r.Port) +} diff --git a/config/tencent.go b/config/tencent.go index 426a952..7eb491f 100644 --- a/config/tencent.go +++ b/config/tencent.go @@ -3,6 +3,8 @@ package config // 腾讯相关配置 type tencentConfig struct { MiniApp wechatMiniAppConfig `mapstructure:"mini-app" yaml:"mini-app"` + Payment wechatPayConfig `mapstructure:"payment" yaml:"payment"` + CApi capiConfig `mapstructure:"capi" yaml:"capi"` } // 微信小程序配置 @@ -10,3 +12,18 @@ type wechatMiniAppConfig struct { AppId string `mapstructure:"app-id" yaml:"app-id"` AppSecret string `mapstructure:"app-secret" yaml:"app-secret"` } + +// 微信支付配置 +type wechatPayConfig struct { + MchId string `mapstructure:"mchId" yaml:"mchId"` // 商户号 + SerialNo string `mapstructure:"serialNo" yaml:"serialNo"` // 商户API证书的证书序列号 + ApiV3Key string `mapstructure:"apiV3Key" yaml:"apiV3Key"` // 支付key + PrivateKey string `mapstructure:"privateKey" yaml:"privateKey"` // 支付私钥绝对路径 +} + +// api密钥配置 +type capiConfig struct { + AppId string `mapstructure:"app-id" yaml:"app-id"` // APP ID + SecretId string `mapstructure:"secret-id" yaml:"secret-id"` // Secret ID + SecretKey string `mapstructure:"secret-key" yaml:"secret-key"` // Secret Key +} diff --git a/core/response.go b/core/response.go index d2b5509..a2db59e 100644 --- a/core/response.go +++ b/core/response.go @@ -2,8 +2,9 @@ package core import ( "Lee-WineList/utils" - "github.com/gin-gonic/gin" "net/http" + + "github.com/gin-gonic/gin" ) // 返回数据包装 diff --git a/go.mod b/go.mod index 58fd068..97ed101 100644 --- a/go.mod +++ b/go.mod @@ -4,30 +4,43 @@ go 1.18 require ( git.echol.cn/loser/logger v1.0.15 - github.com/aliyun/alibaba-cloud-sdk-go v1.62.288 + github.com/aliyun/alibaba-cloud-sdk-go v1.62.296 github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible github.com/duke-git/lancet/v2 v2.1.19 github.com/fsnotify/fsnotify v1.6.0 github.com/gin-gonic/gin v1.9.0 github.com/go-oauth2/oauth2/v4 v4.5.2 github.com/go-oauth2/redis/v4 v4.1.1 + github.com/go-pay/gopay v1.5.92 github.com/go-redis/redis/v8 v8.11.5 + github.com/golang-jwt/jwt v3.2.1+incompatible github.com/google/uuid v1.3.0 github.com/medivhzhan/weapp/v3 v3.6.19 + github.com/robfig/cron/v3 v3.0.1 github.com/spf13/viper v1.15.0 + github.com/stretchr/testify v1.8.1 golang.org/x/crypto v0.8.0 + golang.org/x/sync v0.1.0 gorm.io/driver/mysql v1.5.0 - gorm.io/driver/postgres v1.5.0 gorm.io/gorm v1.25.0 ) require ( + cloud.google.com/go v0.105.0 // indirect + cloud.google.com/go/compute v1.14.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/firestore v1.9.0 // indirect + cloud.google.com/go/longrunning v0.3.0 // indirect git.echol.cn/loser/loki-client-go v1.0.1 // indirect + github.com/armon/go-metrics v0.4.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bytedance/sonic v1.8.0 // indirect github.com/caarlos0/env/v6 v6.9.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd/v22 v22.3.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fatih/color v1.15.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect @@ -40,13 +53,20 @@ require ( github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/goccy/go-json v0.10.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt v3.2.1+incompatible // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect + github.com/hashicorp/consul/api v1.18.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.2.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect - github.com/jackc/pgx/v5 v5.3.0 // indirect + github.com/hashicorp/serf v0.10.1 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect @@ -59,6 +79,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.18 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -67,11 +88,13 @@ require ( github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.12.2 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.34.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24 // indirect + github.com/sagikazarmark/crypt v0.9.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -88,6 +111,11 @@ require ( github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.9 // indirect + go.etcd.io/etcd/api/v3 v3.5.6 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.6 // indirect + go.etcd.io/etcd/client/v2 v2.305.6 // indirect + go.etcd.io/etcd/client/v3 v3.5.6 // indirect + go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.21.0 // indirect @@ -97,6 +125,8 @@ require ( golang.org/x/sys v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/time v0.1.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect + google.golang.org/api v0.107.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect google.golang.org/grpc v1.52.0 // indirect diff --git a/go.sum b/go.sum index 1658d96..7ad6bae 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= +cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -26,8 +28,16 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= +cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.9.0 h1:IBlRyxgGySXu5VuW0RgGFlTtLukSnNkpDiEOMkQkmpA= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= +cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -95,8 +105,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.288 h1:+iF4BDaniUhwnNhyk3ckkDTU5hWSHgmuEqiYa/PKI2o= -github.com/aliyun/alibaba-cloud-sdk-go v1.62.288/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.296 h1:fSZXZMcNHX52w4MwvY/YTVy/7h5d/nHd0uUs6qOTkI0= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.296/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible h1:KpbJFXwhVeuxNtBJ74MCGbIoaBok2uZvkD7QXp2+Wis= github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= @@ -110,6 +120,8 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q= +github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= @@ -159,11 +171,16 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -189,6 +206,7 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3 github.com/duke-git/lancet/v2 v2.1.19 h1:dbRB1m6wOMV1I0ax/3S6ngop8SYM6I7sr+7D9IXjS2E= github.com/duke-git/lancet/v2 v2.1.19/go.mod h1:hNcc06mV7qr+crH/0nP+rlC3TB0Q9g5OrVnO8/TGD4c= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= @@ -202,6 +220,8 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= @@ -314,6 +334,8 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-pay/gopay v1.5.92 h1:W1poLl2wdzIDyl96TqWwdxCyDYSSx9AWH0BmXwVR+W4= +github.com/go-pay/gopay v1.5.92/go.mod h1:9Xqqi6R3WjUCknmWcy8Y+F/lt0Zi817kA+mlIi2PDMw= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -356,6 +378,7 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -374,6 +397,8 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -404,6 +429,7 @@ github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -414,9 +440,12 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -441,8 +470,12 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.1 h1:RY7tHKZcRlk788d5WSo/e83gOyyy742E8GSs771ySpg= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gophercloud/gophercloud v0.13.0/go.mod h1:VX0Ibx85B60B5XOrZr6kaNwrmPUzcmMpwxvQ1WQIIWM= @@ -459,42 +492,68 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.15.0/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/api v1.7.0/go.mod h1:1NSuaUUkFaJzMasbfq/11wKYWSR67Xn6r2DXKhuDNFg= +github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= +github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.6.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= +github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= +github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= +github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.3/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= +github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= +github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hetznercloud/hcloud-go v1.22.0/go.mod h1:xng8lbDUg+xM1dgc0yGHX5EeqbwIq7UYlMWMTx3SQVg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= @@ -513,13 +572,6 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.3.0 h1:/NQi8KHMpKWHInxXesC8yD4DhkXPrVhmnwYkjp9AmBA= -github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= -github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= @@ -579,7 +631,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -631,9 +682,12 @@ github.com/medivhzhan/weapp/v3 v3.6.19/go.mod h1:DBlnuMNGIcDYSDaM8JnBIT14I+OqMaM github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +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-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -642,6 +696,7 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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= @@ -711,6 +766,7 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -743,6 +799,7 @@ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= @@ -778,21 +835,25 @@ github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24 h1:V/4Cj2G github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24/go.mod h1:MDRkz271loM/PrYN+wUNEaTMDGSP760MQzB0yEjdgSQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.9.0 h1:fipzMFW34hFUEc4D7fsLQFtE7yElkpgyS2zruedRdZk= +github.com/sagikazarmark/crypt v0.9.0/go.mod h1:RnH7sEhxfdnPm1z+XMgSLjWTEIjyK4z2dw6+4vHTMuo= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/samuel/go-zookeeper v0.0.0-20200724154423-2164a8ac840e/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= @@ -840,6 +901,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -922,9 +984,16 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd/api/v3 v3.5.6 h1:Cy2qx3npLcYqTKqGJzMypnMv2tiRyifZJ17BlWIWA7A= +go.etcd.io/etcd/api/v3 v3.5.6/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= +go.etcd.io/etcd/client/pkg/v3 v3.5.6 h1:TXQWYceBKqLp4sa87rcPs11SXxUA/mHwH975v+BDvLU= +go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= +go.etcd.io/etcd/client/v2 v2.305.6 h1:fIDR0p4KMjw01MJMfUIDWdQbjo06PD6CeYM5z4EHLi0= +go.etcd.io/etcd/client/v2 v2.305.6/go.mod h1:BHha8XJGe8vCIBfWBpbBLVZ4QjOIlfoouvOwydu63E0= +go.etcd.io/etcd/client/v3 v3.5.6 h1:coLs69PWCXE9G4FKquzNaSHrRyMCAXwF+IX1tAPVO8E= +go.etcd.io/etcd/client/v3 v3.5.6/go.mod h1:f6GRinRMCsFVv9Ht42EyY7nfsVGwrNO0WEoS2pRKzQk= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -938,7 +1007,10 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v0.6.0/go.mod h1:jzBIgIzK43Iu1BpDAXwqOd6UPsSAk+ewVZ5ofSXw4Ek= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -956,6 +1028,7 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= @@ -978,10 +1051,8 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1011,6 +1082,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1022,7 +1094,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1066,16 +1137,17 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1104,7 +1176,6 @@ golang.org/x/sync v0.0.0-20200930132711-30421366ff76/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1175,7 +1246,9 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1184,26 +1257,24 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1285,12 +1356,14 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= @@ -1318,6 +1391,8 @@ google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.107.0 h1:I2SlFjD8ZWabaIFOfeEDg3pf0BHJDh6iYQ1ic3Yu/UU= +google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1368,6 +1443,7 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1389,9 +1465,13 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk= google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1413,7 +1493,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -1446,8 +1525,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.5.0 h1:6hSAT5QcyIaty0jfnff0z0CLDjyRgZ8mlMHLqSt7uXM= gorm.io/driver/mysql v1.5.0/go.mod h1:FFla/fJuCvyTi7rJQd27qlNX2v3L6deTR1GgTjSOLPo= -gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U= -gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A= gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.0 h1:+KtYtb2roDz14EQe4bla8CbQlmb9dN3VejSai3lprfU= gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= diff --git a/initialize/clients.go b/initialize/clients.go index a4bb15b..1518686 100644 --- a/initialize/clients.go +++ b/initialize/clients.go @@ -6,5 +6,4 @@ import "Lee-WineList/client" func initClient() { client.InitMySQLClient() client.InitRedisClient() - //client.InitPostgreSQLClient() } diff --git a/initialize/db_table.go b/initialize/db_table.go index cba0bd7..feafe39 100644 --- a/initialize/db_table.go +++ b/initialize/db_table.go @@ -9,9 +9,9 @@ import ( // 初始化数据库表 func databaseTable() { dbs := []any{ - entity.User{}, - entity.AdminUser{}, - entity.OAuth2Client{}, + new(entity.User), // 普通用户 + new(entity.OAuth2Client), // OAuth2客户端 + } if err := client.MySQL.AutoMigrate(dbs...); err != nil { diff --git a/initialize/init.go b/initialize/init.go index 4561028..abd0a3f 100644 --- a/initialize/init.go +++ b/initialize/init.go @@ -2,7 +2,7 @@ package initialize // InitSystem 初始化系统 func InitSystem() { - initLocaConfig() // 初始化本地配置 + initLocaConfig() // 初始化配置 initClient() // 初始化连接池等信息 databaseTable() // 初始化数据库表信息 } diff --git a/main.go b/main.go new file mode 100644 index 0000000..31c0130 --- /dev/null +++ b/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "Lee-WineList/config" + "Lee-WineList/core" + "Lee-WineList/initialize" + appRoute "Lee-WineList/router" + "fmt" + "git.echol.cn/loser/logger/log" + "github.com/gin-gonic/gin" + "golang.org/x/sync/errgroup" + "net/http" + "time" +) + +var g errgroup.Group + +// 系统初始化 +func init() { + initialize.InitSystem() // 初始化系统配置 + //oauth2.InitOAuth2Server() // 初始化OAuth2服务 +} + +// 启动入口 +func main() { + // 强制日志颜色化 + gin.ForceConsoleColor() + // 定义启动入口 + + app := &http.Server{ + Addr: fmt.Sprintf(":%d", config.Scd.Api.Port), + Handler: api(), + ReadTimeout: 5 * time.Second, + WriteTimeout: 1 * time.Minute, + } + // 启动项目 + g.Go(func() error { + return app.ListenAndServe() + }) + if err := g.Wait(); err != nil { + log.Panicf("启动失败,错误信息:%s", err.Error()) + } + +} + +// 生成接口服务 +func api() http.Handler { + app := gin.New() + app.Use(gin.Recovery()) + // 开启自定义请求方式不允许处理函数 + app.HandleMethodNotAllowed = true + // 处理请求方式不对 + app.NoMethod(core.NoMethodHandler()) + // 404返回数据 + app.NoRoute(core.NoRouteHandler()) + // 初始化路由 + appRoute.InitRoute(app.Group(config.Scd.Api.Prefix)) + return app +} diff --git a/middleware/cors.go b/middleware/cors.go new file mode 100644 index 0000000..2433f31 --- /dev/null +++ b/middleware/cors.go @@ -0,0 +1,21 @@ +package middleware + +import ( + "github.com/gin-gonic/gin" + "net/http" +) + +func Cors() gin.HandlerFunc { + return func(c *gin.Context) { + c.Writer.Header().Set("Access-Control-Allow-Origin", "*") + c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") + c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") + c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT,DELETE") + c.Header("Access-Control-Allow-Credentials", "true") + if c.Request.Method == "OPTIONS" { + c.AbortWithStatus(http.StatusNoContent) + return + } + c.Next() + } +} diff --git a/model/cache/user.go b/model/cache/user.go index 7534269..516eceb 100644 --- a/model/cache/user.go +++ b/model/cache/user.go @@ -4,9 +4,8 @@ import "encoding/json" // UserInfo 登录用的用户信息结构体 type UserInfo struct { - UserType string `json:"userType"` // 用户类型 - RoleCodes string `json:"roleCodes"` // 角色代码 - UserId string `json:"userId"` // 用户Id + UserType string `json:"userType"` // 用户类型 + UserId int `json:"userId"` // 用户Id } // String 实现Stringer接口 diff --git a/model/entity/category.go b/model/entity/category.go deleted file mode 100644 index 324d6f4..0000000 --- a/model/entity/category.go +++ /dev/null @@ -1,8 +0,0 @@ -package entity - -import "Lee-WineList/common/types" - -type Category struct { - types.BaseDbModel - Name string `gorm:"column:name;type:varchar(255);comment:分类名;NOT NULL" json:"name"` -} diff --git a/model/entity/material.go b/model/entity/material.go new file mode 100644 index 0000000..2e9d952 --- /dev/null +++ b/model/entity/material.go @@ -0,0 +1,14 @@ +package entity + +import "Lee-WineList/common/types" + +type Material struct { + types.BaseDbModel + Name string `gorm:"column:name;type:varchar(255);comment:材料名;NOT NULL" json:"name"` + ML string `gorm:"column:ml;type:int(11) unsigned;comment:毫升;NOT NULL" json:"ml"` + WindId int `gorm:"column:wine_id;type:int(11) unsigned;comment:酒ID;NOT NULL" json:"wine_id"` +} + +func (Material) TableName() string { + return "materials" +} diff --git a/model/entity/user.go b/model/entity/user.go index 1721728..9f8d071 100644 --- a/model/entity/user.go +++ b/model/entity/user.go @@ -1,17 +1,20 @@ package entity import ( + "Lee-WineList/common/constant" "Lee-WineList/common/types" ) // User 普通用户表 type User struct { types.BaseDbModel - Phone string `json:"phone" gorm:"index:deleted,unique;type:varchar(255) not null comment '手机号'"` - UnionId string `json:"union_id" gorm:"type:varchar(255) comment '微信UnionId'"` - OpenId string `json:"open_id" gorm:"type:varchar(255) comment '微信OpenId'"` - Nickname string `json:"nickname" gorm:"type:varchar(255) comment '昵称'"` - Avatar string `json:"avatar" gorm:"type:varchar(255) comment '头像'"` + Phone string `json:"phone" gorm:"index:deleted,unique;type:varchar(255) not null comment '手机号'"` + WechatUnionId *string `json:"wechat_union_id" gorm:"type:varchar(255) comment '微信UnionId'"` + WechatOpenId *string `json:"wechat_open_id" gorm:"type:varchar(255) comment '微信OpenId'"` + Nickname string `json:"nickname" gorm:"type:varchar(255) comment '昵称'"` + Avatar string `json:"avatar" gorm:"type:varchar(255) comment '头像'"` + Sex constant.UserSex `json:"sex" gorm:"type:int; default 0; not null comment 性别"` // 1男2女 + Status constant.UserStatus `json:"status" gorm:"type:enum('NORMAL','DISABLE'); default:'NORMAL'; not null; comment:'状态 NORMAL-正常;DISABLE-禁用'"` } func (User) TableName() string { diff --git a/model/entity/wine.go b/model/entity/wine.go index f53f2fe..6abf47c 100644 --- a/model/entity/wine.go +++ b/model/entity/wine.go @@ -4,12 +4,19 @@ import "Lee-WineList/common/types" // Wine 酒 type Wine struct { - types.BaseDbModel - Name string `gorm:"column:name;type:varchar(255);comment:酒名;NOT NULL" json:"name"` - ChineseName string `gorm:"column:chinese_name;type:varchar(255);comment:中文酒名;NOT NULL" json:"chinese_name"` - Ingredients string `gorm:"column:ingredients;type:varchar(255);comment:配料;NOT NULL" json:"ingredients"` - Quote string `gorm:"column:quote;type:varchar(255);comment:引用;NOT NULL" json:"quote"` - CategoryId uint `gorm:"column:category_id;type:int(11) unsigned;comment:分类ID;NOT NULL" json:"category_id"` - Steps string `gorm:"column:steps;type:varchar(255);comment:步骤;NOT NULL" json:"steps"` - Context string `gorm:"column:context;type:varchar(255);comment:酒文;NOT NULL" json:"context"` + types.Model + WineId int `gorm:"column:wine_id;type:int(11) unsigned;primarykey;comment:酒ID;NOT NULL" json:"wine_id"` + Name string `gorm:"column:name;type:varchar(255);comment:酒名;NOT NULL" json:"name"` + ChineseName string `gorm:"column:chinese_name;type:varchar(255);comment:中文酒名;NOT NULL" json:"chinese_name"` + Quote string `gorm:"column:quote;type:varchar(255);comment:引用;NOT NULL" json:"quote"` + Category string `gorm:"column:category;type:varchar(255);comment:分类;NOT NULL" json:"category"` + Steps string `gorm:"column:steps;type:varchar(255);comment:步骤;NOT NULL" json:"steps"` + Context string `gorm:"column:context;type:varchar(255);comment:酒文;NOT NULL" json:"context"` + Materials []Material `gorm:"many2many:wine_materials"` + UserId int `gorm:"column:user_id;type:int(11) unsigned;comment:用户ID;NOT NULL" json:"user_id"` +} + +// TableName 设置表名 +func (Wine) TableName() string { + return "wines" } diff --git a/model/param/login.go b/model/param/login.go index 415b4b9..7eae1bb 100644 --- a/model/param/login.go +++ b/model/param/login.go @@ -1,12 +1,16 @@ package param +import "Lee-WineList/common/constant" + // Login 用户登录入参 type Login struct { - VerifyId string `json:"verifyId" form:"verifyId"` // 验证Id - VerifyCode string `json:"verifyCode" form:"verifyCode"` // 验证码 - Username string `json:"username" form:"username" binding:"required"` // 邮箱或手机号 - Password string `json:"password" form:"password"` // 密码 - Code string `json:"code" form:"code"` // 微信小程序登录code + Username string `json:"username" form:"username" binding:"required"` // 邮箱或手机号 + Password string `json:"password" form:"password"` // 密码 + TypeCode constant.LoginType `json:"type" form:"type" binding:"required"` // 登录方式,默认为空,可选值参见自定义类型 + UserIdentity constant.UserIdentity `json:"identity" form:"identity" binding:"required"` // 用户身份,默认为空,可选值参见自定义类型 + InviteCode string `json:"invite_code" form:"invite_code"` // 邀请码 + NickName string `json:"nickName" form:"nickName"` // 微信昵称 + AvatarUrl string `json:"avatarUrl" form:"avatarUrl"` // 微信头像 } // RefreshToken 刷新Token入参 diff --git a/model/param/user.go b/model/param/user.go index ca29949..e5cd078 100644 --- a/model/param/user.go +++ b/model/param/user.go @@ -1,23 +1,29 @@ package param +import ( + "Lee-WineList/common/constant" +) + // BindingWeChat 绑定微信 type BindingWeChat struct { Code string `json:"code" form:"code" binding:"required"` // 微信code } +//GetUserList 获取普通用户 type GetUserList struct { page Phone string `json:"phone" form:"phone"` // 手机号 Status string `json:"status" form:"status" binding:"oneof='' NORMAL DISABLE"` // 用户状态 StartAt string `json:"startAt" form:"startAt"` // 开始时间 EndAt string `json:"endAt" form:"endAt"` // 结束时间 + Name string `json:"name" form:"name"` //用户名 } // ChangeUserInfo 修改普通用户信息 type ChangeUserInfo struct { - Nickname string `json:"nickname" form:"nickname"` // 昵称 - Avatar string `json:"avatar" form:"avatar"` // 头像 - Birthday string `json:"birthday" form:"birthday"` // 生日 + Nickname string `json:"nickname" form:"nickname"` // 昵称 + Avatar string `json:"avatar" form:"avatar"` // 头像 + Sex constant.UserSex `json:"sex" form:"sex"` // 性别 } // ChangePassword 修改密码 @@ -29,8 +35,10 @@ type ChangePassword struct { // SaveUser 保存用户信息 type SaveUser struct { - Id int `json:"id" form:"id"` // 用户ID - Username string `json:"username" form:"username"` // 用户名 - Nickname string `json:"nickname" form:"nickname"` // 昵称 - Password string `json:"password" form:"password"` // 密码 + Id string `json:"id" form:"id"` // 用户ID + Username string `json:"username" form:"username"` // 用户名 + Nickname string `json:"nickname" form:"nickname"` // 昵称 + Password string `json:"password" form:"password"` // 密码 + Phone string `json:"phone" form:"phone"` + Status constant.UserStatus `json:"status" form:"status" binding:"oneof=NORMAL DISABLE"` // 用户状态 } diff --git a/model/param/wine.go b/model/param/wine.go index a2b2600..bc5bae2 100644 --- a/model/param/wine.go +++ b/model/param/wine.go @@ -1,14 +1,15 @@ package param -import "Lee-WineList/common/types" +type GetWineList struct { + page + Category string `json:"category" form:"category"` // 分类 + UserId int `json:"userId" form:"userId"` // 用户ID +} -type Wine struct { - types.BaseDbModel - Name string `gorm:"column:name;type:varchar(255);comment:酒名;NOT NULL" json:"name"` - ChineseName string `gorm:"column:chinese_name;type:varchar(255);comment:中文酒名;NOT NULL" json:"chinese_name"` - Ingredients string `json:"ingredients"` - Quote string `gorm:"column:quote;type:varchar(255);comment:引用;NOT NULL" json:"quote"` - CategoryId uint `gorm:"column:category_id;type:int(11) unsigned;comment:分类ID;NOT NULL" json:"category_id"` - Steps string `gorm:"column:steps;type:varchar(255);comment:步骤;NOT NULL" json:"steps"` - Context string `gorm:"column:context;type:varchar(255);comment:酒文;NOT NULL" json:"context"` +type GetWineListByUser struct { + page + Category string `json:"category" form:"category"` // 分类 + UserId int `json:"userId" form:"userId"` // 用户ID } + +type AddWine struct{} diff --git a/model/resp/login.go b/model/resp/login.go deleted file mode 100644 index d164048..0000000 --- a/model/resp/login.go +++ /dev/null @@ -1,22 +0,0 @@ -package resp - -// Code2Session 用户登录凭证校验模型 -type Code2Session struct { - Code string - AppId string - AppSecret string -} - -// Code2SessionResult 凭证校验后返回的JSON数据包模型 -type Code2SessionResult struct { - OpenId string `json:"openid"` - SessionKey string `json:"session_key"` - UnionId string `json:"unionid"` - ErrCode uint `json:"errcode"` - ErrMsg string `json:"errmsg"` -} - -// UserInfo 用户信息,OpenID用户唯一标识 -type UserInfo struct { - OpenId string `json:"openId"` -} diff --git a/model/vo/user.go b/model/vo/user.go new file mode 100644 index 0000000..682cd47 --- /dev/null +++ b/model/vo/user.go @@ -0,0 +1,38 @@ +package vo + +import ( + "Lee-WineList/common/constant" + "Lee-WineList/common/types" + "Lee-WineList/model/entity" + "Lee-WineList/utils" +) + +// UserVO 管理员信息 +type UserVO struct { + Id int `json:"id"` + Nickname string `json:"nickname"` + Username string `json:"username"` + Phone string `json:"phone"` + Status constant.UserStatus `json:"status"` + Sex constant.UserSex `json:"sex"` + Avatar string `json:"avatar"` + CreatedAt types.DateTime `json:"createdAt"` +} + +// ParseOrdinary 转换为VO +func (auv *UserVO) ParseOrdinary(u entity.User) { + auv.Id = u.Id + auv.Phone = utils.Desensitization().Phone(u.Phone) + auv.Nickname = u.Nickname + auv.Status = u.Status + auv.Sex = u.Sex + auv.Avatar = u.Avatar + auv.CreatedAt = u.CreatedAt +} + +// UserMiniVO 简要信息 +type UserMiniVO struct { + Id string `json:"id"` + Nickname string `json:"nickname"` + Avatar string `json:"avatar"` +} diff --git a/model/resp/wine.go b/model/vo/wine.go similarity index 98% rename from model/resp/wine.go rename to model/vo/wine.go index f8cd629..2be3112 100644 --- a/model/resp/wine.go +++ b/model/vo/wine.go @@ -1,4 +1,4 @@ -package resp +package vo import "Lee-WineList/common/types" diff --git a/oauth2/handle/oauth2.go b/oauth2/handle/oauth2.go new file mode 100644 index 0000000..7fef48e --- /dev/null +++ b/oauth2/handle/oauth2.go @@ -0,0 +1,166 @@ +package handle + +import ( + "Lee-WineList/client" + "Lee-WineList/common/constant" + "Lee-WineList/model/cache" + "Lee-WineList/model/entity" + "Lee-WineList/repository" + "context" + "encoding/json" + "fmt" + "git.echol.cn/loser/logger/log" + "github.com/go-oauth2/oauth2/v4" + "github.com/go-oauth2/oauth2/v4/errors" + "net/http" + "strconv" + "strings" + "time" +) + +// UserAuthorizationHandler 获取用户Id +func UserAuthorizationHandler(w http.ResponseWriter, r *http.Request) (userId string, err error) { + loginType := constant.LoginType(r.FormValue("type")) // 登录类型 + userIdentity := constant.UserIdentity(r.FormValue("identity")) // 身份类型 + account := r.FormValue("username") // 用户传入账号(或者授权Code) + nikeName := r.FormValue("nickName") // 昵称 + avatarUrl := r.FormValue("avatarUrl") // 头像 + + log.Debugf("预处理用户登录请求,身份类型: %v => 登录类型: %s => 账号: %v", userIdentity, loginType, account) + + // 普通用户 + userId, err = getUser(account, loginType, nikeName, avatarUrl) + + if err != nil { + return + } + + atoi, _ := strconv.Atoi(userId) + // 组装缓存用户信息 + m := cache.UserInfo{ + UserId: atoi, + UserType: userIdentity.String(), + } + userInfo, err := m.String() + if err != nil { + err = errors.New("登录失败,请联系管理员") + return + } + if err = client.Redis.Set(context.Background(), fmt.Sprintf("%s%v", constant.OAuth2UserCacheKey, userId), userInfo, time.Hour*24*7).Err(); err != nil { + log.Errorf("缓存用户信息失败,用户ID:%v,错误信息:%s", userId, err.Error()) + err = errors.New("登录失败,请联系管理员") + return + } + + return +} + +// LoginWithPassword 账号密码登录模式 +func LoginWithPassword(ctx context.Context, clientId, userId, password string) (userID string, err error) { + log.Debugf("[%v]处理登录请求,用户Id:%s --> %s", clientId, userId, password) + + userID = userId + return +} + +// CheckClient 检查是否允许该客户端通过该授权模式请求令牌 +func CheckClient(clientID string, grant oauth2.GrantType) (allowed bool, err error) { + // 解出租户Id和传入的客户端Id + c := entity.OAuth2Client{ClientId: clientID} + + // 查询客户端配置信息 + if err = repository.OAuth2Client().FindOne(&c); err != nil { + log.Errorf("客户端信息查询失败: %v", err.Error()) + err = errors.New("客户端信息查询失败: " + err.Error()) + allowed = false + return + } + // 判断是否包含授权范围 + allowed = strings.Contains(c.Grant, string(grant)) + if !allowed { + err = errors.New("不受允许的grant_type") + } + return +} + +// ExtensionFields 自定义响应Token的扩展字段 +func ExtensionFields(ti oauth2.TokenInfo) (fieldsValue map[string]any) { + fieldsValue = map[string]any{} + fieldsValue["license"] = "Made By Lee" + + // 取出用户信息 + var userInfo entity.User + + userInfo.Id, _ = strconv.Atoi(ti.GetUserID()) + //if err := repository.User().GetUser(&userInfo); err != nil { + // return + //} + repository.User().GetUser(&userInfo) + fieldsValue["newUser"] = time.Now().Sub(userInfo.CreatedAt.ToTime()).Minutes() <= 1 + + fieldsValue["nickname"] = userInfo.Nickname + fieldsValue["phone"] = userInfo.Phone + fieldsValue["userId"] = userInfo.Id + + return +} + +// ResponseToken 返回Token生成结果 +func ResponseToken(w http.ResponseWriter, data map[string]any, header http.Header, statusCode ...int) error { + log.Debugf("返回Token原始数据: %+v", data) + type response struct { + Code int `json:"code"` + Data map[string]any `json:"data"` + Msg string `json:"message"` + } + + status := http.StatusOK + msg := "login success" + if len(statusCode) > 0 && statusCode[0] > 0 { + status = statusCode[0] + msg = fmt.Sprintf("%v", data["error_description"]) + // 处理特殊返回 - 刷新Token到期了 + switch data["error"] { + case "invalid_grant": + msg = "登录已过期,请重新授权登录" + case "invalid_request": + msg = "登录参数错误" + default: + log.Errorf("收到未定义的登录错误: %v", data["error_description"]) + } + data = nil + } + + res := response{ + Code: status, + Msg: msg, + Data: data, + } + + jsonBytes, err := json.Marshal(res) + if err != nil { + return err + } + w.Header().Set("Content-Type", "application/json;charset=UTF-8") + w.Header().Set("Cache-Control", "no-store") + w.Header().Set("Pragma", "no-cache") + + for key := range header { + w.Header().Set(key, header.Get(key)) + } + + w.WriteHeader(status) + _, err = w.Write(jsonBytes) + if err != nil { + log.Errorf("返回Token失败: %v", err.Error()) + return err + } + return err +} + +// InternalErrorHandler 自定义内部错误处理 +func InternalErrorHandler(err error) (re *errors.Response) { + re = errors.NewResponse(err, http.StatusUnauthorized) + re.Description = err.Error() + return +} diff --git a/oauth2/handle/token_gen.go b/oauth2/handle/token_gen.go new file mode 100644 index 0000000..9490b5a --- /dev/null +++ b/oauth2/handle/token_gen.go @@ -0,0 +1,65 @@ +package handle + +import ( + "Lee-WineList/client" + "Lee-WineList/common/constant" + "context" + "encoding/json" + "fmt" + "git.echol.cn/loser/logger/log" + "github.com/go-oauth2/oauth2/v4" + "github.com/google/uuid" + "strings" +) + +func NewAccessGenerate() *AccessGenerate { + return &AccessGenerate{} +} + +type AccessGenerate struct { +} + +// Token 手动实现Token生成,直接生成UUID,替换掉自带的那个憨得一批的长长的字符串 +func (ag *AccessGenerate) Token(ctx context.Context, data *oauth2.GenerateBasic, isGenRefresh bool) (string, string, error) { + u, _ := uuid.NewUUID() + access := strings.ReplaceAll(u.String(), "-", "") + + refresh := "" + if isGenRefresh { + u, _ = uuid.NewUUID() + refresh = strings.ReplaceAll(u.String(), "-", "") + } + // 生成新的,清理掉旧的 + ag.clearOldToken(ctx, data.UserID) + // 返回结果 + return access, refresh, nil +} + +// 清理掉旧的Token和RefreshToken +func (ag *AccessGenerate) clearOldToken(ctx context.Context, userId string) { + rdsKey := constant.OAuth2RedisKey + "*-*" + // 获取所有符合条件的Key + keys, err := client.Redis.Keys(ctx, rdsKey).Result() + if err != nil { + log.Errorf("清理失败,跳过清理") + return + } + for _, key := range keys { + dataStr, err := client.Redis.Get(ctx, key).Result() + if err != nil { + continue + } + var m map[string]any + if err = json.Unmarshal([]byte(dataStr), &m); err != nil { + continue + } + // 找到匹配的数据 + if m["UserID"] == userId { + // 删除AccessToken + client.Redis.Del(ctx, fmt.Sprintf("%v%v", constant.OAuth2RedisKey, m["Access"])) + client.Redis.Del(ctx, fmt.Sprintf("%v%v", constant.OAuth2RedisKey, m["Refresh"])) + client.Redis.Del(ctx, key) + continue + } + } +} diff --git a/oauth2/handle/user.go b/oauth2/handle/user.go new file mode 100644 index 0000000..52eaa1b --- /dev/null +++ b/oauth2/handle/user.go @@ -0,0 +1,68 @@ +package handle + +import ( + "Lee-WineList/common/constant" + "Lee-WineList/model/entity" + "Lee-WineList/repository" + "Lee-WineList/utils" + "errors" + "git.echol.cn/loser/logger/log" + "strconv" +) + +// 获取普通用户信息 +func getUser(account string, loginType constant.LoginType, nikeName string, avatarUrl string) (userId string, err error) { + // 根据登录类型获取用户信息 + + // 定义微信小程序信息 + //var unionId, openId, sessionKey string + var mobile string + // 定义用户信息 + var user entity.User + switch loginType { + case constant.LoginTypeWeChatMiniApp: + mobile, err = utils.WeChatUtils().GetPhoneNumber(account) + if err != nil { + return + } + if mobile == "" { + err = errors.New("获取手机号失败") + return + } + user.Phone = mobile + user.Nickname = nikeName + user.Avatar = avatarUrl + default: + user.Phone = account + user.Nickname = nikeName + user.Avatar = avatarUrl + } + + // 查询用户信息 + if err = repository.User().GetOrCreate(&user); err != nil { + log.Errorf("获取用户信息或创建用户失败,错误信息:%s", err.Error()) + err = errors.New("登录失败,请联系管理员") + return + } + + // 校验用户状态 + if user.Status == constant.UserStatusDisabled { + err = errors.New("账户已被禁用") + return + } + + // 异步缓存小程序SessionKey + //go func() { + // if loginType == constant.LoginTypeWeChatMiniApp { + // // 缓存SessionKey + // if client.Redis.Set(context.Background(), constant.WeChatSessionKey+user.Id, sessionKey, 3*24*time.Hour).Err() != nil { + // log.Errorf("缓存SessionKey失败,用户Id:%s", user.Id) + // } + // } + //}() + + // 返回用户Id + userId = strconv.Itoa(user.Id) + + return +} diff --git a/oauth2/server.go b/oauth2/server.go new file mode 100644 index 0000000..a32cb1d --- /dev/null +++ b/oauth2/server.go @@ -0,0 +1,74 @@ +package oauth2 + +import ( + "Lee-WineList/client" + "Lee-WineList/common/constant" + "Lee-WineList/model/entity" + "Lee-WineList/oauth2/handle" + "Lee-WineList/repository" + "git.echol.cn/loser/logger/log" + "github.com/go-oauth2/oauth2/v4/manage" + "github.com/go-oauth2/oauth2/v4/models" + "github.com/go-oauth2/oauth2/v4/server" + "github.com/go-oauth2/oauth2/v4/store" + od "github.com/go-oauth2/redis/v4" + "time" +) + +var OAuthServer *server.Server // Oauth服务 + +// InitOAuth2Server 初始化OAuth2服务端 +func InitOAuth2Server() { + manager := manage.NewDefaultManager() + // 配置信息 + cfg := &manage.Config{ + AccessTokenExp: time.Hour * 3, // 访问令牌过期时间,三小时 + RefreshTokenExp: time.Hour * 24 * 7, // 更新令牌过期时间,一周 + IsGenerateRefresh: true, // 是否生成新的更新令牌 + } + // 设置密码模式的配置参数 + manager.SetPasswordTokenCfg(cfg) + + manager.MapTokenStorage(od.NewRedisStoreWithCli(client.Redis, constant.OAuth2RedisKey)) + // 生成Token方式 + manager.MapAccessGenerate(handle.NewAccessGenerate()) + + // 配置客户端 + clientStore := store.NewClientStore() + // 从数据库查询所有client信息 + var clients []entity.OAuth2Client + if err := repository.OAuth2Client().FinAll(&clients); err != nil { + log.Panicf("OAuth2服务启动失败[Client信息拉取失败]: %v", err.Error()) + } + if len(clients) == 0 { + log.Panic("未配置OAuth2客户端信息") + } + // 组装数据 + for _, c := range clients { + _ = clientStore.Set(c.ClientId, &models.Client{ + ID: c.ClientId, + Secret: c.ClientSecret, + }) + } + log.Debug("客户端信息初始化完成") + manager.MapClientStorage(clientStore) + + srv := server.NewServer(server.NewConfig(), manager) + // 设置密码登录模式处理逻辑 + srv.SetPasswordAuthorizationHandler(handle.LoginWithPassword) + + // 客户端ID和授权模式检查 + srv.SetClientAuthorizedHandler(handle.CheckClient) + // 自定义响应Token的扩展字段 + srv.SetExtensionFieldsHandler(handle.ExtensionFields) + // 自定义返回数据接口 + srv.SetResponseTokenHandler(handle.ResponseToken) + // 自定义内部错误处理 + srv.SetInternalErrorHandler(handle.InternalErrorHandler) + // 响应错误处理(支持自定义URI及错误明细) + //srv.SetResponseErrorHandler(handle.ResponseErrorHandler) + // 自定义解析用户Id函数 + srv.SetUserAuthorizationHandler(handle.UserAuthorizationHandler) + + OAuthServer = srv +} diff --git a/repository/login.go b/repository/login.go new file mode 100644 index 0000000..79edd4a --- /dev/null +++ b/repository/login.go @@ -0,0 +1,9 @@ +package repository + +type login struct { +} + +// Login ... +func Login() *login { + return &login{} +} diff --git a/repository/oauth2_client.go b/repository/oauth2_client.go new file mode 100644 index 0000000..0c39f16 --- /dev/null +++ b/repository/oauth2_client.go @@ -0,0 +1,23 @@ +package repository + +import ( + "Lee-WineList/client" + "Lee-WineList/model/entity" +) + +type oauth2Client struct{} + +// OAuth2Client ... +func OAuth2Client() *oauth2Client { + return &oauth2Client{} +} + +// FinAll 查询所有客户端 +func (oauth2Client) FinAll(clients *[]entity.OAuth2Client) error { + return client.MySQL.Find(&clients).Error +} + +// FindOne 查询某一个 +func (oauth2Client) FindOne(c *entity.OAuth2Client) error { + return client.MySQL.Take(&c, c).Error +} diff --git a/repository/user.go b/repository/user.go index 9ab2c09..7562ac2 100644 --- a/repository/user.go +++ b/repository/user.go @@ -2,15 +2,10 @@ package repository import ( "Lee-WineList/client" - "Lee-WineList/config" "Lee-WineList/model/entity" - "Lee-WineList/model/resp" - "encoding/json" "errors" - "fmt" "git.echol.cn/loser/logger/log" "gorm.io/gorm" - "net/http" ) type user struct { @@ -26,54 +21,16 @@ func (user) GetUser(user *entity.User) (err error) { return client.MySQL.Take(&user, user).Error } -// Login Code登录 -func (u *user) Login(code string) *entity.User { - var acsJson resp.Code2SessionResult - acs := resp.Code2Session{ - Code: code, - AppId: config.Scd.Tencent.MiniApp.AppId, - AppSecret: config.Scd.Tencent.MiniApp.AppSecret, - } - api := "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code" - res, err := http.DefaultClient.Get(fmt.Sprintf(api, acs.AppId, acs.AppSecret, acs.Code)) - if err != nil { - fmt.Println("微信登录凭证校验接口请求错误") - return nil - } - if err := json.NewDecoder(res.Body).Decode(&acsJson); err != nil { - fmt.Println("decoder error...") - return nil - } - - // 查看用户是否已经存在 - rows := client.MySQL.Where("open_id = ?", acsJson.OpenId).First(&entity.User{}).RowsAffected - if rows == 0 { - // 不存在,添加用户 - fmt.Println(acsJson.OpenId) - user := entity.User{ - OpenId: acsJson.OpenId, - } - row := client.MySQL.Create(&user).RowsAffected - if row == 0 { - fmt.Println("add app user error...") - return nil - } - } - return &entity.User{OpenId: acsJson.OpenId} -} - // GetOrCreate 查询或创建用户 func (user) GetOrCreate(user *entity.User) (err error) { - err = client.MySQL.Take(&user, user).Error + //err = client.MySQL.Take(&user, user).Error + err = client.MySQL.Model(&user).Where("phone = ?", user.Phone).First(&user).Error if err == nil { return } // 如果是没查询到记录,则创建用户 if err == gorm.ErrRecordNotFound { // 用户不存在,创建用户 - user.Nickname = "用户" - //user.Avatar = "https://hyxc-mini.oss-cn-beijing.aliyuncs.com/application/resource/miniapp/index/index-more-love.png" - user.Avatar = "https://hyxc-mini.oss-cn-beijing.aliyuncs.com/avatar/mona-loading-dark.gif" if err = client.MySQL.Create(&user).Error; err != nil { log.Errorf("账号创建失败: %v", err) err = errors.New("登录失败") @@ -86,7 +43,7 @@ func (user) GetOrCreate(user *entity.User) (err error) { // CheckUnionIdIsExist 检查UnionId和OpenId是否存在 func (user) CheckUnionIdIsExist(unionId, openId string) bool { var count int64 - err := client.MySQL.Model(&entity.User{}).Where("union_id = ? and open_id = ?", unionId, openId).Count(&count).Error + err := client.MySQL.Model(&entity.User{}).Where("wechat_union_id = ? and wechat_open_id = ?", unionId, openId).Count(&count).Error if err != nil { return false } diff --git a/repository/wine.go b/repository/wine.go new file mode 100644 index 0000000..6d9245f --- /dev/null +++ b/repository/wine.go @@ -0,0 +1,40 @@ +package repository + +import ( + "Lee-WineList/client" + "Lee-WineList/model/entity" + "Lee-WineList/model/param" + "git.echol.cn/loser/logger/log" +) + +type wine struct { +} + +// Wine ... +func Wine() *wine { + return &wine{} +} + +// GetWineList 获取酒单列表 +func (w *wine) GetWineList(p param.GetWineList) (wines []entity.Wine, err error) { + db := client.MySQL.Model(&wines).Preload("Materials").Scopes(page(p.Current, p.Size)) + + if p.UserId != 0 { + db = db.Where("user_id = ?", p.UserId) + } + if p.Category != "" { + db = db.Where("category = ?", p.Category) + } + err = db.Find(&wines).Error + if err != nil { + log.Errorf("获取酒单列表失败:%s", err.Error()) + return + } + + return +} + +func (w *wine) Add(p param.AddWine) (err error) { + + return +} diff --git a/router/app/login.go b/router/login.go similarity index 51% rename from router/app/login.go rename to router/login.go index d867814..ddb5fe2 100644 --- a/router/app/login.go +++ b/router/login.go @@ -1,8 +1,7 @@ -package app +package router import ( "Lee-WineList/api/app" - "Lee-WineList/middleware" "github.com/gin-gonic/gin" ) @@ -10,6 +9,6 @@ import ( func login(g *gin.RouterGroup) { // 登录相关接口 g.POST("/token", app.LoginApi().Login) - g.POST("/token/refresh", app.LoginApi().Refresh) - g.POST("/token/logout", middleware.AuthorizeToken(), app.LoginApi().Logout) + //g.POST("/token/refresh", app.LoginApi().Refresh) + //g.POST("/token/logout", middleware.AuthorizeToken(), app.LoginApi().Logout) } diff --git a/router/app/route.go b/router/route.go similarity index 88% rename from router/app/route.go rename to router/route.go index af21f60..0ca8de6 100644 --- a/router/app/route.go +++ b/router/route.go @@ -1,4 +1,4 @@ -package app +package router import ( "Lee-WineList/middleware" @@ -9,4 +9,5 @@ import ( func InitRoute(g *gin.RouterGroup) { login(g) // 登录相关路由 user(g.Group("/user", middleware.AuthorizeToken())) // 用户相关路由 + wine(g.Group("/wine")) } diff --git a/router/app/user.go b/router/user.go similarity index 96% rename from router/app/user.go rename to router/user.go index c2d0865..bdfa134 100644 --- a/router/app/user.go +++ b/router/user.go @@ -1,4 +1,4 @@ -package app +package router import ( "Lee-WineList/api/app" diff --git a/router/wine.go b/router/wine.go new file mode 100644 index 0000000..8d00506 --- /dev/null +++ b/router/wine.go @@ -0,0 +1,10 @@ +package router + +import ( + "Lee-WineList/api/app" + "github.com/gin-gonic/gin" +) + +func wine(g *gin.RouterGroup) { + g.GET("", app.WineApi().GetList) +} diff --git a/utils/jwt.go b/utils/jwt.go deleted file mode 100644 index 48181aa..0000000 --- a/utils/jwt.go +++ /dev/null @@ -1,71 +0,0 @@ -package utils - -import ( - "Lee-WineList/config" - "time" - - "github.com/golang-jwt/jwt" -) - -type JWT struct { - claims jwt.MapClaims -} - -// GenerateToken 根据UserId生成并返回Token -func GenerateToken(userId uint64) string { - jwtConfig := config.Scd.JWT - now := time.Now().Unix() - claims := make(jwt.MapClaims) - claims["exp"] = now + jwtConfig.AccessExpire - claims["iat"] = now - claims["rft"] = now + jwtConfig.RefreshAfter - claims["userId"] = userId - - token := jwt.New(jwt.SigningMethodHS256) - token.Claims = claims - tokenStr, _ := token.SignedString([]byte(jwtConfig.AccessSecret)) - - return tokenStr -} - -// ParseToken 解析Token -func ParseToken(tokenStr string) (*JWT, error) { - token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) { - return []byte(config.Scd.JWT.AccessSecret), nil - }) - if err != nil { - return nil, err - } - - return &JWT{claims: token.Claims.(jwt.MapClaims)}, nil -} - -// Valid 验证token是否有效 -func (jwt *JWT) Valid() bool { - if err := jwt.claims.Valid(); err != nil { - return false - } - return true -} - -// CheckRefresh 检查是否可以刷新 -func (jwt *JWT) CheckRefresh() bool { - if time.Now().Unix() > jwt.GetRefreshTime() { - return true - } - return false -} - -func (jwt *JWT) RefreshToken() string { - return GenerateToken(jwt.GetUserId()) -} - -// GetUserId 从Token中解析userId -func (jwt *JWT) GetUserId() uint64 { - return uint64(jwt.claims["userId"].(float64)) -} - -// GetRefreshTime 从Token中解析refreshTime -func (jwt *JWT) GetRefreshTime() int64 { - return int64(jwt.claims["rft"].(float64)) -} diff --git a/utils/timer/timed_task.go b/utils/timer/timed_task.go new file mode 100644 index 0000000..9d09de2 --- /dev/null +++ b/utils/timer/timed_task.go @@ -0,0 +1,104 @@ +package timer + +import ( + "github.com/robfig/cron/v3" + "sync" +) + +type Timer interface { + AddTaskByFunc(taskName string, spec string, task func(), option ...cron.Option) (cron.EntryID, error) + AddTaskByJob(taskName string, spec string, job interface{ Run() }, option ...cron.Option) (cron.EntryID, error) + FindCron(taskName string) (*cron.Cron, bool) + StartTask(taskName string) + StopTask(taskName string) + Remove(taskName string, id int) + Clear(taskName string) + Close() +} + +// timer 定时任务管理 +type timer struct { + taskList map[string]*cron.Cron + sync.Mutex +} + +// AddTaskByFunc 通过函数的方法添加任务 +func (t *timer) AddTaskByFunc(taskName string, spec string, task func(), option ...cron.Option) (cron.EntryID, error) { + t.Lock() + defer t.Unlock() + if _, ok := t.taskList[taskName]; !ok { + t.taskList[taskName] = cron.New(option...) + } + id, err := t.taskList[taskName].AddFunc(spec, task) + t.taskList[taskName].Start() + return id, err +} + +// AddTaskByJob 通过接口的方法添加任务 +func (t *timer) AddTaskByJob(taskName string, spec string, job interface{ Run() }, option ...cron.Option) (cron.EntryID, error) { + t.Lock() + defer t.Unlock() + if _, ok := t.taskList[taskName]; !ok { + t.taskList[taskName] = cron.New(option...) + } + id, err := t.taskList[taskName].AddJob(spec, job) + t.taskList[taskName].Start() + return id, err +} + +// FindCron 获取对应taskName的cron 可能会为空 +func (t *timer) FindCron(taskName string) (*cron.Cron, bool) { + t.Lock() + defer t.Unlock() + v, ok := t.taskList[taskName] + return v, ok +} + +// StartTask 开始任务 +func (t *timer) StartTask(taskName string) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Start() + } +} + +// StopTask 停止任务 +func (t *timer) StopTask(taskName string) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Stop() + } +} + +// Remove 从taskName 删除指定任务 +func (t *timer) Remove(taskName string, id int) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Remove(cron.EntryID(id)) + } +} + +// Clear 清除任务 +func (t *timer) Clear(taskName string) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Stop() + delete(t.taskList, taskName) + } +} + +// Close 释放资源 +func (t *timer) Close() { + t.Lock() + defer t.Unlock() + for _, v := range t.taskList { + v.Stop() + } +} +func NewTimerTask() Timer { + return &timer{taskList: make(map[string]*cron.Cron)} +} diff --git a/utils/timer/timed_task_test.go b/utils/timer/timed_task_test.go new file mode 100644 index 0000000..c01a8f0 --- /dev/null +++ b/utils/timer/timed_task_test.go @@ -0,0 +1,61 @@ +package timer + +import ( + "fmt" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +var job = mockJob{} + +type mockJob struct{} + +func (job mockJob) Run() { + mockFunc() +} +func mockFunc() { + time.Sleep(time.Second) + fmt.Println("1s...") +} +func TestNewTimerTask(t *testing.T) { + tm := NewTimerTask() + _tm := tm.(*timer) + { + _, err := tm.AddTaskByFunc("func", "@every 1s", mockFunc) + assert.Nil(t, err) + _, ok := _tm.taskList["func"] + if !ok { + t.Error("no find func") + } + } + { + _, err := tm.AddTaskByJob("job", "@every 1s", job) + assert.Nil(t, err) + _, ok := _tm.taskList["job"] + if !ok { + t.Error("no find job") + } + } + { + _, ok := tm.FindCron("func") + if !ok { + t.Error("no find func") + } + _, ok = tm.FindCron("job") + if !ok { + t.Error("no find job") + } + _, ok = tm.FindCron("none") + if ok { + t.Error("find none") + } + } + { + tm.Clear("func") + _, ok := tm.FindCron("func") + if ok { + t.Error("find func") + } + } +}