chore: 同步当前开发内容

This commit is contained in:
2025-11-23 01:25:20 +08:00
parent ddf584f212
commit 1169e1f220
58 changed files with 1886 additions and 82 deletions

View File

@@ -0,0 +1,79 @@
using System;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using TakeoutSaaS.Application.Identity.Abstractions;
using TakeoutSaaS.Infrastructure.Identity.Options;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
namespace TakeoutSaaS.Infrastructure.Identity.Services;
/// <summary>
/// 微信 code2Session 实现
/// </summary>
public sealed class WeChatAuthService : IWeChatAuthService
{
private readonly HttpClient _httpClient;
private readonly WeChatMiniOptions _options;
public WeChatAuthService(HttpClient httpClient, IOptions<WeChatMiniOptions> options)
{
_httpClient = httpClient;
_options = options.Value;
}
public async Task<WeChatSessionInfo> Code2SessionAsync(string code, CancellationToken cancellationToken = default)
{
var requestUri = $"sns/jscode2session?appid={Uri.EscapeDataString(_options.AppId)}&secret={Uri.EscapeDataString(_options.Secret)}&js_code={Uri.EscapeDataString(code)}&grant_type=authorization_code";
using var response = await _httpClient.GetAsync(requestUri, cancellationToken);
response.EnsureSuccessStatusCode();
var payload = await response.Content.ReadFromJsonAsync<WeChatSessionResponse>(cancellationToken: cancellationToken);
if (payload == null)
{
throw new BusinessException(ErrorCodes.Unauthorized, "微信登录失败:响应为空");
}
if (payload.ErrorCode.HasValue && payload.ErrorCode.Value != 0)
{
var message = string.IsNullOrWhiteSpace(payload.ErrorMessage)
? $"微信登录失败,错误码:{payload.ErrorCode}"
: payload.ErrorMessage;
throw new BusinessException(ErrorCodes.Unauthorized, message);
}
if (string.IsNullOrWhiteSpace(payload.OpenId) || string.IsNullOrWhiteSpace(payload.SessionKey))
{
throw new BusinessException(ErrorCodes.Unauthorized, "微信登录失败:返回数据无效");
}
return new WeChatSessionInfo
{
OpenId = payload.OpenId,
UnionId = payload.UnionId,
SessionKey = payload.SessionKey
};
}
private sealed class WeChatSessionResponse
{
[JsonPropertyName("openid")]
public string? OpenId { get; set; }
[JsonPropertyName("unionid")]
public string? UnionId { get; set; }
[JsonPropertyName("session_key")]
public string? SessionKey { get; set; }
[JsonPropertyName("errcode")]
public int? ErrorCode { get; set; }
[JsonPropertyName("errmsg")]
public string? ErrorMessage { get; set; }
}
}