feat: import services and standardize Go 1.26.5
This commit is contained in:
103
apps/base/mgt/internal/logic/pub/forget.go
Normal file
103
apps/base/mgt/internal/logic/pub/forget.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package pub
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"git.apinb.com/bsm-apps/mgt/internal/impl"
|
||||
"git.apinb.com/bsm-apps/mgt/internal/libs"
|
||||
"git.apinb.com/bsm-apps/mgt/internal/models"
|
||||
"git.apinb.com/bsm-apps/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
coreutils "git.apinb.com/bsm-sdk/core/utils"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// ForgetPwdBySms 忘记密码-通过短信更改
|
||||
func ForgetPwdBySms(c *gin.Context) {
|
||||
request := types.ForgetPwdRequest{}
|
||||
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := libs.ValidateStruct(&request); err != nil {
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Code == "" {
|
||||
printer.Error("验证码不能为空")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
var data models.MgtUser
|
||||
if err := models.DBService.Model(&models.MgtUser{}).Where("account = ?", request.Account).First(&data).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if data.Phone != request.Phone {
|
||||
printer.Error("账号与手机号不匹配: account=%s, phone=%s", request.Account, request.Phone)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
smsKey := types.KeyPrefix + request.Phone
|
||||
storedCode, err := impl.RedisService.Client.Get(impl.RedisService.Ctx, smsKey).Result()
|
||||
if err != nil {
|
||||
if errors.Is(err, redis.Nil) {
|
||||
printer.Error("验证码已过期或不存在: phone=%s", request.Phone)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
printer.Error("读取验证码异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrInternal)
|
||||
return
|
||||
}
|
||||
if storedCode != request.Code {
|
||||
printer.Error("验证码不正确: phone=%s", request.Phone)
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
if data.Salt == "" {
|
||||
data.Salt = coreutils.UUID()
|
||||
}
|
||||
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(request.Password+data.Salt), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
printer.Error("密码加密异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrInternal)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DBService.Model(&models.MgtUser{}).Where("id = ?", data.ID).Updates(map[string]interface{}{
|
||||
"password": string(hashedPassword),
|
||||
"salt": data.Salt,
|
||||
}).Error; err != nil {
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
|
||||
if err := impl.RedisService.Client.Del(impl.RedisService.Ctx, smsKey).Err(); err != nil {
|
||||
printer.Error("清除验证码缓存异常: %v", err)
|
||||
}
|
||||
|
||||
printer.Info("密码重置成功: account=%s, phone=%s", request.Account, request.Phone)
|
||||
infra.Response.Success(c, "密码重置成功")
|
||||
}
|
||||
|
||||
// ForgetPwdByPwd 忘记密码-通过旧密码更改
|
||||
func ForgetPwdByPwd(c *gin.Context) {
|
||||
}
|
||||
158
apps/base/mgt/internal/logic/pub/login.go
Normal file
158
apps/base/mgt/internal/logic/pub/login.go
Normal file
@@ -0,0 +1,158 @@
|
||||
package pub
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"git.apinb.com/bsm-apps/mgt/internal/impl"
|
||||
"git.apinb.com/bsm-apps/mgt/internal/models"
|
||||
"git.apinb.com/bsm-apps/mgt/internal/types"
|
||||
"git.apinb.com/bsm-sdk/core/crypto/token"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Login 登录
|
||||
// @Summary 登录
|
||||
// @Description 登录
|
||||
// @Tags 登录
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Param role body types.LoginRequest true "登录请求"
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} types.LoginResp "新增成功,返回token"
|
||||
// @Router /login [post]
|
||||
func Login(c *gin.Context) {
|
||||
var (
|
||||
request types.LoginRequest
|
||||
resp = types.LoginResp{}
|
||||
user = models.MgtUser{}
|
||||
extend = map[string]string{}
|
||||
err error
|
||||
account string
|
||||
pwd string
|
||||
)
|
||||
err = c.ShouldBindJSON(&request)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrJsonUnmarshal)
|
||||
return
|
||||
}
|
||||
|
||||
if request.Account != "" && request.Password != "" {
|
||||
account = request.Account
|
||||
pwd = request.Password
|
||||
} else if request.AppId != "" && request.AppKey != "" {
|
||||
account = request.AppId
|
||||
pwd = request.AppKey
|
||||
} else {
|
||||
printer.Error("登录参数异常: 账号密码或AppId/AppKey必须提供")
|
||||
infra.Response.Error(c, errcode.ErrInvalidArgument)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
if err = models.DBService.Model(&models.MgtUser{}).Where("account=?", account).First(&user).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
infra.Response.Error(c, errcode.ErrRecordNotFound)
|
||||
return
|
||||
}
|
||||
infra.Response.Error(c, errcode.ErrDB)
|
||||
return
|
||||
}
|
||||
resp = types.LoginResp{Phone: user.Phone, Email: user.Email, Name: user.Name, UserId: user.ID, Account: user.Account, Avatar: user.Avatar, Identity: user.Identity}
|
||||
// 检测Password与Status
|
||||
if request.AppKey != "" {
|
||||
err = checkAppKeyAndStatus(user.Password, pwd, int16(user.Status))
|
||||
} else {
|
||||
err = checkPwdAndStatus(user.Password, pwd, user.Salt, int16(user.Status))
|
||||
}
|
||||
if err != nil {
|
||||
printer.Error("检测Password与Status异常: %v", err)
|
||||
infra.Response.Error(c, err)
|
||||
return
|
||||
}
|
||||
extend["id"] = strconv.Itoa(int(user.ID))
|
||||
extend["Identity"] = user.Identity
|
||||
extend["status"] = strconv.Itoa(int(user.Status))
|
||||
extend["name"] = user.Name
|
||||
|
||||
// 获取token
|
||||
resp.Token, err = token.New(env.Runtime.JwtSecretKey).GenerateJwt(uint(user.ID), user.Identity, c.ClientIP(), "", nil, extend)
|
||||
if err != nil {
|
||||
printer.Error("获取token异常: %v", err)
|
||||
infra.Response.Error(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = models.UpdateLastLoginDate(uint(user.ID))
|
||||
if err != nil {
|
||||
printer.Error("更新最后登录时间异常: %v", err)
|
||||
infra.Response.Error(c, errcode.ErrInternal)
|
||||
return
|
||||
}
|
||||
|
||||
printer.Info("用户登录成功: account=%s, userId=%d", account, user.ID)
|
||||
infra.Response.Success(c, resp)
|
||||
}
|
||||
|
||||
func SaveToken(id int64, role, token string) error {
|
||||
tokenKey := fmt.Sprintf("%d-%s-%s", uint(id), role, "token")
|
||||
status := impl.RedisService.Client.Set(impl.RedisService.Ctx, tokenKey, token, 0)
|
||||
if status.Val() != "OK" {
|
||||
printer.Error("保存token失败: %v", errcode.ErrTokenAuthTokenChanged)
|
||||
return errcode.ErrTokenAuthTokenChanged
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkPwdAndStatus(userPwd, inPwd, salt string, stat int16) error {
|
||||
// 账号是否禁用
|
||||
if stat == vars.DisabledStatus {
|
||||
printer.Error("检查账号状态异常: 账号已禁用")
|
||||
return errcode.ErrUnavailable
|
||||
}
|
||||
|
||||
err := bcrypt.CompareHashAndPassword([]byte(userPwd), []byte(inPwd+salt))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 如果bcrypt失败,尝试MD5验证(向后兼容旧用户)
|
||||
isBcrypt := len(userPwd) > 4 && (userPwd[0:4] == "$2a$" || userPwd[0:4] == "$2b$" || userPwd[0:4] == "$2y$")
|
||||
if isBcrypt {
|
||||
printer.Error("密码验证失败: bcrypt验证失败")
|
||||
return errcode.ErrPassword
|
||||
}
|
||||
|
||||
hash := md5.Sum([]byte(inPwd + salt))
|
||||
md5Hash := hex.EncodeToString(hash[:])
|
||||
if userPwd == md5Hash {
|
||||
return nil
|
||||
}
|
||||
|
||||
printer.Error("密码验证失败: 所有验证方式均失败")
|
||||
return errcode.ErrPassword
|
||||
}
|
||||
|
||||
func checkAppKeyAndStatus(userPwd, pwd string, stat int16) error {
|
||||
if userPwd != pwd {
|
||||
printer.Error("检查密码异常: 密码不匹配")
|
||||
return errcode.ErrPassword
|
||||
}
|
||||
|
||||
if stat == vars.DisabledStatus {
|
||||
printer.Error("检查账号状态异常: 账号已禁用")
|
||||
return errcode.ErrUnavailable
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
35
apps/base/mgt/internal/logic/pub/refresh.go
Normal file
35
apps/base/mgt/internal/logic/pub/refresh.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package pub
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/crypto/token"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/infra"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Refresh 刷新token
|
||||
// @Summary 刷新token
|
||||
// @Description 刷新token
|
||||
// @Tags 刷新token
|
||||
// @Accept application/json
|
||||
// @Produce application/json
|
||||
// @Security ApiKeyAuth
|
||||
// @Success 200 {object} coreTypes.LoginResp "刷新成功,返回token"
|
||||
// @Router /pub/refresh [post]
|
||||
func Refresh(c *gin.Context) {
|
||||
claims, err := service.ParseMetaCtx(c, nil)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, err)
|
||||
return
|
||||
}
|
||||
// 将 ExpiresAt 转换为 time.Time 类型
|
||||
token, err := token.New(env.Runtime.JwtSecretKey).GenerateJwt(claims.ID, claims.Identity, claims.Client, claims.Role, nil, claims.Extend)
|
||||
if err != nil {
|
||||
infra.Response.Error(c, errcode.ErrTokenGenerate)
|
||||
return
|
||||
}
|
||||
|
||||
infra.Response.Success(c, map[string]string{"token": token})
|
||||
}
|
||||
Reference in New Issue
Block a user