kobe6258 пре 7 месеци
родитељ
комит
ac7e8da771
41 измењених фајлова са 1066 додато и 271 уклоњено
  1. 14 0
      common/component/cache/redis.go
  2. 45 0
      common/component/config/eta_config.go
  3. 43 24
      common/component/database/db_connector.go
  4. 19 0
      common/component/log/log_plugin.go
  5. 5 5
      common/component/sms/emas_sms_sender.go
  6. 1 1
      common/component/sms/juhe_sms_sender.go
  7. 32 25
      common/component/wechat/wechat_client.go
  8. 2 0
      common/contants/contants.go
  9. 49 3
      common/exception/exc_enums.go
  10. 3 0
      common/utils/client/http_client.go
  11. 77 0
      common/utils/jwt/jwt_utils.go
  12. 6 1
      common/utils/redis/key_generator.go
  13. 4 0
      common/utils/redis/redis_client.go
  14. 1 1
      common/utils/sms/sms_client.go
  15. 6 6
      conf/log/log_config.json
  16. 20 21
      controllers/base_controller.go
  17. 50 37
      controllers/user/auth_controller.go
  18. 2 6
      controllers/user/user_controller.go
  19. 7 1
      domian/sms/emas_sms_service.go
  20. 70 0
      domian/sms/sms_service.go
  21. 56 3
      domian/user/user_serivce.go
  22. BIN
      eta_mini_ht_api.exe~
  23. 1 0
      go.mod
  24. 2 0
      go.sum
  25. 27 0
      job/eta/eta_report_task.go
  26. 11 0
      job/eta/eta_report_task_test.go
  27. 30 0
      job/sms/code_expired_task.go
  28. 15 0
      job/task_service.go
  29. 5 2
      main.go
  30. 71 10
      middleware/auth_middleware.go
  31. 18 0
      models/base_db.go
  32. 49 0
      models/eta/eta_report.go
  33. 7 11
      models/sms/api_mt_zsyyt.go
  34. 0 5
      models/sms/sms_code.go
  35. 80 0
      models/sms/verification_record.go
  36. 0 22
      models/user.go
  37. 40 0
      models/user/template_user.go
  38. 1 1
      routers/commentsRouter.go
  39. 182 0
      service/auth/auth_service.go
  40. 9 51
      swagger/swagger.json
  41. 6 35
      swagger/swagger.yml

+ 14 - 0
common/component/cache/redis.go

@@ -57,6 +57,20 @@ type RedisCache struct {
 	redisTemplate redis.UniversalClient
 	redisTemplate redis.UniversalClient
 }
 }
 
 
+func (r *RedisCache) GetHSet(key string) map[string]string {
+	return r.GetHSetWithContext(context.Background(), key)
+}
+func (r *RedisCache) GetHSetWithContext(ctx context.Context, key string) map[string]string {
+	value, _ := r.redisTemplate.HGetAll(ctx, key).Result()
+	return value
+}
+func (r *RedisCache) SetHSet(key string, val string, timeout time.Duration) error {
+	return r.SetHSetWithContext(context.Background(), key, val, timeout)
+}
+func (r *RedisCache) SetHSetWithContext(ctx context.Context, key string, val string, timeout time.Duration) error {
+	return r.redisTemplate.HSet(ctx, key, val).Err()
+}
+
 // GetString  获取一个值
 // GetString  获取一个值
 func (r *RedisCache) GetString(key string) string {
 func (r *RedisCache) GetString(key string) string {
 	return r.GetStringWithContext(context.Background(), key)
 	return r.GetStringWithContext(context.Background(), key)

+ 45 - 0
common/component/config/eta_config.go

@@ -0,0 +1,45 @@
+package config
+
+import (
+	"eta_mini_ht_api/common/contants"
+	"sync"
+)
+
+var (
+	etaOnce   sync.Once
+	etaConfig *ETAConfig
+)
+
+type ETAOpts struct {
+	DBUrl string
+}
+type ETAConfig struct {
+	BaseConfig
+	opts ETAOpts
+}
+
+func (r *ETAConfig) GetDBUrl() string {
+	return r.opts.DBUrl
+}
+
+func (r *ETAConfig) InitConfig() {
+	opts := ETAOpts{
+		DBUrl: r.GetString("database.url"),
+	}
+	r.opts = opts
+}
+func NewETAConfig() Config {
+	if etaConfig == nil {
+		etaOnce.Do(func() {
+			etaConfig = &ETAConfig{
+				BaseConfig: BaseConfig{prefix: contants.ETA},
+				opts:       ETAOpts{},
+			}
+		})
+	}
+	return etaConfig
+}
+
+func init() {
+	Register(contants.ETA, NewETAConfig)
+}

+ 43 - 24
common/component/database/db_connector.go

@@ -13,17 +13,16 @@ import (
 const (
 const (
 	MAIN = "main"
 	MAIN = "main"
 	EMAS = "emas"
 	EMAS = "emas"
+
+	ETA       = "eta"
+	etaDriver = "mysql"
 )
 )
 
 
 var (
 var (
-	db     *gorm.DB
-	dbOnce sync.Once
+	dbOnce    sync.Once
+	etaDBOnce sync.Once
 )
 )
 
 
-func GetInstance() *gorm.DB {
-	return db
-}
-
 var dbInsts = make(map[string]*gorm.DB)
 var dbInsts = make(map[string]*gorm.DB)
 
 
 func Register(name string, dbInst *gorm.DB) {
 func Register(name string, dbInst *gorm.DB) {
@@ -44,22 +43,42 @@ func Select(name string) *gorm.DB {
 }
 }
 func init() {
 func init() {
 	//初始化主数据库
 	//初始化主数据库
-	if db == nil {
-		dbOnce.Do(func() {
-			dbConfig, ok := config.GetConfig(contants.DATABASE).(*config.DBConfig)
-			if !ok {
-				panic("初始化数据库失败,配置文件格式不正确")
-			}
-			driver := dbConfig.GetDriver()
-			dns := dbConfig.GetUrl()
-			open, err := gorm.Open(dialector.GetGormDial(driver).GetDial(dns), &gorm.Config{})
-			if err != nil {
-				logger.Error("初始化数据库失败:%v", err)
-				os.Exit(0)
-			}
-			db = open
-			logger.Info("初始化数据库成功")
-		})
-	}
-	Register(MAIN, db)
+	dbOnce.Do(func() {
+		dbConfig, ok := config.GetConfig(contants.DATABASE).(*config.DBConfig)
+		if !ok {
+			panic("初始化数据库失败,配置文件格式不正确")
+		}
+		driver := dbConfig.GetDriver()
+		dns := dbConfig.GetUrl()
+		open, err := gorm.Open(dialector.GetGormDial(driver).GetDial(dns), &gorm.Config{})
+		if err != nil {
+			logger.Error("初始化数据库失败:%v", err)
+			os.Exit(0)
+		}
+		Register(MAIN, open)
+		logger.Info("初始化主库数据库成功")
+		//第三方的数据库
+		initDataBases()
+
+	})
+}
+
+func initDataBases() {
+	initEtaDatabase()
+}
+func initEtaDatabase() {
+	etaDBOnce.Do(func() {
+		etaConfig, ok := config.GetConfig(contants.ETA).(*config.ETAConfig)
+		if !ok {
+			panic("初始化eta数据库失败,配置文件格式不正确")
+		}
+		dns := etaConfig.GetDBUrl()
+		open, err := gorm.Open(dialector.GetGormDial(etaDriver).GetDial(dns), &gorm.Config{})
+		if err != nil {
+			logger.Error("初始化ETA数据库失败:%v", err)
+			os.Exit(0)
+		}
+		Register(ETA, open)
+		logger.Info("初始化ETA数据库成功")
+	})
 }
 }

+ 19 - 0
common/component/log/log_plugin.go

@@ -8,6 +8,7 @@ import (
 	"log"
 	"log"
 	"os"
 	"os"
 	"path"
 	"path"
+	"sync"
 )
 )
 
 
 const (
 const (
@@ -17,6 +18,7 @@ const (
 
 
 var (
 var (
 	loggerHandler *CustomLogger
 	loggerHandler *CustomLogger
+	logMutex      = &sync.Mutex{}
 )
 )
 
 
 type logger struct {
 type logger struct {
@@ -36,16 +38,33 @@ type Logger interface {
 }
 }
 
 
 func Info(msg string, v ...interface{}) {
 func Info(msg string, v ...interface{}) {
+	logMutex.Lock()
+	defer logMutex.Unlock()
 	loggerHandler.Info(msg, v...)
 	loggerHandler.Info(msg, v...)
 }
 }
 
 
 func Error(msg string, v ...interface{}) {
 func Error(msg string, v ...interface{}) {
+	logMutex.Lock()
+	defer logMutex.Unlock()
 	loggerHandler.Error(msg, v...)
 	loggerHandler.Error(msg, v...)
 }
 }
 
 
 func Warn(msg string, v ...interface{}) {
 func Warn(msg string, v ...interface{}) {
+	logMutex.Lock()
+	defer logMutex.Unlock()
 	loggerHandler.Warn(msg, v...)
 	loggerHandler.Warn(msg, v...)
 }
 }
+func Debug(msg string, v ...interface{}) {
+	loggerHandler.Debug(msg, v...)
+}
+func (c *CustomLogger) Debug(msg string, v ...interface{}) {
+	for _, appender := range c.logs {
+		if appender.GetLevel() >= logs.LevelInfo {
+			appender.Debug(msg, v...)
+		}
+
+	}
+}
 func (c *CustomLogger) Info(msg string, v ...interface{}) {
 func (c *CustomLogger) Info(msg string, v ...interface{}) {
 	for _, appender := range c.logs {
 	for _, appender := range c.logs {
 		if appender.GetLevel() >= logs.LevelInfo {
 		if appender.GetLevel() >= logs.LevelInfo {

+ 5 - 5
common/component/sms/emas_sms_sender.go

@@ -9,7 +9,7 @@ import (
 	"eta_mini_ht_api/common/exception"
 	"eta_mini_ht_api/common/exception"
 	"eta_mini_ht_api/common/utils/sms"
 	"eta_mini_ht_api/common/utils/sms"
 	stringUtils "eta_mini_ht_api/common/utils/string"
 	stringUtils "eta_mini_ht_api/common/utils/string"
-	smsService "eta_mini_ht_api/domian/sms"
+	emasSmsService "eta_mini_ht_api/domian/sms"
 	"gorm.io/gorm"
 	"gorm.io/gorm"
 	"os"
 	"os"
 	"text/template"
 	"text/template"
@@ -32,7 +32,7 @@ func initDBClient(url string) *gorm.DB {
 		logger.Error("初始化亿美短信数据库失败:%v", err)
 		logger.Error("初始化亿美短信数据库失败:%v", err)
 		os.Exit(0)
 		os.Exit(0)
 	}
 	}
-	logger.Info("初始化数据库成功")
+	logger.Info("初始化亿美短信数据库成功")
 	return open
 	return open
 }
 }
 func (emas *EMASSmsSender) InitSender(config *config.SMSConfig) {
 func (emas *EMASSmsSender) InitSender(config *config.SMSConfig) {
@@ -59,15 +59,15 @@ type emasTemplate struct {
 	Code         string
 	Code         string
 }
 }
 
 
-func (emas *EMASSmsSender) SendSms(mobile string, code string) (result string, err error) {
+func (emas *EMASSmsSender) SendSms(mobile string, code string, smId int) (result string, err error) {
 	var content bytes.Buffer
 	var content bytes.Buffer
 	if err = emas.TemplateGenerator.Execute(&content, &emasTemplate{emas.SmsExpireMinute, code}); err != nil {
 	if err = emas.TemplateGenerator.Execute(&content, &emasTemplate{emas.SmsExpireMinute, code}); err != nil {
 		// 处理错误,例如记录日志或返回错误给调用者
 		// 处理错误,例如记录日志或返回错误给调用者
 		logger.Warn("[短信发送]生成短信内容失败:%v", err)
 		logger.Warn("[短信发送]生成短信内容失败:%v", err)
 		return SendFail, exception.New(exception.SendingSMSFailed)
 		return SendFail, exception.New(exception.SendingSMSFailed)
 	}
 	}
-	msg := smsService.Msg{Mobile: mobile, Content: content.String()}
-	err = smsService.SendSms(msg)
+	msg := emasSmsService.Msg{SMId: smId, Mobile: mobile, Content: content.String()}
+	err = emasSmsService.SendSms(msg)
 	if err != nil {
 	if err != nil {
 		logger.Warn("[短信发送]发送短信失败:%v", err)
 		logger.Warn("[短信发送]发送短信失败:%v", err)
 		return SendFail, exception.New(exception.SendingSMSFailed)
 		return SendFail, exception.New(exception.SendingSMSFailed)

+ 1 - 1
common/component/sms/juhe_sms_sender.go

@@ -45,7 +45,7 @@ type Result struct {
 	Count int    `json:"count"`
 	Count int    `json:"count"`
 }
 }
 
 
-func (jh *JuheSmsSender) SendSms(mobile string, code string) (result string, err error) {
+func (jh *JuheSmsSender) SendSms(mobile string, code string, _ int) (result string, err error) {
 	var Url *url.URL
 	var Url *url.URL
 	//初始化参数
 	//初始化参数
 	param := url.Values{}
 	param := url.Values{}

+ 32 - 25
common/component/wechat/wechat_client.go

@@ -2,13 +2,13 @@ package wechat
 
 
 import (
 import (
 	"encoding/json"
 	"encoding/json"
-	"errors"
 	"eta_mini_ht_api/common/component/config"
 	"eta_mini_ht_api/common/component/config"
 	"eta_mini_ht_api/common/component/log"
 	"eta_mini_ht_api/common/component/log"
 	"eta_mini_ht_api/common/component/wechat/we_http"
 	"eta_mini_ht_api/common/component/wechat/we_http"
 	"eta_mini_ht_api/common/contants"
 	"eta_mini_ht_api/common/contants"
+	"eta_mini_ht_api/common/exception"
 	"eta_mini_ht_api/common/utils/client"
 	"eta_mini_ht_api/common/utils/client"
-	"net/http"
+	"io"
 	"net/url"
 	"net/url"
 	"sync"
 	"sync"
 )
 )
@@ -18,8 +18,8 @@ const (
 	codeAPI = "/sns/jscode2session"
 	codeAPI = "/sns/jscode2session"
 )
 )
 const (
 const (
-	// WeChatServerError 微信服务器错误时返回返回消息
-	WeChatServerError = "微信服务器发生错误"
+// WeChatServerError 微信服务器错误时返回返回消息
+
 )
 )
 
 
 var (
 var (
@@ -45,8 +45,7 @@ func GetInstance() *Client {
 			return // 或者采取其他适当的错误处理措施
 			return // 或者采取其他适当的错误处理措施
 		}
 		}
 		// 默认配置
 		// 默认配置
-		wechatClient = NewClient(wechatConf.GetAppid(), wechatConf.GetSecret())//WithHttpClient(http.DefaultClient),
-
+		wechatClient = NewClient(wechatConf.GetAppid(), wechatConf.GetSecret(), WithHttpClient(client.DefaultClient()))
 	})
 	})
 	return wechatClient
 	return wechatClient
 }
 }
@@ -60,19 +59,17 @@ func NewClient(appid, secret string, opts ...func(*Client)) *Client {
 		appid:  appid,
 		appid:  appid,
 		secret: secret,
 		secret: secret,
 	}
 	}
-
 	// 执行额外的配置函数
 	// 执行额外的配置函数
 	for _, fn := range opts {
 	for _, fn := range opts {
 		fn(cli)
 		fn(cli)
 	}
 	}
-
 	return cli
 	return cli
 }
 }
 
 
 // WithHttpClient 自定义 HTTP Client
 // WithHttpClient 自定义 HTTP Client
 func WithHttpClient(hc *client.HttpClient) func(*Client) {
 func WithHttpClient(hc *client.HttpClient) func(*Client) {
 	return func(cli *Client) {
 	return func(cli *Client) {
-		//cli.request = request.NewRequest(hc, request.ContentTypeJSON, cli.Logger)
+		cli.client = hc
 	}
 	}
 }
 }
 
 
@@ -81,42 +78,52 @@ type loginResponse struct {
 	we_http.LoginResponse
 	we_http.LoginResponse
 }
 }
 
 
-// 小程序登录
-func (cli *Client) Login(code string) (lres we_http.LoginResponse, err error) {
+// Login 小程序登录
+func (cli *Client) Login(code string) (wxUser WxUser, err error) {
 	if code == "" {
 	if code == "" {
-		err = errors.New("code不能为空")
+		err = exception.New(exception.WeChatCodeEmpty)
 		return
 		return
 	}
 	}
 	api, err := code2url(cli.appid, cli.secret, code)
 	api, err := code2url(cli.appid, cli.secret, code)
 	if err != nil {
 	if err != nil {
+		err = exception.New(exception.WeChatIllegalRequest)
 		return
 		return
 	}
 	}
-	res, err := http.Get(api)
-	if err != nil {
-		return
-	}
-	defer res.Body.Close()
-
-	if res.StatusCode != 200 {
-		err = errors.New(WeChatServerError)
+	//请求微信接口
+	res, err := cli.client.Get(api)
+	defer func(Body io.ReadCloser) {
+		Body.Close()
+	}(res.Body)
+
+	if err != nil || res.StatusCode != 200 {
+		logger.Error("获取微信用户信息失败:%v", res.Status)
+		err = exception.New(exception.WeChatServerError)
 		return
 		return
 	}
 	}
-
 	var data loginResponse
 	var data loginResponse
 	err = json.NewDecoder(res.Body).Decode(&data)
 	err = json.NewDecoder(res.Body).Decode(&data)
 	if err != nil {
 	if err != nil {
+		logger.Error("解析微信应答失败:%v", err)
+		err = exception.New(exception.WeChatResponseError)
 		return
 		return
 	}
 	}
-
 	if data.Errcode != 0 {
 	if data.Errcode != 0 {
-		err = errors.New(data.Errmsg)
+		logger.Error("获取用户信息失败:%v", data.Errmsg)
+		err = exception.New(exception.WechatUserInfoFailed)
 		return
 		return
 	}
 	}
-
-	lres = data.LoginResponse
+	wxUser = WxUser{
+		OpenId:  data.LoginResponse.OpenID,
+		UnionId: data.LoginResponse.UnionID,
+	}
 	return
 	return
 }
 }
 
 
+type WxUser struct {
+	OpenId  string
+	UnionId string
+}
+
 // 拼接 获取 session_key 的 URL
 // 拼接 获取 session_key 的 URL
 func code2url(appID, secret, code string) (string, error) {
 func code2url(appID, secret, code string) (string, error) {
 
 

+ 2 - 0
common/contants/contants.go

@@ -6,4 +6,6 @@ const (
 	REDIS    = "redis"
 	REDIS    = "redis"
 
 
 	WECHAT = "wechat"
 	WECHAT = "wechat"
+
+	ETA = "eta"
 )
 )

+ 49 - 3
common/exception/exc_enums.go

@@ -16,24 +16,70 @@ const (
 	SysErrCode int = iota + 10000 // iota 自动递增,从 1 开始
 	SysErrCode int = iota + 10000 // iota 自动递增,从 1 开始
 	UnknownError
 	UnknownError
 	Unauthorized
 	Unauthorized
-	// BIZErrCode 业务错误
-	BIZErrCode int = iota + 20000 // iota 自动递增,从 1 开始
+	// SMSErrCode BIZErrCode 业务错误
+	SMSErrCode int = iota + 20000 // iota 自动递增,从 1 开始
+	//短信
 	IllegalCodeLength
 	IllegalCodeLength
 	IllegalPhoneNumber
 	IllegalPhoneNumber
 	SMSCodeGenerateFailed
 	SMSCodeGenerateFailed
 	SendingSMSFailed
 	SendingSMSFailed
+	SMSCodeAlreadySent
+	SMSCodeExpired
+	SMSCodeError
+	// UserErrCode 用户
+	UserErrCode int = iota + 30000 // iota 自动递增,从 1 开始
+	TemplateUserNotFound
+	TemplateUserCreateFailed
+	GenerateTokenFailed
+	JWTTokenDecodeFailed
+
+	JWTTokenExpired
+	JWTTokenInvalid
+	// WechatErrCode 微信
+	WechatErrCode int = iota + 40000 // iota 自动递增,从 1 开始
+	WeChatServerError
+	WeChatResponseError
+	WechatUserInfoFailed
+	WeChatCodeEmpty
+	WeChatIllegalRequest
 )
 )
 
 
 // ErrorMap 用于存储错误码和错误信息的映射
 // ErrorMap 用于存储错误码和错误信息的映射
 var ErrorMap = map[int]string{
 var ErrorMap = map[int]string{
 	UnknownError:          "未知错误",
 	UnknownError:          "未知错误",
-	Unauthorized:          "未授权",
+	Unauthorized:          "用户未授权",
 	IllegalCodeLength:     "无效的验证码位数设置",
 	IllegalCodeLength:     "无效的验证码位数设置",
 	IllegalPhoneNumber:    "无效的手机号码",
 	IllegalPhoneNumber:    "无效的手机号码",
 	SMSCodeGenerateFailed: "生成手机验证码失败",
 	SMSCodeGenerateFailed: "生成手机验证码失败",
 	SendingSMSFailed:      "发送手机验证码失败",
 	SendingSMSFailed:      "发送手机验证码失败",
+	SMSCodeAlreadySent:    "当前手机验证码已发送,请稍后再试",
+	SMSCodeExpired:        "验证码已过期",
+	SMSCodeError:          "验证码错误",
+	//用户
+	TemplateUserNotFound:     "临时用户记录不存在",
+	TemplateUserCreateFailed: "创建临时用户失败",
+	GenerateTokenFailed:      "创建token失败",
+	JWTTokenDecodeFailed:     "token解析失败",
+	JWTTokenExpired:          "token已过期",
+	JWTTokenInvalid:          "token无效",
+	//微信
+	WeChatServerError:    "微信服务器发生错误",
+	WechatUserInfoFailed: "获取微信用户信息失败",
+	WeChatResponseError:  "解析微信响应数据失败",
+	WeChatCodeEmpty:      "微信获取用户信息,code不能为空",
+	WeChatIllegalRequest: "不合法的微信请求",
 }
 }
 
 
+func Equals(code int, message string) bool {
+	if stringUtils.IsEmptyOrNil(message) {
+		return false
+	}
+	return ErrorMap[code] == message
+}
+
+func GetMsg(code int) string {
+	return ErrorMap[code]
+}
 func newException(code int, msg string) error {
 func newException(code int, msg string) error {
 	return &EtaError{
 	return &EtaError{
 		ErrorCode: code,
 		ErrorCode: code,

+ 3 - 0
common/utils/client/http_client.go

@@ -30,6 +30,9 @@ func NewClient(timeout time.Duration, maxRetries int, delayFunc ...RetryDelayFun
 	}
 	}
 }
 }
 
 
+func DefaultClient() *HttpClient {
+	return NewClient(time.Second*10, 3)
+}
 func defaultRetryDelayFunc(attempt int) time.Duration {
 func defaultRetryDelayFunc(attempt int) time.Duration {
 	delay := time.Duration(attempt) * time.Second
 	delay := time.Duration(attempt) * time.Second
 	if attempt > 0 {
 	if attempt > 0 {

+ 77 - 0
common/utils/jwt/jwt_utils.go

@@ -0,0 +1,77 @@
+package jwt
+
+import (
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/exception"
+	"github.com/dgrijalva/jwt-go"
+	"time"
+)
+
+type Claims struct {
+	OpenId string `json:"open_id"`
+	Mobile string `json:"mobile"`
+	jwt.StandardClaims
+}
+
+var (
+	KEY = []byte("5Mb5Gdmb5y")
+)
+
+// CreateToken 生成token
+func CreateToken(openId string, mobile string) (tokenString string, err error) {
+
+	claims := &Claims{
+		openId,
+		mobile,
+		jwt.StandardClaims{
+			NotBefore: time.Now().Unix(),
+			ExpiresAt: time.Now().Add(time.Hour * 24 * 90).Unix(),
+		},
+	}
+	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+	tokenString, err = token.SignedString(KEY)
+	if err != nil {
+		logger.Error("生成token失败", err)
+	}
+	return
+}
+
+type JwtInfo struct {
+	OpenId string
+	Mobile string
+}
+
+// CheckToken 校验token
+func CheckToken(tokenStr string) (info JwtInfo, err error) {
+	token, err := jwt.Parse(tokenStr, func(*jwt.Token) (interface{}, error) {
+		return KEY, nil
+	})
+	if err != nil {
+		logger.Error("解析Token失败:%v", err)
+		err = exception.New(exception.JWTTokenDecodeFailed)
+		return
+	}
+	if claims, ok := token.Claims.(jwt.MapClaims); ok {
+		nbf, _ := claims["nbf"].(float64)
+		exp, _ := claims["exp"].(float64)
+
+		if float64(time.Now().Unix()) < nbf {
+			logger.Error("Token无效")
+			err = exception.New(exception.JWTTokenInvalid)
+			return
+		}
+		if float64(time.Now().Unix()) >= exp {
+			logger.Error("Token已过期")
+			err = exception.New(exception.JWTTokenExpired)
+			return
+		}
+		info = JwtInfo{
+			OpenId: claims["open_id"].(string),
+			Mobile: claims["mobile"].(string),
+		}
+		return
+	}
+	logger.Error("claims解析失败")
+	err = exception.New(exception.JWTTokenDecodeFailed)
+	return
+}

+ 6 - 1
common/utils/redis/key_generator.go

@@ -3,9 +3,14 @@ package redis
 import "fmt"
 import "fmt"
 
 
 const (
 const (
-	SmsKeyPrefix = "sms_code:"
+	SmsKeyPrefix     = "sms_code:"
+	LoginTokenPrefix = "login:token:"
 )
 )
 
 
 func GenerateSmsKey(mobile string) string {
 func GenerateSmsKey(mobile string) string {
 	return fmt.Sprint(SmsKeyPrefix, mobile)
 	return fmt.Sprint(SmsKeyPrefix, mobile)
 }
 }
+
+func GenerateTokenKey(mobile string) string {
+	return fmt.Sprint(LoginTokenPrefix, mobile)
+}

+ 4 - 0
common/utils/redis/redis_client.go

@@ -11,6 +11,10 @@ type RedisClient interface {
 	GetStringWithContext(ctx context.Context, key string) string
 	GetStringWithContext(ctx context.Context, key string) string
 	SetString(key string, val string, timeout time.Duration) error
 	SetString(key string, val string, timeout time.Duration) error
 	SetStringWithContext(ctx context.Context, key string, val string, timeout time.Duration) error
 	SetStringWithContext(ctx context.Context, key string, val string, timeout time.Duration) error
+	GetHSet(key string) string
+	GetHSetWithContext(ctx context.Context, key string) string
+	SetHSet(key string, val string, timeout time.Duration) error
+	SetHSetWithContext(ctx context.Context, key string, val string, timeout time.Duration) error
 	Delete(key string) error
 	Delete(key string) error
 	DeleteWithContext(ctx context.Context, key string) error
 	DeleteWithContext(ctx context.Context, key string) error
 	IsExist(key string) bool
 	IsExist(key string) bool

+ 1 - 1
common/utils/sms/sms_client.go

@@ -17,7 +17,7 @@ const (
 type SMSClient interface {
 type SMSClient interface {
 	InitSender(config *config.SMSConfig)
 	InitSender(config *config.SMSConfig)
 	GetExpireMinute() int
 	GetExpireMinute() int
-	SendSms(mobile string, code string) (rs string, err error)
+	SendSms(mobile string, code string, smId int) (rs string, err error)
 }
 }
 
 
 var clients = make(map[string]Instance)
 var clients = make(map[string]Instance)

+ 6 - 6
conf/log/log_config.json

@@ -10,8 +10,8 @@
     {
     {
       "type": "file",
       "type": "file",
       "filename": "file/error.log",
       "filename": "file/error.log",
-      "maxlines": 10000,
-      "maxsize": 100,
+      "maxlines": 1000000,
+      "maxsize": 102400,
       "daily": true,
       "daily": true,
       "maxdays": 7,
       "maxdays": 7,
       "rotate": true,
       "rotate": true,
@@ -21,8 +21,8 @@
     {
     {
       "type": "file",
       "type": "file",
       "filename": "file/info.log",
       "filename": "file/info.log",
-      "maxlines": 50000,
-      "maxsize": 200,
+      "maxlines": 1000000,
+      "maxsize": 102400,
       "daily": true,
       "daily": true,
       "maxdays": 30,
       "maxdays": 30,
       "rotate": true,
       "rotate": true,
@@ -33,8 +33,8 @@
       "filter": "coin,orm....*",
       "filter": "coin,orm....*",
       "type": "file",
       "type": "file",
       "filename": "db/db.log",
       "filename": "db/db.log",
-      "maxlines": 50000,
-      "maxsize": 200,
+      "maxlines": 1000000,
+      "maxsize": 102400,
       "daily": false,
       "daily": false,
       "maxdays": 30,
       "maxdays": 30,
       "rotate": true,
       "rotate": true,

+ 20 - 21
controllers/base_controller.go

@@ -3,33 +3,28 @@ package controllers
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
-	"eta_mini_ht_api/common/component/cache"
 	logger "eta_mini_ht_api/common/component/log"
 	logger "eta_mini_ht_api/common/component/log"
 	"eta_mini_ht_api/common/exception"
 	"eta_mini_ht_api/common/exception"
 	"eta_mini_ht_api/common/http"
 	"eta_mini_ht_api/common/http"
 	"github.com/beego/beego/v2/server/web"
 	"github.com/beego/beego/v2/server/web"
 )
 )
 
 
-var (
-	redis *cache.RedisCache
-)
-
 type BaseController struct {
 type BaseController struct {
 	web.Controller
 	web.Controller
 }
 }
 
 
 type BaseResponse struct {
 type BaseResponse struct {
-	Ret         int `description:"返回状态码"`
-	Msg         string
-	ErrMsg      string
-	ErrCode     int
-	Data        interface{}
-	Success     bool `description:"true 执行成功,false 执行失败"`
-	IsSendEmail bool `json:"-" description:"true 发送邮件,false 不发送邮件"`
-	IsAddLog    bool `json:"-" description:"true 新增操作日志,false 不新增操作日志" `
+	Ret     int `description:"返回状态码"`
+	Msg     string
+	ErrMsg  string
+	ErrCode int
+	Data    interface{}
+	Success bool `description:"true 执行成功,false 执行失败"`
+	//IsSendEmail bool `json:"-" description:"true 发送邮件,false 不发送邮件"`
+	//IsAddLog    bool `json:"-" description:"true 新增操作日志,false 不新增操作日志" `
 }
 }
 
 
-func (b *BaseController) FailResponse(errInfo error) {
+func (b *BaseController) FailResponse(errInfo error, msg string) {
 
 
 	var retData BaseResponse
 	var retData BaseResponse
 	var etaError *exception.EtaError
 	var etaError *exception.EtaError
@@ -38,7 +33,7 @@ func (b *BaseController) FailResponse(errInfo error) {
 	}
 	}
 	retData = BaseResponse{
 	retData = BaseResponse{
 		Ret:     200,
 		Ret:     200,
-		Msg:     "",
+		Msg:     msg,
 		ErrMsg:  etaError.ErrorMsg,
 		ErrMsg:  etaError.ErrorMsg,
 		ErrCode: etaError.ErrorCode,
 		ErrCode: etaError.ErrorCode,
 		Data:    nil}
 		Data:    nil}
@@ -78,7 +73,7 @@ func Wrap(a *BaseController, fn func() (*WrapData, error)) {
 	result, err := fn()
 	result, err := fn()
 	if err != nil {
 	if err != nil {
 		logger.Error("%v", err)
 		logger.Error("%v", err)
-		a.FailResponse(err)
+		a.FailResponse(err, result.Msg)
 		return
 		return
 	}
 	}
 	a.JsonResult(http.GetHttpStatusByAlias("ok"), http.ErrOK, "", result.Msg, http.Success, result.Data)
 	a.JsonResult(http.GetHttpStatusByAlias("ok"), http.ErrOK, "", result.Msg, http.Success, result.Data)
@@ -89,9 +84,13 @@ type WrapData struct {
 	Data interface{}
 	Data interface{}
 }
 }
 
 
-func (b *BaseController) Cache() *cache.RedisCache {
-	if redis == nil {
-		redis = cache.GetInstance()
-	}
-	return redis
+func (b *BaseController) InitWrapData(msg string) *WrapData {
+	return &WrapData{Msg: msg}
+}
+func (b *BaseController) SuccessResult(msg string, data interface{}, wrapData *WrapData) {
+	wrapData.Msg = msg
+	wrapData.Data = data
+}
+func (b *BaseController) FailedResult(msg string, wrapData *WrapData) {
+	wrapData.Msg = msg
 }
 }

+ 50 - 37
controllers/user/auth_controller.go

@@ -2,53 +2,71 @@ package user
 
 
 import (
 import (
 	logger "eta_mini_ht_api/common/component/log"
 	logger "eta_mini_ht_api/common/component/log"
-	"eta_mini_ht_api/common/component/wechat"
 	"eta_mini_ht_api/common/exception"
 	"eta_mini_ht_api/common/exception"
 	authUtils "eta_mini_ht_api/common/utils/auth"
 	authUtils "eta_mini_ht_api/common/utils/auth"
-	"eta_mini_ht_api/common/utils/redis"
-	"eta_mini_ht_api/common/utils/sms"
 	"eta_mini_ht_api/controllers"
 	"eta_mini_ht_api/controllers"
-	"fmt"
+	"eta_mini_ht_api/service/auth"
 )
 )
 
 
 type AuthController struct {
 type AuthController struct {
 	controllers.BaseController
 	controllers.BaseController
 }
 }
 
 
-var (
-	smsSender sms.SMSClient
+//func (a *AuthController) Prepare() {
+//	if wechatClient == nil {
+//		wechatClient = wechat.GetInstance()
+//	}
+//}
 
 
-	wechatClient *wechat.Client
-)
-
-func (a *AuthController) message() sms.SMSClient {
-	if smsSender == nil {
-		smsSender = sms.GetInstance()
-	}
-	return smsSender
-}
-func (a *AuthController) Prepare() {
-	if wechatClient == nil {
-		wechatClient = wechat.GetInstance()
-	}
-}
-
-// SmsCodeReq 获取验证码请求
+// LoginReq  获取验证码请求
 type LoginReq struct {
 type LoginReq struct {
-	Code string `json:"code"`
+	Code       string `json:"code"`
+	VerifyCode string `json:"verify_code"`
+	Mobile     string `json:"mobile"`
 }
 }
 
 
 // Login 小程序登录接口
 // Login 小程序登录接口
 // @Summary 小程序用户登录
 // @Summary 小程序用户登录
 // @Description 用户通过微信小程序登录
 // @Description 用户通过微信小程序登录
-// @Param   code     body    string  true        "获取微信小程序code"
+// @Param   mobile     body    LoginReq  true        "登录请求体"
 // @Success 200 {object} controllers.BaseResponse
 // @Success 200 {object} controllers.BaseResponse
 // @router /login [post]
 // @router /login [post]
 func (a *AuthController) Login() {
 func (a *AuthController) Login() {
-	loginReq := new(LoginReq)
-	a.GetPostParams(loginReq)
-	wechatClient.Login(loginReq.Code)
-	//wechatClient.GetAccessToken(loginReq.Code)
+	controllers.Wrap(&a.BaseController, func() (result *controllers.WrapData, err error) {
+		result = a.InitWrapData("登录失败")
+		loginReq := new(LoginReq)
+		a.GetPostParams(loginReq)
+		if !authUtils.IsValidMobile(loginReq.Mobile) {
+			a.FailedResult("登录失败", result)
+			err = exception.New(exception.IllegalPhoneNumber)
+			return
+		}
+		err = auth.CheckUser(loginReq.Mobile, loginReq.VerifyCode)
+		if err != nil {
+			a.FailedResult("登录失败", result)
+			logger.Warn("验证码校验失败:%v", err)
+			return
+		}
+		//注册用户或者登录
+		var token string
+		token, err = auth.Login(auth.LoginDTO{
+			VerifyCode: loginReq.VerifyCode,
+			Code:       loginReq.Code,
+			Mobile:     loginReq.Mobile,
+		})
+		if err != nil {
+			a.FailedResult("登录失败", result)
+			return
+		}
+		a.SuccessResult("登录成功", &LoginResp{
+			Token: token,
+		}, result)
+		return
+	})
+}
+
+type LoginResp struct {
+	Token string
 }
 }
 
 
 // SmsCodeReq 获取验证码请求
 // SmsCodeReq 获取验证码请求
@@ -64,25 +82,20 @@ type SmsCodeReq struct {
 // @router /sendCode [post]
 // @router /sendCode [post]
 func (a *AuthController) SMSCode() {
 func (a *AuthController) SMSCode() {
 	controllers.Wrap(&a.BaseController, func() (result *controllers.WrapData, err error) {
 	controllers.Wrap(&a.BaseController, func() (result *controllers.WrapData, err error) {
+		result = a.InitWrapData("发送短信失败")
 		mobile := new(SmsCodeReq)
 		mobile := new(SmsCodeReq)
 		a.GetPostParams(mobile)
 		a.GetPostParams(mobile)
 		phoneNum := mobile.Mobile
 		phoneNum := mobile.Mobile
 		if !authUtils.IsValidMobile(phoneNum) {
 		if !authUtils.IsValidMobile(phoneNum) {
 			return result, exception.New(exception.IllegalPhoneNumber)
 			return result, exception.New(exception.IllegalPhoneNumber)
 		}
 		}
-		code, err := authUtils.GenerateCode(6)
-		if err != nil {
-			logger.Warn("生成验证码失败:%v", err)
-			return result, exception.New(exception.SMSCodeGenerateFailed)
-		}
-		fmt.Println("验证码:", code)
+		//
 		//发送短息
 		//发送短息
-		_, err = a.message().SendSms(phoneNum, code)
+		err = auth.SendSMSCode(phoneNum)
 		if err != nil {
 		if err != nil {
 			logger.Warn("发送短信失败:%v", err)
 			logger.Warn("发送短信失败:%v", err)
-			return result, exception.New(exception.SendingSMSFailed)
+			return result, err
 		}
 		}
-		err = a.Cache().SetString(redis.GenerateSmsKey(phoneNum), code, a.message().GetExpireMinute())
 		if err != nil {
 		if err != nil {
 			return result, err
 			return result, err
 		}
 		}

+ 2 - 6
controllers/user/user_controller.go

@@ -1,11 +1,9 @@
 package user
 package user
 
 
 import (
 import (
-	"errors"
 	"eta_mini_ht_api/common/component/cache"
 	"eta_mini_ht_api/common/component/cache"
 	logger "eta_mini_ht_api/common/component/log"
 	logger "eta_mini_ht_api/common/component/log"
 	"eta_mini_ht_api/controllers"
 	"eta_mini_ht_api/controllers"
-	"eta_mini_ht_api/domian/user"
 	"fmt"
 	"fmt"
 )
 )
 
 
@@ -28,10 +26,8 @@ type LoginCode struct {
 // @Description get all Users
 // @Description get all Users
 // @Success 200 {object} models.User
 // @Success 200 {object} models.User
 // @router / [get]
 // @router / [get]
-func (u *UserController) GetAll() {
-	logger.Warn("查询用户列表:%s", errors.New("chakanjieuog"))
+func (u *UserController) Get() {
+	logger.Warn("查询用户列表:%s")
 	fmt.Print("查询用户列表")
 	fmt.Print("查询用户列表")
-	users := user.GetUsers()
-	u.Data["json"] = users
 	u.ServeJSON()
 	u.ServeJSON()
 }
 }

+ 7 - 1
domian/sms/emas_sms_service.go

@@ -2,7 +2,12 @@ package sms
 
 
 import "eta_mini_ht_api/models/sms"
 import "eta_mini_ht_api/models/sms"
 
 
+const (
+	hzCode = 1
+)
+
 type Msg struct {
 type Msg struct {
+	SMId    int
 	Mobile  string
 	Mobile  string
 	Content string
 	Content string
 }
 }
@@ -18,7 +23,8 @@ func SendSms(msg Msg) (err error) {
 
 
 func convert(msg Msg) sms.ApiMtZsyyt {
 func convert(msg Msg) sms.ApiMtZsyyt {
 	return sms.ApiMtZsyyt{
 	return sms.ApiMtZsyyt{
-		SMID:    1,
+		SrcID:   hzCode,
+		SMID:    msg.SMId,
 		Mobiles: msg.Mobile,
 		Mobiles: msg.Mobile,
 		Content: msg.Content,
 		Content: msg.Content,
 	}
 	}

+ 70 - 0
domian/sms/sms_service.go

@@ -0,0 +1,70 @@
+package sms
+
+import (
+	"eta_mini_ht_api/common/component/cache"
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/utils/redis"
+	"eta_mini_ht_api/models/sms"
+)
+
+const (
+	secondToMinute = 60
+)
+
+var (
+	redisCache *cache.RedisCache
+)
+
+type CodeDTO struct {
+	Mobile       string
+	Code         string
+	ExpireMinute int
+}
+
+func rd() *cache.RedisCache {
+	if redisCache == nil {
+		redisCache = cache.GetInstance()
+	}
+	return redisCache
+}
+
+func TryExpireCode(codeDTO CodeDTO) (err error) {
+	verificationRecord := convertCodeDTO(codeDTO)
+	verificationRecord.Status = sms.StatusExpired
+	return sms.UpdateVerificationRecordByCode(codeDTO.Mobile, codeDTO.Code, verificationRecord)
+}
+
+func TryVerifiedCode(codeDTO CodeDTO) (err error) {
+	verificationRecord := convertCodeDTO(codeDTO)
+	verificationRecord.Status = sms.StatusVerified
+	return sms.UpdateVerificationRecordByCode(codeDTO.Mobile, codeDTO.Code, verificationRecord)
+}
+
+func VerifiedCodeTask() (err error) {
+	return sms.ExpiredCodesByTask()
+}
+func SendSMSCode(codeDTO CodeDTO) (smid int, err error) {
+	verificationRecord := convertCodeDTO(codeDTO)
+	//写库
+	smid, err = sms.InsertVerificationRecord(verificationRecord)
+	if err != nil {
+		logger.Error("插入验证记录失败:", err)
+		return
+	}
+	//设置redis
+	err = rd().SetString(redis.GenerateSmsKey(codeDTO.Mobile), codeDTO.Code, codeDTO.ExpireMinute*secondToMinute)
+	if err != nil {
+		logger.Error("redis验证记录操作失败:", err)
+		return
+	}
+	return
+}
+
+func convertCodeDTO(codeDTO CodeDTO) sms.VerificationRecord {
+	return sms.VerificationRecord{
+		Mobile:          codeDTO.Mobile,
+		Code:            codeDTO.Code,
+		ExpiredDuration: codeDTO.ExpireMinute,
+		Status:          sms.StatusPending,
+	}
+}

+ 56 - 3
domian/user/user_serivce.go

@@ -1,7 +1,60 @@
 package user
 package user
 
 
-import "eta_mini_ht_api/models"
+import (
+	"errors"
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/models/user"
+	"gorm.io/gorm"
+)
 
 
-func GetUsers() *[]models.User {
-	return models.GetAllUsers()
+type UserDTO struct {
+	Username string
+	Mobile   string
+	OpenId   string
+	UnionId  string
+}
+
+func convertUserDTO(user user.TemplateUser) UserDTO {
+	return UserDTO{
+		Username: user.Username,
+		Mobile:   user.Mobile,
+	}
+}
+func GetUserByMobile(mobile string) (UserDTO, error) {
+	var dto UserDTO
+	templateUser, err := user.GetUserByMobile(mobile)
+	if err != nil {
+		if !errors.Is(err, gorm.ErrRecordNotFound) {
+			logger.Error("查询用户失败:%v", err)
+		}
+		return dto, err
+	}
+	dto = convertUserDTO(templateUser)
+	return dto, nil
+}
+
+func RegisterTemplateUser(dto *UserDTO) (err error) {
+	templateUser := convertToTemplateUser(dto)
+	err = user.RegisterTemplateUser(&templateUser)
+	if err != nil {
+		logger.Error("创建临时用户失败:%v", err)
+		return
+	}
+	convertToUserDTO(templateUser, dto)
+	return
+}
+func convertToTemplateUser(dto *UserDTO) user.TemplateUser {
+	return user.TemplateUser{
+		Username: dto.Username,
+		Mobile:   dto.Mobile,
+		OpenId:   dto.OpenId,
+		UnionId:  dto.UnionId,
+	}
+}
+
+func convertToUserDTO(templateUser user.TemplateUser, dto *UserDTO) {
+	dto.Username = templateUser.Username
+	dto.Mobile = templateUser.Mobile
+	dto.OpenId = templateUser.OpenId
+	dto.UnionId = templateUser.UnionId
 }
 }

BIN
eta_mini_ht_api.exe~


+ 1 - 0
go.mod

@@ -15,6 +15,7 @@ require (
 	filippo.io/edwards25519 v1.1.0 // indirect
 	filippo.io/edwards25519 v1.1.0 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
 	github.com/cespare/xxhash/v2 v2.2.0 // indirect
+	github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/fatih/color v1.16.0 // indirect
 	github.com/fatih/color v1.16.0 // indirect
 	github.com/go-sql-driver/mysql v1.8.1 // indirect
 	github.com/go-sql-driver/mysql v1.8.1 // indirect

+ 2 - 0
go.sum

@@ -9,6 +9,8 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 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/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=
 github.com/elazarl/go-bindata-assetfs v1.0.1 h1:m0kkaHRKEu7tUIUFVwhGGGYClXvyl4RE03qmvRTNfbw=

+ 27 - 0
job/eta/eta_report_task.go

@@ -0,0 +1,27 @@
+package eta
+
+import (
+	"context"
+	"eta_mini_ht_api/models/eta"
+	"fmt"
+	"github.com/beego/beego/v2/task"
+)
+
+const (
+	TaskName = "etaReportSyncTask"
+)
+
+// Task ETA取研报的数据
+func Task() task.TaskFunc {
+	return func(ctx context.Context) error {
+		fmt.Println("开始同步研报库")
+		eta.GetETAReports()
+
+		return nil
+	}
+}
+func Init() {
+	tk := task.NewTask(TaskName, "* 0/10 * * * *", Task())
+	task.AddTask(TaskName, tk)
+	//task.StartTask()
+}

+ 11 - 0
job/eta/eta_report_task_test.go

@@ -0,0 +1,11 @@
+package eta
+
+import (
+	"eta_mini_ht_api/models/eta"
+	"testing"
+)
+
+func TestInit(t *testing.T) {
+	eta.GetETAReports()
+
+}

+ 30 - 0
job/sms/code_expired_task.go

@@ -0,0 +1,30 @@
+package sms
+
+import (
+	"context"
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/domian/sms"
+	"fmt"
+	"github.com/beego/beego/v2/task"
+)
+
+const (
+	TaskName = "expiredCodeTask"
+)
+
+// Task ETA取研报的数据
+func Task() task.TaskFunc {
+	return func(ctx context.Context) error {
+		fmt.Println("开始处理过期短信")
+		err := sms.VerifiedCodeTask()
+		if err != nil {
+			logger.Error("自动更新短信状态失败:%v", err)
+		}
+		return err
+	}
+}
+func Init() {
+	tk := task.NewTask(TaskName, "0/10 * * * * *", Task())
+	task.AddTask(TaskName, tk)
+	task.StartTask()
+}

+ 15 - 0
job/task_service.go

@@ -0,0 +1,15 @@
+package job
+
+import (
+	"eta_mini_ht_api/job/sms"
+	"github.com/beego/beego/v2/task"
+)
+
+type ETATask interface {
+	Task() task.TaskFunc
+}
+
+func init() {
+	//eta.Init()
+	sms.Init()
+}

+ 5 - 2
main.go

@@ -3,6 +3,9 @@ package main
 import (
 import (
 	_ "eta_mini_ht_api/common/component"
 	_ "eta_mini_ht_api/common/component"
 	logger "eta_mini_ht_api/common/component/log"
 	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/exception"
+	_ "eta_mini_ht_api/job"
+	"eta_mini_ht_api/middleware"
 	_ "eta_mini_ht_api/routers"
 	_ "eta_mini_ht_api/routers"
 	"github.com/beego/beego/v2/server/web"
 	"github.com/beego/beego/v2/server/web"
 )
 )
@@ -22,9 +25,9 @@ func main() {
 	//	MaxAge:           12 * time.Hour,
 	//	MaxAge:           12 * time.Hour,
 	//}))
 	//}))
 	//增加授权拦截
 	//增加授权拦截
-	//web.InsertFilter("*", web.BeforeRouter, middleware.AuthMiddleware())
+	web.InsertFilter("*", web.BeforeRouter, middleware.AuthMiddleware())
 	//web.ErrorHandler("*", exception.ControllerAdvice())
 	//web.ErrorHandler("*", exception.ControllerAdvice())
-	//web.BConfig.RecoverFunc = exception.PanicAdvice
+	web.BConfig.RecoverFunc = exception.PanicAdvice
 	go func() {
 	go func() {
 		//内存数据预热预加载
 		//内存数据预热预加载
 		logger.Info("开始预加载数据")
 		logger.Info("开始预加载数据")

+ 71 - 10
middleware/auth_middleware.go

@@ -1,29 +1,90 @@
 package middleware
 package middleware
 
 
 import (
 import (
+	"eta_mini_ht_api/common/component/cache"
 	logger "eta_mini_ht_api/common/component/log"
 	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/exception"
+	"eta_mini_ht_api/common/utils/jwt"
+	"eta_mini_ht_api/common/utils/redis"
+	stringUtils "eta_mini_ht_api/common/utils/string"
+	"eta_mini_ht_api/controllers"
 	"github.com/beego/beego/v2/server/web"
 	"github.com/beego/beego/v2/server/web"
 	"github.com/beego/beego/v2/server/web/context"
 	"github.com/beego/beego/v2/server/web/context"
-	"net/http"
+	"strings"
+)
+
+var (
+	rdCache *cache.RedisCache
 )
 )
 
 
 const (
 const (
-	UNAUTHORIZED = "未授权"
-	FORBIDDEN    = "禁止访问"
-	NOTFOUND     = "未找到"
+	UNAUTHORIZED  = "未授权"
+	FORBIDDEN     = "禁止访问"
+	NOTFOUND      = "未找到"
+	authorization = "Authorization"
+	baseUrl       = "/htapi"
 )
 )
 
 
+func rd() *cache.RedisCache {
+	if rdCache == nil {
+		rdCache = cache.GetInstance()
+	}
+	return rdCache
+}
+
+var publicRoutes = []string{
+	"/auth/*",
+}
+
 func AuthMiddleware() web.FilterFunc {
 func AuthMiddleware() web.FilterFunc {
 	return func(ctx *context.Context) {
 	return func(ctx *context.Context) {
 		path := ctx.Input.URL()
 		path := ctx.Input.URL()
 		logger.Info("请求路径:%v", path)
 		logger.Info("请求路径:%v", path)
-		if path == "/swagger" || path == "/swagger/*" || path == "/favicon.ico" {
-			return
+		if !allowed(path) {
+			auth := ctx.Input.Header(authorization)
+			if auth == "" {
+				logger.Error("token信息不存在")
+				_ = ctx.JSONResp(unAuthorized)
+			}
+			info, err := jwt.CheckToken(auth)
+			if err != nil {
+				logger.Error("token无效:%v", err)
+				_ = ctx.JSONResp(unAuthorized)
+			}
+			//校验redis中是否合法
+			redisToken := rd().GetString(redis.GenerateTokenKey(info.Mobile))
+			if redisToken != auth {
+				logger.Error("token无效:用户token已刷新")
+				_ = ctx.JSONResp(unAuthorized())
+			}
 		}
 		}
-		auth := ctx.Input.Header("author")
-		if auth == "" {
-			logger.Error("author is empty")
-			ctx.Abort(http.StatusUnauthorized, UNAUTHORIZED)
+	}
+}
+
+func unAuthorized() controllers.BaseResponse {
+	return controllers.BaseResponse{
+		Ret:    401,
+		Msg:    UNAUTHORIZED,
+		ErrMsg: exception.GetMsg(exception.Unauthorized),
+	}
+}
+func allowed(path string) bool {
+	for _, p := range publicRoutes {
+		if stringUtils.IsBlank(p) {
+			continue
+		}
+		src := baseUrl + p
+		if strings.HasSuffix(p, "*") {
+
+			target := src[:len(src)-1]
+			if strings.HasPrefix(path, target) {
+				return true
+			}
+		} else {
+			if src == path {
+				return true
+			}
 		}
 		}
 	}
 	}
+	return false
 }
 }

+ 18 - 0
models/base_db.go

@@ -0,0 +1,18 @@
+package models
+
+import (
+	"eta_mini_ht_api/common/component/database"
+	"gorm.io/gorm"
+)
+
+func Main() *gorm.DB {
+	return database.Select(database.MAIN)
+}
+
+func EMAS() *gorm.DB {
+	return database.Select(database.EMAS)
+}
+
+func ETA() *gorm.DB {
+	return database.Select(database.ETA)
+}

+ 49 - 0
models/eta/eta_report.go

@@ -0,0 +1,49 @@
+package eta
+
+import (
+	"encoding/json"
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/models"
+	"strings"
+)
+
+const (
+	colunms   = "id,author,abstract,title,publish_time,"
+	published = 2
+	passed    = 6
+
+	limit = 500
+)
+
+var (
+	classifyIds = []string{"classify_id_third", "classify_id_second", "classify_id_first"}
+)
+
+func (ETAReport) TableName() string {
+	return "report"
+}
+
+type ETAReport struct {
+	ID               int    `gorm:"primary_key;auto_increment" json:"id"`
+	ClassifyID       int    `gorm:"_" json:"classify_id"`
+	ClassifyIDFirst  int    `gorm:"column:classify_id_first;default:0" json:"classify_id_first"`
+	ClassifyIDSecond int    `gorm:"column:classify_id_second;default:0" json:"classify_id_second"`
+	ClassifyIDThird  int    `gorm:"column:classify_id_third;default:0" json:"classify_id_third"`
+	Title            string `gorm:"column:title;size:125;" json:"title"`
+	Abstract         string `gorm:"column:abstract;size:255;" json:"abstract"`
+	Author           string `gorm:"column:author;size:50;" json:"author"`
+	PublishTime      string `gorm:"column:publish_time" json:"publish_time"`
+}
+
+func GetETAReports() (reports []ETAReport, err error) {
+	err = models.ETA().Table("report").Select(colunms+strings.Join(classifyIds, ",")).Where("state =? or state=?", published, passed).Where("id > ?", 0).Order("id").Limit(limit).Find(&reports).Error
+	if err != nil {
+		logger.Error("同步eta数据失败", err)
+	}
+	str, _ := json.Marshal(reports[0])
+	logger.Info(string(str))
+	return
+}
+func ClassifyId() {
+
+}

+ 7 - 11
models/sms/api_mt_zsyyt.go

@@ -1,23 +1,22 @@
 package sms
 package sms
 
 
 import (
 import (
-	"eta_mini_ht_api/common/component/database"
-	"gorm.io/gorm"
+	"eta_mini_ht_api/models"
 	"time"
 	"time"
 )
 )
 
 
 type ApiMtZsyyt struct {
 type ApiMtZsyyt struct {
-	SMID           uint32    `gorm:"column:SM_ID;type:decimal(8,0) unsigned;not null;default:0"`
-	SrcID          uint32    `gorm:"column:SRC_ID;type:decimal(8,0) unsigned;not null;default:0"`
+	SMID           int       `gorm:"column:SM_ID;type:decimal(8,0) unsigned;not null;default:0"`
+	SrcID          int       `gorm:"column:SRC_ID;type:decimal(8,0) unsigned;not null;default:0"`
 	Mobiles        string    `gorm:"column:MOBILES;type:longtext;not null"`
 	Mobiles        string    `gorm:"column:MOBILES;type:longtext;not null"`
 	Content        string    `gorm:"column:CONTENT;type:text;not null"`
 	Content        string    `gorm:"column:CONTENT;type:text;not null"`
 	IsWap          bool      `gorm:"column:IS_WAP;type:tinyint(1);not null;default:0"`
 	IsWap          bool      `gorm:"column:IS_WAP;type:tinyint(1);not null;default:0"`
 	URL            string    `gorm:"column:URL;type:varchar(110);not null;default:''"`
 	URL            string    `gorm:"column:URL;type:varchar(110);not null;default:''"`
 	SendTime       time.Time `gorm:"column:SEND_TIME;type:datetime;default:'0000-00-00 00:00:00'"`
 	SendTime       time.Time `gorm:"column:SEND_TIME;type:datetime;default:'0000-00-00 00:00:00'"`
-	SmType         uint8     `gorm:"column:SM_TYPE;type:tinyint(1);not null;default:0"`
+	SmType         int       `gorm:"column:SM_TYPE;type:tinyint(1);not null;default:0"`
 	MsgFmt         int       `gorm:"column:MSG_FMT;type:int(11);not null;default:0"`
 	MsgFmt         int       `gorm:"column:MSG_FMT;type:int(11);not null;default:0"`
-	TpPid          uint8     `gorm:"column:TP_PID;type:tinyint(1);not null;default:0"`
-	TpUdhi         uint8     `gorm:"column:TP_UDHI;type:tinyint(1);not null;default:0"`
+	TpPid          int       `gorm:"column:TP_PID;type:tinyint(1);not null;default:0"`
+	TpUdhi         int       `gorm:"column:TP_UDHI;type:tinyint(1);not null;default:0"`
 	FeeTerminalId  string    `gorm:"column:FEE_TERMINAL_ID;type:varchar(10);not null;default:''"`
 	FeeTerminalId  string    `gorm:"column:FEE_TERMINAL_ID;type:varchar(10);not null;default:''"`
 	FeeType        string    `gorm:"column:FEE_TYPE;type:varchar(10);not null;default:''"`
 	FeeType        string    `gorm:"column:FEE_TYPE;type:varchar(10);not null;default:''"`
 	FeeCode        string    `gorm:"column:FEE_CODE;type:varchar(10);not null;default:''"`
 	FeeCode        string    `gorm:"column:FEE_CODE;type:varchar(10);not null;default:''"`
@@ -28,14 +27,11 @@ type ApiMtZsyyt struct {
 func (ApiMtZsyyt) TableName() string {
 func (ApiMtZsyyt) TableName() string {
 	return "api_mt_zsyyt"
 	return "api_mt_zsyyt"
 }
 }
-func db() *gorm.DB {
-	return database.Select(database.EMAS)
-}
 
 
 // 发送短信方法
 // 发送短信方法
 func Send(msg ApiMtZsyyt) error {
 func Send(msg ApiMtZsyyt) error {
 	// 创建记录
 	// 创建记录
-	err := db().Create(&msg).Error
+	err := models.EMAS().Create(&msg).Error
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 0 - 5
models/sms/sms_code.go

@@ -1,5 +0,0 @@
-package sms
-
-func saveCode() {
-
-}

+ 80 - 0
models/sms/verification_record.go

@@ -0,0 +1,80 @@
+package sms
+
+import (
+	logger "eta_mini_ht_api/common/component/log"
+	stringUtils "eta_mini_ht_api/common/utils/string"
+	"eta_mini_ht_api/models"
+	"gorm.io/gorm"
+	"time"
+)
+
+// VerificationRecord represents a record of verification request and status.
+type VerificationRecord struct {
+	ID              int                `gorm:"primaryKey;autoIncrement;type:bigint(20) unsigned"`
+	Mobile          string             `gorm:"not null;comment:'手机号码';type:varchar(15)"`
+	Code            string             `gorm:"not null;comment:'验证码';type:varchar(10)"`
+	RequestTime     time.Time          `gorm:"default:CURRENT_TIMESTAMP;not null;comment:'请求时间'"`
+	Status          VerificationStatus `gorm:"not null;comment:'操作状态';type:enum('PENDING','VERIFIED','EXPIRED','FAILED')"`
+	ExpiredTime     time.Time          `gorm:"not null;comment:'过期时间'"`
+	ExpiredDuration int                `gorm:"-"`
+}
+
+// VerificationStatus is an enumeration for the status field.
+type VerificationStatus string
+
+const (
+	StatusPending  VerificationStatus = "PENDING"
+	StatusVerified VerificationStatus = "VERIFIED"
+	StatusExpired  VerificationStatus = "EXPIRED"
+)
+
+// BeforeCreate hook to set the current time as the request time before creating a new record.
+func (v *VerificationRecord) BeforeCreate(tx *gorm.DB) (err error) {
+	v.RequestTime = time.Now()
+	v.ExpiredTime = v.RequestTime.Add(time.Duration(v.ExpiredDuration) * time.Minute)
+	return
+}
+
+func UpdateVerificationRecordByCode(mobile string, code string, record VerificationRecord) (err error) {
+	if stringUtils.IsEmptyOrNil(code) {
+		logger.Info("code为空,不做更新")
+		return
+	}
+	conditions := map[string]interface{}{
+		"mobile": mobile,
+		"code":   code,
+	}
+	err = updateByConditions(conditions, record)
+	if err != nil {
+		logger.Error("更新验证码状态失败:%v", err)
+	}
+	return
+}
+func ExpiredCodesByTask() (err error) {
+	db := models.Main()
+	err = db.Model(&VerificationRecord{}).Where("expired_time < ?", time.Now()).Where("status =?", StatusPending).Update("status", StatusExpired).Error
+	if err != nil {
+		logger.Error("批量过期验证码失败:%v", err)
+	}
+	return
+}
+func updateByConditions(conditions map[string]interface{}, record VerificationRecord) (err error) {
+	db := models.Main()
+	// 使用 conditions 构建 WHERE 条件
+	for k, v := range conditions {
+		db = db.Where(k, v)
+	}
+	err = db.Updates(record).Error
+	if err != nil {
+		logger.Error("更新验证码记录失败:%v", err)
+	}
+	return
+}
+func InsertVerificationRecord(record VerificationRecord) (smId int, err error) {
+	err = models.Main().Create(&record).Error
+	if err != nil {
+		logger.Error("插入验证码记录失败:%v", err)
+	}
+	smId = int(record.ID)
+	return
+}

+ 0 - 22
models/user.go

@@ -1,22 +0,0 @@
-package models
-
-import (
-	"eta_mini_ht_api/common/component/database"
-	"gorm.io/gorm"
-)
-
-type User struct {
-	gorm.Model
-	Gender   string `gorm:"column:gender;type:varchar(10);comment:性别"`
-	Username string `gorm:"column:username;type:varchar(20);comment:用户名"`
-	Password string
-	Mobile   string
-	OpenId   string
-	NickName string
-}
-
-func GetAllUsers() *[]User {
-	var users []User
-	database.GetInstance().Unscoped().Find(&users)
-	return &users
-}

+ 40 - 0
models/user/template_user.go

@@ -0,0 +1,40 @@
+package user
+
+import (
+	"eta_mini_ht_api/models"
+	"gorm.io/gorm"
+	"time"
+)
+
+const (
+	NotDeleted = 0
+	Deleted    = 1
+)
+
+type TemplateUser struct {
+	Username    string    `gorm:"column:username;type:varchar(20);comment:用户名"`
+	Mobile      string    `gorm:"column:mobile;type:varchar(15);comment:手机号"`
+	OpenId      string    `gorm:"column:open_id;type:varchar(50);comment:open_id"`
+	UnionId     string    `gorm:"column:union_id;type:varchar(50);comment:union_id"`
+	IsDeleted   int       `gorm:"column:is_deleted;type:int(11);comment:是否删除"`
+	CreatedTime time.Time `gorm:"column:created_time;type:timestamps;comment:创建时间"`
+	UpdatedTime time.Time `gorm:"column:updated_time;type:timestamps;comment:更新时间"`
+}
+
+func (t *TemplateUser) BeforeCreate(tx *gorm.DB) (err error) {
+	t.CreatedTime = time.Now()
+	t.IsDeleted = NotDeleted
+	return
+}
+func GetUserByMobile(mobile string) (user TemplateUser, err error) {
+	return queryByColumn("mobile", mobile)
+}
+
+func queryByColumn(column string, value string) (user TemplateUser, err error) {
+	err = models.Main().Unscoped().Where(column, value).First(&user).Error
+	return
+}
+func RegisterTemplateUser(user *TemplateUser) (err error) {
+	err = models.Main().Create(&user).Error
+	return
+}

+ 1 - 1
routers/commentsRouter.go

@@ -27,7 +27,7 @@ func init() {
 
 
     beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:UserController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:UserController"],
     beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:UserController"] = append(beego.GlobalControllerRouter["eta_mini_ht_api/controllers/user:UserController"],
         beego.ControllerComments{
         beego.ControllerComments{
-            Method: "GetAll",
+            Method: "Get",
             Router: `/`,
             Router: `/`,
             AllowHTTPMethods: []string{"get"},
             AllowHTTPMethods: []string{"get"},
             MethodParams: param.Make(),
             MethodParams: param.Make(),

+ 182 - 0
service/auth/auth_service.go

@@ -0,0 +1,182 @@
+package auth
+
+import (
+	"crypto/rand"
+	"encoding/base64"
+	"errors"
+	"eta_mini_ht_api/common/component/cache"
+	logger "eta_mini_ht_api/common/component/log"
+	"eta_mini_ht_api/common/component/wechat"
+	"eta_mini_ht_api/common/exception"
+	authUtils "eta_mini_ht_api/common/utils/auth"
+	"eta_mini_ht_api/common/utils/jwt"
+	"eta_mini_ht_api/common/utils/redis"
+	"eta_mini_ht_api/common/utils/sms"
+	stringUtils "eta_mini_ht_api/common/utils/string"
+	smsService "eta_mini_ht_api/domian/sms"
+	userService "eta_mini_ht_api/domian/user"
+	"fmt"
+	"gorm.io/gorm"
+	"strings"
+)
+
+var (
+	smsSender sms.SMSClient
+
+	wechatClient *wechat.Client
+
+	redisCache *cache.RedisCache
+)
+
+func message() sms.SMSClient {
+	if smsSender == nil {
+		smsSender = sms.GetInstance()
+	}
+	return smsSender
+}
+
+func wx() *wechat.Client {
+	if wechatClient == nil {
+		wechatClient = wechat.GetInstance()
+	}
+	return wechatClient
+}
+func SendSMSCode(mobile string) (err error) {
+	code := rd().GetString(redis.GenerateSmsKey(mobile))
+	if stringUtils.IsEmptyOrNil(code) {
+		code, err = authUtils.GenerateCode(6)
+		if err != nil {
+			logger.Warn("生成验证码失败:%v", err)
+			return exception.New(exception.SMSCodeGenerateFailed)
+		}
+		codeDTO := smsService.CodeDTO{
+			Mobile:       mobile,
+			Code:         code,
+			ExpireMinute: message().GetExpireMinute(),
+		}
+		//消息domain层
+		var smid int
+		smid, err = smsService.SendSMSCode(codeDTO)
+		if err != nil {
+			logger.Error("发送短信失败:%v", err)
+			err = exception.New(exception.SendingSMSFailed)
+		}
+		logger.Debug("验证码:%v", code)
+		_, err = message().SendSms(mobile, code, smid)
+		if err != nil {
+			logger.Error("发送短信失败:%v", err)
+			err = exception.New(exception.SendingSMSFailed)
+		}
+		return
+	}
+	return exception.New(exception.SMSCodeAlreadySent)
+}
+
+func CheckUser(mobile string, code string) (err error) {
+	smsCode := rd().GetString(redis.GenerateSmsKey(mobile))
+	if stringUtils.IsEmptyOrNil(smsCode) {
+		logger.Warn("验证码已过期:%v", code)
+		codeDTO := smsService.CodeDTO{
+			Mobile: mobile,
+			Code:   code,
+		}
+		_ = smsService.TryExpireCode(codeDTO)
+		err = exception.New(exception.SMSCodeExpired)
+		return
+	}
+	if smsCode != code {
+		err = exception.New(exception.SMSCodeError)
+		return
+	}
+	return nil
+}
+
+type LoginDTO struct {
+	VerifyCode string
+	Code       string
+	Mobile     string
+}
+
+func Login(login LoginDTO) (token string, err error) {
+	var user userService.UserDTO
+	user, err = userService.GetUserByMobile(login.Mobile)
+	if err != nil {
+		if !errors.Is(err, gorm.ErrRecordNotFound) {
+			err = exception.New(exception.UnknownError)
+			return
+		}
+		//注册用户
+		var wechatInfo wechat.WxUser
+		//微信请求异常
+		wechatInfo, err = wx().Login(login.Code)
+		//微信客户端的异常不做处理,已经是EtaError
+		if err != nil {
+			return
+		}
+		user = initUser(wechatInfo, login)
+		err = userService.RegisterTemplateUser(&user)
+		if err != nil {
+			err = exception.New(exception.TemplateUserCreateFailed)
+			return
+		}
+	}
+	token, err = jwt.CreateToken(user.OpenId, user.Mobile)
+	if err != nil {
+		err = exception.New(exception.GenerateTokenFailed)
+		return
+	}
+	err = rd().SetString(redis.GenerateTokenKey(user.Mobile), token, 90*24*60*60)
+	if err != nil {
+		err = exception.New(exception.GenerateTokenFailed)
+		return
+	}
+	codeDTO := smsService.CodeDTO{
+		Mobile: login.Mobile,
+		Code:   login.VerifyCode,
+	}
+	//登录成功删除短信验证码,数据库留痕
+	err = rd().Delete(redis.GenerateSmsKey(login.Mobile))
+	if err != nil {
+		logger.Error("清除redis 短信验证码失败,%v", err)
+		_ = rd().SetString(redis.GenerateSmsKey(login.Mobile), "", 1)
+		return "", err
+	}
+	_ = smsService.TryVerifiedCode(codeDTO)
+	return
+}
+
+func initUser(user wechat.WxUser, dto LoginDTO) userService.UserDTO {
+	username := generateRandomUsername(user.OpenId)
+	if stringUtils.IsBlank(username) {
+		username = dto.Mobile
+	}
+	return userService.UserDTO{
+		OpenId:   user.OpenId,
+		UnionId:  user.UnionId,
+		Username: username,
+		Mobile:   dto.Mobile,
+	}
+}
+
+// GenerateRandomUsername 生成基于UnionId的随机用户名
+func generateRandomUsername(openId string) string {
+	// 生成一个随机的4字节二进制数据
+	randomBytes := make([]byte, 4)
+	_, err := rand.Read(randomBytes)
+	if err != nil {
+		return ""
+	}
+	// 将随机字节转换为base64编码的URL安全字符串
+	// 并去掉可能出现的等于号
+	randomStr := strings.TrimRight(base64.URLEncoding.EncodeToString(randomBytes), "=")
+	// 拼接UnionId和随机字符串
+	username := fmt.Sprintf("%s_%s", openId, randomStr)
+	return username
+}
+
+func rd() *cache.RedisCache {
+	if redisCache == nil {
+		redisCache = cache.GetInstance()
+	}
+	return redisCache
+}

+ 9 - 51
swagger/swagger.json

@@ -15,13 +15,12 @@
                 "parameters": [
                 "parameters": [
                     {
                     {
                         "in": "body",
                         "in": "body",
-                        "name": "code",
-                        "description": "获取微信小程序code",
+                        "name": "mobile",
+                        "description": "登录请求体",
                         "required": true,
                         "required": true,
                         "schema": {
                         "schema": {
-                            "type": "string"
-                        },
-                        "type": "string"
+                            "$ref": "#/definitions/LoginReq"
+                        }
                     }
                     }
                 ],
                 ],
                 "responses": {
                 "responses": {
@@ -81,6 +80,10 @@
         }
         }
     },
     },
     "definitions": {
     "definitions": {
+        "LoginReq": {
+            "title": "LoginReq",
+            "type": "object"
+        },
         "SmsCodeReq": {
         "SmsCodeReq": {
             "title": "SmsCodeReq",
             "title": "SmsCodeReq",
             "type": "object"
             "type": "object"
@@ -117,54 +120,9 @@
             "title": "interface",
             "title": "interface",
             "type": "object"
             "type": "object"
         },
         },
-        "gorm.DeletedAt": {
-            "title": "DeletedAt",
-            "type": "object"
-        },
-        "gorm.Model": {
-            "title": "Model",
-            "type": "object",
-            "properties": {
-                "CreatedAt": {
-                    "type": "string",
-                    "format": "datetime"
-                },
-                "DeletedAt": {
-                    "$ref": "#/definitions/gorm.DeletedAt"
-                },
-                "ID": {
-                    "type": "integer",
-                    "format": "int32"
-                },
-                "UpdatedAt": {
-                    "type": "string",
-                    "format": "datetime"
-                }
-            }
-        },
         "models.User": {
         "models.User": {
             "title": "User",
             "title": "User",
-            "type": "object",
-            "properties": {
-                "Gender": {
-                    "type": "string"
-                },
-                "Mobile": {
-                    "type": "string"
-                },
-                "NickName": {
-                    "type": "string"
-                },
-                "OpenId": {
-                    "type": "string"
-                },
-                "Password": {
-                    "type": "string"
-                },
-                "Username": {
-                    "type": "string"
-                }
-            }
+            "type": "object"
         }
         }
     },
     },
     "tags": [
     "tags": [

+ 6 - 35
swagger/swagger.yml

@@ -12,12 +12,11 @@ paths:
         <br>
         <br>
       parameters:
       parameters:
       - in: body
       - in: body
-        name: code
-        description: 获取微信小程序code
+        name: mobile
+        description: 登录请求体
         required: true
         required: true
         schema:
         schema:
-          type: string
-        type: string
+          $ref: '#/definitions/LoginReq'
       responses:
       responses:
         "200":
         "200":
           description: ""
           description: ""
@@ -57,6 +56,9 @@ paths:
           schema:
           schema:
             $ref: '#/definitions/models.User'
             $ref: '#/definitions/models.User'
 definitions:
 definitions:
+  LoginReq:
+    title: LoginReq
+    type: object
   SmsCodeReq:
   SmsCodeReq:
     title: SmsCodeReq
     title: SmsCodeReq
     type: object
     type: object
@@ -83,40 +85,9 @@ definitions:
   controllers.interface:
   controllers.interface:
     title: interface
     title: interface
     type: object
     type: object
-  gorm.DeletedAt:
-    title: DeletedAt
-    type: object
-  gorm.Model:
-    title: Model
-    type: object
-    properties:
-      CreatedAt:
-        type: string
-        format: datetime
-      DeletedAt:
-        $ref: '#/definitions/gorm.DeletedAt'
-      ID:
-        type: integer
-        format: int32
-      UpdatedAt:
-        type: string
-        format: datetime
   models.User:
   models.User:
     title: User
     title: User
     type: object
     type: object
-    properties:
-      Gender:
-        type: string
-      Mobile:
-        type: string
-      NickName:
-        type: string
-      OpenId:
-        type: string
-      Password:
-        type: string
-      Username:
-        type: string
 tags:
 tags:
 - name: user
 - name: user
   description: |
   description: |