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; /// /// 微信小程序服务实现 /// public class WeChatMiniProgramService : IWeChatMiniProgramService { private readonly IConfiguration _configuration; private readonly ILogger _logger; private const string Code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session"; private const string GetPhoneNumberUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber"; /// /// 构造函数 /// /// 配置 /// 日志记录器 public WeChatMiniProgramService(IConfiguration configuration, ILogger logger) { _configuration = configuration; _logger = logger; } /// /// 微信登录 /// /// 微信登录凭证 /// 微信登录结果 public async Task 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 }; } /// /// 获取手机号 /// /// 获取手机号凭证 /// 手机号信息 public async Task 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 }; } /// /// 模拟调用微信code2session接口 /// /// 登录凭证 /// 微信配置 /// openId private async Task 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(url); // if (response?.errcode == 0) return response.openid; await Task.Delay(100); // 模拟网络请求延迟 return $"demo_openid_{code.GetHashCode():X}"; } /// /// 模拟调用微信获取手机号接口 /// /// 获取手机号凭证 /// 手机号 private async Task 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(tokenUrl); // var accessToken = tokenResponse.access_token; // var phoneUrl = $"{GetPhoneNumberUrl}?access_token={accessToken}"; // var phoneResponse = await HttpHelper.PostAsync(phoneUrl, new { code }); await Task.Delay(100); // 模拟网络请求延迟 return "13800138000"; } /// /// 获取微信配置 /// /// 微信配置对象 private WeChatSettings GetWeChatSettings() { return _configuration.GetSection("WeChatSettings").Get() ?? new WeChatSettings { AppId = "demo_app_id", AppSecret = "demo_app_secret" }; } /// /// 获取JWT配置 /// /// JWT配置对象 private JwtSettings GetJwtSettings() { return _configuration.GetSection("JwtSettings").Get() ?? new JwtSettings { Issuer = "QYZH.InteractiveMagazine", Audience = "QYZH.InteractiveMagazine.Client", SecretKey = "QYZH_InteractiveMagazine_SecretKey_2024", ExpiryMinutes = 120 }; } }