From 8dff802248dcf752b4b5ae378fa065089d6b6d6f Mon Sep 17 00:00:00 2001 From: MSuMshk <2039814060@qq.com> Date: Fri, 30 Jan 2026 07:09:35 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=AE=A1=E7=90=86=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E5=A2=9E=E5=8A=A0=E6=89=8B=E6=9C=BA=E5=8F=B7?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TakeoutSaaS.Docs | 2 +- .../Controllers/AuthController.cs | 18 +----- .../Abstractions/IAdminAuthService.cs | 5 -- .../Identity/Contracts/AdminLoginRequest.cs | 15 +++-- .../Identity/Services/AdminAuthService.cs | 56 +++++++++---------- 5 files changed, 39 insertions(+), 57 deletions(-) diff --git a/TakeoutSaaS.Docs b/TakeoutSaaS.Docs index e962798..2f508d7 160000 --- a/TakeoutSaaS.Docs +++ b/TakeoutSaaS.Docs @@ -1 +1 @@ -Subproject commit e962798f4637273d519d60053304425c9733e823 +Subproject commit 2f508d7b52f849b14e98fd0a7e564edc35a5b684 diff --git a/src/Api/TakeoutSaaS.AdminApi/Controllers/AuthController.cs b/src/Api/TakeoutSaaS.AdminApi/Controllers/AuthController.cs index b68236f..9efd7c4 100644 --- a/src/Api/TakeoutSaaS.AdminApi/Controllers/AuthController.cs +++ b/src/Api/TakeoutSaaS.AdminApi/Controllers/AuthController.cs @@ -23,7 +23,7 @@ namespace TakeoutSaaS.AdminApi.Controllers; public sealed class AuthController(IAdminAuthService authService, IMediator mediator) : BaseApiController { /// - /// 登录获取 Token + /// 账号名+手机号登录获取 Token /// /// 登录请求。 /// 取消标记。 @@ -37,22 +37,6 @@ public sealed class AuthController(IAdminAuthService authService, IMediator medi return ApiResponse.Ok(response); } - /// - /// 免租户号登录(仅账号+密码)。 - /// - /// 登录请求。 - /// 取消标记。 - /// 包含访问令牌与刷新令牌的响应。 - /// 用于前端简化登录,无需额外传递租户号。 - [HttpPost("login/simple")] - [AllowAnonymous] - [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)] - public async Task> LoginSimple([FromBody] AdminLoginRequest request, CancellationToken cancellationToken) - { - var response = await authService.LoginSimpleAsync(request, cancellationToken); - return ApiResponse.Ok(response); - } - /// /// 刷新 Token /// diff --git a/src/Application/TakeoutSaaS.Application/Identity/Abstractions/IAdminAuthService.cs b/src/Application/TakeoutSaaS.Application/Identity/Abstractions/IAdminAuthService.cs index ee6935c..6e00acc 100644 --- a/src/Application/TakeoutSaaS.Application/Identity/Abstractions/IAdminAuthService.cs +++ b/src/Application/TakeoutSaaS.Application/Identity/Abstractions/IAdminAuthService.cs @@ -12,11 +12,6 @@ public interface IAdminAuthService /// Task LoginAsync(AdminLoginRequest request, CancellationToken cancellationToken = default); - /// - /// 简化登录:与标准登录一致(Admin Portal)。 - /// - Task LoginSimpleAsync(AdminLoginRequest request, CancellationToken cancellationToken = default); - /// /// 刷新 Token。 /// diff --git a/src/Application/TakeoutSaaS.Application/Identity/Contracts/AdminLoginRequest.cs b/src/Application/TakeoutSaaS.Application/Identity/Contracts/AdminLoginRequest.cs index 865e263..4321e0d 100644 --- a/src/Application/TakeoutSaaS.Application/Identity/Contracts/AdminLoginRequest.cs +++ b/src/Application/TakeoutSaaS.Application/Identity/Contracts/AdminLoginRequest.cs @@ -5,19 +5,26 @@ namespace TakeoutSaaS.Application.Identity.Contracts; /// /// 管理后台登录请求。 /// -public sealed class AdminLoginRequest +public sealed record AdminLoginRequest { /// - /// 账号。 + /// 账号名。 /// [Required] [MaxLength(64)] - public string Account { get; set; } = string.Empty; + public string AccountName { get; init; } = string.Empty; + + /// + /// 手机号。 + /// + [Required] + [MaxLength(32)] + public string Phone { get; init; } = string.Empty; /// /// 密码。 /// [Required] [MaxLength(128)] - public string Password { get; set; } = string.Empty; + public string Password { get; init; } = string.Empty; } diff --git a/src/Application/TakeoutSaaS.Application/Identity/Services/AdminAuthService.cs b/src/Application/TakeoutSaaS.Application/Identity/Services/AdminAuthService.cs index 24c9302..b3b9dca 100644 --- a/src/Application/TakeoutSaaS.Application/Identity/Services/AdminAuthService.cs +++ b/src/Application/TakeoutSaaS.Application/Identity/Services/AdminAuthService.cs @@ -32,11 +32,28 @@ public sealed class AdminAuthService( /// 账号或密码错误时抛出 public async Task LoginAsync(AdminLoginRequest request, CancellationToken cancellationToken = default) { - // 1. 根据账号查找用户 - var user = await userRepository.FindByAccountAsync(PortalType.Admin, null, request.Account, cancellationToken) - ?? throw new BusinessException(ErrorCodes.Unauthorized, "账号或密码错误"); + // 1. 标准化输入 + var accountName = request.AccountName?.Trim() ?? string.Empty; + var phone = request.Phone?.Trim() ?? string.Empty; + var password = request.Password; - // 2. 校验账号状态 + // 2. (空行后) 参数校验 + if (string.IsNullOrWhiteSpace(accountName) || string.IsNullOrWhiteSpace(phone) || string.IsNullOrWhiteSpace(password)) + { + throw new BusinessException(ErrorCodes.BadRequest, "账号名、手机号与密码不能为空"); + } + + // 3. (空行后) 根据账号查找用户 + var user = await userRepository.FindByAccountAsync(PortalType.Admin, null, accountName, cancellationToken) + ?? throw new BusinessException(ErrorCodes.Unauthorized, "账号名、手机号或密码错误"); + + // 4. (空行后) 校验手机号匹配 + if (!string.Equals(user.Phone?.Trim(), phone, StringComparison.Ordinal)) + { + throw new BusinessException(ErrorCodes.Unauthorized, "账号名、手机号或密码错误"); + } + + // 5. (空行后) 校验账号状态 var now = DateTime.UtcNow; if (user.Status == IdentityUserStatus.Disabled) { @@ -58,43 +75,22 @@ public sealed class AdminAuthService( throw new BusinessException(ErrorCodes.Forbidden, "账号需要重置密码,请通过重置链接设置新密码"); } - // 3. 验证密码(使用 ASP.NET Core Identity 的密码哈希器) - var result = passwordHasher.VerifyHashedPassword(user, user.PasswordHash, request.Password); + // 6. (空行后) 验证密码(使用 ASP.NET Core Identity 的密码哈希器) + var result = passwordHasher.VerifyHashedPassword(user, user.PasswordHash, password); if (result == PasswordVerificationResult.Failed) { await IncreaseFailedLoginAsync(user.Id, now, cancellationToken); - throw new BusinessException(ErrorCodes.Unauthorized, "账号或密码错误"); + throw new BusinessException(ErrorCodes.Unauthorized, "账号名、手机号或密码错误"); } - // 4. 更新登录成功状态 + // 7. (空行后) 更新登录成功状态 await UpdateLoginSuccessAsync(user.Id, now, cancellationToken); - // 5. 构建用户档案并生成令牌 + // 8. (空行后) 构建用户档案并生成令牌 var profile = await BuildProfileAsync(user, cancellationToken); return await jwtTokenService.CreateTokensAsync(profile, false, cancellationToken); } - /// - /// 简化登录:与标准登录一致(Admin Portal)。 - /// - /// 登录请求 - /// 取消令牌 - /// 令牌响应 - public async Task LoginSimpleAsync(AdminLoginRequest request, CancellationToken cancellationToken = default) - { - // 1. 参数校验 - if (string.IsNullOrWhiteSpace(request.Account)) - { - throw new BusinessException(ErrorCodes.BadRequest, "账号不能为空"); - } - - // 2. (空行后) 标准化账号 - request.Account = request.Account.Trim(); - - // 3. (空行后) 走标准登录逻辑(Admin Portal) - return await LoginAsync(request, cancellationToken); - } - /// /// 刷新访问令牌:使用刷新令牌获取新的访问令牌和刷新令牌。 ///