|
@@ -0,0 +1,888 @@
|
|
|
+package controllers
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/base64"
|
|
|
+ "encoding/json"
|
|
|
+ "fmt"
|
|
|
+ "github.com/mojocn/base64Captcha"
|
|
|
+ "hongze/hongze_ETA_mobile_api/models"
|
|
|
+ "hongze/hongze_ETA_mobile_api/models/company"
|
|
|
+ "hongze/hongze_ETA_mobile_api/models/system"
|
|
|
+ "hongze/hongze_ETA_mobile_api/services"
|
|
|
+ "hongze/hongze_ETA_mobile_api/utils"
|
|
|
+ "image/color"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+// UserLoginController 登录-无需Token
|
|
|
+type UserLoginController struct {
|
|
|
+ BaseCommonController
|
|
|
+}
|
|
|
+
|
|
|
+// UserLoginAuthController 登录-需Token
|
|
|
+type UserLoginAuthController struct {
|
|
|
+ BaseAuthController
|
|
|
+}
|
|
|
+
|
|
|
+// GenerateCaptcha
|
|
|
+// @Title 生成图形验证码
|
|
|
+// @Description 生成图形验证码
|
|
|
+// @Success 200 Ret=200 获取成功
|
|
|
+// @router /get_captcha [get]
|
|
|
+func (this *UserLoginController) GenerateCaptcha() {
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
+ defer func() {
|
|
|
+ if br.ErrMsg == "" {
|
|
|
+ br.IsSendEmail = false
|
|
|
+ }
|
|
|
+ this.Data["json"] = br
|
|
|
+ this.ServeJSON()
|
|
|
+ }()
|
|
|
+
|
|
|
+ //driver := base64Captcha.DefaultDriverDigit
|
|
|
+ // 自定义验证码样式
|
|
|
+ var driver base64Captcha.Driver
|
|
|
+ driverString := base64Captcha.DriverString{
|
|
|
+ Height: 60, //高度
|
|
|
+ Width: 120, //宽度
|
|
|
+ NoiseCount: 0, //干扰数
|
|
|
+ ShowLineOptions: 2 | 4, //展示个数
|
|
|
+ Length: 4, //长度
|
|
|
+ //Source: "1234567890qwertyuioplkjhgfdsazxcvbnm", //验证码随机字符串来源
|
|
|
+ Source: "1234567890", //验证码随机字符串来源
|
|
|
+ BgColor: &color.RGBA{ // 背景颜色
|
|
|
+ R: 0,
|
|
|
+ G: 0,
|
|
|
+ B: 0,
|
|
|
+ A: 0,
|
|
|
+ },
|
|
|
+ Fonts: []string{"wqy-microhei.ttc"}, // 字体
|
|
|
+ }
|
|
|
+ driver = driverString.ConvertFonts()
|
|
|
+
|
|
|
+ // 生成验证码
|
|
|
+ store := services.CaptchaRedis{}
|
|
|
+ captcha := base64Captcha.NewCaptcha(driver, store)
|
|
|
+ id, b64s, err := captcha.Generate()
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "生成失败"
|
|
|
+ br.ErrMsg = "生成验证码失败, Err: " + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ type CaptchaResult struct {
|
|
|
+ Id string
|
|
|
+ Base64Blob string
|
|
|
+ }
|
|
|
+ res := new(CaptchaResult)
|
|
|
+ res.Id = id
|
|
|
+ res.Base64Blob = b64s
|
|
|
+
|
|
|
+ br.Ret = 200
|
|
|
+ br.Success = true
|
|
|
+ br.Msg = "获取成功"
|
|
|
+ br.Data = res
|
|
|
+}
|
|
|
+
|
|
|
+// GetVerifyCode
|
|
|
+// @Title 获取短信/邮箱验证码
|
|
|
+// @Description 获取短信/邮箱验证码
|
|
|
+// @Param request body VerifyCodeReq true "type json string"
|
|
|
+// @Success 200 Ret=200 获取成功
|
|
|
+// @router /verify_code [post]
|
|
|
+func (this *UserLoginController) GetVerifyCode() {
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
+ defer func() {
|
|
|
+ if br.ErrMsg == "" {
|
|
|
+ br.IsSendEmail = false
|
|
|
+ }
|
|
|
+ this.Data["json"] = br
|
|
|
+ this.ServeJSON()
|
|
|
+ }()
|
|
|
+
|
|
|
+ type VerifyCodeReq struct {
|
|
|
+ VerifyType int `description:"验证方式: 1-手机号; 2-邮箱"`
|
|
|
+ CaptchaId string `description:"验证码ID"`
|
|
|
+ CaptchaCode string `description:"图形验证码"`
|
|
|
+ Mobile string `description:"手机号"`
|
|
|
+ TelAreaCode string `description:"手机区号"`
|
|
|
+ Email string `description:"邮箱"`
|
|
|
+ Source int `description:"来源:1-登录;2-异常登录校验;3-忘记密码"`
|
|
|
+ }
|
|
|
+ var req VerifyCodeReq
|
|
|
+ err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "参数解析异常!"
|
|
|
+ br.ErrMsg = "参数解析失败,Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.VerifyType != 1 && req.VerifyType != 2 {
|
|
|
+ br.Msg = "验证方式有误"
|
|
|
+ br.ErrMsg = "验证方式有误"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.Source != 1 && req.Source != 2 && req.Source != 3 {
|
|
|
+ br.Msg = "来源有误"
|
|
|
+ br.ErrMsg = "来源有误"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 忘记密码图形校验在前一步, 这一步不再校验图形验证码
|
|
|
+ if req.Source != 3 {
|
|
|
+ if req.CaptchaId == "" || req.CaptchaCode == "" {
|
|
|
+ br.Msg = "请输入图形验证码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if req.VerifyType == 1 {
|
|
|
+ if req.TelAreaCode == "" {
|
|
|
+ br.Msg = "请选择区号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.Mobile == "" {
|
|
|
+ br.Msg = "请输入手机号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.TelAreaCode == "86" && !utils.ValidateMobileFormatat(req.Mobile) {
|
|
|
+ br.Msg = "您的手机号输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ _, e := system.GetSysUserByMobile(req.Mobile)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "您的手机号未绑定账号, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "您的手机号未绑定账号, 请检查"
|
|
|
+ br.ErrMsg = "手机号获取用户失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if req.VerifyType == 2 {
|
|
|
+ if req.Email == "" {
|
|
|
+ br.Msg = "请输入邮箱"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if !utils.ValidateEmailFormatat(req.Email) {
|
|
|
+ br.Msg = "您的邮箱输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ _, e := system.GetSysUserByEmail(req.Email)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "您的邮箱未绑定账号, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "您的邮箱未绑定账号, 请检查"
|
|
|
+ br.ErrMsg = "邮箱获取用户失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if req.Source != 3 {
|
|
|
+ store := services.CaptchaRedis{}
|
|
|
+ ok := store.Verify(req.CaptchaId, req.CaptchaCode, true)
|
|
|
+ if !ok {
|
|
|
+ br.Msg = "图形验证码错误, 请重新输入"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 限制最多60s获取一次
|
|
|
+ var lockKey string
|
|
|
+ if req.VerifyType == 1 {
|
|
|
+ lockKey = fmt.Sprint(utils.CaptchaCachePrefix, req.Mobile)
|
|
|
+ }
|
|
|
+ if req.VerifyType == 2 {
|
|
|
+ lockKey = fmt.Sprint(utils.CaptchaCachePrefix, req.Email)
|
|
|
+ }
|
|
|
+ locked := utils.Rc.SetNX(lockKey, 1, time.Minute)
|
|
|
+ if !locked {
|
|
|
+ br.Msg = "请勿频繁发送"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 发送验证码
|
|
|
+ sendRes := false
|
|
|
+ if req.VerifyType == 1 {
|
|
|
+ r, e := services.SendAdminMobileVerifyCode(req.Source, req.Mobile, req.TelAreaCode)
|
|
|
+ if e != nil {
|
|
|
+ br.Msg = "发送失败"
|
|
|
+ br.ErrMsg = "发送短信验证码失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sendRes = r
|
|
|
+ }
|
|
|
+ if req.VerifyType == 2 {
|
|
|
+ r, e := services.SendAdminEmailVerifyCode(req.Source, req.Email)
|
|
|
+ if e != nil {
|
|
|
+ br.Msg = "发送失败"
|
|
|
+ br.ErrMsg = "发送邮箱验证码失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sendRes = r
|
|
|
+ }
|
|
|
+ if !sendRes {
|
|
|
+ br.Msg = "发送失败"
|
|
|
+ br.ErrMsg = "发送短信验证码失败"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ br.Ret = 200
|
|
|
+ br.Success = true
|
|
|
+ br.Msg = "发送成功"
|
|
|
+}
|
|
|
+
|
|
|
+// Login
|
|
|
+// @Title 用户登录
|
|
|
+// @Description 用户登录
|
|
|
+// @Param request body UserLoginReq true "type json string"
|
|
|
+// @Success 200 {object} models.LoginResp
|
|
|
+// @router /login [post]
|
|
|
+func (this *UserLoginController) Login() {
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
+ defer func() {
|
|
|
+ if br.ErrMsg != "" {
|
|
|
+ br.IsSendEmail = false
|
|
|
+ }
|
|
|
+ this.Data["json"] = br
|
|
|
+ this.ServeJSON()
|
|
|
+ }()
|
|
|
+
|
|
|
+ // 入参
|
|
|
+ type UserLoginReq struct {
|
|
|
+ LoginType int `description:"登录方式: 1-账号; 2-手机号; 3-邮箱"`
|
|
|
+ Username string `description:"账号"`
|
|
|
+ Password string `description:"密码"`
|
|
|
+ Mobile string `description:"手机号"`
|
|
|
+ Email string `description:"邮箱"`
|
|
|
+ VerifyCode string `description:"验证码"`
|
|
|
+ }
|
|
|
+ var req UserLoginReq
|
|
|
+ err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "参数解析异常!"
|
|
|
+ br.ErrMsg = "参数解析失败,Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ req.Username = strings.TrimSpace(req.Username)
|
|
|
+ req.Mobile = strings.TrimSpace(req.Mobile)
|
|
|
+ if req.Mobile != "" {
|
|
|
+ if !utils.ValidateMobileFormatat(req.Mobile) {
|
|
|
+ br.Msg = "您的手机号输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ req.Email = strings.TrimSpace(req.Email)
|
|
|
+ if req.Email != "" {
|
|
|
+ if !utils.ValidateEmailFormatat(req.Email) {
|
|
|
+ br.Msg = "您的邮箱输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ req.VerifyCode = strings.TrimSpace(req.VerifyCode)
|
|
|
+ if req.LoginType != 1 && req.LoginType != 2 && req.LoginType != 3 {
|
|
|
+ br.Msg = "登录方式有误"
|
|
|
+ br.ErrMsg = fmt.Sprintf("登录方式有误, Type: %d", req.LoginType)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ sysUser := new(system.Admin)
|
|
|
+ // 账号密码登录
|
|
|
+ if req.LoginType == 1 {
|
|
|
+ if req.Username == "" {
|
|
|
+ br.Msg = "请输入账号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.Password == "" {
|
|
|
+ br.Msg = "请输入密码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断账号是否为异常登录, 算作异常的话就需要换另外的方式去做登录了
|
|
|
+ abnormalKey := fmt.Sprint(utils.CACHE_ABNORMAL_LOGIN, req.Username)
|
|
|
+ isAbnormal, _ := utils.Rc.RedisString(abnormalKey)
|
|
|
+ if isAbnormal != "" {
|
|
|
+ br.Ret = models.BaseRespCodeAbnormalLogin
|
|
|
+ br.Msg = "账号异常, 请进行手机号/邮箱校验"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 账号密码校验
|
|
|
+ errPassKey := fmt.Sprint(utils.CACHE_LOGIN_ERR_PASS, req.Username)
|
|
|
+ accountUser, e := system.CheckSysUser(req.Username, req.Password)
|
|
|
+ if e != nil {
|
|
|
+ br.Ret = models.BaseRespCodeLoginErr
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "登录失败, 账号或密码错误"
|
|
|
+ if isAbnormal != "" {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // 错误密码计数, 超过6次标记异常
|
|
|
+ if !utils.Rc.IsExist(errPassKey) {
|
|
|
+ _ = utils.Rc.Put(errPassKey, 1, utils.GetTodayLastSecond())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ errNum, _ := utils.Rc.RedisInt(errPassKey)
|
|
|
+ errNum += 1
|
|
|
+ if errNum >= 6 {
|
|
|
+ br.Ret = models.BaseRespCodeAbnormalLogin
|
|
|
+ br.Msg = "账号异常, 请进行手机号/邮箱校验"
|
|
|
+ // 标记异常登录, 重置计数
|
|
|
+ _ = utils.Rc.Put(abnormalKey, "true", utils.GetTodayLastSecond())
|
|
|
+ _ = utils.Rc.Delete(errPassKey)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ _ = utils.Rc.Put(errPassKey, errNum, utils.GetTodayLastSecond())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "登录失败, 账号或密码错误"
|
|
|
+ br.ErrMsg = "登录失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if accountUser.Enabled == 0 {
|
|
|
+ br.Msg = "您的账号已被禁用, 如需登录, 请联系管理员"
|
|
|
+ br.ErrMsg = fmt.Sprintf("账号已被禁用, 登录账号: %s, 账户名称: %s", accountUser.AdminName, accountUser.RealName)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 异常登录-是否登录间隔大于60天
|
|
|
+ if isAbnormal == "" {
|
|
|
+ abnormalTime := time.Now().AddDate(0, 0, -60)
|
|
|
+ lastLogin, _ := time.ParseInLocation(utils.FormatDateTime, accountUser.LastLoginTime, time.Local)
|
|
|
+ if !lastLogin.IsZero() && lastLogin.Before(abnormalTime) {
|
|
|
+ br.Msg = "请进行异常登录校验"
|
|
|
+ br.Ret = models.BaseRespCodeAbnormalLogin
|
|
|
+ // 标记异常登录
|
|
|
+ _ = utils.Rc.Put(abnormalKey, "true", utils.GetTodayLastSecond())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 登录成功, 清除异常标记
|
|
|
+ _ = utils.Rc.Delete(abnormalKey)
|
|
|
+ _ = utils.Rc.Delete(errPassKey)
|
|
|
+ sysUser = accountUser
|
|
|
+ }
|
|
|
+
|
|
|
+ // 手机号
|
|
|
+ if req.LoginType == 2 {
|
|
|
+ if req.Mobile == "" {
|
|
|
+ br.Msg = "请输入手机号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if !utils.ValidateMobileFormatat(req.Mobile) {
|
|
|
+ br.Msg = "您的手机号输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.VerifyCode == "" {
|
|
|
+ br.Msg = "请输入验证码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ expiredTime := time.Now().Add(utils.VerifyCodeExpireMinute * time.Minute).Format(utils.FormatDateTime)
|
|
|
+ recordCond := ` AND source = ? AND mobile = ? AND code = ? AND expired_time <= ?`
|
|
|
+ recordPars := make([]interface{}, 0)
|
|
|
+ recordPars = append(recordPars, system.AdminVerifyCodeRecordSourceLogin, req.Mobile, req.VerifyCode, expiredTime)
|
|
|
+ recordOb := new(system.AdminVerifyCodeRecord)
|
|
|
+ _, e := recordOb.GetItemByCondition(recordCond, recordPars)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ br.ErrMsg = "获取手机号登陆验证码失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ mobileUser, e := system.GetSysUserByMobile(req.Mobile)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "您的手机号未绑定账号, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "您的手机号未绑定账号, 请检查"
|
|
|
+ br.ErrMsg = "手机号获取用户失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if mobileUser.Enabled == 0 {
|
|
|
+ br.Msg = "您的账号已被禁用, 如需登录, 请联系管理员"
|
|
|
+ br.ErrMsg = fmt.Sprintf("账号已被禁用, 登录手机号: %s", req.Mobile)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sysUser = mobileUser
|
|
|
+ }
|
|
|
+
|
|
|
+ // 邮箱登录
|
|
|
+ if req.LoginType == 3 {
|
|
|
+ if req.Email == "" {
|
|
|
+ br.Msg = "请输入邮箱"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if !utils.ValidateEmailFormatat(req.Email) {
|
|
|
+ br.Msg = "您的邮箱输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.VerifyCode == "" {
|
|
|
+ br.Msg = "请输入验证码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ expiredTime := time.Now().Add(utils.VerifyCodeExpireMinute * time.Minute).Format(utils.FormatDateTime)
|
|
|
+ recordCond := ` AND source = ? AND email = ? AND code = ? AND expired_time <= ?`
|
|
|
+ recordPars := make([]interface{}, 0)
|
|
|
+ recordPars = append(recordPars, system.AdminVerifyCodeRecordSourceLogin, req.Email, req.VerifyCode, expiredTime)
|
|
|
+ recordOb := new(system.AdminVerifyCodeRecord)
|
|
|
+ _, e := recordOb.GetItemByCondition(recordCond, recordPars)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ br.ErrMsg = "获取手机号登陆验证码失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ emailUser, e := system.GetSysUserByEmail(req.Email)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "您的邮箱未绑定账号, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "您的邮箱未绑定账号, 请检查"
|
|
|
+ br.ErrMsg = "邮箱获取用户失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if emailUser.Enabled == 0 {
|
|
|
+ br.Msg = "您的账号已被禁用, 如需登录, 请联系管理员"
|
|
|
+ br.ErrMsg = fmt.Sprintf("账号已被禁用, 登录邮箱: %s", req.Email)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ sysUser = emailUser
|
|
|
+ }
|
|
|
+
|
|
|
+ // 登录成功(无论哪种方式登录), 清除异常标记
|
|
|
+ abnormalCache := fmt.Sprint(utils.CACHE_ABNORMAL_LOGIN, sysUser.AdminName)
|
|
|
+ errPassCache := fmt.Sprint(utils.CACHE_LOGIN_ERR_PASS, sysUser.AdminName)
|
|
|
+ _ = utils.Rc.Delete(abnormalCache)
|
|
|
+ _ = utils.Rc.Delete(errPassCache)
|
|
|
+
|
|
|
+ account := utils.MD5(sysUser.AdminName)
|
|
|
+ token := utils.GenToken(account)
|
|
|
+ sysSession := new(system.SysSession)
|
|
|
+ sysSession.UserName = req.Username
|
|
|
+ sysSession.SysUserId = sysUser.AdminId
|
|
|
+ sysSession.ExpiredTime = time.Now().AddDate(0, 0, 90)
|
|
|
+ sysSession.IsRemember = 0 // 均需要做过期校验
|
|
|
+ sysSession.CreatedTime = time.Now()
|
|
|
+ sysSession.LastUpdatedTime = time.Now()
|
|
|
+ sysSession.AccessToken = token
|
|
|
+ if e := system.AddSysSession(sysSession); e != nil {
|
|
|
+ br.Msg = "登录失败"
|
|
|
+ br.ErrMsg = "新增session信息失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 修改最后登录时间
|
|
|
+ {
|
|
|
+ sysUser.LastLoginTime = time.Now().Format(utils.FormatDateTime)
|
|
|
+ sysUser.LastUpdatedTime = time.Now().Format(utils.FormatDateTime)
|
|
|
+ _ = sysUser.Update([]string{"LastLoginTime", "LastUpdatedTime"})
|
|
|
+ }
|
|
|
+
|
|
|
+ resp := new(system.LoginResp)
|
|
|
+ resp.Authorization = token
|
|
|
+ resp.Authorization = "authorization=" + token + "$account=" + account
|
|
|
+ resp.RealName = sysUser.RealName
|
|
|
+ resp.AdminName = sysUser.AdminName
|
|
|
+ resp.RoleName = sysUser.RoleName
|
|
|
+ resp.SysRoleTypeCode = sysUser.RoleTypeCode //系统角色编码
|
|
|
+ resp.RoleTypeCode = sysUser.RoleTypeCode
|
|
|
+ if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_GROUP {
|
|
|
+ resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
|
|
|
+ }
|
|
|
+ if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_TEAM {
|
|
|
+ resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
|
|
|
+ }
|
|
|
+ if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_FICC_DEPARTMENT {
|
|
|
+ resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
|
|
|
+ }
|
|
|
+ if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_GROUP {
|
|
|
+ resp.RoleTypeCode = utils.ROLE_TYPE_CODE_RAI_SELLER
|
|
|
+ }
|
|
|
+ if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_RAI_DEPARTMENT {
|
|
|
+ resp.RoleTypeCode = utils.ROLE_TYPE_CODE_RAI_SELLER
|
|
|
+ }
|
|
|
+ if sysUser.RoleName == utils.ROLE_NAME_FICC_DIRECTOR {
|
|
|
+ resp.RoleTypeCode = utils.ROLE_TYPE_CODE_FICC_SELLER
|
|
|
+ }
|
|
|
+ resp.AdminId = sysUser.AdminId
|
|
|
+ var productName string
|
|
|
+ productId := services.GetProductId(sysUser.RoleTypeCode)
|
|
|
+ if productId == 1 {
|
|
|
+ productName = utils.COMPANY_PRODUCT_FICC_NAME
|
|
|
+ } else if productId == 2 {
|
|
|
+ productName = utils.COMPANY_PRODUCT_RAI_NAME
|
|
|
+ } else {
|
|
|
+ productName = "admin"
|
|
|
+ }
|
|
|
+ resp.ProductName = productName
|
|
|
+ resp.Authority = sysUser.Authority
|
|
|
+
|
|
|
+ // 设置redis缓存
|
|
|
+ {
|
|
|
+ // 获取不可信的登录态,并将该登录态重置掉,不允许多次登录
|
|
|
+ noTrustLoginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN_NO_TRUST, sysUser.AdminId)
|
|
|
+ noTrustLoginId, _ := utils.Rc.RedisString(noTrustLoginKey)
|
|
|
+ if noTrustLoginId != `` { // 如果存在不可信设备,那么将其下架
|
|
|
+ oldNoTrustLoginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, noTrustLoginId)
|
|
|
+ _ = utils.Rc.Put(oldNoTrustLoginKey, "0", 30*time.Minute)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果当前是不可信设备,那么将其加入到不可信名单
|
|
|
+ loginKey := fmt.Sprint(utils.CACHE_ACCESS_TOKEN_LOGIN, sysSession.Id)
|
|
|
+ _ = utils.Rc.Put(loginKey, "1", 30*time.Minute)
|
|
|
+ _ = utils.Rc.Put(noTrustLoginKey, sysSession.Id, 30*time.Minute)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 新增登录记录
|
|
|
+ go func() {
|
|
|
+ record := new(system.SysUserLoginRecord)
|
|
|
+ record.Uid = sysUser.AdminId
|
|
|
+ record.UserName = req.Username
|
|
|
+ record.Ip = this.Ctx.Input.IP()
|
|
|
+ record.Stage = "login"
|
|
|
+ record.CreateTime = time.Now()
|
|
|
+ _ = system.AddSysUserLoginRecord(record)
|
|
|
+ }()
|
|
|
+
|
|
|
+ br.Data = resp
|
|
|
+ br.Ret = 200
|
|
|
+ br.Success = true
|
|
|
+ br.Msg = "登录成功"
|
|
|
+}
|
|
|
+
|
|
|
+// ForgetAccountGet
|
|
|
+// @Title 忘记密码-账号校验
|
|
|
+// @Description 忘记密码-账号校验
|
|
|
+// @Param request body ForgetAccountGetReq true "type json string"
|
|
|
+// @Success 200 Ret=200 获取成功
|
|
|
+// @router /forget/account_get [post]
|
|
|
+func (this *UserLoginController) ForgetAccountGet() {
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
+ defer func() {
|
|
|
+ if br.ErrMsg == "" {
|
|
|
+ br.IsSendEmail = false
|
|
|
+ }
|
|
|
+ this.Data["json"] = br
|
|
|
+ this.ServeJSON()
|
|
|
+ }()
|
|
|
+
|
|
|
+ type ForgetAccountGetReq struct {
|
|
|
+ CaptchaId string `description:"验证码ID"`
|
|
|
+ CaptchaCode string `description:"图形验证码"`
|
|
|
+ UserName string `description:"用户名"`
|
|
|
+ }
|
|
|
+ var req ForgetAccountGetReq
|
|
|
+ err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "参数解析异常!"
|
|
|
+ br.ErrMsg = "参数解析失败,Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ req.UserName = strings.TrimSpace(req.UserName)
|
|
|
+ if req.UserName == "" {
|
|
|
+ br.Msg = "请输入账号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.CaptchaId == "" || req.CaptchaCode == "" {
|
|
|
+ br.Msg = "请输入图形验证码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ store := services.CaptchaRedis{}
|
|
|
+ ok := store.Verify(req.CaptchaId, req.CaptchaCode, true)
|
|
|
+ if !ok {
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ sysUser, e := system.GetSysUserByAdminName(req.UserName)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "用户不存在, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "账号错误, 请重新输入"
|
|
|
+ br.ErrMsg = "用户名获取用户失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ type ForgetAccountCheckResp struct {
|
|
|
+ Mobile string `description:"手机号"`
|
|
|
+ Email string `description:"邮箱"`
|
|
|
+ TelAreaCode string `description:"手机区号"`
|
|
|
+ }
|
|
|
+ resp := ForgetAccountCheckResp{
|
|
|
+ Mobile: sysUser.Mobile,
|
|
|
+ Email: sysUser.Email,
|
|
|
+ TelAreaCode: sysUser.TelAreaCode,
|
|
|
+ }
|
|
|
+
|
|
|
+ br.Data = resp
|
|
|
+ br.Ret = 200
|
|
|
+ br.Success = true
|
|
|
+ br.Msg = "获取成功"
|
|
|
+}
|
|
|
+
|
|
|
+// ForgetCodeVerify
|
|
|
+// @Title 忘记密码-验证码校验
|
|
|
+// @Description 忘记密码-验证码校验
|
|
|
+// @Param request body ForgetCodeVerifyReq true "type json string"
|
|
|
+// @Success 200 Ret=200 获取成功
|
|
|
+// @router /forget/code_verify [post]
|
|
|
+func (this *UserLoginController) ForgetCodeVerify() {
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
+ defer func() {
|
|
|
+ if br.ErrMsg == "" {
|
|
|
+ br.IsSendEmail = false
|
|
|
+ }
|
|
|
+ this.Data["json"] = br
|
|
|
+ this.ServeJSON()
|
|
|
+ }()
|
|
|
+
|
|
|
+ type ForgetCodeVerifyReq struct {
|
|
|
+ FindType int `description:"密码找回方式: 1-手机号; 2-邮箱"`
|
|
|
+ VerifyCode string `description:"验证码"`
|
|
|
+ UserName string `description:"用户名"`
|
|
|
+ Mobile string `description:"手机号"`
|
|
|
+ Email string `description:"邮箱"`
|
|
|
+ }
|
|
|
+ var req ForgetCodeVerifyReq
|
|
|
+ err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "参数解析异常!"
|
|
|
+ br.ErrMsg = "参数解析失败,Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ req.UserName = strings.TrimSpace(req.UserName)
|
|
|
+ if req.UserName == "" {
|
|
|
+ br.Msg = "请输入账号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.VerifyCode == "" {
|
|
|
+ br.Msg = "请输入验证码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 手机号找回
|
|
|
+ var verifyRes bool
|
|
|
+ if req.FindType == 1 {
|
|
|
+ req.Mobile = strings.TrimSpace(req.Mobile)
|
|
|
+ if req.Mobile == "" {
|
|
|
+ br.Msg = "请输入手机号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if !utils.ValidateMobileFormatat(req.Mobile) {
|
|
|
+ br.Msg = "您的手机号输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ expiredTime := time.Now().Add(utils.VerifyCodeExpireMinute * time.Minute).Format(utils.FormatDateTime)
|
|
|
+ recordCond := ` AND source = ? AND mobile = ? AND code = ? AND expired_time <= ?`
|
|
|
+ recordPars := make([]interface{}, 0)
|
|
|
+ recordPars = append(recordPars, system.AdminVerifyCodeRecordSourceForget, req.Mobile, req.VerifyCode, expiredTime)
|
|
|
+ recordOb := new(system.AdminVerifyCodeRecord)
|
|
|
+ _, e := recordOb.GetItemByCondition(recordCond, recordPars)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ br.ErrMsg = "获取手机号登陆验证码失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ verifyRes = true
|
|
|
+ }
|
|
|
+
|
|
|
+ // 邮箱找回
|
|
|
+ if req.FindType == 2 {
|
|
|
+ req.Email = strings.TrimSpace(req.Email)
|
|
|
+ if req.Email == "" {
|
|
|
+ br.Msg = "请输入邮箱"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if !utils.ValidateEmailFormatat(req.Email) {
|
|
|
+ br.Msg = "您的邮箱输入有误, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ expiredTime := time.Now().Add(utils.VerifyCodeExpireMinute * time.Minute).Format(utils.FormatDateTime)
|
|
|
+ recordCond := ` AND source = ? AND email = ? AND code = ? AND expired_time <= ?`
|
|
|
+ recordPars := make([]interface{}, 0)
|
|
|
+ recordPars = append(recordPars, system.AdminVerifyCodeRecordSourceForget, req.Email, req.VerifyCode, expiredTime)
|
|
|
+ recordOb := new(system.AdminVerifyCodeRecord)
|
|
|
+ _, e := recordOb.GetItemByCondition(recordCond, recordPars)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "验证码错误, 请重新输入"
|
|
|
+ br.ErrMsg = "获取手机号登陆验证码失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ verifyRes = true
|
|
|
+ }
|
|
|
+
|
|
|
+ if verifyRes {
|
|
|
+ successKey := fmt.Sprint(utils.CACHE_FIND_PASS_VERIFY, req.UserName)
|
|
|
+ _ = utils.Rc.Put(successKey, "true", utils.GetTodayLastSecond())
|
|
|
+ }
|
|
|
+
|
|
|
+ br.Data = verifyRes
|
|
|
+ br.Ret = 200
|
|
|
+ br.Success = true
|
|
|
+ br.Msg = "操作成功"
|
|
|
+}
|
|
|
+
|
|
|
+// ForgetResetPass
|
|
|
+// @Title 忘记密码-重置密码
|
|
|
+// @Description 忘记密码-重置密码
|
|
|
+// @Param request body ForgetResetPassReq true "type json string"
|
|
|
+// @Success 200 Ret=200 获取成功
|
|
|
+// @router /forget/reset_pass [post]
|
|
|
+func (this *UserLoginController) ForgetResetPass() {
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
+ defer func() {
|
|
|
+ if br.ErrMsg == "" {
|
|
|
+ br.IsSendEmail = false
|
|
|
+ }
|
|
|
+ this.Data["json"] = br
|
|
|
+ this.ServeJSON()
|
|
|
+ }()
|
|
|
+
|
|
|
+ type ForgetResetPassReq struct {
|
|
|
+ UserName string `description:"用户名"`
|
|
|
+ Password string `description:"密码"`
|
|
|
+ RePassword string `description:"重复密码"`
|
|
|
+ }
|
|
|
+ var req ForgetResetPassReq
|
|
|
+ err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "参数解析异常!"
|
|
|
+ br.ErrMsg = "参数解析失败,Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ req.UserName = strings.TrimSpace(req.UserName)
|
|
|
+ if req.UserName == "" {
|
|
|
+ br.Msg = "请输入账号"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ req.Password = strings.TrimSpace(req.Password)
|
|
|
+ if req.Password == "" {
|
|
|
+ br.Msg = "请输入新密码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ req.RePassword = strings.TrimSpace(req.RePassword)
|
|
|
+ if req.RePassword == "" {
|
|
|
+ br.Msg = "请确认新密码"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if req.Password != req.RePassword {
|
|
|
+ br.Msg = "两次密码输入不一致, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 接上一步-验证码校验成功后才允许修改
|
|
|
+ successKey := fmt.Sprint(utils.CACHE_FIND_PASS_VERIFY, req.UserName)
|
|
|
+ verifyOk, _ := utils.Rc.RedisString(successKey)
|
|
|
+ if verifyOk != "true" {
|
|
|
+ br.Msg = "验证码校验失效, 请重新验证"
|
|
|
+ br.ErrMsg = "重置密码异常, 验证码校验已失效"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ sysUser, e := system.GetSysAdminByName(req.UserName)
|
|
|
+ if e != nil {
|
|
|
+ if e.Error() == utils.ErrNoRow() {
|
|
|
+ br.Msg = "用户不存在, 请检查"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ br.Msg = "操作失败"
|
|
|
+ br.ErrMsg = "密码找回获取用户失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ b, e := base64.StdEncoding.DecodeString(req.Password)
|
|
|
+ if e != nil {
|
|
|
+ br.Msg = "操作失败"
|
|
|
+ br.ErrMsg = "解析密码失败, Err:" + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ pwd := string(b)
|
|
|
+ pwd = utils.MD5(pwd)
|
|
|
+
|
|
|
+ sysUser.Password = pwd
|
|
|
+ sysUser.LastUpdatedPasswordTime = time.Now().Format(utils.FormatDateTime)
|
|
|
+ // 重置密码后更新一下登录时间, 不然账号密码登录如果超过60天还会被异常校验再校验一次, 影响体验
|
|
|
+ sysUser.LastLoginTime = time.Now().Format(utils.FormatDateTime)
|
|
|
+ sysUser.LastUpdatedTime = time.Now().Format(utils.FormatDateTime)
|
|
|
+ if e = sysUser.Update([]string{"Password", "LastUpdatedPasswordTime", "LastLoginTime", "LastUpdatedTime"}); e != nil {
|
|
|
+ br.Msg = "操作失败"
|
|
|
+ br.ErrMsg = "更新密码失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果有异常标记也清除掉
|
|
|
+ abnormalKey := fmt.Sprint(utils.CACHE_ABNORMAL_LOGIN, req.UserName)
|
|
|
+ _ = utils.Rc.Delete(abnormalKey)
|
|
|
+ _ = utils.Rc.Delete(successKey)
|
|
|
+
|
|
|
+ br.Data = true
|
|
|
+ br.Ret = 200
|
|
|
+ br.Success = true
|
|
|
+ br.Msg = "操作成功"
|
|
|
+}
|
|
|
+
|
|
|
+// AreaCodeList
|
|
|
+// @Title 手机号区号列表
|
|
|
+// @Description 手机号区号列表
|
|
|
+// @Success 200 Ret=200 获取成功
|
|
|
+// @router /area_code/list [get]
|
|
|
+func (this *UserLoginController) AreaCodeList() {
|
|
|
+ br := new(models.BaseResponse).Init()
|
|
|
+ defer func() {
|
|
|
+ if br.ErrMsg == "" {
|
|
|
+ br.IsSendEmail = false
|
|
|
+ }
|
|
|
+ this.Data["json"] = br
|
|
|
+ this.ServeJSON()
|
|
|
+ }()
|
|
|
+
|
|
|
+ type AreaCodeListResp struct {
|
|
|
+ Name string `description:"地区"`
|
|
|
+ Value string `description:"区号"`
|
|
|
+ }
|
|
|
+ resp := make([]AreaCodeListResp, 0)
|
|
|
+ confAuth, e := company.GetConfigDetailByCode(company.ConfAreaCodeListKey)
|
|
|
+ if e != nil {
|
|
|
+ br.Msg = "获取失败"
|
|
|
+ br.ErrMsg = "获取手机号区号配置失败, Err: " + e.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if confAuth.ConfigValue == "" {
|
|
|
+ br.Msg = "获取失败"
|
|
|
+ br.ErrMsg = "手机号区号配置为空"
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if e := json.Unmarshal([]byte(confAuth.ConfigValue), &resp); e != nil {
|
|
|
+ br.Msg = "获取失败"
|
|
|
+ br.ErrMsg = "手机号区号配置有误"
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ br.Data = resp
|
|
|
+ br.Ret = 200
|
|
|
+ br.Success = true
|
|
|
+ br.Msg = "获取成功"
|
|
|
+}
|