diff --git a/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs b/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs index ba7a9bc..5c4f785 100644 --- a/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs +++ b/src/SimpleAdmin.Api.IntegrationTests/WeChatRouteIntegrationTests.cs @@ -37,6 +37,7 @@ public class WeChatRouteIntegrationTests host.RoutePatterns.Should().Contain("wechat/customer/register"); host.RoutePatterns.Should().Contain("wechat/customer/bind"); host.RoutePatterns.Should().Contain("rbac/auth/wx-login/status"); + host.RoutePatterns.Should().Contain("rbac/auth/wx-oauth-login"); } [Fact] diff --git a/src/SimpleAdmin.Api/Auth/AuthRequestDtos.cs b/src/SimpleAdmin.Api/Auth/AuthRequestDtos.cs index 8927898..c1c40fb 100644 --- a/src/SimpleAdmin.Api/Auth/AuthRequestDtos.cs +++ b/src/SimpleAdmin.Api/Auth/AuthRequestDtos.cs @@ -31,6 +31,13 @@ public class OmsWxLoginInput public string LoginUuid { get; set; } = string.Empty; } +/// 微信网页授权登录(code 换 openid)。 +public class OmsWxOAuthLoginInput +{ + [Required] + public string Code { get; set; } = string.Empty; +} + public class OmsCustomerOmsLoginInput { [Required] diff --git a/src/SimpleAdmin.Api/Auth/AuthService.cs b/src/SimpleAdmin.Api/Auth/AuthService.cs index f716464..c9bda03 100644 --- a/src/SimpleAdmin.Api/Auth/AuthService.cs +++ b/src/SimpleAdmin.Api/Auth/AuthService.cs @@ -190,6 +190,52 @@ public partial class AuthService( return await BuildLoginResultAsync(userGuid.Value, OmsLoginType.Customer, cancellationToken); } + /// + /// 微信网页授权登录(H5 内点按钮授权,无需扫码)。 + /// + [AllowAnonymous] + [HttpPost("/rbac/auth/wx-oauth-login")] + public async Task WxOAuthLoginAsync( + [FromBody] OmsWxOAuthLoginInput input, + CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(input.Code)) + { + throw new BusinessException("缺少微信授权 code"); + } + + var token = await WeChatMpApiClient.GetOAuthAccessTokenAsync(input.Code.Trim(), cancellationToken); + if (token == null || string.IsNullOrWhiteSpace(token.OpenId)) + { + throw new BusinessException("微信授权失败,请重试"); + } + + var customer = await customerRepository.GetByWechatOpenidAsync(token.OpenId, cancellationToken); + if (customer == null) + { + throw new BusinessException("未绑定微信,请先注册或绑定账号"); + } + + if (customer.ParentCustomerId.HasValue) + { + throw new BusinessException("子客户不支持微信授权登录"); + } + + ValidateMainCustomerStatus(customer); + + customer.LastLoginIp = httpContextAccessor.HttpContext?.Connection.RemoteIpAddress?.ToString(); + customer.LastLoginTime = DateTime.Now; + await customerRepository.UpdateAsync(customer, cancellationToken); + + var userGuid = await GetRbacUserGuidByMapIdAsync(customer.UserId, cancellationToken); + if (!userGuid.HasValue) + { + throw new BusinessException("客户未关联用户"); + } + + return await BuildLoginResultAsync(userGuid.Value, OmsLoginType.Customer, cancellationToken); + } + private async Task ResolveCustomerFromWxSessionAsync( WeChatLoginSessionPayload session, CancellationToken cancellationToken)