Commit f5365530 authored by wangp's avatar wangp

拉卡拉统一支付新项目

parent 68357129
.idea/
.DS_Store
logs/*
tmp
main
# 声明镜像来源为golang:alpine
FROM golang:alpine
# 设置环境变量GO111MODULE为on
ENV GO111MODULE=on
# 设置环境变量GOPROXY为https://goproxy.io,direct
ENV GOPROXY=https://goproxy.cn,direct
# 声明工作目录
WORKDIR /go/src/system_pay
# 拷贝当前工程代码到工作目录
COPY . .
# go env为查看go的环境变量, go build -o server . 为打包项目,二进制
RUN go env && go mod tidy && go build -o server .
# ======= 以下为多阶段构建 =======
# 声明镜像来源为alpine:latest
FROM alpine:latest
ENV TZ=Asia/Shanghai
RUN echo "http://mirrors.aliyun.com/alpine/v3.4/main/" > /etc/apk/repositories \
&& apk --no-cache add tzdata zeromq \
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo '$TZ' > /etc/timezone
# 声明工作目录
WORKDIR /go/src/system_pay
# 拷贝打包好的server二进制文件到当前工作目录
COPY --from=0 /go/src/system_pay/server ./
# 拷贝配置文件到当前工作目录
COPY --from=0 /go/src/system_pay/conf/dev ./conf
# 拷贝国际化文件夹到当前工作目录
COPY --from=0 /go/src/system_pay/i18n ./i18n
# 拷贝国际化文件夹到当前工作目录
COPY --from=0 /go/src/system_pay/docs ./docs
# 运行打包好的二进制
ENTRYPOINT ./server
\ No newline at end of file
# 声明镜像来源为golang:alpine
FROM golang:alpine
# 设置环境变量GO111MODULE为on
ENV GO111MODULE=on
# 设置环境变量GOPROXY为https://goproxy.io,direct
ENV GOPROXY=https://goproxy.cn,direct
# 声明工作目录
WORKDIR /go/src/system_pay
# 拷贝当前工程代码到工作目录
COPY . .
# go env为查看go的环境变量, go build -o server . 为打包项目,二进制
RUN go env && go mod tidy && go build -o server .
# ======= 以下为多阶段构建 =======
# 声明镜像来源为alpine:latest
FROM alpine:latest
ENV TZ=Asia/Shanghai
RUN echo "http://mirrors.aliyun.com/alpine/v3.4/main/" > /etc/apk/repositories \
&& apk --no-cache add tzdata zeromq \
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo '$TZ' > /etc/timezone
# 声明工作目录
WORKDIR /go/src/system_pay
# 拷贝打包好的server二进制文件到当前工作目录
COPY --from=0 /go/src/system_pay/server ./
# 拷贝配置文件到当前工作目录
COPY --from=0 /go/src/system_pay/conf/prod ./conf
COPY --from=0 /go/src/system_pay/conf/consts.go ./conf
# 拷贝国际化文件夹到当前工作目录
COPY --from=0 /go/src/system_pay/i18n ./i18n
# 拷贝国际化文件夹到当前工作目录
COPY --from=0 /go/src/system_pay/docs ./docs
# 运行打包好的二进制
ENTRYPOINT ./server
\ No newline at end of file
# system_pay
谛语-谛宝医生数据分析平台
## 项目结构
```bigquery
├── conf 配置文件
├── controller controller层
│   ├── api
│   │   └── v1
│   └── base controller共用方法
├── docs swagger
├── i18n 多语言文件
├── logs 日志
├── middleware 中间件
│   └── jwt
├── models 结构体
├── mysql
├── pkg 第三方包
│   ├── logging
│   └── sms
├── redis redis
├── repository 数据层
├── router
│   ├── pack 路由封装
│   ├── router.go 路由入口
│   └── v1 v1版本接口
├── run-dev.sh 启动脚本
├── service 业务
├── setting 配置
├── tests 测试
└── utils 工具
├── main.go 项目入口
├── go.mod gomod
├── go.sum
```
## 关于国际化-i18n
国际化文件
` base.ResponseErrorWithMsg(c, base.ServerError)`
ServerError为200,在i18n对应文件写
200 = "对应文字"
`t.SetLanguage(语言类型)`
语言类型即使toml文件的文件名
## 关于swagger
` swag init ` 更新swagger
## 关于热更新
` air ` 启动air热更新
<br/>
` air -d ` 启动air热更新并且显示具体日志
<br/>
安装air
<br/>
`
curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
`
<br/>
`
curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sh -s
`
<br/>
`
air -v
`
package conf
import "time"
//token过期时间
const TokenExpireDuration = time.Hour * 24 * 7
//Redis过期时间
const RedisExpireDuration = time.Minute*10 //默认(短信验证码)
const RedisExpireDurationExpress = time.Minute*120 //查看物流
//Redis前缀
const RedisPrefix = "system_pay_"
const (
AesKey = "dbcaespassword01"
SmsAes = "dbcaespassword01"
)
//采购订单状态
//const (
// PURCHASE_ORDER_SUBMITTED = 10 // 待发货
// PURCHASE_ORDER_PENDING = 11 // 待付款(已发货)
// PURCHASE_ORDER_ACCEPTED = 20 // 已付款
// PURCHASE_ORDER_CHARGED = 21 // 已挂账
// PURCHASE_ORDER_FINISHED = 40 // 已结算(平台)
// PURCHASE_ORDER_EXAMINE = 60 // 已核查(卖家)
// PURCHASE_ORDER_CANCELED = 0 // 已取消
//)
//
//const (
// purchase_order_submitted = "待发货"
// purchase_order_pending = "待付款"
// purchase_order_accepted = "已付款"
// purchase_order_charged = "已挂账"
// purchase_order_finished = "已结算"
// purchase_order_examined = "已核查"
// purchase_order_canceled = "已取消"
//)
//const (
// // BILL_COMPLETE_STATUS 账单完成状态
// BILL_COMPLETE_STATUS = "1, 4, 6, 7"
// // 部分退款
// BILL_COMPLETE_STATUS_REBATES = "1, 4, 6, 7,2"
//)
//const (
// // 时间格式化
// TIME_FMT_DAY = "2006-01-02"
// TIME_FMT_DAY_SQL = "'%Y-%m-%d'"
//)
// PhonePrefix 号码前缀
//var PhonePrefix = map[int]string{
// 1: "86",
// 2: "60",
//}
// PayType 支付方式
//var PayType = map[int]string{
// 1: "现金",
// 2: "银行卡",
// 3: "支付宝",
// 4: "微信支付",
// //5: "预收款",
// //6: "预付款",
// 7: "押金",
// 8: "会员卡余额",
// 9: "会员卡赠额",
// 10: "团购",
//}
// PayTypeZhCN 支付方式
//var PayTypeZhCN = map[int]int{
// 1: 0,
// 2: 2,
// 3: 1,
//}
// SecondaryCardLineChartList 次卡折线图
//var SecondaryCardLineChartList = map[int]int{
// //1: 1306,
// 2: 1307,
// 3: 1308,
// 4: 1309,
//}
//var CountryPrefix = map[string]string{
// "86": "中国",
// "60": "马来西亚",
//}
// PrefixLocalList 开通列表
//var PrefixLocalList = map[string]string{
// "86": "zh-CN",
// "60": "en-US",
//}
// ZH_CN 中国开通列表
//var ZH_CN = []string{
// "免费试用%v%v",
// "支付宝支付",
// "微信支付",
//}
// EN_US 美国
//var EN_US = []string{
// "Free trial for %v %v",
// "Alipay Pay",
// "WeChat Pay",
//}
// PayTypeListAddKey 前端开通列表ID差
//var PayTypeListAddKey = map[string]int{
// "zh-CN": 1,
// "en-US": 4,
//}
// PayTypeList 开通列表
//var PayTypeList = map[string]interface{}{
// "zh-CN": ZH_CN,
// "en-US": EN_US,
//}
// pay
//const (
// QueryIsOpenDY = "/gateway/dy/is_open_py" // 查询医院是否开通谛语智慧
// DYTrial = "/gateway/dy/trial" // 谛语智慧试用
// PurchasePacs = "/gateway/dy/buy" // 谛语智慧购买
// OpeningData = "/gateway/dy/data" // 谛语智慧购买页信息
// //QueryDYBuy = "/gateway/dy/buy" // 查询 订单
// //QueryDYMeal = "/gateway/py/py_meal" // pacs 套餐列表
// //QueryDcmList = "/gateway/py/dcm_list" // pacs 套餐列表
//)
//const (
// AesKey = "dbcaespassword01"
// SmsAes = "dbcaespassword01"
//)
# 服务
server:
runMode: 'debug'
httpport: 19880
readtimeout: 60
writetimeout: 60
# 通用设置
app:
name: 'system_pay'
version: '1.0.0.0'
timeformat: 20060102
# 数据库
database:
type: 'mysql'
#crmdb: "root:abc123456@tcp(39.96.85.45:3307)/dbc_crm_manage?charset=utf8"
shopdb: "root:abc123456@tcp(39.96.85.45:3307)/dbc_shop?charset=utf8"
#accountdb: 'dbc_saas:dbc_saas888888@tcp(rm-2zepcf8kag0aol0q48o.mysql.rds.aliyuncs.com:3306)/hos_database?charset=utf8'
#userdb: 'root_dbc:dbc_root888888@tcp(rm-2ze8jnj44l6ta299pro.mysql.rds.aliyuncs.com:3306)/mysql?charset=utf8'
#seconddb: 'root_dbc:dbc_root888888@tcp(rm-2ze095l91j14r251wno.mysql.rds.aliyuncs.com:3306)/mysql?charset=utf8'
#paydb: 'dbc_saas:dbc_saas888888@tcp(rm-2zepcf8kag0aol0q48o.mysql.rds.aliyuncs.com:3306)/diyu_analysis?charset=utf8'
max_open_conns: 200
max_idle_conns: 50
# host: "127.0.0.1"
# user: "root"
# password: "rootroot"
# port: 3306
# dbname: "test_food"
# redis
redis:
host: '39.96.85.45'
port: 6382
password: 'saas123456'
db: 0
pool_size: 200
# mongo
#mongo:
# dburl: 'mongodb://saas888:saas888@39.97.234.228:27018'
# max_open_conns: 300
# 日志
log:
logsavepath: logs/
logsavename: log
logfileext: log
level: 'debug'
max_size: 200
max_age: 30
max_backups: 7
sms:
smskey: 'dbc2021888000000'
sendsmsurl: 'https://tsms.pet-dbc.cn/v1/send'
smscontent: '【谛宝医生】登录验证码为:%s'
# 支付
#payurl:
# checkorder: 'https://tpay.pet-dbc.cn/v1/pay/unified_order'
# orderstate: 'https://tpay.pet-dbc.cn/v1/pay/order_state/'
# gateway
#gateway:
# url: 'http://saas.pet-dbc.cn'
# port: '8003'
# gateway
#gatewaydev:
# url: '127.0.0.1'
# port: '80'
#图片上传目录
uploadimage:
upload_dir: 'credit_shop'
max_file_size: 50000000
image_types: '(jpg|jpeg|png|pdf|gif|zip|rar)'
accept_file_types: 'IMAGE_TYPES'
#OSS配置
oss:
oss_url: 'https://dbc-static.oss-cn-beijing.aliyuncs.com/'
accesskeyid: 'LTAIDfwPBC9AnsRt'
accesskeysecret: 'Z6FtUptrAk0Sl6H8vrVBGZLbBzXEpO'
endpoint: 'oss-cn-beijing.aliyuncs.com'
bucket: 'dbc-static'
#阿里云 - 全国快递物流查询
alicloud:
appcode: '6d1da9eb15b540688a505c1814e0c25f'
#time_duration: 7200
#e签宝
esign:
project_id: "5111575783"
project_secret: "5255e7159b6262b92b03c4e307a23ed2"
organ_auth_url: "https://openapi2.tsign.cn:8444/realname/rest/external/organ/orgAuth"
info_auth_url: "https://openapi2.tsign.cn:8444/realname/rest/external/organ/infoAuth-special"
# jwt 与 des解密
jwtsecret: 'Rtg8BPKNEf5mo4mgvKONGPZZQSaJWNLijxJ52qRgq0iBb7'
deskey: 'yaoll123'
#system_pay777
# 服务
server:
runMode: 'release'
httpport: 19880
readtimeout: 60
writetimeout: 60
# 通用设置
app:
name: 'system_pay'
version: '1.0.0.0'
timeformat: 20060102
# 数据库
database:
type: 'mysql'
#crmdb: "root_shop:DBC_shopqwe@tcp(rm-2zenl1z0v6209a4jrbo.mysql.rds.aliyuncs.com:3306)/dbc_crm_manage?charset=utf8"
shopdb: "root_shop:DBC_shopqwe@tcp(rm-2zenl1z0v6209a4jrbo.mysql.rds.aliyuncs.com:3306)/dbc_shop?charset=utf8"
# accountdb: 'dbc_saas:dbc_saas888888@tcp(rm-2zepcf8kag0aol0q48o.mysql.rds.aliyuncs.com:3306)/hos_database?charset=utf8'
# userdb: 'root_dbc:dbc_root888888@tcp(rm-2ze8jnj44l6ta299pro.mysql.rds.aliyuncs.com:3306)/mysql?charset=utf8'
# seconddb: 'root_dbc:dbc_root888888@tcp(rm-2ze095l91j14r251wno.mysql.rds.aliyuncs.com:3306)/mysql?charset=utf8'
# paydb: 'dbc_saas:dbc_saas888888@tcp(rm-2zepcf8kag0aol0q48o.mysql.rds.aliyuncs.com:3306)/diyu_analysis?charset=utf8'
max_open_conns: 200
max_idle_conns: 50
# host: "127.0.0.1"
# user: "root"
# password: "rootroot"
# port: 3306
# dbname: "test_food"
# redis
redis:
host: '39.97.179.15'
port: 6382
password: 'saas123456'
db: 0
pool_size: 200
# mongo
#mongo:
# dburl: 'mongodb://saas888:saas888@39.97.179.15:27017'
# max_open_conns: 300
# 日志
log:
logsavepath: logs/
logsavename: log
logfileext: log
level: 'debug'
max_size: 200
max_age: 30
max_backups: 7
# 国际化短信服务
sms:
smskey: 'dbc2021888000000'
sendsmsurl: 'https://sms.pet-dbc.cn/v1/send'
smscontent: '【谛宝多多】登录验证码为:%s'
# 支付
#payurl:
# checkorder: 'https://pay.pet-dbc.cn/v1/pay/unified_order'
# orderstate: 'https://pay.pet-dbc.cn/v1/pay/order_state/'
# gateway
#gateway:
# url: 'http://saas.pet-dbc.cn'
# port: '8003'
# gateway
#gatewaydev:
# url: '127.0.0.1'
# port: '80'
#图片上传目录
uploadimage:
upload_dir: 'credit_shop'
max_file_size: 50000000
image_types: '(jpg|jpeg|png|pdf|gif|zip|rar)'
accept_file_types: 'IMAGE_TYPES'
#OSS配置
oss:
oss_url: 'https://dbc-static.oss-cn-beijing.aliyuncs.com/'
accesskeyid: 'LTAIDfwPBC9AnsRt'
accesskeysecret: 'Z6FtUptrAk0Sl6H8vrVBGZLbBzXEpO'
endpoint: 'oss-cn-beijing.aliyuncs.com'
bucket: 'dbc-static'
#阿里云 - 全国快递物流查询
alicloud:
appcode: '6d1da9eb15b540688a505c1814e0c25f'
time_duration: 7200
#e签宝
esign:
project_id: "7438819206"
project_secret: "64c6e023ee98c82a1a7180107c320d08"
organ_auth_url: "http://smlrealname.tsign.cn:8080/realname/rest/external/organ/orgAuth"
info_auth_url: "http://smlrealname.tsign.cn:8080/realname/rest/external/organ/infoAuth-special"
# jwt 与 des解密
jwtsecret: 'Rtg8BPKNEf5mo4mgvKONGPZZQSaJWNLijxJ52qRgq0iBb7'
deskey: 'yaoll123'
package pay
import (
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"system_pay/controller/base"
"system_pay/models"
"system_pay/repository/pay"
)
// 卡拉卡统一支付
type PayController struct {
}
// UnifiedOrder 拉卡拉统一支付
// @Summary 拉卡拉统一支付
// @Description 拉卡拉统一支付
// @Tags 拉卡拉统一支付
// @Accept application/json
// @Produce application/json
// @Param body body models.PlaceAnOrderParamInput true "参数"
// @Param language header string ture "语言类型 zh-CN简体中文 en-US英文 ja 日文 默认中文"
// @Success 200
// @router /api/v1/index/unified_order [post]
func (l *PayController) UnifiedOrder(c *gin.Context) {
ph := new(models.PlaceAnOrderParamInput)
err := c.ShouldBind(ph)
if err != nil {
zap.L().Error(err.Error())
base.ResponseErrorWithMsg(c, base.ServerError)
return
}
// 绑定
rtn, err := pay.UnifiedOrder(ph)
if err != nil {
zap.L().Error(err.Error())
//base.ResponseErrorWithMsg(c, base.ServerError)
base.ResponseErrorMsg(c, err.Error())
return
}
base.ResponseSuccess(c, rtn)
}
package base
import (
"github.com/gin-gonic/gin"
)
// 获取登录时保存的常量
func GetMyClaimsItem(c *gin.Context, name string) (string) {
return c.MustGet(name).(string)
}
//// GetHospitalCode 获取hospital code
//func GetHospitalCode(c *gin.Context) string {
//
// hospitalCode := c.MustGet("hospital_code").(string)
//
// if hospitalCode == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital code 失败", zap.Error(err))
// return ""
// }
//
// hospitalCode = utils.ToDesDecrypt(parseToken.HospitalCode)
// }
//
// return hospitalCode
//}
//
//
//
//
//// GetChainID get chainID
//func GetChainID(c *gin.Context) string {
//
// ChainID := c.MustGet("chain_id").(string)
//
// if ChainID == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("chain_id 失败", zap.Error(err))
// return ""
// }
//
// ChainID = utils.ToDesDecrypt(parseToken.ChainID)
// }
//
// return ChainID
//}
//
//// GetUserPhone 获取user phone
//func GetUserPhone(c *gin.Context) string {
//
// userPhone := c.MustGet("user_phone").(string)
//
// if userPhone == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital code 失败", zap.Error(err))
// return ""
// }
//
// userPhone = utils.ToDesDecrypt(parseToken.UserPhone)
// }
//
// return userPhone
//
//}
//
//// GetChainCode 获取chain code
//func GetChainCode(c *gin.Context) string {
//
// chainCode := c.MustGet("chain_code").(string)
//
// if chainCode == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital code 失败", zap.Error(err))
// return ""
// }
//
// chainCode = utils.ToDesDecrypt(parseToken.ChainCode)
// }
//
// return chainCode
//
//}
//
//// GetHospitalID 获取hospital id
//func GetHospitalID(c *gin.Context) string {
//
// hospitalID := c.MustGet("hospital_id").(string)
//
// if hospitalID == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital id 失败", zap.Error(err))
// return ""
// }
//
// hospitalID = utils.ToDesDecrypt(parseToken.HospitalID)
// }
//
// return hospitalID
//
//}
//
//// GetHospitalIDAndChainCode 获取hospital id
//func GetHospitalIDAndChainCode(c *gin.Context) (hospitalIDS, chainCodeS string) {
//
// hospitalID := c.MustGet("hospital_id").(string)
//
// if hospitalID == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital id 失败", zap.Error(err))
// return "", ""
// }
//
// hospitalID = utils.ToDesDecrypt(parseToken.HospitalID)
// }
//
// chainCode := c.MustGet("chain_code").(string)
//
// if chainCode == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital code 失败", zap.Error(err))
// return "", ""
// }
//
// chainCode = utils.ToDesDecrypt(parseToken.ChainCode)
// }
//
// return hospitalID, chainCode
//
//}
//
//
//// GetHospitalIDAndChainID 获取hospital id and chain id
//func GetHospitalIDAndChainID(c *gin.Context) (hospitalIDS, chainIDS string) {
//
// hospitalID := c.MustGet("hospital_id").(string)
//
// if hospitalID == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital id 失败", zap.Error(err))
// return "", ""
// }
//
// hospitalID = utils.ToDesDecrypt(parseToken.HospitalID)
// }
//
// ChainID := c.MustGet("chain_id").(string)
//
// if ChainID == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("chain_id 失败", zap.Error(err))
// return "", "" }
//
// ChainID = utils.ToDesDecrypt(parseToken.ChainID)
// }
//
//
// return hospitalID, ChainID
//
//}
//
//
//
//// GetHospitalName 获取hospital name
//func GetHospitalName(c *gin.Context) (name string) {
//
// hospitalName := c.MustGet("hospital_name").(string)
//
// if hospitalName == "" {
//
// token := c.Request.Header.Get("Authorization")
//
// parseToken, err := utils.ParseToken(token)
// if err != nil {
// zap.L().Error("获取hospital name 失败", zap.Error(err))
// return ""
// }
//
// hospitalName = utils.ToDesDecrypt(parseToken.HospitalName)
// }
//
//
//
// return hospitalName
//
//}
//
//func ParamInt(c *gin.Context, key string) (int, error) {
//
// showType := c.Param(key)
//
// showTypeInt, err := strconv.Atoi(showType)
//
// return showTypeInt, err
//}
//
//
//func QueryInt(c *gin.Context, key string) int {
//
// showType := c.Query(key)
//
// showTypeInt, _ := strconv.Atoi(showType)
//
// return showTypeInt
//}
package base
/*
返回码
*/
const (
// Success 请求成功
Success = 1000
// ServerError 服务器错误
ServerError = 1100
// Warning 警告
Warning = 1200
// FailedToObtainVerificationCode 验证码获取失败
//FailedToObtainVerificationCode = 1001
// PleaseCheckIfThePhoneNumberIsEnteredCorrectly 请检查电话号码是否输入正确
//PleaseCheckIfThePhoneNumberIsEnteredCorrectly = 1002
// VerificationCodeError 验证码错误
//VerificationCodeError = 1003
// AuthorizationEmpty token为空
AuthorizationEmpty = 1004
// ThisAccountDoesNotHavePermission 此账号没有权限
//ThisAccountDoesNotHavePermission = 1005
// ParameterValidationFailed 参数效验失败
//ParameterValidationFailed = 1006
// 此国家暂不支持
//NotCurrentlySupportedInThisCountry = 1007
)
package base
import (
"github.com/gin-gonic/gin"
"github.com/gogf/gf/i18n/gi18n"
"strconv"
)
/*
国际化处理
*/
var (
t *gi18n.Manager
)
// InternationalizedMsg 国际化msg
func InternationalizedMsg(ctx *gin.Context, code int) string {
t = gi18n.New()
languageType := ctx.Request.Header.Get("language")
// 设置默认语言类型
if languageType == "" {
languageType = "zh-CN"
}
// 设置语言类型
t.SetLanguage(languageType)
// 传入错误码
stringCode := strconv.Itoa(code)
// 拿到对应国家的错误信息
translateMsg := t.Translate(ctx, stringCode)
return translateMsg
}
// InternationalizedMsgByLanguageType 国际化msg
func InternationalizedMsgByLanguageType(languageType string, code int) string {
t = gi18n.New()
// 设置默认语言类型
if languageType == "" {
languageType = "zh-CN"
}
// 设置语言类型
t.SetLanguage(languageType)
// 传入错误码
stringCode := strconv.Itoa(code)
// 拿到对应国家的错误信息
translateMsg := t.Translate(nil, stringCode)
return translateMsg
}
func GetLanguageType(c *gin.Context) string {
languageType := c.Request.Header.Get("language")
if languageType == "" {
languageType = "zh-CN"
}
return languageType
}
// BuriedPointMsg 国际化msg
func BuriedPointMsg(code int) string {
t = gi18n.New()
//languageType := ctx.Request.Header.Get("language")
// 设置默认语言类型
//if languageType == "" {
languageType := "bp"
//}
// 设置语言类型
t.SetLanguage(languageType)
// 传入错误码
stringCode := strconv.Itoa(code)
// 拿到对应国家的错误信息
translateMsg := t.Translate(nil, stringCode)
return translateMsg
}
package base
import (
"github.com/gin-gonic/gin"
"net/http"
)
/*
{
"code": 10000, // 程序中的错误码
"msg": xx, // 提示信息
"data": {}, // 数据
}
*/
// ResponseData 统一返回数据
type ResponseData struct {
Code int `json:"code"`
Msg interface{} `json:"msg"`
Data interface{} `json:"data,omitempty"`
}
// ResponseErrorWithMsg 返回错误
func ResponseErrorWithMsg(c *gin.Context, code int) {
c.JSON(http.StatusOK, &ResponseData{
Code: code,
Msg: InternationalizedMsg(c, code),
Data: nil,
})
}
// ResponseSuccess 返回正确
func ResponseSuccess(c *gin.Context, data interface{}) {
c.JSON(http.StatusOK, &ResponseData{
Code: Success,
Msg: InternationalizedMsg(c, Success),
Data: data,
})
}
// ResponseErrorMsg 直接返回msg
func ResponseErrorMsg(c *gin.Context, msg string) {
c.JSON(http.StatusOK, &ResponseData{
Code: Warning,
Msg: msg,
Data: nil,
})
}
\ No newline at end of file
#!/bin/bash
git pull
export runmode=dev
docker-compose up --build -d
docker image prune -f
\ No newline at end of file
version: '3.5'
services:
system_pay_dev:
restart: always
build:
context: .
args:
ENVARG: dev
dockerfile: Dockerfile
image: system_pay:dev
ports:
- 19880:19880
environment:
runmode: dev
networks:
- system_pay_network
networks:
system_pay_network:
driver: bridge
// Package docs GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag
package docs
import (
"bytes"
"encoding/json"
"strings"
"text/template"
"github.com/swaggo/swag"
)
var doc = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{.Description}}",
"title": "{{.Title}}",
"contact": {},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/api/v1/index/unified_order": {
"post": {
"description": "拉卡拉统一支付",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"拉卡拉统一支付"
],
"summary": "拉卡拉统一支付",
"parameters": [
{
"description": "参数",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.PlaceAnOrderParamInput"
}
},
{
"type": "string",
"description": "语言类型 zh-CN简体中文 en-US英文 ja 日文 默认中文",
"name": "language",
"in": "header"
}
],
"responses": {
"200": {
"description": ""
}
}
}
}
},
"definitions": {
"models.PlaceAnOrderParamInput": {
"type": "object",
"properties": {
"app_id": {
"type": "string"
},
"attach_info": {
"type": "string"
},
"customer": {
"type": "string"
},
"dynamic_id": {
"type": "string"
},
"goods_des": {
"type": "string"
},
"goods_detail": {
"type": "string"
},
"goods_price": {
"type": "number"
},
"is_serve": {
"type": "integer"
},
"notice_url": {
"type": "string"
},
"open_id": {
"type": "string"
},
"operator": {
"type": "string"
},
"pay_type": {
"type": "integer"
},
"platform_info": {
"type": "string"
},
"platform_type": {
"type": "integer"
},
"quit_url": {
"type": "string"
},
"return_url": {
"type": "string"
},
"source_code": {
"type": "integer"
},
"store_sn": {
"type": "string"
},
"sub_mchid": {
"type": "string"
},
"wap_name": {
"type": "string"
},
"wap_url": {
"type": "string"
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
}
}`
type swaggerInfo struct {
Version string
Host string
BasePath string
Schemes []string
Title string
Description string
}
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = swaggerInfo{
Version: "1.0",
Host: "",
BasePath: "",
Schemes: []string{},
Title: "谛宝多多平台",
Description: "采购订单项目",
}
type s struct{}
func (s *s) ReadDoc() string {
sInfo := SwaggerInfo
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
t, err := template.New("swagger_info").Funcs(template.FuncMap{
"marshal": func(v interface{}) string {
a, _ := json.Marshal(v)
return string(a)
},
}).Parse(doc)
if err != nil {
return doc
}
var tpl bytes.Buffer
if err := t.Execute(&tpl, sInfo); err != nil {
return doc
}
return tpl.String()
}
func init() {
swag.Register(swag.Name, &s{})
}
{
"swagger": "2.0",
"info": {
"description": "采购订单项目",
"title": "谛宝多多平台",
"contact": {},
"version": "1.0"
},
"paths": {
"/api/v1/index/unified_order": {
"post": {
"description": "拉卡拉统一支付",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"拉卡拉统一支付"
],
"summary": "拉卡拉统一支付",
"parameters": [
{
"description": "参数",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/models.PlaceAnOrderParamInput"
}
},
{
"type": "string",
"description": "语言类型 zh-CN简体中文 en-US英文 ja 日文 默认中文",
"name": "language",
"in": "header"
}
],
"responses": {
"200": {
"description": ""
}
}
}
}
},
"definitions": {
"models.PlaceAnOrderParamInput": {
"type": "object",
"properties": {
"app_id": {
"type": "string"
},
"attach_info": {
"type": "string"
},
"customer": {
"type": "string"
},
"dynamic_id": {
"type": "string"
},
"goods_des": {
"type": "string"
},
"goods_detail": {
"type": "string"
},
"goods_price": {
"type": "number"
},
"is_serve": {
"type": "integer"
},
"notice_url": {
"type": "string"
},
"open_id": {
"type": "string"
},
"operator": {
"type": "string"
},
"pay_type": {
"type": "integer"
},
"platform_info": {
"type": "string"
},
"platform_type": {
"type": "integer"
},
"quit_url": {
"type": "string"
},
"return_url": {
"type": "string"
},
"source_code": {
"type": "integer"
},
"store_sn": {
"type": "string"
},
"sub_mchid": {
"type": "string"
},
"wap_name": {
"type": "string"
},
"wap_url": {
"type": "string"
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
}
}
\ No newline at end of file
definitions:
models.PlaceAnOrderParamInput:
properties:
app_id:
type: string
attach_info:
type: string
customer:
type: string
dynamic_id:
type: string
goods_des:
type: string
goods_detail:
type: string
goods_price:
type: number
is_serve:
type: integer
notice_url:
type: string
open_id:
type: string
operator:
type: string
pay_type:
type: integer
platform_info:
type: string
platform_type:
type: integer
quit_url:
type: string
return_url:
type: string
source_code:
type: integer
store_sn:
type: string
sub_mchid:
type: string
wap_name:
type: string
wap_url:
type: string
type: object
info:
contact: {}
description: 采购订单项目
title: 谛宝多多平台
version: "1.0"
paths:
/api/v1/index/unified_order:
post:
consumes:
- application/json
description: 拉卡拉统一支付
parameters:
- description: 参数
in: body
name: body
required: true
schema:
$ref: '#/definitions/models.PlaceAnOrderParamInput'
- description: 语言类型 zh-CN简体中文 en-US英文 ja 日文 默认中文
in: header
name: language
type: string
produces:
- application/json
responses:
"200":
description: ""
summary: 拉卡拉统一支付
tags:
- 拉卡拉统一支付
securityDefinitions:
ApiKeyAuth:
in: header
name: Authorization
type: apiKey
swagger: "2.0"
module system_pay
go 1.16
require (
github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible
github.com/astaxie/beego v1.12.3
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fsnotify/fsnotify v1.5.1
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
github.com/gin-gonic/gin v1.7.4
github.com/go-redis/redis v6.15.9+incompatible
github.com/go-sql-driver/mysql v1.6.0
github.com/gogf/gf v1.16.6
github.com/google/uuid v1.3.0
github.com/jmoiron/sqlx v1.3.4
github.com/json-iterator/go v1.1.11
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.16.0 // indirect
github.com/pkg/errors v0.9.1
github.com/satori/go.uuid v1.2.0
github.com/spf13/viper v1.8.1
github.com/swaggo/gin-swagger v1.3.1
github.com/swaggo/swag v1.7.1
go.mongodb.org/mongo-driver v1.7.2
go.uber.org/zap v1.19.1
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
)
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
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.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
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=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
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/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.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
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=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
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/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible h1:ht2+VfbXtNLGhCsnTMc6/N26nSTBK6qdhktjYyjJQkk=
github.com/aliyun/aliyun-oss-go-sdk v2.2.0+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
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-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ=
github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 h1:LdXxtjzvZYhhUaonAaAKArG3pyC67kGL3YY+6hGG8G4=
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
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/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
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.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc=
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogf/gf v1.16.6 h1:Yp5YfwnGz41d1tiVqxcWXiPXyuzjTb7ax4SnPSXxDE8=
github.com/gogf/gf v1.16.6/go.mod h1:4LoHfEBl2jbVmZpVx+qk2La3zWr1V315FtF2PVZuyQ8=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
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/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=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
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.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
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/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/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grokify/html-strip-tags-go v0.0.0-20190921062105-daaa06bf1aaf h1:wIOAyJMMen0ELGiFzlmqxdcV1yGbkyHBAB6PolcNbLA=
github.com/grokify/html-strip-tags-go v0.0.0-20190921062105-daaa06bf1aaf/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
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-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
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.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/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.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/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
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.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.0 h1:wCi7urQOGBsYcQROHqpUUX4ct84xp40t9R9JX0FuA/U=
github.com/prometheus/client_golang v1.7.0/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0 h1:RyRA7RzGXQZiW+tGMr7sxa85G1z0yOpM1qq5c8lNawc=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFBS8=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
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/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/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
github.com/swaggo/gin-swagger v1.3.1 h1:mO9MU8O99WX+RM3jekzOV54g9Fo+Nbkk7rgrN1u9irM=
github.com/swaggo/gin-swagger v1.3.1/go.mod h1:Z6NtRBK2PRig0EUmy1Xu75CnCEs6vGYu9QZd/QWRYKU=
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
github.com/swaggo/swag v1.7.1 h1:gY9ZakXlNWg/i/v5bQBic7VMZ4teq4m89lpiao74p/s=
github.com/swaggo/swag v1.7.1/go.mod h1:gAiHxNTb9cIpNmA/VEGUP+CyZMCP/EW7mdtc8Bny+p8=
github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q=
github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc=
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4=
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
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/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
go.mongodb.org/mongo-driver v1.7.2 h1:pFttQyIiJUHEn50YfZgC9ECjITMT44oiN36uArf/OFg=
go.mongodb.org/mongo-driver v1.7.2/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
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.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opentelemetry.io/otel v1.0.0-RC2 h1:SHhxSjB+omnGZPgGlKe+QMp3MyazcOHdQ8qwo89oKbg=
go.opentelemetry.io/otel v1.0.0-RC2/go.mod h1:w1thVQ7qbAy8MHb0IFj8a5Q2QU0l2ksf8u/CN8m3NOM=
go.opentelemetry.io/otel/oteltest v1.0.0-RC2/go.mod h1:kiQ4tw5tAL4JLTbcOYwK1CWI1HkT5aiLzHovgOVnz/A=
go.opentelemetry.io/otel/trace v1.0.0-RC2 h1:dunAP0qDULMIT82atj34m5RgvsIK6LcsXf1c/MsYg1w=
go.opentelemetry.io/otel/trace v1.0.0-RC2/go.mod h1:JPQ+z6nNw9mqEGT8o3eoPTdnNI+Aj5JcxEsVGREIAy4=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
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=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
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-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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 h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/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-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
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 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/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 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
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.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
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.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.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
# 数据分析
# 9000 = ""
# 9001 = "数据概览"
# 9002 = "顾客分析"
# 9003 = "会员卡分析"
# 9004 = "次卡分析"
# 9005 = "病历量分析"
# 9006 = "医疗消费分析"
# 9007 = "商品分析"
# 9008 = "员工分析"
#
# 9100 = ""
# 9101 = "新增用户"
# 9102 = "到店消费"
# 9103 = "新客消费"
# 9104 = "老客消费"
# 9105 = "新增办卡数"
# 9106 = "会员卡充值额度"
# 9107 = "赠额充值额度"
# 9108 = "会员卡消费次数"
# 9109 = "会员卡消费金额"
# 9110 = "就诊量"
# 9111 = "新客户初诊"
# 9112 = "老客户初诊"
# 9113 = "新客户复诊"
# 9114 = "老客户复诊"
# 9115 = "销量下跌"
# 9116 = "滞销商品"
# 英语
1000 = "success"
1100 = "server error"
# 1001 = "failed to obtain verification code"
# 1002 = "Please check if the phone number is entered correctly"
# 1003 = "Verification code error"
1004 = "authorizatione is error"
# 1005 = "this account does not have permission"
# 1006 = "parameter validation failed"
# 1007 = "this country does not currently support"
# 项目中key
# 1300 = "Business sales performance"
# 1301 = "Sub-card performance"
# 1302 = "Service performance"
# 1303 = "Year"
# 1304 = "Month"
# 1305 = "Day"
# 1306 = "Recharge amount"
# 1307 = "Number of recharges"
# 1308 = "Number of purchases"
# 1309 = "Add a new card"
\ No newline at end of file
# 日语
1000 = "success"
1100 = "サーバエラー"
1004 = "authorizationeが正しくない"
# 1007 = "この国はしばらくサポートしていません"
# 简体中文
1000 = "success"
1100 = "服务器错误"
# 1001 = "验证码获取失败"
# 1002 = "请检查电话号码是否输入正确"
# 1003 = "验证码错误"
1004 = "Authorization不正确" #Authorization为空
# 1005 ="此帐号没有权限"
# 1006 ="参数效验失败"
# 1007 = "此国家暂时不支持"
# 警告信息
# 1200 = "您已经是VIP用户,无需试用"
# 1201 = "试用已经到期, 请付费后使用"
# 1202 = "正在试用中"
# 1203 = "服务已经到期, 请付费后使用"
# 项目中key
# 1300 = "经营销售业绩"
# 1301 = "次卡业绩"
# 1302 = "服务业绩"
# 1303 = "年"
# 1304 = "个月"
# 1305 = "日"
# 1306 = "充值金额"
# 1307 = "充值次数"
# 1308 = "消费次数"
# 1309 = "新增次卡"
#
# 1500 = "用户名长度错误,应保持在3到25位之间"
# 1501 = "密码长度错误,应保持在6-20位之间"
# 1502 = "手机号码格式错误"
\ No newline at end of file
package main
import (
"bytes"
"fmt"
"github.com/fvbock/endless"
"github.com/gin-gonic/gin"
"os"
"os/exec"
_ "system_pay/docs"
logger "system_pay/pkg/logging"
"system_pay/redis"
routers "system_pay/router"
"system_pay/setting"
)
// @title 谛宝多多平台
// @version 1.0
// @description 采购订单项目
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
func main() {
if os.Getenv("runmode") == "release" {
gin.SetMode(gin.ReleaseMode)
} else {
gin.SetMode(gin.DebugMode)
}
// 设置
if err := setting.Init(); err != nil {
panic("load config failed, new_error:"+ err.Error())
//fmt.Printf("load config failed, new_error:%v\n", new_error)
//return
}
if gin.Mode() == gin.TestMode || gin.Mode() == gin.DebugMode {
//自动更新swagger
runCommand()
}
// 日志
if err := logger.Init(setting.Conf.LogSetting); err != nil {
panic("init logger failed, new_error:"+ err.Error())
//fmt.Printf("init logger failed, new_error:%v\n", new_error)
//return
}
// redis
if err := redis.Init(setting.Conf.Redis); err != nil {
panic("init redis failed, new_error:"+ err.Error())
//fmt.Printf("init redis failed, new_error:%v\n", new_error)
//return
}
// 关闭项目时候关闭redis连接
defer redis.Close()
// mongo
//MongoDB, err := mongo.ConnectToMongoDB()
//if err != nil {
// panic("err" + err.Error())
//}
//defer mongo.Close(MongoDB)
// 注册路由
r := routers.InitRouter()
// 优雅启停
err := endless.ListenAndServe(setting.GetPort(), r)
if err != nil {
panic("route initialization failed, new_error:"+ err.Error())
//fmt.Println("route_initialization_failed" + new_error.Error())
//return
}
}
// runCommand 重启时候更新swagger
func runCommand() {
cmd := exec.Command("swag", "init")
fmt.Println("Cmd", cmd.Args)
var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = os.Stderr
err := cmd.Start()
if err != nil {
fmt.Println(err)
}
fmt.Println(out.String())
}
package jwt
import (
"fmt"
"github.com/gin-gonic/gin"
"system_pay/controller/base"
"system_pay/utils"
)
//var DataAnalysisCh chan models.DataAnalysisModel
func init() {
//DataAnalysisCh = make(chan models.DataAnalysisModel, 1000)
//go DataAnalysisChannel()
}
// JWTAuthMiddleWare 基于JWT的认证中间件
func JWTAuthMiddleWare() func(c *gin.Context) {
return func(c *gin.Context) {
//客户端携带Token放在请求头
authHeader := c.Request.Header.Get("Authorization")
if authHeader == "" {
base.ResponseErrorWithMsg(c, base.AuthorizationEmpty)
c.Abort()
return
}
mc, err := utils.ParseToken(authHeader)
if err != nil {
base.ResponseErrorWithMsg(c, base.AuthorizationEmpty)
c.Abort()
return
}
// des解密
phoneMob := utils.ToDesDecrypt(mc.PhoneMob)
userId := utils.ToDesDecrypt(mc.UserId)
userName := utils.ToDesDecrypt(mc.UserName)
//hospitalCode := utils.ToDesDecrypt(mc.HospitalCode)
//chainCode := utils.ToDesDecrypt(mc.ChainCode)
//hospitalID := utils.ToDesDecrypt(mc.HospitalID)
//hospitalName := utils.ToDesDecrypt(mc.HospitalName)
//ChainID := utils.ToDesDecrypt(mc.ChainID)
// 将当前请求的username信息保存到请求的上下文c上
c.Set("phone_mob", phoneMob)
fmt.Println(phoneMob)
c.Set("user_id", userId)
fmt.Println(userId)
c.Set("user_name", userName)
fmt.Println(userName)
//c.Set("hospital_code", hospitalCode)
//c.Set("chain_code", chainCode)
//c.Set("hospital_id", hospitalID)
//c.Set("hospital_name", hospitalName)
//c.Set("chain_id", ChainID)
// 后续的处理函数可以用过c.Get("username")来获取当前请求的用户信息
// 埋点生产者
//BuriedProducer(c, hospitalCode, hospitalName, hospitalID)
c.Next()
}
}
// 埋点消费者
//func DataAnalysisChannel() {
//
// for {
// select {
// case c := <-DataAnalysisCh:
// buried_point.BuriedPointDistribution(c)
// default:
// //fmt.Println("当前没有处理的数据")
// time.Sleep(500 * time.Millisecond )
// }
// }
//}
//
//func BuriedProducer(c *gin.Context, hospitalCode, hospitalName, hospitalID string) {
//
// // 记录埋点
// var d models.DataAnalysisModel
// d.HospitalCode = hospitalCode
// d.HospitalName = hospitalName
// d.HospitalID = hospitalID
// d.RequestBody = c.Request.Body
// d.RequestTime = time.Now().Format("2006-01-02 15:04:05")
// d.RequestUrl = c.Request.RequestURI
// d.RequestPath = c.Request.URL.Path
// d.RequestShowType = base.QueryInt(c, "showType")
//
// //为防止对接口入侵达到最小 达到接口隔离效果 舍弃此方法 副本传递到下一方法
// //data, _ := c.GetRawData()
// //d.RequestData = data
// ////解决gin框架框架的数据不能重复用的问题(拿出来后放回去) 关键点
// //c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(data))
//
// // 埋点生产者
// DataAnalysisCh <- d
//}
package models
import (
"errors"
"github.com/astaxie/beego/validation"
"reflect"
)
type PlaceAnOrderParamInput struct {
PlatformType uint8 `json:"platform_type" description:"平台类型 1: saas 2: shop 3: shop mobile 4: 收银台"`
PlatformInfo string `json:"platform_info" description:"平台信息"`
GoodsDes string `json:"goods_des" description:"商品描述"`
GoodsDetail string `json:"goods_detail" description:"商品详情"`
AttachInfo string `json:"attach_info" description:"附加信息"`
GoodsPrice float64 `json:"goods_price" description:"商品金额,个位为分"`
NoticeURL string `json:"notice_url" description:"客户端回调的url"`
PayType int `json:"pay_type" description:"1: 微信,2: 支付宝, 3: 拉卡拉 4: 收钱吧"`
SourceCode uint8 `json:"source_code" description:"1: 微信 Native 2:微信小程序 3:微信内支付 4:h5 跳微信 5:支付宝(web)-扫码或登录支付宝账户 6:alipay(mobile) 7:alipay(app) 9: B2C 10:bk支付宝web 11:bk 支付宝手机"`
OpenID string `json:"open_id" description:"此参数 支付类型是 JS API 的时候 必传"`
WapURL string `json:"wap_url" description:"WAP网站URL地址, 支付方式为微信MWEB时 必传"`
WapName string `json:"wap_name" description:"WAP网站名称, 支付方式为微信MWEB时 必传"`
QuitURL string `json:"quit_url" description:"返回按钮 可用于用户付款中途退出并返回到该参数指定的商户网站地址, 支付方式为 支付宝手机网站时 必传(尽量传)"`
ReturnURL string `json:"return_url" description:"用户在完成支付后,会根据商户在请求支付API中传入的前台回跳地址return_url自动跳转return_url地址页面(必传)"`
AppID string `json:"app_id,omitempty" description:"wxAppId source code 2 小程序支付时必传、同时小程序支付必须关联了商户号支付"`
Operator string `json:"operator" description:"操作员"`
Customer string `json:"customer" description:"顾客信息"`
DynamicID string `json:"dynamic_id" description:"顾客手机条码的内容"`
StoreSn string `json:"store_sn" description:"商户门店编号"`
IsServe uint `json:"is_serve" description:"0直连模式 1服务商模式"`
OrderId string `json:"-" description:"订单号"`
SubMchid string `json:"sub_mchid" description:"通过进件接口申请的支付商户号、这是由微信生成并下发的"`
Nonce string `json:"-"`
ServeNoticeUrl string `json:"-" description:"传递给支付渠道的、而不是业务方的"`
}
func (this *PlaceAnOrderParamInput) ValidPlaceAnOrderParamInput() (err error) {
valid := validation.Validation{}
if b, _ := valid.Valid(this); !b {
//表示获取验证的结构体
st := reflect.TypeOf(PlaceAnOrderParamInput{})
for _, err := range valid.Errors {
//获取验证的字段名和提示信息的别名
filed, _ := st.FieldByName(err.Field)
var alias= filed.Tag.Get("alias")
//返回验证的错误信息
return errors.New(alias + err.Message)
}
}
return nil
}
type LakalaParamInput struct {
Version string `json:"version" description:"版本"`
ReqTime string `json:"req_time" description:"请求时间"`
ReqData LakalaParamData `json:"req_data"`
}
type LakalaParamData struct {
OutOrderNo string `json:"out_order_no" description:"商户订单号"`
MerchantNo string `json:"merchant_no" description:"银联商户号"`
TotalAmount float64 `json:"total_amount" description:"订单金额,单位:分"`
OrderEfficientTime string `json:"order_efficient_time" description:"订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天"`
NotifyUrl string `json:"notify_url" description:"订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com"`
CallbackUrl string `json:"callback_url" description:"客户端下单完成支付后返回的商户网页跳转地址"`
OrderInfo string `json:"order_info" description:"订单标题,在使用收银台扫码支付时必输入,交易时送往账户端"`
GoodsMark string `json:"goods_mark" description:"商品信息标识 (1:含商品信息,不填默认不含商品信息)"`
}
\ No newline at end of file
package mysql
-------医疗消费分析------------
-- 饼状图 默认值 1:商品销售 2:挂号 3:住院每日消费 4.住院门诊
-- 41:住院门诊化验 42:住院门诊影像 43:住院门诊处方 44:住院门诊手术
-- 45:住院门诊处置 5:住院商品销售 6:普通门诊 61:普通门诊化验
-- 62:普通门诊影像 63:普通门诊处方 64:普通门诊手术 65:普通门诊处置
-- 7:美容 8:寄养每日消费 9:寄养商品销售 10:疫苗 11:驱虫 12:订单结算商品销售',
SELECT
consumption.top_category_id,
con._name,
convert(ifnull(sum(consumption.quantity*consumption.payprice), 0) / 1000000, decimal(11,3))
FROM
his_consumption consumption
left JOIN his_bill bill ON consumption.his_bill_id = bill.id
LEFT JOIN con_category con ON consumption.top_category_id = con.id
WHERE
consumption.delflag = 0
AND consumption.sys_hospital_id IN ( 0, 1 )
AND bill.billtype IN (1,4,6,7)
and consumption.his_retreatbill_id = 0
and consumption.commodity_ismeal = 0
and consumption.meter_num = 0
AND consumption.top_category_id IN ( 1,2,3,4,5,6,7,8,9,10)
GROUP BY
consumption.top_category_id
-- 下方数据
SELECT
consumption.top_category_id as top_id ,
con._name as _name,
convert(ifnull(sum(consumption.quantity*consumption.payprice), 0) / 1000000, decimal(11,3)) AS money,
DATE_FORMAT(consumption.createtime,'%Y-%m-%d') AS _time
FROM
his_consumption consumption
left JOIN his_bill bill ON consumption.his_bill_id = bill.id
LEFT JOIN con_category con ON consumption.top_category_id = con.id
WHERE
consumption.delflag = 0
AND consumption.sys_hospital_id IN ( 0, 1 )
AND bill.billtype IN (1,4,6,7)
and consumption.his_retreatbill_id = 0
and consumption.commodity_ismeal = 0
and consumption.meter_num = 0
AND consumption.top_category_id IN ( 1,2,3,4,5,6,7,9,10)
AND DATE_FORMAT(consumption.createtime,'%Y-%m-%d') BETWEEN "2021-01-01" AND "2022-01-01"
GROUP BY
consumption.top_category_id,DATE_FORMAT(consumption.createtime,'%Y-%m-%d')
---- 商品分析
---商品数量以及分类数量
-- 商品库存总量
select
COUNT(quantity)
from
g_stock
where
delflag = 0
and sys_hospital_id = 1
-- 服务商品总量
--商品总种类
select
count( 0 ) as counts
FROM
(
SELECT
commodity.id
FROM
g_stock stock
LEFT JOIN con_commodity commodity ON stock.con_commodity_id = commodity.id
LEFT JOIN con_category category ON category.id = commodity.con_category_id
WHERE
stock.delflag = 0
AND stock.sys_hospital_id = 1
AND commodity.top_category_id IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12)
GROUP BY
commodity.id
) a
-- 普通商品
select
count( 0 ) as counts
FROM
(
SELECT
commodity.id
FROM
g_stock stock
LEFT JOIN con_commodity commodity ON stock.con_commodity_id = commodity.id
LEFT JOIN con_category category ON category.id = commodity.con_category_id
WHERE
stock.delflag = 0
AND stock.sys_hospital_id = 1
AND commodity.top_category_id IN ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
GROUP BY
commodity.id
) a
-- 商品其他种类 在in中填写 种类id
select
count( 0 ) as counts
FROM
(
SELECT
commodity.id
FROM
g_stock stock
LEFT JOIN con_commodity commodity ON stock.con_commodity_id = commodity.id
LEFT JOIN con_category category ON category.id = commodity.con_category_id
WHERE
stock.delflag = 0
AND stock.sys_hospital_id = 1
AND commodity.top_category_id IN ( 11)
GROUP BY
commodity.id
) a
--
select
count( 0 ) as counts
FROM
(
SELECT
commodity.id
FROM
g_stock stock
LEFT JOIN con_commodity commodity ON stock.con_commodity_id = commodity.id
LEFT JOIN con_category category ON category.id = commodity.con_category_id
WHERE
stock.delflag = 0
AND stock.sys_hospital_id = 1
AND commodity.top_category_id IN ( 12)
GROUP BY
commodity.id
) a
--商品警惕
SELECT
c.con_commodity_id,
c.commodity_name,
COUNT(0)
FROM
his_consumption AS c
LEFT JOIN his_bill AS b ON b.id = c.his_bill_id
LEFT JOIN g_stock AS g ON g.con_commodity_id = c.con_commodity_id
WHERE
c.delflag = 0
AND c.sys_hospital_id = 1
AND c.his_retreatbill_id = 0
AND c.commodity_ismeal = 0
AND c.meter_num = 0
AND b.billtype IN ( 1, 4, 6, 7 )
and DATE_FORMAT(b.paytime, "%Y-%m-%d") BETWEEN "2021-01-01" AND "2022-01-01"
GROUP BY
c.con_commodity_id
--商品销售分析
SELECT
c.con_commodity_id,
c.commodity_name,
c.top_category_id,
SUM(c.quantity) ,
CONVERT (
ifnull( sum( c.quantity * c.payprice ), 0 ) / 1000000,
DECIMAL ( 11, 3 )),
CONVERT (
ifnull( sum( c.quantity * g.costmoney ), 0 ) / 1000000,
DECIMAL ( 11, 3 ))
FROM
his_consumption AS c
LEFT JOIN his_bill AS b ON b.id = c.his_bill_id
LEFT JOIN g_stock AS g ON g.con_commodity_id = c.con_commodity_id
WHERE
c.delflag = 0
AND c.sys_hospital_id = 1
AND c.his_retreatbill_id = 0
AND c.commodity_ismeal = 0
AND c.meter_num = 0
AND b.billtype IN ( 1, 4, 6, 7 )
GROUP BY
c.con_commodity_id
---员工分析
-- 首先查出所有的已结订单
--B端小程序
--- 数据概览
-- 新增用户
select count(*) from his_consumer where delflag = 0 and DATE_FORMAT(addtime, ?) = ?
--新增会员(新增会员卡与次卡去重后就是新增会员)
-- 新增的会员卡用户
SELECT
c.id
FROM
his_consumer c
INNER JOIN his_card card ON c.id = card.his_consumer_id
AND c.id not IN (select his_consumer_id FROM his_card WHERE delflag = 0 AND sys_hospital_id = 1 AND createtime < "2021-01-01")
AND c.id not IN (select his_consumer_id FROM his_metercard WHERE delflag = 0 AND sys_hospital_id = 1 AND createtime < "2021-01-01")
-- 新增的次卡用户
SELECT
c.id
FROM
his_consumer c
INNER JOIN his_metercard card ON c.id = card.his_consumer_id
AND c.id not IN (select his_consumer_id FROM his_card WHERE delflag = 0 AND sys_hospital_id = 1 AND createtime < "2021-01-01")
AND c.id not IN (select his_consumer_id FROM his_metercard WHERE delflag = 0 AND sys_hospital_id = 1 AND createtime < "2021-01-01")
--- 新客消费 老客消费 到店消费
-- 新客
SELECT
his_consumer_id,
SUM( paymoney / 1000 ) price
FROM
his_bill
WHERE
delflag = 0
AND his_consumer_id > 0
AND billtype != 5
AND billtype != 7
AND sys_hospital_id = 1
AND DATE_FORMAT( paytime, '%Y-%m-%d' ) = "2021-04-06"
AND his_consumer_id NOT IN (
SELECT
his_consumer_id
FROM
his_bill
WHERE
delflag = 0
AND his_consumer_id > 0
AND billtype != 5
AND billtype != 7
AND sys_hospital_id = 1
AND DATE_FORMAT( paytime, '%Y-%m-%d' ) < "2021-04-06"
GROUP BY
his_consumer_id
)
GROUP BY
DATE_FORMAT( paytime, '%Y-%m-%d' ),
his_consumer_id
-- 老客
SELECT
his_consumer_id,
SUM( paymoney / 1000 ) price
FROM
his_bill
WHERE
delflag = 0
AND his_consumer_id > 0
AND billtype != 5
AND billtype != 7
AND sys_hospital_id = 1
AND date_format( paytime, '%Y-%m-%d' ) = "2021-04-06"
AND his_consumer_id IN (
SELECT
his_consumer_id
FROM
his_bill
WHERE
delflag = 0
AND his_consumer_id > 0
AND billtype != 5
AND billtype != 7
AND sys_hospital_id = 1
AND DATE_FORMAT( paytime, '%Y-%m-%d' ) < "2021-04-06"
GROUP BY
his_consumer_id
)
GROUP BY
DATE_FORMAT( paytime, '%Y-%m-%d' ),
his_consumer_id
-- 到店 为 新客加老客
-- 次卡分析
-- 次卡分析按时间与次卡id
-- 次卡充值的可以使用的次数SUM( meter ),与新开次卡张数 COUNT( 0 )
SELECT
DATE_FORMAT( card.createtime, '%Y-%m-%d' ) ,
card.con_metercardtype_id,
type._name,
ifnull( SUM( meter ), 0 ),
COUNT( 0 )
FROM
dbc_hueqzfp2kn.his_metercard card
LEFT JOIN dbc_hueqzfp2kn.con_metercardtype type ON type.id = card.con_metercardtype_id
WHERE
card.delflag = 0
AND card.sys_hospital_id = 1
AND DATE_FORMAT( card.createtime, '%Y-%m-%d' ) BETWEEN "2021-01-01"
AND "2022-01-01"
AND card.con_metercardtype_id = 3
GROUP BY
DATE_FORMAT( card.createtime, '%Y-%m-%d' )
-- 次卡分析之详细数据
SELECT
DATE_FORMAT( meter_detail.eventtime, '%Y-%m-%d' ),
SUM( CONVERT ( ifnull( meter_detail.money, 0 ), DECIMAL ( 11, 3 )) ) / 1000 AS money,
meter_type.id
FROM
dbc_hueqzfp2kn.his_metercard_detail AS meter_detail
LEFT JOIN dbc_hueqzfp2kn.his_metercard AS meter ON meter_detail.his_metercard_id = meter.id
LEFT JOIN dbc_hueqzfp2kn.con_metercardtype AS meter_type ON meter.con_metercardtype_id = meter_type.id
WHERE
meter_detail.sys_hospital_id = 1
AND meter_detail.eventtype = 2
AND meter_detail.delflag = 0
AND DATE_FORMAT( meter_detail.eventtime, '%Y-%m-%d' ) BETWEEN "2021-01-01"
AND "2022-01-01"
AND meter_type.id = 2
GROUP BY
DATE_FORMAT( meter_detail.eventtime, '%Y-%m-%d' )
-- 数据概览
-- 开卡 充值 排行
-- 会员卡
SELECT
card_type._name,
ifnull(SUM(card_pay.money) / 1000,0)
FROM
his_card card
LEFT JOIN con_cardtype card_type ON card_type.id = card.con_cardtype_id
LEFT JOIN his_card_detail card_detail ON. card_detail.his_card_id = card.id
left JOIN his_card_detail_pay card_pay ON card_pay.his_card_detail_id = card_detail.id
AND card.sys_hospital_id = 1
GROUP BY card.con_cardtype_id
-- 次卡
SELECT
card_type._name,
ifnull(SUM(card_pay.money),0) / 1000
FROM
his_metercard card
LEFT JOIN con_metercardtype card_type ON card_type.id = card.con_metercardtype_id
LEFT JOIN his_metercard_detail card_detail ON. card_detail.his_metercard_id = card.id
left JOIN his_metercard_detail_pay card_pay ON card_pay.his_metercard_detail_id = card_detail.id
AND card.sys_hospital_id = 1
GROUP BY card.con_metercardtype_id
-- 押金
SELECT
SUM(p.money) / 1000
FROM
his_deposit_detail d
LEFT JOIN his_deposit_detail_pay p ON d.id = p.his_deposit_detail_id
WHERE
d.sys_hospital_id = 1
-- 新客户初诊
SELECT
COUNT(0)
FROM
(SELECT
id,
DATE_FORMAT( eventtime, '%Y-%m-%d' ) AS _time
FROM
his_clinic
WHERE
delflag = 0
AND sys_hospital_id = 1
AND DATE_FORMAT( eventtime, '%Y-%m-%d' ) BETWEEN "2021-09-01"
AND "2021-10-10"
AND group_id = 0
AND his_consumer_id NOT IN (
SELECT
his_consumer_id
FROM
his_clinic
WHERE
delflag = 0
AND sys_hospital_id = 1
AND DATE_FORMAT( eventtime, '%Y-%m-%d' ) < "2021-09-10"
)
GROUP BY his_consumer_id) as a
package mysql
import (
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"system_pay/setting"
)
var (
shopDB *sqlx.DB
//db *sqlx.DB
// 0 ~ h
//userDB *sqlx.DB
// i ~ z
//secondDB *sqlx.DB
// PayDB 支付
//payDB *sqlx.DB
err error
)
// NewShopConn is 连接谛宝多多库
func NewShopConn() (*sqlx.DB, error) {
if shopDB == nil {
shopDB, err = sqlx.Connect("mysql", setting.Conf.DatabaseSetting.ShopDB)
return shopDB, err
}
//shopDB.SetMaxOpenConns(setting.Conf.DatabaseSetting.MaxOpenConns)
return shopDB, err
}
// ShopDBClose 关闭MySQL连接
func ShopDBClose() {
_ = shopDB.Close()
}
// NewAccountConn is 连接医院用户库
//func NewAccountConn() (*sqlx.DB, error) {
// if db == nil {
// db, err = sqlx.Connect("mysql", setting.Conf.DatabaseSetting.AccountDB)
// return db, err
// }
// //db.SetMaxOpenConns(setting.Conf.DatabaseSetting.MaxOpenConns)
// return db, err
//}
// NewUserConn 连接用户存放数据的库
//func NewUserConn(chainCode string) (*sqlx.DB, error) {
//
// chainCode = strings.ToLower(chainCode)
// if len(chainCode[:1]) != 1 {
// return nil, err
// }
// word := chainCode[:1]
// if word > "h" {
// if secondDB == nil {
// secondDB, err = sqlx.Connect("mysql", setting.Conf.DatabaseSetting.SecondDB)
// return secondDB, err
// }
// //secondDB.SetMaxOpenConns(setting.Conf.DatabaseSetting.MaxOpenConns)
// return secondDB, err
// }
//
// if userDB == nil {
// userDB, err = sqlx.Connect("mysql", setting.Conf.DatabaseSetting.UserDB)
// return userDB, err
// }
// //userDB.SetMaxOpenConns(setting.Conf.DatabaseSetting.MaxOpenConns)
// return userDB, err
//}
// NewPayConn 支付
//func NewPayConn() (*sqlx.DB, error) {
// if payDB == nil {
// payDB, err = sqlx.Connect("mysql", setting.Conf.DatabaseSetting.PayDB)
// return payDB, err
// }
// //payDB.SetMaxOpenConns(setting.Conf.DatabaseSetting.MaxOpenConns)
// return payDB, err
//}
// Close 关闭MySQL连接
//func Close() {
// _ = db.Close()
//}
// PayDBClose 关闭MySQL连接
//func PayDBClose() {
// _ = payDB.Close()
//}
\ No newline at end of file
package logging
import (
"fmt"
"system_pay/setting"
"time"
)
// getLogFilePath 获取日志文件保存路径
func getLogFilePath() string {
return fmt.Sprintf("%s" , setting.Conf.LogSetting.LogSavePath)
}
// getLogFileName 获取日志文件的保存名称
func getLogFileName() string {
return fmt.Sprintf("%s%s.%s",
setting.Conf.LogSetting.LogSaveName,
time.Now().Format(setting.Conf.AppSetting.TimeFormat),
setting.Conf.LogSetting.LogFileExt,
)
}
package logging
import (
"github.com/gin-gonic/gin"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"os"
"system_pay/setting"
)
var (
// DBCNormalLogger log
DBCNormalLogger *zap.Logger
)
// Init 初始化log
func Init(cfg *setting.Log) (err error) {
fileName := getLogFileName()
filePath := getLogFilePath()
writeSyncer := getLogWriter(filePath+fileName, cfg.MaxSize, cfg.MaxBackups, cfg.MaxAge)
encoder := getEncoder()
var l = new(zapcore.Level)
err = l.UnmarshalText([]byte(cfg.Level))
if err != nil {
return
}
var core zapcore.Core
if gin.Mode() == gin.DebugMode {
// 进入开发模式,日志输出到终端
consoleEncoder := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
core = zapcore.NewTee(
zapcore.NewCore(encoder, writeSyncer, l),
zapcore.NewCore(consoleEncoder, zapcore.Lock(os.Stdout), zapcore.DebugLevel),
)
} else {
core = zapcore.NewCore(encoder, writeSyncer, l)
}
DBCNormalLogger = zap.New(core, zap.AddCaller())
zap.ReplaceGlobals(DBCNormalLogger)
zap.L().Info("init logger success")
return
}
func getEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.TimeKey = "time"
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
encoderConfig.EncodeDuration = zapcore.SecondsDurationEncoder
encoderConfig.EncodeCaller = zapcore.ShortCallerEncoder
return zapcore.NewJSONEncoder(encoderConfig)
}
func getLogWriter(filename string, maxSize, maxBackup, maxAge int) zapcore.WriteSyncer {
lumberJackLogger := &lumberjack.Logger{
Filename: filename,
MaxSize: maxSize,
MaxBackups: maxBackup,
MaxAge: maxAge,
}
return zapcore.AddSync(lumberJackLogger)
}
//// GinLogger 接收gin框架默认的日志
//func GinLogger() gin.HandlerFunc {
// return func(c *gin.Context) {
// start := time.Now()
// path := c.Request.URL.Path
// query := c.Request.URL.RawQuery
// c.Next()
//
// cost := time.Since(start)
// DBCNormalLogger.Info(path,
// zap.Int("status", c.Writer.Status()),
// zap.String("method", c.Request.Method),
// zap.String("path", path),
// zap.String("query", query),
// zap.String("ip", c.ClientIP()),
// zap.String("user-agent", c.Request.UserAgent()),
// zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),
// zap.Duration("cost", cost),
// )
// }
//}
//
//// GinRecovery recover掉项目可能出现的panic,并使用zap记录相关日志
//func GinRecovery(stack bool) gin.HandlerFunc {
// return func(c *gin.Context) {
// defer func() {
// if err := recover(); err != nil {
// // Check for a broken connection, as it is not really a
// // condition that warrants a panic stack trace.
// var brokenPipe bool
// if ne, ok := err.(*net.OpError); ok {
// if se, ok := ne.Err.(*os.SyscallError); ok {
// if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
// brokenPipe = true
// }
// }
// }
//
// httpRequest, _ := httputil.DumpRequest(c.Request, false)
// if brokenPipe {
// DBCNormalLogger.Error(c.Request.URL.Path,
// zap.Any("error", err),
// zap.String("request", string(httpRequest)),
// )
// // If the connection is dead, we can't write a status to it.
// c.Error(err.(error)) // nolint: errcheck
// c.Abort()
// return
// }
//
// if stack {
// DBCNormalLogger.Error("[Recovery from panic]",
// zap.Any("error", err),
// zap.String("request", string(httpRequest)),
// zap.String("stack", string(debug.Stack())),
// )
// } else {
// DBCNormalLogger.Error("[Recovery from panic]",
// zap.Any("error", err),
// zap.String("request", string(httpRequest)),
// )
// }
// c.AbortWithStatus(http.StatusInternalServerError)
// }
// }()
// c.Next()
// }
//}
package sms
//func TestSendSmsChina(t *testing.T) {
//
// var tModel Send
//
// tModel.AreaCode = "86"
// tModel.Phone = "17538147716"
// tModel.Content = "【谛宝医生】验证码:433212,三分钟内有效"
// tModel.Source = 2
// tModel.SourceName = "谛语智慧"
//
// b, _ := json.Marshal(tModel)
//
// sign, _ := AesEncrypt(b, []byte("dbc2021888000000"))
//
// t.Log("sign: ", sign)
//
// client := &http.Client{}
// req, err := http.NewRequest("POST", "https://tsms.pet-dbc.cn/v1/send", bytes.NewReader(b))
// if err != nil {
// panic(err)
// }
//
// req.Header.Set("Content-Type", "application/json")
// req.Header.Set("sign", sign)
//
// resp, err := client.Do(req)
// if err != nil {
// panic(err)
// }
//
// defer resp.Body.Close()
// body, err := ioutil.ReadAll(resp.Body)
// if err != nil {
// panic(err)
// }
//
// fmt.Println("body: ", string(body))
//}
//
//func TestSendSmsOtherRegion(t *testing.T) {
//
// var tModel Send
//
// tModel.AreaCode = "60"
// // 手机号在刚哥那里
// tModel.Phone = "1139427345"
// tModel.Content = "【DBC】Verification code: 229900, Valid within three minutes"
//
// b, _ := json.Marshal(tModel)
//
// sign, _ := AesEncrypt(b, []byte("dbc2021888000000"))
//
// t.Log("sign: ", sign)
//
// client := &http.Client{}
// req, err := http.NewRequest("POST", "https://tsms.pet-dbc.cn/v1/send", bytes.NewReader(b))
// if err != nil {
// panic(err)
// }
//
// req.Header.Set("Content-Type", "application/json")
// req.Header.Set("sign", sign)
//
// resp, err := client.Do(req)
// if err != nil {
// panic(err)
// }
//
// defer resp.Body.Close()
// body, err := ioutil.ReadAll(resp.Body)
// if err != nil {
// panic(err)
// }
//
// fmt.Println("body: ", string(body))
//}
package sms
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"strings"
)
//Aes 对称加密
func AesEncrypt(origData, key []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
blockSize := block.BlockSize()
origData = PKCS7Padding(origData, blockSize)
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
result := base64.StdEncoding.EncodeToString(crypted)
return result, nil
}
//Aes 对称解密
func AesDecrypt(crypted, key []byte) (string, error) {
ciphertext := strings.Replace(string(crypted), " ", "", -1)
cryptedOri, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
origData := make([]byte, len(cryptedOri))
blockMode.CryptBlocks(origData, cryptedOri)
origData = PKCS7UnPadding(origData)
return string(origData), nil
}
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
package sms
type Send struct {
Phone string `json:"phone" description:"手机号"`
Content string `json:"content" description:"发送的内容、注意需要携带短信签名 【】"`
AreaCode string `json:"area_code" description:"区号"`
Source int `json:"source" description:"来源 1:谛宝多多 2:谛宝医生 3:收银台 4:谛宠有品 5:CRM 6:谛赋"`
SourceName string `json:"source_name" description:"业务子系统名称 业务系统自定义"`
}
\ No newline at end of file
version: '3.5'
services:
system_pay:
restart: always
build:
context: .
args:
ENVARG: prod
dockerfile: PROD.Dockerfile
image: system_pay:prod
ports:
- 19880:19880
environment:
runmode: prod
networks:
- system_pay_network
networks:
system_pay_network:
driver: bridge
#!/bin/bash
git pull
export runmode=prod
docker-compose -f prod-docker-compose.yaml up --build -d
docker image prune -f
\ No newline at end of file
package redis
import (
"fmt"
"github.com/go-redis/redis"
"system_pay/setting"
)
var (
Redisclient *redis.Client
Nil = redis.Nil
)
// Init 初始化连接
func Init(cfg *setting.RedisConfig) (err error) {
Redisclient = redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
Password: cfg.Password, // no password set
DB: cfg.DB, // use default DB
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
})
_, err = Redisclient.Ping().Result()
if err != nil {
return err
}
return err
}
func Close() {
_ = Redisclient.Close()
}
package repository
import (
"strings"
)
////QueryChainCodeAndLocalIDByPhone 查询用户信息
//func QueryChainCodeAndLocalIDByPhone(phone string) (string, int, error) {
//
// db, err := mysql.NewAccountConn()
// if err != nil {
// return "", 0, err
// }
// // 查询医院是否存在
// var chainCode string
// var employeeLocalID int
// err = db.QueryRow(`select default_chain_code, employee_local_id from hos_database.employee_wx
// where employee_phone = ?`, phone).Scan(&chainCode, &employeeLocalID)
// switch {
// case err == sql.ErrNoRows:
// return "", 0, errors.New("没有这个用户")
// case err != nil:
// return "", 0, err
// }
//
// return chainCode, employeeLocalID, nil
//}
//
//// 根据医院code 获取云端id
//func GetHospitalIdByCode(hospitalCode string) (string, error) {
//
// db, err := mysql.NewAccountConn()
// if err != nil {
// return "", err
// }
//
// var hospitalId string
//
// err = db.QueryRow("select id from hospital_main where hospital_code = ?", hospitalCode).Scan(&hospitalId)
// if err != nil {
// return "", err
// }
//
// return hospitalId, nil
//}
//
//// QueryChainCodeByPhone 查询用户使用的是哪个医院的数据
//func QueryChainCodeByPhone(phone string) (chain string, err error) {
//
// db, err := mysql.NewAccountConn()
// if err != nil {
// return "", err
// }
//
// // 查询医院是否存在
// var chainCode string
// err = db.QueryRow(`select default_chain_code from employee_wx
// where employee_phone = ?`, phone).Scan(&chainCode)
// if err != nil {
// return "", err
// }
//
// if chainCode == "" {
// return "", errors.New("查不到这个用户")
// }
//
// return chainCode, nil
//}
//
//// QueryChainCode 查询chain_code
//func QueryChainCode(phone string) (string, error) {
//
// db, err := mysql.NewAccountConn()
// if err != nil {
// return "", err
// }
//
// var code string
//
// err = db.QueryRow(`select c.chain_code from hospital_main as h
// LEFT JOIN chain_main as c on h.chain_id = c.id
// where c.delflag = 0 AND h.delflag = 0 AND h.create_phone = ?`, phone).Scan(&code)
//
// if err != nil {
// return "", err
// }
//
// return code, nil
//}
//
//// QueryChainID 查询chain_ID
//func QueryChainID(phone string) (int, error) {
//
// db, err := mysql.NewAccountConn()
// if err != nil {
// return 0, err
// }
//
// var id int
//
// err = db.QueryRow(`select c.id from hospital_main as h
// LEFT JOIN chain_main as c on h.chain_id = c.id
// where c.delflag = 0 AND h.delflag = 0 AND h.create_phone = ?`, phone).Scan(&id)
//
// if err != nil {
// return 0, err
// }
//
// return id, nil
//}
//
//// QueryHospitalCode 查询医院码
//func QueryHospitalCode(phone string) (string, error) {
//
// db, err := mysql.NewAccountConn()
// if err != nil {
// return "", err
// }
//
// var code string
//
// err = db.QueryRow(`select hospital_code from hospital_main where delflag = 0 and create_phone = ?`, phone).Scan(&code)
//
// if err != nil {
// return "", err
// }
//
// return code, nil
//}
//
//// CheckHospitalPhone 检查手机号码是否有效
//func CheckHospitalPhone(phone string) (bool, error) {
//
// db, err := mysql.NewAccountConn()
// if err != nil {
// return false, err
// }
//
// var (
// code int
// authorizeState int
// storageMethod int
// chainID int64
// )
// // 查询是否注册过
// err = db.QueryRow(`select count(*) from hospital_main where create_phone = ?`, phone).Scan(&code)
// if err != nil {
// return false, err
// }
//
// //chain_id
// err = db.QueryRow(`select chain_id from hospital_main where create_phone = ?`, phone).Scan(&chainID)
// if err != nil {
// return false, err
// }
//
// // 查询是否授权
// err = db.QueryRow(`SELECT IFNULL(b.authorize_state ,0) FROM hospital_main AS a left join hospital_operate AS b
// ON a.id = b.hospital_main_id WHERE a.create_phone = ? `, phone).Scan(&authorizeState)
// if err != nil {
// return false, err
// }
//
// // 查询是否授权
// err = db.QueryRow(`SELECT store_type FROM chain_config where chain_main_id = ? `, chainID).Scan(&storageMethod)
// if err != nil {
// return false, err
// }
//
// if authorizeState == 1 && code > 0 && storageMethod == 0 {
// return true, nil
// }
//
// return false, err
//}
// PackingDatabaseName 包装数据库名称
func PackingDatabaseName(tableName, code string) string {
return "dbc_" + strings.ToLower(code) + "." + tableName
}
// QueryHospitalID 查询医院码
//func QueryHospitalID(chainCode, hospitalCode string) (int, string, error) {
//
// db, err := mysql.NewUserConn(chainCode)
// if err != nil {
// return 0, "", err
// }
//
// tableName := PackingDatabaseName("sys_hospital", chainCode)
//
// querySQL := fmt.Sprintf(`select id,_name from %s
// where delflag = 0 and hospital_code = ?`, tableName)
//
// var (
// id int
// name string
// )
//
// err = db.QueryRow(querySQL, hospitalCode).Scan(&id, &name)
// if err != nil {
// zap.L().Error("err", zap.Error(err))
// return 0, "", err
// }
// return id, name, err
//}
//GetTheCostOfGoods 获取商品成本
//func GetTheCostOfGoods(chainCode, hospitalID string, db *sqlx.DB) ([]models.CommodityCost, error) {
//
// commodityCosts := make([]models.CommodityCost, 0)
//
// getTheCostOfGoodsSQL := fmt.Sprintf(`select con_commodity_id,costmoney from g_stock
// where delflag = 0 and sys_hospital_id = %d`, hospitalID)
//
// rows, err := db.Query(getTheCostOfGoodsSQL)
// if err != nil {
// zap.L().Error("err", zap.Error(err))
// return nil, err
// }
//
// for rows.Next() {
// var t models.CommodityCost
// err = rows.Scan(&t.CommodityID, t.CommodityCostPrice)
// if err != nil {
// zap.L().Error("err", zap.Error(err))
// return nil, err
// }
// commodityCosts = append(commodityCosts, t)
// }
//
// return commodityCosts, err
//
//}
package pay
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"github.com/astaxie/beego/httplib"
"strings"
"system_pay/models"
)
// 拉卡拉支付
func UnifiedOrder(input *models.PlaceAnOrderParamInput) (interface{}, error) {
//if input.ChainCode=="" || input.HospitalCode=="" || input.VendorId=="" || seller_id=="" {
// return nil, errors.New("输入项为空")
//}
//db, err := mysql.NewShopConn()
//if err != nil {
// return nil, err
//}
//rtn := make(map[string]string)
data := make(map[string]interface{})
data["req_time"] = "20220714160009"
data["version"] = "3.0"
data["out_org_code"] = "OP00000003"
//"out_order_no": "KFPT20220714160009228907288",
// "merchant_no": "8222900701106PZ",
// "vpos_id": "587305941625155584",
// "channel_id": "2021052614391",
// "total_amount": "1",
// "busi_mode": "PAY",
// "order_efficient_time": "20220714170009",
// "notify_url": "http://run.mocky.io/v3/b02c9448-20a2-4ff6-a678-38ecab30161d",
// "support_cancel": "0",
// "support_refund": "1",
// "support_repeat_pay": "1",
// "busi_type_param": "[{\"busi_type\":\"UPCARD\",\"params\":{\"crd_flg\":\"CRDFLG_D|CRDFLG_C|CRDFLG_OTH\"}},{\"busi_type\":\"SCPAY\",\"params\":{\"pay_mode\":\"WECHAT\",\"crd_flg\":\"CRDFLG_D\"}}]",
// "counter_param": "{\"pay_mode\":\"ALIPAY\"}",
// "out_user_id": "",
// "order_info": "自动化测试",
// "extend_info": "自动化测试",
// "callback_url": ""
data2 := make(map[string]interface{})
data2["out_trade_no"] = "FD660E1FAA3A4470933CDEDAE1EC1DEE"
data2["merchant_no"] = "822290070111135"
data2["term_no"] = "29034705"
data2["auth_code"] = "135178236713755038"
data2["total_amount"] = "0.01"
data2["out_order_no"] = "08F4542EEC6A4497BC419161747A92EE"
data2["order_efficient_time"] = "20230620130000" //订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
data2["notify_url"] = input.NoticeURL //订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
data2["callback_url"] = input.ReturnURL //客户端下单完成支付后返回的商户网页跳转地址
data2["order_info"] = "必康测试订单标题" //订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
//data2["goods_mark"] = input.AttachInfo //商品信息标识 (1:含商品信息,不填默认不含商品信息)
data["req_data"] = make(map[string]interface{})
data["req_data"] = data2
//data3 := make(map[string]interface{})
//data3["request_ip"] = "10.176.1.192"
//data3["location"] = "+37.123456789,-121.123456789"
//data2["location_info"] = make(map[string]inteace{})
//data2["location_info"] = data3
//data2["out_order_no"] = input.AttachInfo //商户订单号
//data2["total_amount"] = input.AttachInfo //订单金额,单位:分
//data2["order_efficient_time"] = input.AttachInfo //订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
//
//data2["notify_url"] = input.AttachInfo //订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
//data2["callback_url"] = input.AttachInfo //商户订单号
//data2["order_info"] = input.AttachInfo //订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
//data2["goods_mark"] = input.AttachInfo //商品信息标识 (1:含商品信息,不填默认不含商品信息)
//var data model.LakalaParamInput
//data.Version = "3.0"
//data.ReqTime = "20220714160009"
//
//data.ReqData.OutOrderNo = input.AttachInfo //商户订单号
////data.ReqData.MerchantNo = //银联商户号
//data.ReqData.TotalAmount = input.GoodsPrice //订单金额,单位:分
////data.ReqData.OrderEfficientTime = //订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
//
//data.ReqData.NotifyUrl = input.NoticeURL //订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
//data.ReqData.CallbackUrl = input.ReturnURL //客户端下单完成支付后返回的商户网页跳转地址
////data.ReqData.OrderInfo = input.OrderId //订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
//data.ReqData.GoodsMark = input.GoodsDes //商品信息标识 (1:含商品信息,不填默认不含商品信息)
//数据重组 - end
////var data = input.ReqData
//fmt.Println(111)
fmt.Println("拉卡拉输入参数")
fmt.Println(data)
data_json, err := json.Marshal(data)
if err != nil {
//this.Data["json"] = utils.CheckError(errors.New("Map转化为byte数组失败"),"异常")
//this.ServeJSON()
return nil, err
}
//url := "https://test.wsmsd.cn/sit/api/v3/labs/trans/preorder" //聚合主扫url
//url := "https://test.wsmsd.cn/sit/api/v3/labs/trans/micropay" //聚合被扫url
url := "https://test.wsmsd.cn/sit/api/v3/ccss/counter/order/create" //拉卡拉收银台订单创建url
//调拉卡拉接口
err, m_web_url := lakala_post(url, data_json)
if err != nil {
//this.Data["json"] = utils.CheckError(err,"拉卡拉错误")
//this.ServeJSON()
return nil, err
}
response := make(map[string]string)
response["m_web_url"] = m_web_url
//this.Data["json"] = utils.SuccessLakala(response)
//this.ServeJSON()
//rtn["token"] = token
//rtn["user_id"] = seller_id
//rtn["user_name"] = seller_name
return response, nil
//1.校验供应商账号(手机号)是否已注册
//err = db.QueryRow(`SELECT user_name, phone_mob, available, steps
// FROM ecm_member WHERE user_type=2 AND user_id=? LIMIT 1`,
// seller_id).Scan(&seller_name, &phone_mob, &available, &steps)
//if err != nil && err != sql.ErrNoRows {
// return nil, err
//}
//2.获取医院Id
//var buyer_id string
//err = db.QueryRow(`SELECT user_id FROM ecm_member WHERE user_type=1 AND chain_code=? AND hospital_code=? LIMIT 1`,
// input.ChainCode, input.HospitalCode).Scan(&buyer_id)
//if err != nil && err != sql.ErrNoRows {
// return nil, err
//}
//if (buyer_id=="") {
// return nil, errors.New("未绑定,请先绑定谛宝医院")
//}
//
////3.谛宝医生与供应商已绑定校验
//var seller_id2 string
//err = db.QueryRow(`SELECT mc.seller_id FROM ecm_member_cross mc
// LEFT JOIN ecm_member m ON mc.seller_id=m.user_id WHERE buyer_id=? AND vendor_id=?`,
// buyer_id, input.VendorId).Scan(&seller_id2)
//if err != nil && err != sql.ErrNoRows {
// return "", err
//}
//
////3.1已绑定其它账号
//if seller_id2!="" && seller_id2!=seller_id {
// return nil, errors.New("已绑定其它账号,请勿重复绑定")
//}
//
////3.2已绑定,返回token,完成登录
//if seller_id2==seller_id {
// //token, err := utils.GetToken(phone_mob, seller_id, seller_name)
// //if err != nil {
// // return "", err
// //}
// //
// //rtn["token"] = token
// //rtn["user_id"] = seller_id
// ////rtn["user_name"] = seller_name
// return nil, nil
// //return nil, errors.New("已绑定该账号,请勿重复绑定")
//}
////fmt.Println(buyer_id)
////fmt.Println(seller_id)
////fmt.Println(input.VendorId)
//
//var vendor_id string
//err = db.QueryRow(`SELECT vendor_id FROM ecm_member_cross mc
// LEFT JOIN ecm_member m ON mc.seller_id=m.user_id WHERE buyer_id=? AND seller_id=?`,
// buyer_id, seller_id).Scan(&vendor_id)
//if err != nil && err != sql.ErrNoRows {
// return "", err
//}
//
//if vendor_id!="" && vendor_id!=input.VendorId {
// //3.3更新绑定
// //sql := "UPDATE ecm_member_cross SET " +
// // "vendor_id='" + input.VendorId + "' " +
// // "WHERE buyer_id=? AND seller_id=?"
// //_, err = db.Exec(sql, buyer_id, seller_id)
// //if err != nil {
// // return nil, err
// //}
// return nil, errors.New("已绑定其它账号,请勿重复绑定")
//}
//
////3.4添加绑定
//exec, err := db.Exec(`INSERT INTO ecm_member_cross (buyer_id, seller_id, vendor_id) VALUES (?,?,?)`,
// buyer_id, seller_id, input.VendorId)
//_, err = exec, err
//if err != nil {
// return nil, err
//}
//3.4绑定完成,返回token,完成登录
//token, err := utils.GetToken(phone_mob, seller_id, seller_name)
//if err != nil {
// return "", err
//}
//rtn["token"] = token
//rtn["user_id"] = seller_id
//rtn["user_name"] = seller_name
//return nil, nil
}
// @Title
// @Description 拉卡拉统一支付
// @Param data body model.PlaceAnOrderParamInput true "输入项"
// @Success 200
// @router /unified_order [post]
//func (this *PayController)UnifiedOrder() {
//
// //Params
// var input model.PlaceAnOrderParamInput
// if err := json.Unmarshal(this.Ctx.Input.RequestBody, &input); err != nil {
// this.Data["json"] = utils.CheckError(err, "")
// this.ServeJSON()
// return
// //this.Data["json"] = utils.CheckError(errors.New(languages.ParamsError), languages.SystemError)
// //this.ServeJSON()
// //return
// }
//
// //validate
// if err := input.ValidPlaceAnOrderParamInput(); err != nil {
// this.Data["json"] = utils.CheckError(err,"")
// this.ServeJSON()
// return
// }
//
// if input.PayType==1 {
//
// }
//
// data := make(map[string]interface{})
// data["req_time"] = "20220714160009"
// data["version"] = "3.0"
// data["out_org_code"] = "OP00000003"
//
// data2 := make(map[string]interface{})
// data2["merchant_no"] = "822290070111135"
// data2["term_no"] = "29034705"
// //data2["out_trade_no"] = "FD660E1FAA3A4470933CDEDAE1EC1D8E"
// data2["out_trade_no"] = "FD660E1FAA3A4470933CDEDAE1EC1D8E"
// data2["auth_code"] = "135178236713755038"
// data2["total_amount"] = "123"
// //data2["out_order_no"] = "08F4542EEC6A4497BC419161747A92FA"
// data2["out_order_no"] = "08F4542EEC6A4497BC419161747A92FA"
// data["req_data"] = make(map[string]interface{})
// data["req_data"] = data2
//
// data3 := make(map[string]interface{})
// data3["request_ip"] = "10.176.1.192"
// data3["location"] = "+37.123456789,-121.123456789"
// data2["location_info"] = make(map[string]interface{})
// data2["location_info"] = data3
//
// //data2["out_order_no"] = input.AttachInfo //商户订单号
// //data2["total_amount"] = input.AttachInfo //订单金额,单位:分
// //data2["order_efficient_time"] = input.AttachInfo //订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
//
// //data2["notify_url"] = input.AttachInfo //订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
// //data2["callback_url"] = input.AttachInfo //商户订单号
// //data2["order_info"] = input.AttachInfo //订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
// //data2["goods_mark"] = input.AttachInfo //商品信息标识 (1:含商品信息,不填默认不含商品信息)
//
// //var data model.LakalaParamInput
// //data.Version = "3.0"
// //data.ReqTime = "20220714160009"
//
// //data.ReqData.OutOrderNo = input.AttachInfo //商户订单号
// ////data.ReqData.MerchantNo = //银联商户号
// //data.ReqData.TotalAmount = input.GoodsPrice //订单金额,单位:分
// ////data.ReqData.OrderEfficientTime = //订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
//
// //data.ReqData.NotifyUrl = input.NoticeURL //订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
// //data.ReqData.CallbackUrl = input.ReturnURL //客户端下单完成支付后返回的商户网页跳转地址
// ////data.ReqData.OrderInfo = input.OrderId //订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
// //data.ReqData.GoodsMark = input.GoodsDes //商品信息标识 (1:含商品信息,不填默认不含商品信息)
// //数据重组 - end
//
// ////var data = input.ReqData
// //fmt.Println(111)
// //fmt.Println(data)
//
// data_json, err := json.Marshal(data)
// if err != nil {
// this.Data["json"] = utils.CheckError(errors.New("Map转化为byte数组失败"),"异常")
// this.ServeJSON()
// return
// }
//
// //url := "https://test.wsmsd.cn/sit/api/v3/labs/trans/preorder" //聚合主扫url
// //url := "https://test.wsmsd.cn/sit/api/v3/labs/trans/micropay" //聚合被扫url
// url := "https://test.wsmsd.cn/sit/api/v3/ccss/counter/order/create" //拉卡拉收银台订单创建url
//
// //调拉卡拉接口
// err = lakala_post(url, data_json)
// if err != nil {
// this.Data["json"] = utils.CheckError(err,"拉卡拉错误")
// this.ServeJSON()
// return
// }
//
// this.Data["json"] = utils.Success(nil)
// this.ServeJSON()
//}
func lakala_post(url string, data_json []byte) (error, string) {
authorization, err := getAuthorization(string(data_json))
if err != nil {
return err, ""
}
fmt.Println(url)
fmt.Println(authorization)
req := httplib.Post(url)
//req.Header("Authorization", "LKLAPI-SHA256withRSA appid=\"\", serial_no=\"\", timestamp=\"\", nonce_str=\"\", signature=\"2233\"")
req.Header("Authorization", authorization)
req.Header("Accept", "application/json")
req.Header("Content-Type", "application/json")
req.Body(data_json)
body, err := req.Bytes()
if err != nil {
return err, ""
}
temp := make(map[string]interface{}, 0)
if err = json.Unmarshal(body, &temp); err != nil {
return err, ""
}
fmt.Println("拉卡拉返回值")
fmt.Println(temp)
//todo
if temp["code"] != "000000" {
//this.Data["json"] = utils.CheckError(errors.New("拉卡拉错误"), temp["msg"].(string)) //todo
//this.ServeJSON()
return errors.New(temp["msg"].(string)), ""
}
temp2, _ := temp["resp_data"].(map[string]string)
if temp2["counter_url"]=="" {
return errors.New("拉卡拉返回值「counter_url」为空错误"), ""
}
return nil, temp2["counter_url"]
}
func getAuthorization(body string) (string, error) {
appid := "OP00000003"
mchSerialNo := "00dfba8194c41b84cf"
//nonceStr := strconv.Itoa(rand.Intn(32)) // 构造随机数
nonceStr := "12345678901234567890123456789012" // 构造随机数
//timestamp := strconv.FormatInt(time.Now().Unix(), 10)
timestamp := "1686808027"
//String nonceStr = generateNonceStr();
//long timestamp = generateTimestamp();
message := appid + "\n" + mchSerialNo + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
//System.out.println("getToken message : " + message);
//PrivateKey merchantPrivateKey = loadPrivateKey(new FileInputStream(new File(merchantPrivateKeyPath)));
//String signature = this.sign(message.getBytes(ENCODING), merchantPrivateKey);
//privateRaw := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDokGGq7SlDoULN\nPULY8lcb2uXJcrFKkJI/lSfPppIkGH4xPfQytZXRlonpXqgOvovflJT5VhRvoLe2\ninJ/59kRF59KTerbCG5sG2IHhR/qCUGHervnZuPwgrjOOlnB19VCCUKY1tcplkZa\nKIksUU3TVh09GB3lUngkuOeO15ihcFHMIknOiSpL+Q04+qQf0g++9CxdQUtNY5za\nZ2Jdvch/4yFstR59qQu73ZCCYHFqXaVakyfOC3xOQkRB58jPOUvIab9zwo2hPukT\n+6qkqfokqMhX979HhNshPAJEEUXp4szk0QtP+2n8hq8t3Dws+GY8ElAFvmeGHx5j\nWzPYAcXvAgMBAAECggEBALIsu8caf/zCdc2MW8SelkJPCLG330DDVmjEO4YJlfl1\nkmjjkE2xdSDn9q0GyjbRoZQf36rPWkTTmyyNEYAQ/urrcCybWY2J/h9xMz+TrIm/\noabMT13QJF5FqJTHe7DZTReUxKMYJixEZ433dHCxsbByT2BZM75X2pg32aBEaTl0\nv9OfIMwfaJ5fSBmleJv4q/Lfd232/oOPzyr+EHfsMpTwOrgzQwPNoah1GvH+jBhz\ngoafi36vT8HVjJ+ZjOreH+Z2zVas683Le62rQaN/51jHS5vQGd2+z3qrI3kvu8KK\nWu0kIDQwCKtSFUT00MiKSaklE9JHf8rCNm3+en4kjfECgYEA/0Z2QaP4sOUt1+cZ\nIOprsMkJOl2sLTTDx3MseD2BxUukLDT8P3HTWLtBN9AkGlL6XD8WSs1k9YlGCqf2\ny9qC43Bgwsky8CH1ACk5K4PuWidGUQiqW4Oll/ris2vjagE+QfMHFFa7IalV5FvI\nv9L01jMqSL4duoM5w/WlLyLu8s0CgYEA6TlppWuxUMbxhEL5jmCZSSvsyhmIOdRk\nt4V9MuxwiRuItzywMo4+O7Hs6tjAxTnV/ROa33qyQtm4Olmd4Oa/TkmAJFX+mUrW\njUohDvm7Js2Y7/eeSRcRQLcgCjncpNe3AJoeVEvrGeaJMERYXnTwboUDKxsRyFFq\nAyuZHfuh86sCgYAm3pjFF+2XKd5YIKUv4OHy8jmIfJjp7T3eUcg0qtDmtMTTwmGi\nW3ed7C1bDUNiCr56a1S+oRW9WWCj4L1wft4tOYBSSIaMD++ZTa2Z1aXmblKDpjki\nZCJDyPzZ6xSeoH/VVOcADtDBqGIeumcP5lRHhVTr7J7kNnUGRJIZYk1WBQKBgQCl\nLAIEI4cKnDrD3uL60LL+vVsPrpFp02AZETMf84+nqpZin1pyE4dDo7kUgbnUdCd2\n+oF+sFi7O5Jb0MgdVY47FZbpJPYQ/o2AtvU+s+K1knozyPyS6wFPAeJxG5WGMTfr\n9zpvnOy+BSU3x8+F5e+5df5OcvdfFTmtUR05vNJvzQKBgHUtziAeWo7H6vxknFcc\nkVv7++a4IWF59eP+rpxlaHOtPTI43PLxJgSHEbw3epEzTUnCL9dpP8n48fuYuwM+\n+vpAujDcaGjGffmxW40E6wuGjOYBNg1zjSfEyjxF2fY+D9WoICSPHnrWB0/BEAZB\naL9Lho8+BUEFergUMjxUdvAS"
//privateRaw := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW"
//privateRaw := "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW\n-----END PRIVATE KEY-----";
privateRaw := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW"
//privateRaw := "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW\n-----END PRIVATE KEY-----"
signature, err := Sha256WithRsa(privateRaw, message)
if err != nil {
return signature, err
}
//fmt.Println(777)
//fmt.Println(signature)
authorization := "LKLAPI-SHA256withRSA " + "appid=\"" + appid + "\"," + "serial_no=\"" + mchSerialNo + "\"," + "timestamp=\"" + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\"";
//System.out.println("authorization message :" + authorization);
return authorization, nil
}
func Sha256WithRsa(privateRaw string, msg string) (string, error) {
privateRaw = strings.Trim(privateRaw, "\n")
if !strings.HasPrefix(privateRaw, "-----BEGIN RSA PRIVATE KEY-----") {
privateRaw = fmt.Sprintf("%s\n%s\n%s", "-----BEGIN RSA PRIVATE KEY-----", privateRaw, "-----END RSA PRIVATE KEY-----")
}
//fmt.Println(888)
//fmt.Println(privateRaw)
blockPri, _ := pem.Decode([]byte(privateRaw))
if blockPri == nil {
return "", fmt.Errorf("blockPri is nil")
}
rsaPri, e := genPriKey(blockPri.Bytes, PKCS8)
if e != nil {
panic(e)
}
h := sha256.New()
h.Write([]byte(msg))
d := h.Sum(nil)
signature, err := rsa.SignPKCS1v15(rand.Reader, rsaPri, crypto.SHA256, d)
if err != nil {
//return "", errorx.Wrap(err)
return "", err
}
encodedSig := base64.StdEncoding.EncodeToString(signature)
return encodedSig, nil
}
const (
PKCS1 int64 = iota
PKCS8
)
func genPriKey(privateKey []byte, privateKeyType int64) (*rsa.PrivateKey, error) {
var priKey *rsa.PrivateKey
var err error
switch privateKeyType {
case PKCS1:
{
priKey, err = x509.ParsePKCS1PrivateKey([]byte(privateKey))
if err != nil {
return nil, err
}
}
case PKCS8:
{
prkI, err := x509.ParsePKCS8PrivateKey([]byte(privateKey))
if err != nil {
return nil, err
}
priKey = prkI.(*rsa.PrivateKey)
}
default:
{
return nil, fmt.Errorf("unsupport private key type")
}
}
return priKey, nil
}
package pack
const (
PayUrl = "/api/v1/pay/"
)
// 卡拉卡统一支付
func PayUrlPacking(s string) string {
return PayUrl + s
}
\ No newline at end of file
package routers
import (
"github.com/gin-gonic/gin"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
v1_router "system_pay/router/v1"
)
// InitRouter 注册路由
func InitRouter() *gin.Engine {
if gin.Mode() == gin.ReleaseMode {
gin.SetMode(gin.ReleaseMode) // gin设置成发布模式
}
r := gin.Default()
// 测试与开发状态启用swagger
if gin.Mode() == gin.TestMode || gin.Mode() == gin.DebugMode {
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}
// 发布后禁用swagger
if gin.Mode() == gin.ReleaseMode {
r.GET("/swagger/*any", ginSwagger.DisablingWrapHandler(swaggerFiles.Handler, "NAME_OF_ENV_VARIABLE"))
}
// 拉卡拉统一支付
v1_router.PayRouter(r)
// 登录
//v1_router.LoginRouter(r)
// 注册
//v1_router.RegisterRouter(r)
// 上传
//v1_router.UploadRouter(r)
// v1版本接口
//v1 := r.Group("/api/v1")
//v1.Use(jwt.JWTAuthMiddleWare())
//{
// // 全国快递物流
// v1_router.ExpressRouter(v1)
//
// // 谛宝多多账号
// v1_router.MemberRouter(v1)
//
// // 采购订单
// v1_router.PurchaseOrderRouter(v1)
//
// // 数据概览
// //v1_router.DataOverview(v1)
// //
// //// 顾客分析
// //v1_router.CustomerAnalysisRouter(v1)
// //
// //// 会员卡分析
// //v1_router.MembershipCardAnalysis(v1)
// //
// //// 次卡分析
// //v1_router.SecondaryCardAnalysis(v1)
// //
// //// 医疗消费
// //v1_router.MedicalConsumptionAnalysis(v1)
// //
// //// 病历量分析
// //v1_router.MedicalRecordsAnalysis(v1)
// //
// //// 商品分析
// //v1_router.CommodityAnalysis(v1)
// //
// //// 员工分析
// //v1_router.EmployeeAnalysis(v1)
// //
// //// 支付相关
// //v1_router.PayMoney(v1)
// //
// //// 埋点
// //v1_router.BuriedPoint(v1)
//}
return r
}
package v1
import (
"github.com/gin-gonic/gin"
"system_pay/controller/api/v1/pay"
"system_pay/router/pack"
)
// 统一支付
func PayRouter (r *gin.Engine) {
PayController := pay.PayController{}
// 卡拉卡统一支付
r.POST(pack.PayUrlPacking("unified_order"), PayController.UnifiedOrder)
}
# 设置运行时环境
export runmode=dev
# 热加载
air
# 设置运行时环境
export runmode=prod
# 热加载
air
\ No newline at end of file
package setting
import (
"fmt"
"strconv"
"time"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
)
var Conf = new(Config)
type Config struct {
ServerSetting *Server `mapstructure:"server"`
AppSetting *App `mapstructure:"app"`
DatabaseSetting *Database `mapstructure:"database"`
Redis *RedisConfig `mapstructure:"redis"`
LogSetting *Log `mapstructure:"log"`
Sms *SmsInternationalConfig `mapstructure:"sms"`
UploadImage *UploadImage `mapstructure:"uploadimage"`
Oss *Oss `mapstructure:"oss"`
AliCloud *AliCloud `mapstructure:"alicloud"`
Esign *Esign `mapstructure:"esign"`
JwtSecret string `mapstructure:"jwtsecret"`
DesKey string `mapstructure:"deskey"`
//SmsInternational *SmsInternationalConfig `mapstructure:"newsms"`
//GateWay *GateWayDetail `mapstructure:"gateway"`
//GateWayDev *GateWayDevDetail `mapstructure:"gatewaydev"`
//Mongo *MongoConfig `mapstructure:"mongo"`
//PayUrl *PayUrlDetail `mapstructure:"payurl"`
}
type App struct {
Name string `mapstructure:"name"`
Version string `mapstructure:"version"`
TimeFormat string `mapstructure:"timeformat""`
}
type Log struct {
LogSavePath string `mapstructure:"logsavepath"`
LogSaveName string `mapstructure:"logsavename"`
LogFileExt string `mapstructure:"logfileext"`
Level string `mapstructure:"level"`
MaxSize int `mapstructure:"max_size"`
MaxAge int `mapstructure:"max_age"`
MaxBackups int `mapstructure:"max_backups"`
}
// Server 服务
type Server struct {
RunMode string `mapstructure:"runmode"`
HttpPort int `mapstructure:"httpport"`
ReadTimeout time.Duration `mapstructure:"readtimeout"`
WriteTimeout time.Duration `mapstructure:"writetimeout"`
}
// Database DB
type Database struct {
Type string `mapstructure:"type""`
ShopDB string `mapstructure:"shopdb"`
UserDB string `mapstructure:"userdb"`
SecondDB string `mapstructure:"seconddb"`
AccountDB string `mapstructure:"accountdb"`
PayDB string `mapstructure:"paydb"`
//MaxOpenConns int `mapstructure:"max_open_conns"`
//MaxIdleConns int `mapstructure:"max_idle_conns"`
//Host string `mapstructure:"host"`
//User string `mapstructure:"user""`
//Password string `mapstructure:"password""`
//Port int `mapstructure:"port"`
//DB string `mapstructure:"dbname"`
}
// RedisConfig redis
type RedisConfig struct {
Host string `mapstructure:"host"`
Password string `mapstructure:"password"`
Port int `mapstructure:"port"`
DB int `mapstructure:"db"`
PoolSize int `mapstructure:"pool_size"`
MinIdleConns int `mapstructure:"min_idle_conns"`
}
// MongoConfig mongo设置
//type MongoConfig struct {
// DBUrl string `mapstructure:"dburl"`
// MaxOpenConns uint64 `mapstructure:"max_open_conns"`
//}
// SmsInternationalConfig 国际化短信
type SmsInternationalConfig struct {
SmsKey string `mapstructure:"smskey"`
SendSmsUrl string `mapstructure:"sendsmsurl"`
SmsContent string `mapstructure:"smscontent"`
}
//
//// GateWayDetail 网关
//type GateWayDetail struct {
// URL string `mapstructure:"url"`
// Port string `mapstructure:"port"`
//}
//
//// GateWayDevDetail 网关
//type GateWayDevDetail struct {
// URL string `mapstructure:"url"`
// Port string `mapstructure:"port"`
//}
//
//// PayUrlDetail 网关
//type PayUrlDetail struct {
// CheckOrder string `mapstructure:"checkorder"`
// OrderState string `mapstructure:"orderstate"`
//}
type UploadImage struct {
UploadDir string `mapstructure:"upload_dir"`
MaxFileSize int `mapstructure:"max_file_size"`
ImageTypes string `mapstructure:"image_types""`
AcceptFileTypes string `mapstructure:"accept_file_types""`
}
type Oss struct {
OssUrl string `mapstructure:"oss_url"`
AccessKeyID string `mapstructure:"accesskeyid"`
AccessKeySecret string `mapstructure:"accesskeysecret""`
EndPoint string `mapstructure:"endpoint""`
Bucket string `mapstructure:"bucket""`
}
type AliCloud struct {
AppCode string `mapstructure:"appcode"`
TimeDuration int `mapstructure:"time_duration"`
}
//e签宝
type Esign struct {
ProjectId string `mapstructure:"project_id"`
ProjectSecret string `mapstructure:"project_secret"`
OrganAuthUrl string `mapstructure:"organ_auth_url"`
InfoAuthUrl string `mapstructure:"info_auth_url"`
}
// Init 支持热修改的viper设置
func Init() error {
viper.SetConfigFile("conf/dev/config.yaml") // 指定配置文件路径
err := viper.ReadInConfig() // 读取配置信息
if err != nil { // 读取配置信息失败
fmt.Printf("viper.ReadInConfig failed, new_error:%v\n", err)
return err
}
// 将读取的配置信息保存至全局变量Conf
if err = viper.Unmarshal(Conf); err != nil {
fmt.Printf("viper.Unmarshal failed, new_error:%v\n", err)
}
// 监控配置文件变化
viper.WatchConfig()
// 注意!!!配置文件发生变化后要同步到全局变量Conf
viper.OnConfigChange(func(in fsnotify.Event) {
fmt.Println("配置文件被修改啦...")
if err = viper.Unmarshal(Conf); err != nil {
fmt.Printf("viper.Unmarshal failed, new_error:%v\n", err)
}
//fmt.Println(Conf)
})
return err
}
func GetPort() string {
s := strconv.Itoa(Conf.ServerSetting.HttpPort)
return ":" + s
}
{
// The tab key will cycle through the settings when first created
// Visit http://wbond.net/sublime_packages/sftp/settings for help
// sftp, ftp or ftps
"type": "sftp",
"save_before_upload": true,
"upload_on_save": true,
"sync_down_on_open": false,
"sync_skip_deletes": false,
"sync_same_age": true,
"confirm_downloads": false,
"confirm_sync": true,
"confirm_overwrite_newer": true,
"host": "39.96.85.45",
"user": "root",
"password": "dbc_root123",
"port": "22",
"remote_path": "/docker/system_pay",
"ignore_regexes": [
"\\.sublime-(project|workspace)", "sftp-config(-alt\\d?)?\\.json",
"sftp-settings\\.json", "/venv/", "\\.svn/", "\\.hg/", "\\.git/",
"\\.bzr", "_darcs", "CVS", "\\.DS_Store", "Thumbs\\.db", "desktop\\.ini"
],
//"file_permissions": "664",
//"dir_permissions": "775",
//"extra_list_connections": 0,
"connect_timeout": 30,
//"keepalive": 120,
//"ftp_passive_mode": true,
//"ftp_obey_passive_host": false,
//"ssh_key_file": "~/.ssh/id_rsa",
//"sftp_flags": ["-F", "/path/to/ssh_config"],
//"preserve_modification_times": false,
//"remote_time_offset_in_hours": 0,
//"remote_encoding": "utf-8",
//"remote_locale": "C",
//"allow_config_upload": false,
}
package utils
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"encoding/base64"
"fmt"
"io"
"strings"
)
//Utf8ToGBK is will encoding utf8 to gbk
//func Utf8ToGBK(content string) string {
// enc := mahonia.NewEncoder("gbk")
// return enc.ConvertString(content)
//}
//MD55 will create str out md5
func MD55(str string) string {
m := md5.New()
io.WriteString(m, str)
return strings.ToLower(fmt.Sprintf("%x", m.Sum(nil)))
}
//Aes 对称加密
func AesEncrypt(origData, key []byte) (string, error) {
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
blockSize := block.BlockSize()
origData = PKCS7Padding(origData, blockSize)
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
result := base64.StdEncoding.EncodeToString(crypted)
return result, nil
}
//Aes 对称解密
func AesDecrypt(crypted, key []byte) (string, error) {
ciphertext := strings.Replace(string(crypted), " ", "", -1)
cryptedOri, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
origData := make([]byte, len(cryptedOri))
blockMode.CryptBlocks(origData, cryptedOri)
origData = PKCS7UnPadding(origData)
return string(origData), nil
}
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
package utils
import (
"bytes"
"crypto/cipher"
"crypto/des"
"encoding/base64"
"go.uber.org/zap"
"system_pay/setting"
)
//利用秘钥通过DES算法实现明文的加密
//利用秘钥通过DES算法实现密文的解密
//在加密和解密之前,首先需要补码和去码的操作
// PKCS5Padding 补码
func PKCS5Padding(orgData []byte, blockSize int) []byte {
//abc55555
padding := blockSize - len(orgData)%8
padtxt := bytes.Repeat([]byte{byte(padding)}, padding)
return append(orgData, padtxt...)
}
// PKCS5UnPadding 去码
func PKCS5UnPadding(cipherTxt []byte) []byte {
length := len(cipherTxt)
unpadding := int(cipherTxt[length-1])
return cipherTxt[:length-unpadding]
//cipherTxt[:4]
}
// DesEncrypt DES加密,加密会用到补码
func DesEncrypt(orig []byte, key []byte) []byte {
//首先检验秘钥是否合法
//DES加密算法,秘钥的长度必须为8bit block.BlockSize() = 8;
block, _ := des.NewCipher(key)
//补码
origData := PKCS5Padding(orig, block.BlockSize())
//设置加密方式
blockMode := cipher.NewCBCEncrypter(block, key)
//加密处理
crypted := make([]byte, len(origData)) //存放加密后的密文
blockMode.CryptBlocks(crypted, origData)
return crypted
}
// DesDecrypt DES解密,解密要用到去码
func DesDecrypt(cipherTxt []byte, key []byte) []byte {
//校验key的有效性
block, _ := des.NewCipher(key)
//设置解码方式
blockMode := cipher.NewCBCDecrypter(block, key)
//创建缓冲,存放解密后的数据
orgData := make([]byte, len(cipherTxt))
//开始解密
blockMode.CryptBlocks(orgData, cipherTxt)
//去掉编码
orgData = PKCS5UnPadding(orgData)
return orgData
}
// GetEncryptDes 进行des加密
func GetEncryptDes(s string) string {
return base64.StdEncoding.EncodeToString(DesEncrypt([]byte(s), []byte(setting.Conf.DesKey)))
// 通过base64处理秘文 打印成string
// base64.StdEncoding.EncodeToString(cipherTxt)
}
// ToDesDecrypt des对称解密
func ToDesDecrypt(cipherTxt string) string {
decodeString, err := base64.StdEncoding.DecodeString(cipherTxt)
if err != nil {
zap.L().Error("解密错误")
}
return string(DesDecrypt(decodeString, []byte(setting.Conf.DesKey)))
}
package utils
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"github.com/astaxie/beego"
"github.com/astaxie/beego/httplib"
"system_pay/setting"
)
//func SignflowsGet(url, token string) (interface{}, error) {
// Writelog(url, time.Now().Format("2006-01-02")+"SignflowsGetReq")
// req := httplib.Get(url)
// req.Header("X-Tsign-Open-App-Id", beego.AppConfig.String("PROJECT_ID"))
// req.Header("X-Tsign-Open-Token", token)
// req.Header("Content-Type", "application/json")
// body, err := req.Bytes()
// fmt.Println(string(body))
// Writelog(string(body), time.Now().Format("2006-01-02")+"SignflowsGetReply")
// if err != nil {
// return nil, err
// }
// temp := make(map[string]interface{}, 0)
// if err = json.Unmarshal(body, &temp); err != nil {
// return nil, err
// }
// errCode, ok := temp["code"].(float64)
//
// if ok != true {
// return nil, errors.New("获取签署失败")
// }
//
// if errCode != 0 {
// return nil, errors.New(temp["message"].(string))
// }
// return temp["data"], err
//}
//func SignHttpPost(url string, data map[string]interface{}, request string, response string) (map[string]interface{}, error) {
// byte, _ := json.Marshal(data)
// //Writelog(string(byte), time.Now().Format("2006-01-02")+request)
// req := httplib.Post(url)
// req.Header("X-Tsign-Open-App-Id", beego.AppConfig.String("PROJECT_ID"))
// req.Header("X-Tsign-Open-App-Secret", beego.AppConfig.String("PROJECT_SECRET"))
// req.Header("Content-Type", "application/json")
// req.Body(byte)
// body, err := req.Bytes()
// //Writelog(string(body), time.Now().Format("2006-01-02")+response)
// if err != nil {
// return nil, err
// }
// temp := make(map[string]interface{}, 0)
// if err = json.Unmarshal(body, &temp); err != nil {
// return nil, err
// }
// return temp, err
//}
//
//, request string, response string
func OrganizeAuthPost(url string, data []byte) (map[string]interface{}, error) {
//Writelog(url, time.Now().Format("2006-01-02")+"url")
//Writelog(string(data), time.Now().Format("2006-01-02")+request)
signature := ComputeHmacSha256(string(data), beego.AppConfig.String("PROJECT_SECRET"))
req := httplib.Post(url)
req.Header("X-timevale-mode", "package")
req.Header("X-timevale-project-id", beego.AppConfig.String("PROJECT_ID"))
req.Header("X-timevale-signature", signature)
req.Header("X-timevale-signature-algorithm", "hmac-sha256")
req.Header("Content-Type", "application/json")
req.Body(data)
body, err := req.Bytes()
//Writelog(string(body), time.Now().Format("2006-01-02")+response)
temp := make(map[string]interface{}, 0)
if err = json.Unmarshal(body, &temp); err != nil {
return nil, err
}
return temp, err
}
func ComputeHmacSha256(message string, secret string) string {
key := []byte(secret)
h := hmac.New(sha256.New, key)
h.Write([]byte(message))
sha := hex.EncodeToString(h.Sum(nil))
return sha
}
//func HttpPost(url string, data []byte, request string, response string) (map[string]interface{}, error) {
// Writelog(string(data), time.Now().Format("2006-01-02")+request)
// req := httplib.Post(url)
// req.Body(data)
// body, err := req.Bytes()
// Writelog(string(body), time.Now().Format("2006-01-02")+response)
// if err != nil {
// return nil, err
// }
// temp := make(map[string]interface{}, 0)
// if err = json.Unmarshal(body, &temp); err != nil {
// return nil, err
// }
// fmt.Println(temp)
// return temp, err
//}
//
//func CreateData(url string, param map[string]interface{}) (interface{}, error) {
//
// data, err := SignHttpPost(url, param, "", "")
//
// if err != nil {
// return nil, err
// }
//
// errCode, ok := data["errCode"].(float64)
//
// if ok != true {
// return nil, errors.New("CreateData转换失败")
// }
//
// if errCode != 0 {
// return nil, errors.New(data["msg"].(string))
// }
//
// return data["data"], nil
//}
//
//func SendHttpPUT(url, contentBase64Md5 string, fileContent []byte) (map[string]interface{}, error) {
// req := httplib.Put(url)
// req.Header("Content-Type", "application/pdf")
// req.Header("Content-Md5", contentBase64Md5)
// req.Body(fileContent)
// body, err := req.Bytes()
// temp := make(map[string]interface{}, 0)
//
// err = json.Unmarshal(body, &temp)
//
// if err != nil {
// return nil, err
// }
// return temp, err
//}
//
//func GetUploadurl(url string, param map[string]interface{}) (map[string]interface{}, error) {
//
// filePath, ok := param["filePath"].(string)
//
// if ok != true {
// return nil, errors.New("文件直传filePath转换失败")
// }
//
// req := httplib.Get(filePath)
// fileContent, err := req.Bytes()
//
// uuidValue, err := uuid.NewV4()
//
// if err != nil {
// return nil, err
// }
//
// //产生文件唯一值
// guid := uuidValue.String()
// f, err := os.Create(guid + ".pdf")
// defer f.Close()
//
// if err != nil {
// return nil, err
// }
// _, err = f.Write(fileContent)
//
// fileSize := len(fileContent)
//
// fileMd5, err := GetContentBase64Md5(guid + ".pdf")
// if err != nil {
// return nil, err
// }
//
// //删除文件
// if err = os.Remove(guid + ".pdf"); err != nil {
// return nil, err
// }
//
// param["fileSize"] = fileSize
// param["contentType"] = "application/pdf"
// param["contentMd5"] = fileMd5
//
// data, err := CreateData(url, param)
//
// if err != nil {
// return nil, err
// }
//
// contentMd5, ok := fileMd5.(string)
//
// if ok != true {
// return nil, errors.New(languages.AssertionFailure)
// }
//
// if ok != true {
// return nil, errors.New(languages.AssertionFailure)
// }
//
// uploadUrl, ok := data.(map[string]interface{})["uploadUrl"].(string)
//
// if ok != true {
// return nil, errors.New(languages.AssertionFailure)
// }
//
// uploadRes, err := SendHttpPUT(uploadUrl, contentMd5, fileContent)
//
// if err != nil || uploadRes["errCode"].(float64) != 0 {
// return nil, err
// }
//
// return data.(map[string]interface{}), nil
//}
//阿里云 - 全国快递物流查询
func SendHttpExpress(querys string) (map[string]interface{}, error) {
//appcode := beego.AppConfig.String("AppCode")
appcode := setting.Conf.AliCloud.AppCode
//appcode = "6d1da9eb15b540688a505c1814e0c25f"
//querys = "no=JDVB03807259358&type=JD" //example
//querys = "no=432230466057007"
url := "https://wuliu.market.alicloudapi.com/kdi?" + querys //url拼接
//fmt.Println(appcode)
//fmt.Println(url)
req := httplib.Get(url)
req.Header("Authorization", "APPCODE "+appcode)
req.Body("")
body, err := req.Bytes()
temp := make(map[string]interface{}, 0)
err = json.Unmarshal(body, &temp)
//fmt.Println(temp)
if err != nil {
return nil, err
}
if temp["status"] != "0" {
if temp["msg"]=="" {
err = errors.New("物流信息取得失败")
} else {
err = errors.New(temp["msg"].(string))
}
}
return temp, err
}
package utils
import (
"github.com/dgrijalva/jwt-go"
"github.com/pkg/errors"
"system_pay/conf"
"system_pay/setting"
"time"
)
// MyClaims 自定义声明结构体并内嵌jwt.StandardClaims
// jwt包自带的jwt.StandardClaims只包含了官方字段
// 我们这里需要额外记录一个username字段,所以要自定义结构体
// 如果想要保存更多信息,都可以添加到这个结构体中
type MyClaims struct {
UserName string `json:"user_name" description:"用户名称"` // 用户名称
UserId string `json:"user_id" description:"用户ID"` // 用户ID
PhoneMob string `json:"phone_mob" description:"用户手机号"` // 用户手机号
//HospitalCode string `json:"hospital_code" description:"医院唯一码"` // 医院唯一码
//ChainCode string `json:"chain_code" description:"连锁码"` // 连锁码
//HospitalID string `json:"hospital_id" description:"医院ID"` // 医院ID
//HospitalName string `json:"hospital_name" description:"医院名称"` // 医院名称
//ChainID string `json:"chain_id" description:"连锁ID"` // 连锁ID
jwt.StandardClaims
}
var MySecret = []byte(setting.Conf.JwtSecret)
//const TokenExpireDuration = time.Hour * 24 * 7
// ParseToken 解析JWT
func ParseToken(tokenString string) (*MyClaims, error) {
// 解析token
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (i interface{}, err error) {
return MySecret, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*MyClaims); ok && token.Valid { // 校验token
return claims, nil
}
return nil, errors.New("invalid token")
}
// GetToken 生成JWT
func GetToken(phoneMob, userId, userName string) (string, error) {
// 进行des加密
desUserName := GetEncryptDes(userName)
desUserId := GetEncryptDes(userId)
desPhoneMob := GetEncryptDes(phoneMob)
//desHospitalCode := GetEncryptDes(hospitalCode)
//
//desChainCode := GetEncryptDes(chainCode)
//
//desHospitalName := GetEncryptDes(hospitalName)
//
//strHospitalID := strconv.Itoa(hospitalID)
//
//desHospitalID := GetEncryptDes(strHospitalID)
//
//strChainID := strconv.Itoa(chainID)
//
//desChainID := GetEncryptDes(strChainID)
// 创建一个我们自己的声明
c := MyClaims{
desUserName, // 自定义字段
desUserId, // 自定义字段
desPhoneMob, // 自定义字段
//"", // 自定义字段
//"", // 自定义字段
//"",
//"",
//"", // 自定义字段
jwt.StandardClaims{
ExpiresAt: time.Now().Add(conf.TokenExpireDuration).Unix(), // 过期时间
Issuer: "system_pay", // 签发人
},
}
//使用指定的签名方法创建签名对象
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
//使用指定的secret签名并获得完整的编码后的字符串token
return token.SignedString(MySecret)
}
// GetToken 生成JWT
//func GetToken(userPhone, hospitalCode, chainCode, hospitalName string, hospitalID int, chainID int) (string, error) {
//
// // 进行des加密
// desUserPhone := GetEncryptDes(userPhone)
//
// desHospitalCode := GetEncryptDes(hospitalCode)
//
// desChainCode := GetEncryptDes(chainCode)
//
// desHospitalName := GetEncryptDes(hospitalName)
//
// strHospitalID := strconv.Itoa(hospitalID)
//
// desHospitalID := GetEncryptDes(strHospitalID)
//
// strChainID := strconv.Itoa(chainID)
//
// desChainID := GetEncryptDes(strChainID)
//
// // 创建一个我们自己的声明
// c := MyClaims{
// desUserPhone, // 自定义字段
// desHospitalCode, // 自定义字段
// desChainCode, // 自定义字段
// desHospitalID,
// desHospitalName,
// desChainID, // 自定义字段
// jwt.StandardClaims{
// ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
// Issuer: "system_pay", // 签发人
// },
// }
// //使用指定的签名方法创建签名对象
// token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
// //使用指定的secret签名并获得完整的编码后的字符串token
// return token.SignedString(MySecret)
//
//}
// GetTheInformationCarriedInTheToken 获取token中信息
//func GetTheInformationCarriedInTheToken(token string) (userPhone string, chainCode string, err error) {
//
// parseToken, err := ParseToken(token)
// if err != nil {
// zap.L().Error("解析token失败")
// return "", "", err
// }
//
// return ToDesDecrypt(parseToken.UserPhone), ToDesDecrypt(parseToken.HospitalCode), nil
//
//}
package utils
import (
"crypto/md5"
"encoding/hex"
)
// EncodeMD5 md5 encryption
func EncodeMD5(value string) string {
m := md5.New()
m.Write([]byte(value))
return hex.EncodeToString(m.Sum(nil))
}
// MD5 md5加密
func MD5(s string) string {
h := md5.New()
h.Write([]byte(s))
x := h.Sum(nil)
y := make([]byte, 32)
hex.Encode(y, x)
return string(y)
}
package utils
import (
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"system_pay/setting"
"time"
)
var(
//setting
//accessKeyID = setting.Conf.JwtSecret
//endPoint = setting.Conf.endPoint
//bucket = setting.Conf.bucket
//accessKeySecret = setting.Conf.accessKeySecret
//accessKeyID = setting.Conf.Oss.AccessKeyID
//accessKeySecret = setting.Conf.Oss.AccessKeySecret
//endPoint = setting.Conf.Oss.EndPoint
//bucket = setting.Conf.Oss.Bucket
//accessKeyID = "LTAIDfwPBC9AnsRt"
//endPoint = "Z6FtUptrAk0Sl6H8vrVBGZLbBzXEpO"
//bucket = "oss-cn-beijing.aliyuncs.com"
//accessKeySecret = "dbc-static"
Buckets *oss.Bucket
)
func GetOssBucket() (*oss.Bucket, error) {
// oss
accessKeyID := setting.Conf.Oss.AccessKeyID
accessKeySecret := setting.Conf.Oss.AccessKeySecret
endPoint := setting.Conf.Oss.EndPoint
bucket := setting.Conf.Oss.Bucket
if Buckets == nil {
client, err := oss.New(endPoint, accessKeyID, accessKeySecret)
if err != nil {
return nil, err
}
// 获取存储空间。
Buckets, err = client.Bucket(bucket)
if err != nil {
return nil, err
}
}
return Buckets, nil
}
func GetDate() string {
year := time.Now().Format("2006")
month := time.Now().Format("01")
day := time.Now().Format("02")
return year + month + day
}
package utils
type PageData struct {
Page int64
PageSize int64
TotalCount int64
TotalPage int64
Data interface{}
}
//GetPageData 获取分页数据
func GetPageData(page, pageSize, total int64) (int64, int64, PageData) {
if page <= 0 {
page = 1
}
if pageSize <= 0 {
pageSize = 10
}
var pageData PageData
pageData.Page = page
pageData.PageSize = pageSize
pageData.TotalCount = total
pageData.TotalPage = total / pageSize
if total%pageSize > 0 {
pageData.TotalPage += 1
}
if page > pageData.TotalPage {
page = pageData.TotalPage
pageData.Page = page
}
start := pageSize * (page - 1)
if start < 0 {
start = 0
}
return pageSize, start, pageData
}
package utils
import (
"regexp"
)
//检查手机号格式
func CheckPhoneNo(phone_no string)(bool) {
reg := `^1\d{10}$`
rgx := regexp.MustCompile(reg)
if (!rgx.MatchString(phone_no)) {
return false
}
return true
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment