Ver código fonte

统一登录平台

huangyan 1 ano atrás
commit
9da6a5f4da

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 1 - 0
.idea/.name

@@ -0,0 +1 @@
+Ic_oauth

+ 9 - 0
.idea/Ic_oauth.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/Ic_oauth.iml" filepath="$PROJECT_DIR$/.idea/Ic_oauth.iml" />
+    </modules>
+  </component>
+</project>

+ 134 - 0
app/controller/user.go

@@ -0,0 +1,134 @@
+package controller
+
+import (
+	"Ic_ouath/app/e"
+	"Ic_ouath/app/service"
+	"Ic_ouath/app/service/imp"
+	"Ic_ouath/global"
+	"Ic_ouath/models"
+	"Ic_ouath/page"
+	"Ic_ouath/utils"
+	"github.com/astaxie/beego/validation"
+	"github.com/gin-gonic/gin"
+)
+
+var users service.User = &imp.User{}
+
+// PhoneRegist 手机号注册
+func PhoneRegist(c *gin.Context) {
+	var userRegist models.UserRegist
+	err := c.ShouldBindJSON(&userRegist)
+	if err != nil {
+		e.ResponseError(c, e.JSONParsingFailed)
+		return
+	}
+	rescode := users.PhoneRegist(userRegist)
+	e.ResponseError(c, rescode)
+}
+
+// SendCode 发送验证码
+func SendCode(c *gin.Context) {
+	phone := c.PostForm("phone")
+	utils.SendModel(phone)
+	v := validation.Validation{}
+	v.Mobile(phone, "phone")
+	v.Required(phone, "phone")
+	if v.HasErrors() {
+		e.ResponseWithMsg(c, e.ThePhoneNumberIsWrong, "手机号码格式不正确")
+	} else {
+		rescode := utils.SendModel(phone)
+		if rescode != e.SUCCESS {
+			e.ResponseWithMsg(c, rescode, rescode.GetMsg())
+		} else {
+			e.ResponseSuccess(c, "发送成功")
+		}
+	}
+}
+
+// Login 账号登录
+func Login(c *gin.Context) {
+	var userRegist models.UserRegist
+	err := c.ShouldBindJSON(&userRegist)
+	if err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	} else {
+		login, rescode := users.Login(userRegist)
+		if rescode == e.SUCCESS {
+			e.ResponseSuccess(c, login)
+		} else {
+			e.ResponseWithMsg(c, rescode, rescode.GetMsg())
+		}
+	}
+}
+
+// CodeLogin  验证码登录
+func CodeLogin(c *gin.Context) {
+	var userRegist models.UserRegist
+	err := c.ShouldBindJSON(&userRegist)
+	if err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	login, rescode := users.CodeLogin(userRegist)
+	if rescode == e.SUCCESS {
+		e.ResponseSuccess(c, login)
+	} else {
+		e.ResponseWithMsg(c, rescode, rescode.GetMsg())
+	}
+}
+
+// GetUserAll 获取所有用户
+func GetUserAll(c *gin.Context) {
+	user, rescode := users.GetUserAll()
+	if rescode == e.SUCCESS {
+		e.ResponseSuccess(c, user)
+	} else {
+		e.ResponseWithMsg(c, rescode, rescode.GetMsg())
+	}
+}
+
+// GetUserAlls 获取所有用户
+func GetUserAlls(c *gin.Context) {
+	var pages page.PageParams
+	err := c.ShouldBindJSON(&pages)
+	if err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	result, total, err := page.Paginate(global.DBLink, pages, models.User{})
+	if err != nil {
+		e.ResponseWithMsg(c, e.PaginationFailed, e.PaginationFailed.GetMsg())
+		return
+	}
+	e.ResPonsePage(c, result, total, pages)
+}
+
+// UpdateUserById 修改用户信息
+func UpdateUserById(c *gin.Context) {
+	var userVo models.UserVo
+	userId := c.MustGet("user_id")
+	err := c.ShouldBindJSON(&userVo)
+	if err != nil {
+		e.ResponseWithMsg(c, e.JSONParsingFailed, e.JSONParsingFailed.GetMsg())
+		return
+	}
+	recode := users.UpdateUser(userId, userVo)
+	if recode == e.SUCCESS {
+		e.ResponseSuccess(c, "修改成功")
+	} else {
+		e.ResponseWithMsg(c, recode, recode.GetMsg())
+	}
+}
+
+// DeleteUserById 删除用户信息
+func DeleteUserById(c *gin.Context) {
+	ids := c.QueryArray("ids")
+	recode := users.DeleteUser(ids)
+	if recode == e.SUCCESS {
+		e.ResponseSuccess(c, "删除成功")
+	} else {
+		e.ResponseWithMsg(c, recode, recode.GetMsg())
+	}
+
+}

+ 47 - 0
app/e/R.go

@@ -0,0 +1,47 @@
+package e
+
+import (
+	"Ic_ouath/page"
+	"github.com/gin-gonic/gin"
+	"net/http"
+)
+
+type R struct {
+	Code    Rescode     `json:"code"`
+	Message any         `json:"message"`
+	Data    interface{} `json:"data"`
+}
+
+func ResponseError(c *gin.Context, code Rescode) {
+	c.JSON(http.StatusOK, &R{
+		Code:    code,
+		Message: code.GetMsg(),
+		Data:    nil,
+	})
+}
+func ResponseSuccess(c *gin.Context, data interface{}) {
+	c.JSON(http.StatusOK, &R{
+		Code:    SUCCESS,
+		Message: SUCCESS.GetMsg(),
+		Data:    data,
+	})
+}
+func ResponseWithMsg(c *gin.Context, code Rescode, msg any) {
+	c.JSON(http.StatusOK, &R{
+		Code:    code,
+		Message: msg,
+		Data:    nil,
+	})
+}
+func ResPonsePage(c *gin.Context, data interface{}, total int64, params page.PageParams) {
+	c.JSON(http.StatusOK, &R{
+		Code:    SUCCESS,
+		Message: SUCCESS.GetMsg(),
+		Data: gin.H{
+			"result":    data,
+			"total":     total,
+			"page":      params.Page,
+			"page_size": params.Size,
+		},
+	})
+}

+ 61 - 0
app/e/code_msg.go

@@ -0,0 +1,61 @@
+package e
+
+type Rescode int64
+
+const (
+	SUCCESS Rescode = 200 + iota
+	ERROR
+)
+
+const (
+	TokenIsInvalid Rescode = 1001 + iota
+	TokenIsExpired
+	DELETEFAIL
+	UPDATEFAIL
+	PaginationFailed
+	JSONParsingFailed
+	TheUserAlreadyExists
+	AlreadyExists
+	TheSystemIsAbnormal
+	CodeIsError
+	Theuseralreadyexists
+	ThePhoneNumberIsWrong
+	AnExceptionOccursWhenSendingAnSMSVerificationCode
+	TokenIsFaild
+	ThePasswordIsWrongOrThePhoneNumberIsIncorrect
+	HasSend
+	TheUserIsEmpty
+)
+
+var MsgFlags = map[Rescode]string{
+	SUCCESS:               "ok",
+	ERROR:                 "fail",
+	DELETEFAIL:            "删除失败",
+	TheUserAlreadyExists:  "用户已存在",
+	TheSystemIsAbnormal:   "系统异常",
+	CodeIsError:           "验证码错误",
+	UPDATEFAIL:            "更新失败",
+	Theuseralreadyexists:  "用户已存在",
+	JSONParsingFailed:     "json解析失败",
+	ThePhoneNumberIsWrong: "手机号错误",
+	HasSend:               "验证码已发送",
+	AlreadyExists:         "手机号已存在",
+	PaginationFailed:      "分页查询失败",
+	AnExceptionOccursWhenSendingAnSMSVerificationCode: "发送短信验证码出现异常",
+	ThePasswordIsWrongOrThePhoneNumberIsIncorrect:     "手机号或者密码错误",
+	TokenIsInvalid: "Token 无效",
+	TokenIsExpired: "Token 过期",
+	TokenIsFaild:   "Token 生成失败",
+	TheUserIsEmpty: "用户为空",
+}
+
+func (c Rescode) GetMsg() string {
+	// 检查Rescode是否在MsgFlags中定义,避免返回意外的消息
+	msg, ok := MsgFlags[c]
+	if ok {
+		return msg
+	} else {
+		// 如果Rescode无效,则返回错误消息
+		return MsgFlags[ERROR]
+	}
+}

+ 103 - 0
app/middlewares/log_middleware.go

@@ -0,0 +1,103 @@
+package middleware
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
+	"github.com/rifflock/lfshook"
+	"github.com/sirupsen/logrus"
+	"os"
+	"path"
+	"time"
+)
+
+// LoggerToFile 日志记录到文件
+func LoggerToFile() gin.HandlerFunc {
+
+	logFilePath := "./log/"
+	logFileName := "log"
+
+	// 日志文件
+	fileName := path.Join(logFilePath, logFileName)
+
+	// 写入文件
+	src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
+	if err != nil {
+		fmt.Println("err", err)
+	}
+
+	// 实例化
+	logger := logrus.New()
+
+	// 设置输出
+	logger.Out = src
+
+	// 设置日志级别
+	logger.SetLevel(logrus.DebugLevel)
+
+	// 设置 rotatelogs
+	logWriter, err := rotatelogs.New(
+		// 分割后的文件名称
+		fileName+".%Y%m%d.log",
+
+		// 生成软链,指向最新日志文件
+		rotatelogs.WithLinkName(fileName),
+
+		// 设置最大保存时间(7天)
+		rotatelogs.WithMaxAge(7*24*time.Hour),
+
+		// 设置日志切割时间间隔(1天)
+		rotatelogs.WithRotationTime(24*time.Hour),
+	)
+
+	writeMap := lfshook.WriterMap{
+		logrus.InfoLevel:  logWriter,
+		logrus.FatalLevel: logWriter,
+		logrus.DebugLevel: logWriter,
+		logrus.WarnLevel:  logWriter,
+		logrus.ErrorLevel: logWriter,
+		logrus.PanicLevel: logWriter,
+	}
+
+	lfHook := lfshook.NewHook(writeMap, &logrus.JSONFormatter{
+		TimestampFormat: "2006-01-02 15:04:05",
+	})
+
+	// 新增 Hook
+	logger.AddHook(lfHook)
+
+	return func(c *gin.Context) {
+		// 开始时间
+		startTime := time.Now()
+
+		// 处理请求
+		c.Next()
+
+		// 结束时间
+		endTime := time.Now()
+
+		// 执行时间
+		latencyTime := endTime.Sub(startTime)
+
+		// 请求方式
+		reqMethod := c.Request.Method
+
+		// 请求路由
+		reqUri := c.Request.RequestURI
+
+		// 状态码
+		statusCode := c.Writer.Status()
+
+		// 请求IP
+		clientIP := c.ClientIP()
+
+		// 日志格式
+		logger.WithFields(logrus.Fields{
+			"status_code":  statusCode,
+			"latency_time": latencyTime,
+			"client_ip":    clientIP,
+			"req_method":   reqMethod,
+			"req_uri":      reqUri,
+		}).Info()
+	}
+}

+ 24 - 0
app/middlewares/token_middleware.go

@@ -0,0 +1,24 @@
+package middleware
+
+import (
+	"Ic_ouath/app/e"
+	"Ic_ouath/utils"
+	"github.com/gin-gonic/gin"
+)
+
+func Authentication() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		header := c.GetHeader("Authorization")
+		token, err := utils.ParseToken(header)
+		if err != nil {
+			e.ResponseWithMsg(c, e.TokenIsInvalid, e.TokenIsInvalid.GetMsg())
+			c.Abort()
+			return
+		} else if token.Role != "admin" {
+			e.ResponseWithMsg(c, e.TokenIsInvalid, e.TokenIsInvalid.GetMsg())
+			c.Abort()
+		}
+		c.Set("user_id", token.UserId)
+		c.Next()
+	}
+}

+ 17 - 0
app/router.go

@@ -0,0 +1,17 @@
+package app
+
+import (
+	middleware "Ic_ouath/app/middlewares"
+	"Ic_ouath/app/routers"
+	"Ic_ouath/global"
+	"github.com/gin-gonic/gin"
+)
+
+func InitRouter() error {
+	engine := gin.New()
+	//记录日志
+	engine.Use(middleware.LoggerToFile())
+	gin.SetMode(global.ServerSetting.Mode)
+	routers.UserRouter(engine)
+	return engine.Run(global.ServerSetting.Port)
+}

+ 22 - 0
app/routers/user.go

@@ -0,0 +1,22 @@
+package routers
+
+import (
+	"Ic_ouath/app/controller"
+	middleware "Ic_ouath/app/middlewares"
+	"github.com/gin-gonic/gin"
+)
+
+func UserRouter(r *gin.Engine) {
+	group := r.Group("/api")
+	group.POST("/user", controller.PhoneRegist)
+	group.POST("/sendcode", controller.SendCode)
+	group.POST("/login", controller.Login)
+	group.POST("/codelogin", controller.CodeLogin)
+
+	adminGroup := r.Group("/api/admin")
+	adminGroup.Use(middleware.Authentication())
+	adminGroup.POST("/getalluser", controller.GetUserAlls)
+	adminGroup.POST("/user", controller.UpdateUserById)
+	adminGroup.DELETE("/user", controller.DeleteUserById)
+
+}

+ 144 - 0
app/service/imp/user_imp.go

@@ -0,0 +1,144 @@
+package imp
+
+import (
+	"Ic_ouath/app/e"
+	"Ic_ouath/global"
+	"Ic_ouath/models"
+	"Ic_ouath/utils"
+	"context"
+	"fmt"
+	"strconv"
+)
+
+type User struct{}
+
+func (u *User) PhoneRegist(userRegist models.UserRegist) e.Rescode {
+	//查找账号是否注册或者手机号已经注册,一个手机号只能注册一个账号
+	tx := global.DBLink.Where("account = ?", userRegist.Account).Find(&models.User{})
+	row := global.DBLink.Where("phone = ?", userRegist.Phone).Find(&models.User{})
+	if row.RowsAffected > 0 {
+		return e.AlreadyExists
+	}
+	if tx.RowsAffected > 0 {
+		return e.TheUserAlreadyExists
+	} else {
+		ctx := context.Background()
+		result, err := global.Rdb.Get(ctx, userRegist.Phone).Result()
+		if err != nil {
+			return e.TheSystemIsAbnormal
+		} else if result != userRegist.Code {
+			return e.CodeIsError
+		}
+		var user = models.User{
+			Phone:    userRegist.Phone,
+			Account:  userRegist.Account,
+			Password: utils.MD5(userRegist.Password),
+			Username: userRegist.Username,
+			State:    true,
+		}
+		tx = global.DBLink.Create(&user)
+		if tx.RowsAffected > 0 {
+			return e.SUCCESS
+		}
+	}
+	return e.ERROR
+}
+
+// Login 账号密码登录
+func (u *User) Login(userRegist models.UserRegist) (models.UserDto, e.Rescode) {
+	var count int64
+	var userdto models.UserDto
+	var user models.User
+	md5 := utils.MD5(userRegist.Password)
+	global.DBLink.Where("account=?", userRegist.Account).Where("password=?", md5).Find(&user).Count(&count)
+	if count > 0 {
+		token, err := utils.CreateToken(user.ID, user.Username, user.Role)
+		if err != nil {
+			return userdto, e.TokenIsFaild
+		} else {
+			userdto.Token = token
+			userdto.Username = user.Username
+			userdto.Account = user.Account
+			userdto.Avatar = user.Avatar
+			userdto.ID = user.ID
+			return userdto, e.SUCCESS
+		}
+	} else {
+		return userdto, e.ThePasswordIsWrongOrThePhoneNumberIsIncorrect
+	}
+}
+
+// CodeLogin 验证码登录
+func (u *User) CodeLogin(userRegist models.UserRegist) (models.UserDto, e.Rescode) {
+	var user models.User
+	var userdto models.UserDto
+	tx := global.DBLink.Where("phone=?", userRegist.Phone).Find(&user)
+	ctx := context.Background()
+	result, err := global.Rdb.Get(ctx, userRegist.Phone).Result()
+	if err != nil {
+		return userdto, e.TheSystemIsAbnormal
+	} else if result != userRegist.Code {
+		return userdto, e.CodeIsError
+	}
+	token, err := utils.CreateToken(user.ID, user.Username, user.Role)
+	userdto.Token = token
+	if tx.RowsAffected > 0 {
+		userdto.Username = user.Username
+		userdto.Account = user.Account
+		userdto.Avatar = user.Avatar
+		userdto.ID = user.ID
+		return userdto, e.SUCCESS
+	} else {
+		user.Account = userRegist.Account
+		user.Phone = userRegist.Phone
+		user.State = true
+		create := global.DBLink.Create(&user)
+		if create.RowsAffected > 0 {
+			return userdto, e.SUCCESS
+		}
+		return userdto, e.TheSystemIsAbnormal
+	}
+}
+
+// GetUserAll 获取所有用户
+func (u *User) GetUserAll() ([]models.User, e.Rescode) {
+	//TODO implement me
+	var users []models.User
+	tx := global.DBLink.Find(&users)
+	if tx.RowsAffected > 0 {
+		return users, e.SUCCESS
+	}
+	return users, e.TheUserIsEmpty
+}
+
+// UpdateUser 更新用户
+func (u *User) UpdateUser(id any, uservo models.UserVo) e.Rescode {
+	var user models.User
+	atoi, _ := strconv.Atoi(fmt.Sprint(id))
+	tx := global.DBLink.Model(&user).
+		Where("id=?", uservo.Id).
+		Updates(models.User{
+			Username: uservo.Username,
+			State:    uservo.State,
+			Avatar:   uservo.Avatar,
+			Account:  uservo.Account,
+			Phone:    uservo.Phone,
+			Password: utils.MD5(uservo.Password),
+			UpdateBy: atoi,
+		})
+	if tx.RowsAffected > 0 {
+		return e.SUCCESS
+	}
+	return e.UPDATEFAIL
+}
+
+// DeleteUser 删除用户
+func (u *User) DeleteUser(ids []string) e.Rescode {
+	for _, id := range ids {
+		tx := global.DBLink.Where("id=?", id).Delete(&models.User{})
+		if tx.RowsAffected > 0 {
+			return e.SUCCESS
+		}
+	}
+	return e.DELETEFAIL
+}

+ 21 - 0
app/service/user_service.go

@@ -0,0 +1,21 @@
+package service
+
+import (
+	"Ic_ouath/app/e"
+	"Ic_ouath/models"
+)
+
+type User interface {
+	// PhoneRegist 手机号注册
+	PhoneRegist(user models.UserRegist) e.Rescode
+	// Login 账号密码登录
+	Login(user models.UserRegist) (models.UserDto, e.Rescode)
+	// CodeLogin 验证码登录
+	CodeLogin(user models.UserRegist) (models.UserDto, e.Rescode)
+	// GetUserAll 获取所有用户
+	GetUserAll() ([]models.User, e.Rescode)
+	//UpdateUser 更新用户信息
+	UpdateUser(id any, user models.UserVo) e.Rescode
+	// DeleteUser 删除用户信息
+	DeleteUser(ids []string) e.Rescode
+}

+ 42 - 0
configs/config.yaml

@@ -0,0 +1,42 @@
+database:
+  # 数据库类型
+  dialect: mysql
+  # host地址
+  host: 127.0.0.1
+  # 端口
+  port: 3306
+  # 数据库名称
+  db: lc_oauth
+  # 数据库用户名
+  userName: root
+  # 数据库密码
+  password: 123456
+  # 其他配置参数
+  otherParams: charset=utf8mb4&parseTime=True&loc=Local
+  # 最大空闲连接数
+  maxIdleConn: 20
+  # 最大连接数
+  maxOpenConn: 200
+  # 连接超时关闭时间,单位:秒
+  connMaxLifetime: 60
+jwt:
+  secret: "xxxxx"
+  refresh_expire: 168
+  Issuer: "lc_oauth"
+# 服务相关配置
+server:
+  # 启动模式 debug、release
+  mode: debug
+  # http服务信息
+  insecureServingInfo:
+  # 监听端口
+  port: ":8080"
+subMail:
+  appid: "97173"
+  signature: "f639a60e41ee0554921d89884f5ff87e"
+redis:
+  addr: "192.168.0.100:6379"
+  password: ""
+  db: 0
+nats:
+  NatsServer_Url: "nats://127.0.0.0:4222"

+ 46 - 0
configs/setting.go

@@ -0,0 +1,46 @@
+package global
+
+import "github.com/spf13/viper"
+
+type Settings struct {
+	vp *viper.Viper
+}
+
+var sections = make(map[string]interface{})
+
+// NewSetting 读取配置
+func NewSetting() (*Settings, error) {
+	vp := viper.New()
+	vp.SetConfigName("config")
+	vp.AddConfigPath("configs")
+	vp.SetConfigType("yaml")
+	err := vp.ReadInConfig()
+	if err != nil {
+		return nil, err
+	}
+	s := &Settings{vp}
+	return s, nil
+}
+
+// ReadSection 读取指定的一段
+func (s *Settings) ReadSection(k string, v interface{}) error {
+	err := s.vp.UnmarshalKey(k, v)
+	if err != nil {
+		return err
+	}
+	if _, ok := sections[k]; !ok {
+		sections[k] = v
+	}
+	return nil
+}
+
+// ReloadAllSection 重新加载
+func (s *Settings) ReloadAllSection() error {
+	for k, v := range sections {
+		err := s.ReadSection(k, v)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}

+ 36 - 0
global/db.go

@@ -0,0 +1,36 @@
+package global
+
+import (
+	"Ic_ouath/models"
+	"fmt"
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+)
+
+var (
+	DBLink *gorm.DB
+)
+
+func SetupDBLink() error {
+	var err error
+	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?%s",
+		DatabaseSetting.UserName,
+		DatabaseSetting.Password,
+		DatabaseSetting.Host,
+		DatabaseSetting.Db,
+		DatabaseSetting.OtherParams,
+	)
+	DBLink, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
+		DisableForeignKeyConstraintWhenMigrating: true,
+		Logger:                                   logger.Default.LogMode(logger.Info),
+	})
+	if err != nil {
+		return err
+	}
+	//DBLink.SingularTable(true)
+	//DBLink.DB().SetMaxIdleConns(DatabaseSetting.MaxIdleConn)
+	//DBLink.DB().SetMaxOpenConns(DatabaseSetting.MaxOpenConn)
+	DBLink.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&models.User{})
+	return nil
+}

+ 25 - 0
global/redis.go

@@ -0,0 +1,25 @@
+package global
+
+import (
+	"context"
+	"fmt"
+	"github.com/go-redis/redis/v8"
+)
+
+var Rdb *redis.Client
+
+func init() {
+	//addr := RedisSetting.Addr
+	//password := RedisSetting.Password
+	//db := RedisSetting.DB
+	Rdb = redis.NewClient(&redis.Options{
+		Addr:     "192.168.11.70:6379",
+		Password: "",
+		DB:       0,
+	})
+	ctx := context.Background()
+	_, err := Rdb.Ping(ctx).Result()
+	if err != nil {
+		fmt.Println(err)
+	}
+}

+ 72 - 0
global/setting.go

@@ -0,0 +1,72 @@
+package global
+
+import (
+	global "Ic_ouath/configs"
+	"time"
+)
+
+// DatabaseSettingS 数据库配置
+type DatabaseSettingS struct {
+	Dialect         string `json:"dialect"`
+	Host            string `json:"host"`
+	Port            string `json:"port"`
+	UserName        string `json:"userName"`
+	Password        string `json:"password"`
+	Db              string `json:"db"`
+	OtherParams     string `json:"otherParams"`
+	MaxIdleConn     int    `json:"max_idle_conn"`
+	MaxOpenConn     int    `json:"max_open_conn"`
+	ConnMaxLifetime string `json:"conn_max_lifetime"`
+}
+
+// Nats 配置
+type Nats struct {
+	NatsServerUrl string `json:"NatsServer_Url"`
+}
+
+// Jwt 配置
+type Jwt struct {
+	Secret        string `json:"secret"`
+	RefreshExpire int    `json:"refresh_expire"`
+	Issuer        string `json:"issuer"`
+}
+
+// ServerSettingS 服务器配置
+type ServerSettingS struct {
+	Mode                string `json:"mode"`
+	Port                string `json:"port"`
+	InsecureServingInfo string `json:"insecure_serving_info"`
+}
+type SubMail struct {
+	Appid     string `json:"appid"`
+	Signature string `json:"signature"`
+}
+type Redis struct {
+	Addr     string `json:"addr"`
+	Password string `json:"password"`
+	DB       int    `json:"db"`
+}
+
+var (
+	DatabaseSetting *DatabaseSettingS
+	NatsSetting     *Nats
+	JwtSetting      *Jwt
+	ServerSetting   *ServerSettingS
+	SubMailSetting  *SubMail
+	RedisSetting    *Redis
+)
+
+// SetupSetting 读取配置到全局变量
+func SetupSetting() error {
+	s, err := global.NewSetting()
+	err = s.ReadSection("Database", &DatabaseSetting)
+	err = s.ReadSection("Nats", &NatsSetting)
+	err = s.ReadSection("Jwt", &JwtSetting)
+	err = s.ReadSection("Server", &ServerSetting)
+	err = s.ReadSection("SubMail", &SubMailSetting)
+	err = s.ReadSection("Redis", &RedisSetting)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 73 - 0
go.mod

@@ -0,0 +1,73 @@
+module Ic_ouath
+
+go 1.21
+
+require (
+	github.com/astaxie/beego v1.12.3
+	github.com/bytedance/sonic v1.11.3
+	github.com/gin-gonic/gin v1.9.1
+	github.com/go-redis/redis/v8 v8.11.5
+	github.com/go-resty/resty/v2 v2.12.0
+	github.com/golang-jwt/jwt/v4 v4.5.0
+	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
+	github.com/nats-io/nats.go v1.34.0
+	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
+	github.com/sirupsen/logrus v1.9.3
+	github.com/spf13/viper v1.18.2
+	go.uber.org/zap v1.27.0
+	gorm.io/driver/mysql v1.5.6
+	gorm.io/gorm v1.25.9
+)
+
+require (
+	github.com/cespare/xxhash/v2 v2.1.2 // indirect
+	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
+	github.com/chenzhuoyu/iasm v0.9.1 // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+	github.com/fsnotify/fsnotify v1.7.0 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.19.0 // indirect
+	github.com/go-sql-driver/mysql v1.7.0 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/hashicorp/hcl v1.0.0 // indirect
+	github.com/jinzhu/inflection v1.0.0 // indirect
+	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/jonboulle/clockwork v0.4.0 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/compress v1.17.2 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.7 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	github.com/lestrrat-go/strftime v1.0.6 // indirect
+	github.com/magiconair/properties v1.8.7 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/mitchellh/mapstructure v1.5.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/nats-io/nkeys v0.4.7 // indirect
+	github.com/nats-io/nuid v1.0.1 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.0 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	github.com/sagikazarmark/locafero v0.4.0 // indirect
+	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
+	github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
+	github.com/sourcegraph/conc v0.3.0 // indirect
+	github.com/spf13/afero v1.11.0 // indirect
+	github.com/spf13/cast v1.6.0 // indirect
+	github.com/spf13/pflag v1.0.5 // indirect
+	github.com/subosito/gotenv v1.6.0 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.12 // indirect
+	go.uber.org/multierr v1.10.0 // indirect
+	golang.org/x/arch v0.7.0 // indirect
+	golang.org/x/crypto v0.21.0 // indirect
+	golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
+	golang.org/x/net v0.22.0 // indirect
+	golang.org/x/sys v0.18.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
+	google.golang.org/protobuf v1.33.0 // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)

+ 415 - 0
go.sum

@@ -0,0 +1,415 @@
+cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic=
+cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
+cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
+cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=
+cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
+cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
+cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+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/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
+github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ=
+github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
+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/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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
+github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA=
+github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
+github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
+github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
+github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
+github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
+github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
+github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
+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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
+github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+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/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
+github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+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.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
+github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
+github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
+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-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
+github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
+github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
+github.com/go-resty/resty/v2 v2.12.0 h1:rsVL8P90LFvkUYq/V5BTVe203WfRIU4gvcf+yfzJzGA=
+github.com/go-resty/resty/v2 v2.12.0/go.mod h1:o0yGPrkS3lOe1+eFajk6kBW8ScXzwU3hD69/gt2yB/0=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+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-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+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.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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.3/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/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
+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.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
+github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
+github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
+github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
+github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g=
+github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
+github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+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/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
+github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
+github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
+github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/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/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+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.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
+github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
+github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
+github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-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/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nats-io/nats.go v1.34.0 h1:fnxnPCNiwIG5w08rlMcEKTUw4AV/nKyGCOJE8TdhSPk=
+github.com/nats-io/nats.go v1.34.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
+github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
+github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
+github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+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.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+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.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.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
+github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
+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/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
+github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
+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.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+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/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.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/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/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
+github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/epOxZN58PbZDg=
+github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
+github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
+github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
+github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
+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/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.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
+github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
+github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
+github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+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.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
+github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
+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/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+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/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
+github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
+go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI=
+go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U=
+go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA=
+go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc=
+go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
+go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
+golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
+golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
+golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
+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-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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+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-20181116152217-5ac8a444bdc5/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
+golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
+golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/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-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
+google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
+google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc=
+google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
+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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+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-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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
+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.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.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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
+gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
+gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8=
+gorm.io/gorm v1.25.9/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

+ 14 - 0
log/log.20240329.log

@@ -0,0 +1,14 @@
+{"client_ip":"::1","latency_time":15316779000,"level":"info","msg":"","req_method":"GET","req_uri":"/test","status_code":200,"time":"2024-03-29 11:33:17"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"GET","req_uri":"/favicon.ico","status_code":404,"time":"2024-03-29 11:33:17"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":404,"time":"2024-03-29 15:54:58"}
+{"client_ip":"::1","latency_time":209834100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 15:55:53"}
+{"client_ip":"::1","latency_time":13337109700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 15:59:30"}
+{"client_ip":"::1","latency_time":13702511300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:00:17"}
+{"client_ip":"::1","latency_time":29335300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-03-29 16:01:33"}
+{"client_ip":"::1","latency_time":1045600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:03:10"}
+{"client_ip":"::1","latency_time":7207674100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:03:37"}
+{"client_ip":"::1","latency_time":55022719800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:09:09"}
+{"client_ip":"::1","latency_time":80228822400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:14:01"}
+{"client_ip":"::1","latency_time":8976190400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:14:33"}
+{"client_ip":"::1","latency_time":12944140500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:16:09"}
+{"client_ip":"::1","latency_time":7160143900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-29 16:17:32"}

+ 42 - 0
log/log.20240330.log

@@ -0,0 +1,42 @@
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"POST","req_uri":"/api//sendcode","status_code":404,"time":"2024-03-30 14:05:51"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"POST","req_uri":"/api//sendcode","status_code":404,"time":"2024-03-30 14:06:29"}
+{"client_ip":"::1","latency_time":40318098100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:07:33"}
+{"client_ip":"::1","latency_time":369089500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:11:34"}
+{"client_ip":"::1","latency_time":4943800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:12:26"}
+{"client_ip":"::1","latency_time":4067200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:13:35"}
+{"client_ip":"::1","latency_time":3480200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:14:01"}
+{"client_ip":"::1","latency_time":3987600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:15:24"}
+{"client_ip":"::1","latency_time":4186800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:15:25"}
+{"client_ip":"::1","latency_time":14915300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:15:26"}
+{"client_ip":"::1","latency_time":4583000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:15:27"}
+{"client_ip":"::1","latency_time":4132700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:15:28"}
+{"client_ip":"::1","latency_time":4124600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:17:37"}
+{"client_ip":"::1","latency_time":371774200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:14"}
+{"client_ip":"::1","latency_time":2697200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:37"}
+{"client_ip":"::1","latency_time":2576000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:38"}
+{"client_ip":"::1","latency_time":3461600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:39"}
+{"client_ip":"::1","latency_time":3532800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:40"}
+{"client_ip":"::1","latency_time":2912400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:41"}
+{"client_ip":"::1","latency_time":2821400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:42"}
+{"client_ip":"::1","latency_time":2409200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:19:43"}
+{"client_ip":"::1","latency_time":2894900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:21:42"}
+{"client_ip":"::1","latency_time":18657800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-03-30 14:30:41"}
+{"client_ip":"::1","latency_time":15723200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-03-30 14:30:58"}
+{"client_ip":"::1","latency_time":1348900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-03-30 14:31:08"}
+{"client_ip":"::1","latency_time":22278800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-03-30 14:57:59"}
+{"client_ip":"::1","latency_time":4951300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 15:28:26"}
+{"client_ip":"::1","latency_time":28911600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-03-30 15:30:33"}
+{"client_ip":"::1","latency_time":1794400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 15:31:46"}
+{"client_ip":"::1","latency_time":1256300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 15:33:03"}
+{"client_ip":"::1","latency_time":63394261700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 15:34:21"}
+{"client_ip":"::1","latency_time":19850100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 15:34:50"}
+{"client_ip":"::1","latency_time":770922262700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 16:30:28"}
+{"client_ip":"::1","latency_time":35570845600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 16:31:58"}
+{"client_ip":"::1","latency_time":18193200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 20:28:00"}
+{"client_ip":"::1","latency_time":4255600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 20:28:03"}
+{"client_ip":"::1","latency_time":19824700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-03-30 20:30:23"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":404,"time":"2024-03-30 22:12:09"}
+{"client_ip":"::1","latency_time":35868600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":200,"time":"2024-03-30 22:12:30"}
+{"client_ip":"::1","latency_time":41330524100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":200,"time":"2024-03-30 22:16:53"}
+{"client_ip":"::1","latency_time":26630664800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":200,"time":"2024-03-30 22:17:30"}
+{"client_ip":"::1","latency_time":2968029600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":200,"time":"2024-03-30 22:19:08"}

+ 112 - 0
log/log.20240402.log

@@ -0,0 +1,112 @@
+{"client_ip":"::1","latency_time":2059600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-02 09:33:29"}
+{"client_ip":"::1","latency_time":12632700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 09:34:58"}
+{"client_ip":"::1","latency_time":297539100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/sendcode","status_code":200,"time":"2024-04-02 09:36:16"}
+{"client_ip":"::1","latency_time":28262500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-04-02 09:37:26"}
+{"client_ip":"::1","latency_time":3289600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":200,"time":"2024-04-02 09:39:36"}
+{"client_ip":"::1","latency_time":396100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 09:40:27"}
+{"client_ip":"::1","latency_time":17227000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-04-02 09:51:03"}
+{"client_ip":"::1","latency_time":18499600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/user","status_code":200,"time":"2024-04-02 09:52:34"}
+{"client_ip":"::1","latency_time":1804400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-02 09:56:30"}
+{"client_ip":"::1","latency_time":16375200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":200,"time":"2024-04-02 09:59:19"}
+{"client_ip":"::1","latency_time":2732100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/codelogin","status_code":200,"time":"2024-04-02 09:59:46"}
+{"client_ip":"::1","latency_time":9027603400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:02:39"}
+{"client_ip":"::1","latency_time":14564000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:05:34"}
+{"client_ip":"::1","latency_time":15653400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:21:38"}
+{"client_ip":"::1","latency_time":19818900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:38:20"}
+{"client_ip":"::1","latency_time":520500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:38:32"}
+{"client_ip":"::1","latency_time":964200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:40:37"}
+{"client_ip":"::1","latency_time":1521000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:44:32"}
+{"client_ip":"::1","latency_time":344853974900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:51:55"}
+{"client_ip":"::1","latency_time":22277358600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:54:26"}
+{"client_ip":"::1","latency_time":2123344500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:55:11"}
+{"client_ip":"::1","latency_time":4507831300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-02 10:55:33"}
+{"client_ip":"::1","latency_time":22387400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-02 10:55:58"}
+{"client_ip":"::1","latency_time":765900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:56:27"}
+{"client_ip":"::1","latency_time":18805609800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 10:57:07"}
+{"client_ip":"::1","latency_time":15597800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 11:01:35"}
+{"client_ip":"::1","latency_time":1643000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-02 11:01:57"}
+{"client_ip":"::1","latency_time":1129600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/getuserall","status_code":200,"time":"2024-04-02 11:02:08"}
+{"client_ip":"::1","latency_time":1532600,"level":"info","msg":"","req_method":"GET","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 11:18:15"}
+{"client_ip":"::1","latency_time":3238900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-02 11:18:26"}
+{"client_ip":"::1","latency_time":739300,"level":"info","msg":"","req_method":"GET","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 11:18:47"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:41:25"}
+{"client_ip":"::1","latency_time":3672400,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:41:59"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:42:10"}
+{"client_ip":"::1","latency_time":743300,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:43:18"}
+{"client_ip":"::1","latency_time":52689560800,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:44:35"}
+{"client_ip":"::1","latency_time":13657345200,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:46:46"}
+{"client_ip":"::1","latency_time":44575856600,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:48:06"}
+{"client_ip":"::1","latency_time":2281706000,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:48:28"}
+{"client_ip":"::1","latency_time":1652047300,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:48:42"}
+{"client_ip":"::1","latency_time":1997932700,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:48:53"}
+{"client_ip":"::1","latency_time":6484288800,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:50:26"}
+{"client_ip":"::1","latency_time":4343791900,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:51:51"}
+{"client_ip":"::1","latency_time":13669048900,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:53:23"}
+{"client_ip":"::1","latency_time":1706645800,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:53:47"}
+{"client_ip":"::1","latency_time":11133868100,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 14:59:28"}
+{"client_ip":"::1","latency_time":9202626300,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:01:16"}
+{"client_ip":"::1","latency_time":10201487200,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:01:44"}
+{"client_ip":"::1","latency_time":3884770000,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:01:56"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":404,"time":"2024-04-02 15:02:19"}
+{"client_ip":"::1","latency_time":32936449100,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=3,4","status_code":200,"time":"2024-04-02 15:03:36"}
+{"client_ip":"::1","latency_time":8167720900,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=664","status_code":200,"time":"2024-04-02 15:04:27"}
+{"client_ip":"::1","latency_time":10967547900,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=9","status_code":200,"time":"2024-04-02 15:08:07"}
+{"client_ip":"::1","latency_time":3530399300,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=9","status_code":200,"time":"2024-04-02 15:08:56"}
+{"client_ip":"::1","latency_time":51465948600,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=[3],[4]","status_code":200,"time":"2024-04-02 15:10:47"}
+{"client_ip":"::1","latency_time":7670034000,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=3,4","status_code":200,"time":"2024-04-02 15:10:47"}
+{"client_ip":"::1","latency_time":9574153300,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=[3,4]","status_code":200,"time":"2024-04-02 15:11:22"}
+{"client_ip":"::1","latency_time":20574136500,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=3%0D%0A4%0D%0A5","status_code":200,"time":"2024-04-02 15:13:13"}
+{"client_ip":"::1","latency_time":1162600,"level":"info","msg":"","req_method":"GET","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:16:38"}
+{"client_ip":"::1","latency_time":36084900,"level":"info","msg":"","req_method":"DELETE","req_uri":"/api/admin/user?ids=3","status_code":200,"time":"2024-04-02 15:16:52"}
+{"client_ip":"::1","latency_time":2389000,"level":"info","msg":"","req_method":"GET","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:17:08"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:44:38"}
+{"client_ip":"::1","latency_time":37854128000,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:50:40"}
+{"client_ip":"::1","latency_time":75905009700,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:52:18"}
+{"client_ip":"::1","latency_time":36346063700,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:53:01"}
+{"client_ip":"::1","latency_time":9773936000,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:53:37"}
+{"client_ip":"::1","latency_time":9814953300,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:57:40"}
+{"client_ip":"::1","latency_time":10967554600,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:58:06"}
+{"client_ip":"::1","latency_time":6576779600,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 15:59:28"}
+{"client_ip":"::1","latency_time":20699916500,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:03:20"}
+{"client_ip":"::1","latency_time":12420536500,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:04:45"}
+{"client_ip":"::1","latency_time":27227536600,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:05:46"}
+{"client_ip":"::1","latency_time":30549698100,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:06:24"}
+{"client_ip":"::1","latency_time":17546523300,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:06:49"}
+{"client_ip":"::1","latency_time":12058865500,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:07:19"}
+{"client_ip":"::1","latency_time":6946476800,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:09:18"}
+{"client_ip":"::1","latency_time":99202582700,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:28:34"}
+{"client_ip":"::1","latency_time":20797100,"level":"info","msg":"","req_method":"GET","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:29:20"}
+{"client_ip":"::1","latency_time":8126802800,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:31:37"}
+{"client_ip":"::1","latency_time":2268233700,"level":"info","msg":"","req_method":"PUT","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:33:09"}
+{"client_ip":"::1","latency_time":7083897000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:34:42"}
+{"client_ip":"::1","latency_time":6252476500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:35:24"}
+{"client_ip":"::1","latency_time":688047222700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:47:04"}
+{"client_ip":"::1","latency_time":540400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:47:04"}
+{"client_ip":"::1","latency_time":87100880000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:56:45"}
+{"client_ip":"::1","latency_time":66025437200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 16:57:54"}
+{"client_ip":"::1","latency_time":5338615800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 17:18:02"}
+{"client_ip":"::1","latency_time":2052105800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 17:18:25"}
+{"client_ip":"::1","latency_time":904000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 17:23:01"}
+{"client_ip":"::1","latency_time":375400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 17:23:29"}
+{"client_ip":"::1","latency_time":723500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 17:25:00"}
+{"client_ip":"::1","latency_time":7309690200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 17:34:19"}
+{"client_ip":"::1","latency_time":15868634500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:01:39"}
+{"client_ip":"::1","latency_time":6160407300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:10:08"}
+{"client_ip":"::1","latency_time":14899200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:11:45"}
+{"client_ip":"::1","latency_time":15466600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:14:31"}
+{"client_ip":"::1","latency_time":14869900,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:21:01"}
+{"client_ip":"::1","latency_time":16035400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:31:10"}
+{"client_ip":"::1","latency_time":1966600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:31:30"}
+{"client_ip":"::1","latency_time":42725600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:33:32"}
+{"client_ip":"::1","latency_time":614600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:35:05"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:38:01"}
+{"client_ip":"::1","latency_time":225500,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:38:56"}
+{"client_ip":"::1","latency_time":67609907700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:40:20"}
+{"client_ip":"::1","latency_time":1917643100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:40:22"}
+{"client_ip":"::1","latency_time":2736334000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:40:47"}
+{"client_ip":"::1","latency_time":18574432400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:54:27"}
+{"client_ip":"::1","latency_time":13015957800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 20:57:23"}
+{"client_ip":"::1","latency_time":49696131100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 21:00:08"}
+{"client_ip":"::1","latency_time":16937800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 21:03:14"}
+{"client_ip":"::1","latency_time":14377554000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 21:06:21"}
+{"client_ip":"::1","latency_time":4024652200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/user","status_code":200,"time":"2024-04-02 21:06:41"}

+ 0 - 0
log/log.20240402.log_lock


+ 0 - 0
log/log.20240402.log_symlink


+ 7 - 0
log/log.20240403.log

@@ -0,0 +1,7 @@
+{"client_ip":"::1","latency_time":296800,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/getalluser","status_code":200,"time":"2024-04-03 11:34:34"}
+{"client_ip":"::1","latency_time":15116700,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-03 11:34:44"}
+{"client_ip":"::1","latency_time":11759400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/getalluser","status_code":200,"time":"2024-04-03 11:34:56"}
+{"client_ip":"::1","latency_time":2853300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/getalluser","status_code":200,"time":"2024-04-03 11:35:08"}
+{"client_ip":"::1","latency_time":17915400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-03 15:26:42"}
+{"client_ip":"::1","latency_time":11580600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-03 15:40:32"}
+{"client_ip":"::1","latency_time":5588600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/admin/getalluser","status_code":200,"time":"2024-04-03 16:45:11"}

+ 1 - 0
log/log.20240404.log

@@ -0,0 +1 @@
+{"client_ip":"::1","latency_time":4517200,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-04 14:00:46"}

+ 3 - 0
log/log.20240407.log

@@ -0,0 +1,3 @@
+{"client_ip":"::1","latency_time":5204300,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-07 08:57:30"}
+{"client_ip":"::1","latency_time":42892100,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-07 14:00:09"}
+{"client_ip":"::1","latency_time":0,"level":"info","msg":"","req_method":"POST","req_uri":"/api/shop","status_code":404,"time":"2024-04-07 14:01:11"}

+ 3 - 0
log/log.20240408.log

@@ -0,0 +1,3 @@
+{"client_ip":"::1","latency_time":61847000,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-08 09:44:23"}
+{"client_ip":"::1","latency_time":5460600,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-08 09:45:46"}
+{"client_ip":"::1","latency_time":3928400,"level":"info","msg":"","req_method":"POST","req_uri":"/api/login","status_code":200,"time":"2024-04-08 09:53:20"}

+ 26 - 0
main.go

@@ -0,0 +1,26 @@
+package main
+
+import (
+	"Ic_ouath/app"
+	"Ic_ouath/global"
+	"Ic_ouath/nats"
+	_ "Ic_ouath/nats"
+	"log"
+)
+
+func init() {
+	err := global.SetupSetting()
+	if err != nil {
+		log.Fatalf("init.SetupSetting err: %v", err)
+	}
+	err = global.SetupDBLink()
+	if err != nil {
+		log.Fatalf("init.SetupDBLink err: %v", err)
+	}
+	nats.SetupNats()
+}
+func main() {
+	err := app.InitRouter()
+	if err != nil {
+	}
+}

+ 44 - 0
models/user.go

@@ -0,0 +1,44 @@
+package models
+
+import (
+	"gorm.io/gorm"
+)
+
+type User struct {
+	gorm.Model
+	Username   string `json:"username"` //用户名
+	Account    string `json:"account"`
+	Phone      string `json:"phone"`
+	Avatar     string `json:"avatar"`
+	Password   string `json:"password"`
+	OpenId     string `json:"open_id"`
+	Role       string `json:"role"`  //只有管理员拥有权限admin
+	State      bool   `json:"state"` //用户状态
+	SessionKey string `json:"session_key"`
+	UpdateBy   int    `json:"update_by"` //更新
+}
+
+func (*User) TableName() string {
+	return "user"
+}
+
+type UserRegist struct {
+	Username string `json:"username" validate:"required,min=2,max=20"` // 用户名
+	Phone    string `json:"phone" validate:"required,min=11,max=11"`   //手机号
+	Account  string `json:"account" validate:"required,min=6,max=20"`  //账号
+	Password string `json:"password" validate:"required,min=6,max=20"` // 密码
+	Code     string `json:"code" validate:"required,min=6,max=6"`      // 验证码
+}
+type UserVo struct {
+	Id       int    `json:"id"`
+	Username string `json:"username" validate:"required,min=2,max=20"` // 用户名
+	Phone    string `json:"phone" validate:"required,min=11,max=11"`   //手机号
+	Account  string `json:"account" validate:"required,min=6,max=20"`  //账号
+	Password string `json:"password" validate:"required,min=6,max=20"` // 密码
+	State    bool   `json:"state"`
+	Avatar   string `json:"avatar"` //用户状态
+}
+type UserDto struct {
+	User
+	Token string `json:"token"`
+}

+ 56 - 0
nats/Nats.go

@@ -0,0 +1,56 @@
+package nats
+
+import (
+	"Ic_ouath/global"
+	"Ic_ouath/utils"
+	"fmt"
+	"github.com/bytedance/sonic"
+	"github.com/nats-io/nats.go"
+)
+
+var Nats *nats.Conn
+
+// UserResponse 定义响应结构体
+type UserResponse struct {
+	Code    int    `json:"code"`
+	Message string `json:"message"`
+	User    any    `json:"user,omitempty"`
+}
+
+func SetupNats() {
+	var err error
+	Nats, err = nats.Connect(global.NatsSetting.NatsServerUrl)
+	//Nats, err = nats.Connect("nats://116.204.6.184:4222")
+	if err != nil {
+		fmt.Println("nats 连接失败!")
+		panic(err)
+	}
+	fmt.Println("nats OK!")
+	go NatsInit()
+}
+func NatsInit() {
+	_, _ = Nats.Subscribe("login_token_validation", func(msg *nats.Msg) {
+		//		fmt.Println("login_token_validation msg:", string(msg.Data))
+		verification, user := utils.Verification(string(msg.Data))
+		response := UserResponse{
+			Code:    0,
+			Message: "",
+			User:    nil,
+		}
+		if verification {
+			response.Code = 200
+			response.Message = "success"
+			response.User = user
+		} else {
+			response.Code = 201
+			response.Message = "请重新登录"
+			response.User = user
+		}
+		marshal, err := sonic.Marshal(response)
+		if err != nil {
+			fmt.Println("nats 响应失败!")
+			panic(err)
+		}
+		_ = Nats.Publish(msg.Reply, marshal)
+	})
+}

+ 26 - 0
page/page.go

@@ -0,0 +1,26 @@
+package page
+
+import (
+	"gorm.io/gorm"
+)
+
+type PageParams struct {
+	Page int    `json:"page" form:"page"`
+	Size int    `json:"size" form:"size"`
+	Desc string `json:"desc" form:"desc"`
+}
+
+// Paginate 使用给定的DB连接执行分页查询
+func Paginate[T any](db *gorm.DB, params PageParams, model T) (result []T, total int64, err error) {
+	var count int64
+	if err = db.Model(model).Count(&count).Error; err != nil {
+		return nil, 0, err
+	}
+	// 计算偏移量并设置分页大小
+	offset := (params.Page - 1) * params.Size
+	// 执行实际分页查询
+	if err = db.Offset(offset).Limit(params.Size).Order(params.Desc).Find(&result).Error; err != nil {
+		return nil, 0, err
+	}
+	return result, count, nil
+}

+ 16 - 0
test/token_test.go

@@ -0,0 +1,16 @@
+package test
+
+import (
+	"Ic_ouath/utils"
+	"testing"
+)
+
+func TestCreateToken(t *testing.T) {
+	token, err := utils.CreateToken(1, "xxxx", "sss")
+	if err != nil {
+		t.Error(err)
+	} else {
+		t.Log(token)
+	}
+
+}

+ 47 - 0
utils/create_code.go

@@ -0,0 +1,47 @@
+package utils
+
+import (
+	"Ic_ouath/app/e"
+	"Ic_ouath/global"
+	"context"
+	"fmt"
+	"go.uber.org/zap"
+	"math/rand"
+	"time"
+)
+
+func CreatCode() string {
+	const chars = "0123456789"
+	result := make([]byte, 6)
+	rand.Seed(time.Now().UnixNano())
+	for i := range result {
+		index := rand.Intn(len(chars))
+		result[i] = chars[index]
+	}
+	return string(result)
+}
+
+func SendModel(phone string) e.Rescode {
+	ctx := context.Background()
+	ss := NewSMS(global.SubMailSetting.Appid, global.SubMailSetting.Signature)
+	result, err := global.Rdb.Exists(ctx, phone).Result()
+	if result == 1 {
+		fmt.Println("验证码已经发送", zap.Error(err))
+		return e.HasSend
+	}
+	if err != nil {
+		fmt.Println("redis查询出现异常", zap.Error(err))
+		return e.TheSystemIsAbnormal
+	}
+	code := CreatCode()
+	content := fmt.Sprintf("【冷链智控系统】您的短信验证码:%s,请在5分钟内输入", code)
+	res, err := ss.Send(phone, content)
+	if err != nil || res.Status != SUCCESS {
+		fmt.Println("发送短信验证码出现异常", zap.Any("res", res), zap.Error(err))
+		return e.AnExceptionOccursWhenSendingAnSMSVerificationCode
+	} else {
+		//验证码装入redis并且设置过期时间
+		err = global.Rdb.Set(ctx, phone, code, 300*time.Second).Err()
+		return e.SUCCESS
+	}
+}

+ 59 - 0
utils/create_token.go

@@ -0,0 +1,59 @@
+package utils
+
+import (
+	"Ic_ouath/global"
+	"errors"
+	"github.com/golang-jwt/jwt/v4"
+	"time"
+)
+
+type MyClaims struct {
+	UserId   uint   `json:"user_id"`
+	UserName string `json:"user_name"`
+	Role     string `json:"role"`
+	jwt.RegisteredClaims
+}
+
+const TokenExpireDuration = time.Hour * 72
+
+func CreateToken(userId uint, userName, role string) (string, error) {
+	claims := MyClaims{
+		UserId:   userId,
+		UserName: userName,
+		Role:     role,
+		RegisteredClaims: jwt.RegisteredClaims{
+			ExpiresAt: jwt.NewNumericDate(time.Now().Add(TokenExpireDuration)),
+			Issuer:    global.JwtSetting.Issuer,
+		},
+	}
+	var mySerect = []byte(global.JwtSetting.Secret)
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	return token.SignedString(mySerect)
+}
+func ParseToken(tokenStr string) (*MyClaims, error) {
+	// 使用全局配置中的密钥对token进行解析。
+	var mySecret = []byte(global.JwtSetting.Secret)
+
+	// 尝试解析并验证JWT令牌。
+	claims := new(MyClaims)
+	token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
+		return mySecret, nil
+	})
+
+	if err != nil {
+		if errors.Is(err, jwt.ErrSignatureInvalid) || errors.Is(err, jwt.ErrInvalidKey) {
+			return nil, errors.New("无效的签名或密钥")
+		} else if ve, ok := err.(*jwt.ValidationError); ok && ve.Errors&jwt.ValidationErrorExpired != 0 {
+			return nil, errors.New("令牌已过期")
+		}
+		return nil, err
+	}
+
+	// 验证令牌是否有效。
+	if !token.Valid {
+		return nil, errors.New("无效的令牌")
+	}
+
+	// 如果令牌有效,则返回解析出的声明信息。
+	return claims, nil
+}

+ 13 - 0
utils/md5.go

@@ -0,0 +1,13 @@
+package utils
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+)
+
+func MD5(password string) string {
+	bytes := []byte(password)
+	sum := md5.Sum(bytes)
+	toString := hex.EncodeToString(sum[:])
+	return toString
+}

+ 55 - 0
utils/sms.go

@@ -0,0 +1,55 @@
+package utils
+
+import (
+	"encoding/json"
+	"github.com/go-resty/resty/v2"
+)
+
+const (
+	SUCCESS = "success"
+)
+
+type SMS struct {
+	Appid     string
+	Signature string
+}
+
+func NewSMS(appid, signature string) *SMS {
+	return &SMS{
+		Appid:     appid,
+		Signature: signature,
+	}
+}
+
+type SendRes struct {
+	Status  string `json:"status"`
+	Send_id string `json:"send_id"`
+	Fee     int    `json:"fee"`
+	Msg     string `json:"msg"`
+	Code    int    `json:"code"`
+}
+
+// Send 短信发送
+func (t *SMS) Send(to, content string) (SendRes, error) {
+	client := resty.New()
+	resp, err := client.R().
+		SetHeader("Content-Type", "application/x-www-form-urlencoded").
+		SetFormData(map[string]string{
+			"appid":     t.Appid,
+			"signature": t.Signature,
+			"to":        to,
+			"content":   content,
+		}).
+		SetResult(&SendRes{}).
+		Post("https://api-v4.mysubmail.com/sms/send.json")
+
+	if err != nil {
+		return SendRes{}, err
+	}
+
+	temp := SendRes{}
+	if err = json.Unmarshal(resp.Body(), &temp); err != nil {
+		return SendRes{}, err
+	}
+	return temp, nil
+}

+ 20 - 0
utils/token.go

@@ -0,0 +1,20 @@
+package utils
+
+import (
+	"Ic_ouath/global"
+	"Ic_ouath/models"
+)
+
+func Verification(token string) (bool, models.User) {
+	var user models.User
+	parseToken, err := ParseToken(token)
+	if err != nil {
+		return false, user
+	} else {
+		tx := global.DBLink.Where("id = ?", parseToken.UserId).First(&user)
+		if tx.RowsAffected > 0 {
+			return true, user
+		}
+		return false, user
+	}
+}