fix: 微信手机号登录时同时获取openid,解决微信支付无法拉起的问题

This commit is contained in:
zpc 2026-02-11 20:43:35 +08:00
parent 951d9638fb
commit dca7ba7b1c
7 changed files with 74 additions and 23 deletions

View File

@ -88,13 +88,23 @@ export const isTokenExpired = () => {
/** /**
* 微信手机号快速验证登录 * 微信手机号快速验证登录
* @param {String} code 微信手机号授权codegetPhoneNumber返回 * @param {String} phoneCode 微信手机号授权codegetPhoneNumber返回
* @param {String} pid 推荐人ID * @param {String} pid 推荐人ID
* @returns {Promise} 登录结果 * @returns {Promise} 登录结果
*/ */
export const wxPhoneLogin = async (code, pid = '') => { export const wxPhoneLogin = async (phoneCode, pid = '') => {
// 先获取微信登录code用于获取openid
const loginRes = await new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: resolve,
fail: reject
});
});
return await RequestManager.post('/wxPhoneLogin', { return await RequestManager.post('/wxPhoneLogin', {
code, phoneCode,
loginCode: loginRes.code,
pid pid
}); });
}; };

View File

@ -115,20 +115,21 @@ public class AuthController : ControllerBase
/// <remarks> /// <remarks>
/// POST /api/wxPhoneLogin /// POST /api/wxPhoneLogin
/// ///
/// 使用微信getPhoneNumber获取的code进行登录返回双TokenAccess Token + Refresh Token /// 使用微信getPhoneNumber获取的code进行登录同时使用uni.login的code获取openid用于微信支付
/// 返回双TokenAccess Token + Refresh Token
/// </remarks> /// </remarks>
/// <param name="request">微信手机号登录请求参数包含手机号授权code</param> /// <param name="request">微信手机号登录请求参数包含手机号授权code和登录code</param>
/// <returns>登录成功返回LoginResponse包含accessToken、refreshToken、expiresIn失败返回错误信息</returns> /// <returns>登录成功返回LoginResponse包含accessToken、refreshToken、expiresIn失败返回错误信息</returns>
[HttpPost("wxPhoneLogin")] [HttpPost("wxPhoneLogin")]
[ProducesResponseType(typeof(ApiResponse<LoginResponse>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(ApiResponse<LoginResponse>), StatusCodes.Status200OK)]
public async Task<ApiResponse<LoginResponse>> WechatPhoneLogin([FromBody] WechatPhoneLoginRequest request) public async Task<ApiResponse<LoginResponse>> WechatPhoneLogin([FromBody] WechatPhoneLoginRequest request)
{ {
if (request == null || string.IsNullOrWhiteSpace(request.Code)) if (request == null || string.IsNullOrWhiteSpace(request.PhoneCode))
{ {
return ApiResponse<LoginResponse>.Fail("手机号授权code不能为空"); return ApiResponse<LoginResponse>.Fail("手机号授权code不能为空");
} }
var result = await _authService.WechatPhoneLoginAsync(request.Code, request.Pid); var result = await _authService.WechatPhoneLoginAsync(request.PhoneCode, request.LoginCode, request.Pid);
if (result.Success && result.LoginResponse != null) if (result.Success && result.LoginResponse != null)
{ {

View File

@ -47,9 +47,10 @@ public interface IAuthService
/// 微信手机号快速验证登录 /// 微信手机号快速验证登录
/// </summary> /// </summary>
/// <param name="phoneCode">微信手机号授权codegetPhoneNumber返回</param> /// <param name="phoneCode">微信手机号授权codegetPhoneNumber返回</param>
/// <param name="loginCode">微信登录codeuni.login返回用于获取openid</param>
/// <param name="pid">推荐人ID</param> /// <param name="pid">推荐人ID</param>
/// <returns>登录结果</returns> /// <returns>登录结果</returns>
Task<LoginResult> WechatPhoneLoginAsync(string phoneCode, int? pid); Task<LoginResult> WechatPhoneLoginAsync(string phoneCode, string? loginCode, int? pid);
/// <summary> /// <summary>
/// 记录登录信息 /// 记录登录信息

View File

@ -386,15 +386,15 @@ public class AuthService : IAuthService
/// <summary> /// <summary>
/// 微信手机号快速验证登录 /// 微信手机号快速验证登录
/// 使用微信getPhoneNumber获取的code直接登录 /// 使用微信getPhoneNumber获取的code直接登录同时获取openid用于微信支付
/// </summary> /// </summary>
public async Task<LoginResult> WechatPhoneLoginAsync(string phoneCode, int? pid) public async Task<LoginResult> WechatPhoneLoginAsync(string phoneCode, string? loginCode, int? pid)
{ {
_logger.LogInformation("[AuthService] 微信手机号登录开始pid={Pid}", pid); _logger.LogInformation("[AuthService] 微信手机号登录开始pid={Pid}, hasLoginCode={HasLoginCode}", pid, !string.IsNullOrEmpty(loginCode));
if (string.IsNullOrWhiteSpace(phoneCode)) if (string.IsNullOrWhiteSpace(phoneCode))
{ {
_logger.LogWarning("[AuthService] 微信手机号登录失败:code为空"); _logger.LogWarning("[AuthService] 微信手机号登录失败:phoneCode为空");
return new LoginResult return new LoginResult
{ {
Success = false, Success = false,
@ -417,7 +417,7 @@ public class AuthService : IAuthService
}; };
} }
// 调用微信API获取手机号 // 1. 调用微信API获取手机号
_logger.LogInformation("[AuthService] 开始调用微信API获取手机号..."); _logger.LogInformation("[AuthService] 开始调用微信API获取手机号...");
var mobileResult = await _wechatService.GetMobileAsync(phoneCode); var mobileResult = await _wechatService.GetMobileAsync(phoneCode);
@ -434,7 +434,26 @@ public class AuthService : IAuthService
var mobile = mobileResult.Mobile; var mobile = mobileResult.Mobile;
_logger.LogInformation("[AuthService] 获取手机号成功: {Mobile}", MaskMobile(mobile)); _logger.LogInformation("[AuthService] 获取手机号成功: {Mobile}", MaskMobile(mobile));
// 根据手机号查找用户 // 2. 如果有loginCode获取openid
string? openId = null;
string? unionId = null;
if (!string.IsNullOrWhiteSpace(loginCode))
{
_logger.LogInformation("[AuthService] 开始调用微信API获取openid...");
var wechatResult = await _wechatService.GetOpenIdAsync(loginCode);
if (wechatResult.Success)
{
openId = wechatResult.OpenId;
unionId = wechatResult.UnionId;
_logger.LogInformation("[AuthService] 获取openid成功: {OpenId}", openId);
}
else
{
_logger.LogWarning("[AuthService] 获取openid失败: {Error},继续登录但无法使用微信支付", wechatResult.ErrorMessage);
}
}
// 3. 根据手机号查找用户
var user = await _userService.GetUserByMobileAsync(mobile); var user = await _userService.GetUserByMobileAsync(mobile);
if (user == null) if (user == null)
@ -444,31 +463,37 @@ public class AuthService : IAuthService
var createDto = new CreateUserDto var createDto = new CreateUserDto
{ {
Mobile = mobile, Mobile = mobile,
OpenId = openId,
UnionId = unionId,
Nickname = $"用户{Random.Shared.Next(100000, 999999)}", Nickname = $"用户{Random.Shared.Next(100000, 999999)}",
Headimg = GenerateDefaultAvatar(mobile), Headimg = GenerateDefaultAvatar(mobile),
Pid = pid?.ToString() Pid = pid?.ToString()
}; };
user = await _userService.CreateUserAsync(createDto); user = await _userService.CreateUserAsync(createDto);
_logger.LogInformation("[AuthService] 新用户创建成功: UserId={UserId}, Mobile={Mobile}, OpenId={OpenId}",
// 设置手机号已绑定状态 user.Id, MaskMobile(mobile), openId ?? "null");
await _userService.UpdateUserAsync(user.Id, new UpdateUserDto { Mobile = mobile });
_logger.LogInformation("[AuthService] 新用户创建成功: UserId={UserId}, Mobile={Mobile}", user.Id, MaskMobile(mobile));
} }
else else
{ {
_logger.LogInformation("[AuthService] 找到已有用户: UserId={UserId}", user.Id); _logger.LogInformation("[AuthService] 找到已有用户: UserId={UserId}", user.Id);
// 4. 如果用户存在但没有openid更新openid
if (!string.IsNullOrWhiteSpace(openId) && string.IsNullOrWhiteSpace(user.OpenId))
{
_logger.LogInformation("[AuthService] 更新用户openid: UserId={UserId}", user.Id);
await _userService.UpdateUserAsync(user.Id, new UpdateUserDto { OpenId = openId, UnionId = unionId });
}
} }
// 生成双 Token // 5. 生成双 Token
_logger.LogInformation("[AuthService] 开始生成双 Token: UserId={UserId}", user.Id); _logger.LogInformation("[AuthService] 开始生成双 Token: UserId={UserId}", user.Id);
var loginResponse = await GenerateLoginResponseAsync(user, null); var loginResponse = await GenerateLoginResponseAsync(user, null);
// 更新UserAccount表 // 更新UserAccount表
await CreateOrUpdateAccountTokenAsync(user.Id, loginResponse.AccessToken); await CreateOrUpdateAccountTokenAsync(user.Id, loginResponse.AccessToken);
_logger.LogInformation("[AuthService] 微信手机号登录成功: UserId={UserId}", user.Id); _logger.LogInformation("[AuthService] 微信手机号登录成功: UserId={UserId}, HasOpenId={HasOpenId}", user.Id, !string.IsNullOrWhiteSpace(openId));
return new LoginResult return new LoginResult
{ {

View File

@ -145,6 +145,9 @@ public class UserService : BaseService<User, int>, IUserService
if (!string.IsNullOrWhiteSpace(dto.Mobile)) if (!string.IsNullOrWhiteSpace(dto.Mobile))
user.Mobile = dto.Mobile; user.Mobile = dto.Mobile;
if (!string.IsNullOrWhiteSpace(dto.OpenId))
user.OpenId = dto.OpenId;
if (!string.IsNullOrWhiteSpace(dto.UnionId)) if (!string.IsNullOrWhiteSpace(dto.UnionId))
user.UnionId = dto.UnionId; user.UnionId = dto.UnionId;

View File

@ -61,6 +61,11 @@ public class UpdateUserDto
/// </summary> /// </summary>
public string? Mobile { get; set; } public string? Mobile { get; set; }
/// <summary>
/// 微信openid
/// </summary>
public string? OpenId { get; set; }
/// <summary> /// <summary>
/// 微信unionid /// 微信unionid
/// </summary> /// </summary>

View File

@ -10,8 +10,14 @@ public class WechatPhoneLoginRequest
/// <summary> /// <summary>
/// 微信手机号授权codegetPhoneNumber返回的code /// 微信手机号授权codegetPhoneNumber返回的code
/// </summary> /// </summary>
[JsonPropertyName("code")] [JsonPropertyName("phoneCode")]
public string Code { get; set; } = string.Empty; public string PhoneCode { get; set; } = string.Empty;
/// <summary>
/// 微信登录codeuni.login返回的code用于获取openid
/// </summary>
[JsonPropertyName("loginCode")]
public string? LoginCode { get; set; }
/// <summary> /// <summary>
/// 推荐人ID前端可能传空字符串所以用string接收 /// 推荐人ID前端可能传空字符串所以用string接收