package user import ( "context" "database/sql" "os" "time" "in-server/app/main/api/internal/svc" "in-server/app/main/api/internal/types" "in-server/app/main/model" "in-server/common/xerr" "in-server/pkg/lzkit/crypto" "github.com/pkg/errors" "github.com/zeromicro/go-zero/core/logx" ) // PasswordLoginLogic 账号密码登录(使用手机号作为账号) type PasswordLoginLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewPasswordLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PasswordLoginLogic { return &PasswordLoginLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *PasswordLoginLogic) PasswordLogin(req *types.PasswordLoginReq) (resp *types.PasswordLoginResp, err error) { // 加密手机号以匹配数据库中的存储格式 secretKey := l.svcCtx.Config.Encrypt.SecretKey encryptedMobile, err := crypto.EncryptMobile(req.Mobile, secretKey) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "密码登录, 加密手机号失败: %+v", err) } // 查找用户 user, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, sql.NullString{String: encryptedMobile, Valid: true}) if findUserErr != nil && !errors.Is(findUserErr, model.ErrNotFound) { return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "密码登录, 查询用户失败, mobile: %s, err: %+v", encryptedMobile, findUserErr) } if user == nil { return nil, errors.Wrapf(xerr.NewErrMsg("账号或密码错误"), "密码登录, 用户不存在: %s", encryptedMobile) } // 校验密码(开发环境允许空密码快速登录,便于调试) if os.Getenv("ENV") == "development" && req.Password == "" { logx.Infof("密码登录开发模式下允许空密码, userId=%s", user.Id) } else { if !user.Password.Valid || user.Password.String == "" { return nil, errors.Wrapf(xerr.NewErrMsg("账号未设置密码,请联系管理员"), "密码登录, 用户未设置密码: %s", encryptedMobile) } if !crypto.PasswordVerify(req.Password, user.Password.String) { return nil, errors.Wrapf(xerr.NewErrMsg("账号或密码错误"), "密码登录, 密码不匹配: %s", encryptedMobile) } } // 生成访问 Token token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, user.Id) if err != nil { return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "密码登录, 生成token失败 : %s", user.Id) } now := time.Now().Unix() return &types.PasswordLoginResp{ AccessToken: token, AccessExpire: now + l.svcCtx.Config.JwtAuth.AccessExpire, RefreshAfter: now + l.svcCtx.Config.JwtAuth.RefreshAfter, }, nil }