refactor: 移除租户端简化登录接口及相关依赖
- 移除 /api/tenant/v1/auth/login/simple 接口 - 移除 IAdminAuthService.LoginSimpleAsync 方法 - 移除 AdminAuthService.LoginSimpleAsync 实现 - 移除 IsLikelyPhone 辅助方法 - 清理未使用的 ITenantContextAccessor 和 ITenantRepository 依赖 - 添加 CLAUDE.md 开发规范文件 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,11 +13,6 @@ public interface IAdminAuthService
|
||||
/// </summary>
|
||||
Task<TokenResponse> LoginAsync(AdminLoginRequest request, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 简化登录:支持使用“账号@手机号”自动解析租户后登录。
|
||||
/// </summary>
|
||||
Task<TokenResponse> LoginSimpleAsync(AdminLoginRequest request, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 刷新 Token。
|
||||
/// </summary>
|
||||
|
||||
@@ -4,7 +4,6 @@ using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
using TakeoutSaaS.Domain.Identity.Enums;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Domain.Tenants.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
||||
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
@@ -25,9 +24,7 @@ public sealed class AdminAuthService(
|
||||
IPasswordHasher<IdentityUser> passwordHasher,
|
||||
IJwtTokenService jwtTokenService,
|
||||
IRefreshTokenStore refreshTokenStore,
|
||||
ITenantProvider tenantProvider,
|
||||
ITenantContextAccessor tenantContextAccessor,
|
||||
ITenantRepository tenantRepository) : IAdminAuthService
|
||||
ITenantProvider tenantProvider) : IAdminAuthService
|
||||
{
|
||||
private const string TenantAdminRoleCode = "tenant-admin";
|
||||
|
||||
@@ -89,60 +86,6 @@ public sealed class AdminAuthService(
|
||||
return await jwtTokenService.CreateTokensAsync(profile, false, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 简化登录:支持使用“账号@手机号”解析租户后登录。
|
||||
/// </summary>
|
||||
/// <param name="request">登录请求</param>
|
||||
/// <param name="cancellationToken">取消令牌</param>
|
||||
/// <returns>令牌响应</returns>
|
||||
public async Task<TokenResponse> LoginSimpleAsync(AdminLoginRequest request, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// 1. 标准化输入
|
||||
var rawAccount = request.Account?.Trim() ?? string.Empty;
|
||||
|
||||
// 2. 尝试解析 “账号@手机号”
|
||||
var atIndex = rawAccount.LastIndexOf('@');
|
||||
if (atIndex > 0 && atIndex < rawAccount.Length - 1)
|
||||
{
|
||||
var accountPart = rawAccount[..atIndex].Trim();
|
||||
var phonePart = rawAccount[(atIndex + 1)..].Trim();
|
||||
|
||||
if (IsLikelyPhone(phonePart))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(accountPart))
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.BadRequest, "账号格式错误,应为 账号@手机号");
|
||||
}
|
||||
|
||||
var tenantId = await tenantRepository.FindTenantIdByContactPhoneAsync(phonePart, cancellationToken);
|
||||
if (!tenantId.HasValue || tenantId.Value == 0)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.Unauthorized, "账号或密码错误");
|
||||
}
|
||||
|
||||
var originalTenant = tenantContextAccessor.Current;
|
||||
tenantContextAccessor.Current = new TenantContext(tenantId.Value, null, "login:simple:contact_phone");
|
||||
try
|
||||
{
|
||||
return await LoginAsync(new AdminLoginRequest { Account = accountPart, Password = request.Password }, cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
tenantContextAccessor.Current = originalTenant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 未携带手机号时,要求外部已解析租户(Header/Host 等)
|
||||
if (tenantProvider.GetCurrentTenantId() == 0)
|
||||
{
|
||||
throw new BusinessException(ErrorCodes.BadRequest, "缺少租户标识,请使用 账号@手机号 登录");
|
||||
}
|
||||
|
||||
// 4. 走原有登录逻辑
|
||||
return await LoginAsync(new AdminLoginRequest { Account = rawAccount, Password = request.Password }, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新访问令牌:使用刷新令牌获取新的访问令牌和刷新令牌。
|
||||
/// </summary>
|
||||
@@ -398,35 +341,6 @@ public sealed class AdminAuthService(
|
||||
await userRepository.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private static bool IsLikelyPhone(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var span = value.AsSpan();
|
||||
if (span[0] == '+')
|
||||
{
|
||||
span = span[1..];
|
||||
}
|
||||
|
||||
if (span.Length < 6 || span.Length > 32)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var ch in span)
|
||||
{
|
||||
if (!char.IsDigit(ch))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static IReadOnlyList<MenuNodeDto> BuildMenuTree(
|
||||
IReadOnlyList<Domain.Identity.Entities.MenuDefinition> definitions,
|
||||
IReadOnlyList<string> permissions)
|
||||
|
||||
Reference in New Issue
Block a user