Files
QYZH.InteractiveMagazine/QYZH.InteractiveMagazine.Service/WeChatMiniProgramService.cs
2026-06-01 13:42:40 +08:00

168 lines
5.8 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 Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using QYZH.InteractiveMagazine.Common.Helpers;
using QYZH.InteractiveMagazine.IService;
using QYZH.InteractiveMagazine.IService.Dto;
using QYZH.InteractiveMagazine.Models.Common;
using QYZH.InteractiveMagazine.Models.Settings;
using QYZH.InteractiveMagazine.Infrastructure.Auth;
namespace QYZH.InteractiveMagazine.Service;
/// <summary>
/// 微信小程序服务实现
/// </summary>
public class WeChatMiniProgramService : IWeChatMiniProgramService
{
private readonly IConfiguration _configuration;
private readonly ILogger<WeChatMiniProgramService> _logger;
private const string Code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session";
private const string GetPhoneNumberUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";
/// <summary>
/// 构造函数
/// </summary>
/// <param name="configuration">配置</param>
/// <param name="logger">日志记录器</param>
public WeChatMiniProgramService(IConfiguration configuration, ILogger<WeChatMiniProgramService> logger)
{
_configuration = configuration;
_logger = logger;
}
/// <summary>
/// 微信登录
/// </summary>
/// <param name="code">微信登录凭证</param>
/// <returns>微信登录结果</returns>
public async Task<WeChatLoginOutput> WeChatLoginAsync(string code)
{
_logger.LogInformation("微信登录尝试code: {Code}", code);
if (string.IsNullOrWhiteSpace(code))
{
throw new BusinessException("登录凭证不能为空", 400);
}
// 获取微信配置
var weChatSettings = GetWeChatSettings();
if (string.IsNullOrWhiteSpace(weChatSettings.AppId) || string.IsNullOrWhiteSpace(weChatSettings.AppSecret))
{
throw new BusinessException("微信配置不完整", 500);
}
// 演示版本模拟调用微信code2session接口
var openId = await SimulateCode2SessionAsync(code, weChatSettings);
// 获取JWT配置并生成令牌
var jwtSettings = GetJwtSettings();
var token = JwtHelper.GenerateToken(1, "微信用户", jwtSettings);
_logger.LogInformation("微信登录成功openId: {OpenId}", openId);
return new WeChatLoginOutput
{
Token = token,
UserId = 1,
UserName = "微信用户",
OpenId = openId
};
}
/// <summary>
/// 获取手机号
/// </summary>
/// <param name="code">获取手机号凭证</param>
/// <returns>手机号信息</returns>
public async Task<WeChatPhoneNumberOutput> GetPhoneNumberAsync(string code)
{
_logger.LogInformation("获取微信手机号尝试code: {Code}", code);
if (string.IsNullOrWhiteSpace(code))
{
throw new BusinessException("获取手机号凭证不能为空", 400);
}
// 演示版本:模拟返回手机号
var phoneNumber = await SimulateGetPhoneNumberAsync(code);
_logger.LogInformation("获取微信手机号成功");
return new WeChatPhoneNumberOutput
{
PhoneNumber = phoneNumber
};
}
/// <summary>
/// 模拟调用微信code2session接口
/// </summary>
/// <param name="code">登录凭证</param>
/// <param name="weChatSettings">微信配置</param>
/// <returns>openId</returns>
private async Task<string> SimulateCode2SessionAsync(string code, WeChatSettings weChatSettings)
{
// 演示版本模拟返回openId
// 实际实现应调用微信API
// var url = $"{Code2SessionUrl}?appid={weChatSettings.AppId}&secret={weChatSettings.AppSecret}&js_code={code}&grant_type=authorization_code";
// var response = await HttpHelper.GetAsync<dynamic>(url);
// if (response?.errcode == 0) return response.openid;
await Task.Delay(100); // 模拟网络请求延迟
return $"demo_openid_{code.GetHashCode():X}";
}
/// <summary>
/// 模拟调用微信获取手机号接口
/// </summary>
/// <param name="code">获取手机号凭证</param>
/// <returns>手机号</returns>
private async Task<string> SimulateGetPhoneNumberAsync(string code)
{
// 演示版本:模拟返回手机号
// 实际实现应调用微信API获取access_token然后调用获取手机号接口
// var tokenUrl = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={appSecret}";
// var tokenResponse = await HttpHelper.GetAsync<dynamic>(tokenUrl);
// var accessToken = tokenResponse.access_token;
// var phoneUrl = $"{GetPhoneNumberUrl}?access_token={accessToken}";
// var phoneResponse = await HttpHelper.PostAsync<dynamic>(phoneUrl, new { code });
await Task.Delay(100); // 模拟网络请求延迟
return "13800138000";
}
/// <summary>
/// 获取微信配置
/// </summary>
/// <returns>微信配置对象</returns>
private WeChatSettings GetWeChatSettings()
{
return _configuration.GetSection("WeChatSettings").Get<WeChatSettings>()
?? new WeChatSettings
{
AppId = "demo_app_id",
AppSecret = "demo_app_secret"
};
}
/// <summary>
/// 获取JWT配置
/// </summary>
/// <returns>JWT配置对象</returns>
private JwtSettings GetJwtSettings()
{
return _configuration.GetSection("JwtSettings").Get<JwtSettings>()
?? new JwtSettings
{
Issuer = "QYZH.InteractiveMagazine",
Audience = "QYZH.InteractiveMagazine.Client",
SecretKey = "QYZH_InteractiveMagazine_SecretKey_2024",
ExpiryMinutes = 120
};
}
}