live-forum/server/webapi/LiveForum/LiveForum.Service/Others/WechatMiniProgramService.cs
2026-03-24 11:27:37 +08:00

149 lines
5.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using LiveForum.IService.Others;
using LiveForum.Model.Dto.Wechat;
using Microsoft.Extensions.Logging;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using System;
using System.Threading.Tasks;
namespace LiveForum.Service.Others
{
/// <summary>
/// 微信小程序服务实现
/// 使用 SKIT.FlurlHttpClient.Wechat.Api 实现
/// </summary>
public class WechatMiniProgramService : IWechatMiniProgramService
{
private readonly IWechatApiClientManager _clientManager;
private readonly ILogger<WechatMiniProgramService> _logger;
public WechatMiniProgramService(
IWechatApiClientManager clientManager,
ILogger<WechatMiniProgramService> logger)
{
_clientManager = clientManager ?? throw new ArgumentNullException(nameof(clientManager));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
/// <summary>
/// 通过 code 获取用户的 openId 和 sessionKey
/// </summary>
public async Task<WechatLoginInfoDto> GetLoginInfoByCodeAsync(string jsCode)
{
if (string.IsNullOrWhiteSpace(jsCode))
{
throw new ArgumentException("jsCode 不能为空", nameof(jsCode));
}
try
{
// 从 Manager 获取最新客户端实例(支持动态配置更新)
var client = _clientManager.GetClient();
if (client == null)
{
_logger.LogError("微信 API 客户端不可用");
return new WechatLoginInfoDto
{
IsSuccessful = false,
ErrorMessage = "微信 API 客户端不可用,请检查配置"
};
}
// 调用微信 API
var request = new SnsJsCode2SessionRequest
{
JsCode = jsCode
};
var response = await client.ExecuteSnsJsCode2SessionAsync(request);
// 转换为业务 DTO
return new WechatLoginInfoDto
{
OpenId = response.OpenId,
SessionKey = response.SessionKey,
UnionId = response.UnionId,
IsSuccessful = response.IsSuccessful(),
ErrorCode = response.ErrorCode,
ErrorMessage = response.ErrorMessage
};
}
catch (Exception ex)
{
_logger.LogError(ex, "获取微信登录信息失败jsCode: {JsCode}", jsCode?.Substring(0, Math.Min(10, jsCode?.Length ?? 0)));
return new WechatLoginInfoDto
{
IsSuccessful = false,
ErrorMessage = $"获取微信登录信息失败:{ex.Message}"
};
}
}
/// <summary>
/// 通过手机号 code 获取用户手机号
/// </summary>
public async Task<string?> GetPhoneNumberByCodeAsync(string phoneCode)
{
if (string.IsNullOrWhiteSpace(phoneCode))
{
throw new ArgumentException("phoneCode 不能为空", nameof(phoneCode));
}
try
{
var client = _clientManager.GetClient();
if (client == null)
{
_logger.LogError("微信 API 客户端不可用");
return null;
}
// 获取手机号接口需要 access_token先获取它
var accessTokenRequest = new CgibinTokenRequest();
var accessTokenResponse = await client.ExecuteCgibinTokenAsync(accessTokenRequest);
if (!accessTokenResponse.IsSuccessful())
{
_logger.LogError("获取 access_token 失败: ErrorCode={ErrorCode}, ErrorMessage={ErrorMessage}",
accessTokenResponse.ErrorCode, accessTokenResponse.ErrorMessage);
return null;
}
_logger.LogInformation("获取 access_token 成功, token前10位: {TokenPrefix}...",
accessTokenResponse.AccessToken?.Substring(0, Math.Min(10, accessTokenResponse.AccessToken?.Length ?? 0)));
var request = new WxaBusinessGetUserPhoneNumberRequest
{
Code = phoneCode,
AccessToken = accessTokenResponse.AccessToken
};
_logger.LogInformation("开始获取手机号, phoneCode前10位: {PhoneCodePrefix}..., AccessToken是否存在: {HasToken}",
phoneCode?.Substring(0, Math.Min(10, phoneCode?.Length ?? 0)),
!string.IsNullOrEmpty(request.AccessToken));
var response = await client.ExecuteWxaBusinessGetUserPhoneNumberAsync(request);
if (response.IsSuccessful() && response.PhoneInfo != null)
{
_logger.LogInformation("获取手机号成功: {Phone}", response.PhoneInfo.PurePhoneNumber ?? response.PhoneInfo.PhoneNumber);
return response.PhoneInfo.PurePhoneNumber ?? response.PhoneInfo.PhoneNumber;
}
_logger.LogWarning("获取手机号失败: ErrorCode={ErrorCode}, ErrorMessage={ErrorMessage}",
response.ErrorCode, response.ErrorMessage);
return null;
}
catch (Exception ex)
{
_logger.LogError(ex, "获取微信手机号异常");
return null;
}
}
}
}