feat(wxapi): 新增小程序 Donut 多端能力服务端接口

This commit is contained in:
Fu Diwei 2024-01-15 22:13:28 +08:00
parent d64443d5fd
commit 940713307b
17 changed files with 456 additions and 0 deletions

View File

@ -16,6 +16,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api
/// <para>REF: https://developers.weixin.qq.com/minigame/dev/api-backend/open-api/access-token/auth.getAccessToken.html </para>
/// <para>REF: https://developers.weixin.qq.com/doc/channels/API/basics/getaccesstoken.html </para>
/// <para>REF: https://developers.weixin.qq.com/doc/channels/API/windowproduct/getaccesstoken.html </para>
/// <para>REF: https://dev.weixin.qq.com/docs/framework/dev/openapi/getaccesstoken.html </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>

View File

@ -0,0 +1,116 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.Api
{
public static class WechatApiClientExecuteDonutExtensions
{
/// <summary>
/// <para>异步调用 [GET] /donut/code2verifyinfo 接口。</para>
/// <para>REF: https://dev.weixin.qq.com/docs/framework/dev/openapi/code2Verifyinfo.html </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DonutCode2VerifyInfoResponse> ExecuteDonutCode2VerifyInfoAsync(this WechatApiClient client, Models.DonutCode2VerifyInfoRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Get, "donut", "code2verifyinfo")
.SetQueryParam("access_token", request.AccessToken)
.SetQueryParam("appid", client.Credentials.AppId)
.SetQueryParam("appsecret", client.Credentials.AppSecret)
.SetQueryParam("code", request.Code)
.SetQueryParam("grant_type", request.GrantType);
return await client.SendRequestWithJsonAsync<Models.DonutCode2VerifyInfoResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /donut/unbindphone 接口。</para>
/// <para>REF: https://dev.weixin.qq.com/docs/framework/dev/openapi/unbindphone.html </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DonutUnbindPhoneResponse> ExecuteDonutUnbindPhoneAsync(this WechatApiClient client, Models.DonutUnbindPhoneRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "donut", "unbindphone")
.SetQueryParam("access_token", request.AccessToken);
return await client.SendRequestWithJsonAsync<Models.DonutUnbindPhoneResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /donut/unbindweixin 接口。</para>
/// <para>REF: https://dev.weixin.qq.com/docs/framework/dev/openapi/unbindweixin.html </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DonutUnbindWeixinResponse> ExecuteDonutUnbindWeixinAsync(this WechatApiClient client, Models.DonutUnbindWeixinRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "donut", "unbindweixin")
.SetQueryParam("access_token", request.AccessToken);
return await client.SendRequestWithJsonAsync<Models.DonutUnbindWeixinResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /donut/unbindapple 接口。</para>
/// <para>REF: https://dev.weixin.qq.com/docs/framework/dev/openapi/unbindapple.html </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DonutUnbindAppleResponse> ExecuteDonutUnbindAppleAsync(this WechatApiClient client, Models.DonutUnbindAppleRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "donut", "unbindapple")
.SetQueryParam("access_token", request.AccessToken);
return await client.SendRequestWithJsonAsync<Models.DonutUnbindAppleResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
/// <summary>
/// <para>异步调用 [POST] /donut/unregisteruser 接口。</para>
/// <para>REF: https://dev.weixin.qq.com/docs/framework/dev/openapi/unregisteruser.html </para>
/// </summary>
/// <param name="client"></param>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public static async Task<Models.DonutUnregisterUserResponse> ExecuteDonutUnregisterUserAsync(this WechatApiClient client, Models.DonutUnregisterUserRequest request, CancellationToken cancellationToken = default)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (request is null) throw new ArgumentNullException(nameof(request));
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "donut", "unregisteruser")
.SetQueryParam("access_token", request.AccessToken);
return await client.SendRequestWithJsonAsync<Models.DonutUnregisterUserResponse>(flurlReq, data: request, cancellationToken: cancellationToken);
}
}
}

View File

@ -0,0 +1,22 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [GET] /donut/code2verifyinfo 接口的请求。</para>
/// </summary>
public class DonutCode2VerifyInfoRequest : WechatApiRequest, IInferable<DonutCode2VerifyInfoRequest, DonutCode2VerifyInfoResponse>
{
/// <summary>
/// 获取或设置临时登录凭证。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string Code { get; set; } = string.Empty;
/// <summary>
/// <i>(使用默认值即可,无需修改)</i>
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string GrantType { get; set; } = "authorization_code";
}
}

View File

@ -0,0 +1,179 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [GET] /donut/code2verifyinfo 接口的响应。</para>
/// </summary>
public class DonutCode2VerifyInfoResponse : WechatApiResponse
{
public static class Types
{
public class LoginInfo
{
/// <summary>
/// 获取或设置登录方式。
/// </summary>
[Newtonsoft.Json.JsonProperty("type")]
[System.Text.Json.Serialization.JsonPropertyName("type")]
public string Type { get; set; } = default!;
/// <summary>
/// 获取或设置登录时间戳。
/// </summary>
[Newtonsoft.Json.JsonProperty("login_time")]
[System.Text.Json.Serialization.JsonPropertyName("login_time")]
public long LoginTimestamp { get; set; }
/// <summary>
/// 获取或设置微信 AppId。
/// </summary>
[Newtonsoft.Json.JsonProperty("appid")]
[System.Text.Json.Serialization.JsonPropertyName("appid")]
public string? AppId { get; set; }
}
public class UserInfo
{
public static class Types
{
public class OpenAppUserInfo
{
/// <summary>
/// 获取或设置微信 AppId。
/// </summary>
[Newtonsoft.Json.JsonProperty("appid")]
[System.Text.Json.Serialization.JsonPropertyName("appid")]
public string AppId { get; set; } = default!;
/// <summary>
/// 获取或设置用户的 OpenId。
/// </summary>
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public string OpenId { get; set; } = default!;
/// <summary>
/// 获取或设置用户的 UnionId。
/// </summary>
[Newtonsoft.Json.JsonProperty("unionid")]
[System.Text.Json.Serialization.JsonPropertyName("unionid")]
public string? UnionId { get; set; }
/// <summary>
/// 获取或设置用户头像 URL。
/// </summary>
[Newtonsoft.Json.JsonProperty("headimgurl")]
[System.Text.Json.Serialization.JsonPropertyName("headimgurl")]
public string? HeadImageUrl { get; set; }
/// <summary>
/// 获取或设置用户昵称。
/// </summary>
[Newtonsoft.Json.JsonProperty("nickname")]
[System.Text.Json.Serialization.JsonPropertyName("nickname")]
public string? Nickname { get; set; }
}
public class MiniProgramUserInfo
{
/// <summary>
/// 获取或设置微信 AppId。
/// </summary>
[Newtonsoft.Json.JsonProperty("appid")]
[System.Text.Json.Serialization.JsonPropertyName("appid")]
public string AppId { get; set; } = default!;
/// <summary>
/// 获取或设置用户的 OpenId。
/// </summary>
[Newtonsoft.Json.JsonProperty("openid")]
[System.Text.Json.Serialization.JsonPropertyName("openid")]
public string OpenId { get; set; } = default!;
/// <summary>
/// 获取或设置用户的 UnionId。
/// </summary>
[Newtonsoft.Json.JsonProperty("unionid")]
[System.Text.Json.Serialization.JsonPropertyName("unionid")]
public string? UnionId { get; set; }
}
public class PhoneUserInfo
{
/// <summary>
/// 获取或设置手机号码。
/// </summary>
[Newtonsoft.Json.JsonProperty("phone")]
[System.Text.Json.Serialization.JsonPropertyName("phone")]
public string MobileNumber { get; set; } = default!;
}
public class AppleUserInfo
{
/// <summary>
/// 获取或设置苹果应用 ID。
/// </summary>
[Newtonsoft.Json.JsonProperty("bundleid")]
[System.Text.Json.Serialization.JsonPropertyName("bundleid")]
public string BundleId { get; set; } = default!;
/// <summary>
/// 获取或设置苹果用户 ID。
/// </summary>
[Newtonsoft.Json.JsonProperty("apple_user_id")]
[System.Text.Json.Serialization.JsonPropertyName("apple_user_id")]
public string AppleUserId { get; set; } = default!;
}
}
/// <summary>
/// 获取或设置多端用户 ID。
/// </summary>
[Newtonsoft.Json.JsonProperty("user_id")]
[System.Text.Json.Serialization.JsonPropertyName("user_id")]
public string UserId { get; set; } = default!;
/// <summary>
/// 获取或设置微信移动应用的用户信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("openapp_info")]
[System.Text.Json.Serialization.JsonPropertyName("openapp_info")]
public Types.OpenAppUserInfo? OpenAppUserInfo { get; set; }
/// <summary>
/// 获取或设置微信小程序的用户信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("miniprogram_info")]
[System.Text.Json.Serialization.JsonPropertyName("miniprogram_info")]
public Types.MiniProgramUserInfo? MiniProgramUserInfo { get; set; }
/// <summary>
/// 获取或设置手机号用户信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("phone_info")]
[System.Text.Json.Serialization.JsonPropertyName("phone_info")]
public Types.PhoneUserInfo? PhoneUserInfo { get; set; }
/// <summary>
/// 获取或设置苹果用户信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("apple_info")]
[System.Text.Json.Serialization.JsonPropertyName("apple_info")]
public Types.AppleUserInfo? AppleUserInfo { get; set; }
}
}
/// <summary>
/// 获取或设置登录信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("login_info")]
[System.Text.Json.Serialization.JsonPropertyName("login_info")]
public Types.LoginInfo LoginInfo { get; set; } = default!;
/// <summary>
/// 获取或设置用户信息。
/// </summary>
[Newtonsoft.Json.JsonProperty("user_info")]
[System.Text.Json.Serialization.JsonPropertyName("user_info")]
public Types.UserInfo UserInfo { get; set; } = default!;
}
}

View File

@ -0,0 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unbindapple 接口的请求。</para>
/// </summary>
public class DonutUnbindAppleRequest : WechatApiRequest, IInferable<DonutUnbindAppleRequest, DonutUnbindAppleResponse>
{
/// <summary>
/// 获取或设置多端用户 ID。
/// </summary>
[Newtonsoft.Json.JsonProperty("user_id")]
[System.Text.Json.Serialization.JsonPropertyName("user_id")]
public string UserId { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,9 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unbindapple 接口的响应。</para>
/// </summary>
public class DonutUnbindAppleResponse : WechatApiResponse
{
}
}

View File

@ -0,0 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unbindphone 接口的请求。</para>
/// </summary>
public class DonutUnbindPhoneRequest : WechatApiRequest, IInferable<DonutUnbindPhoneRequest, DonutUnbindPhoneResponse>
{
/// <summary>
/// 获取或设置多端用户 ID。
/// </summary>
[Newtonsoft.Json.JsonProperty("user_id")]
[System.Text.Json.Serialization.JsonPropertyName("user_id")]
public string UserId { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,9 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unbindphone 接口的响应。</para>
/// </summary>
public class DonutUnbindPhoneResponse : WechatApiResponse
{
}
}

View File

@ -0,0 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unbindweixin 接口的请求。</para>
/// </summary>
public class DonutUnbindWeixinRequest : WechatApiRequest, IInferable<DonutUnbindWeixinRequest, DonutUnbindWeixinResponse>
{
/// <summary>
/// 获取或设置多端用户 ID。
/// </summary>
[Newtonsoft.Json.JsonProperty("user_id")]
[System.Text.Json.Serialization.JsonPropertyName("user_id")]
public string UserId { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,9 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unbindweixin 接口的响应。</para>
/// </summary>
public class DonutUnbindWeixinResponse : WechatApiResponse
{
}
}

View File

@ -0,0 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unregisteruser 接口的请求。</para>
/// </summary>
public class DonutUnregisterUserRequest : WechatApiRequest, IInferable<DonutUnregisterUserRequest, DonutUnregisterUserResponse>
{
/// <summary>
/// 获取或设置多端用户 ID。
/// </summary>
[Newtonsoft.Json.JsonProperty("user_id")]
[System.Text.Json.Serialization.JsonPropertyName("user_id")]
public string UserId { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,9 @@
namespace SKIT.FlurlHttpClient.Wechat.Api.Models
{
/// <summary>
/// <para>表示 [POST] /donut/unregisteruser 接口的响应。</para>
/// </summary>
public class DonutUnregisterUserResponse : WechatApiResponse
{
}
}

View File

@ -0,0 +1,30 @@
{
"errcode": 0,
"login_info": {
"type": "weixinApp",
"login_time": 12345678,
"appid": "aaa"
},
"user_info": {
"user_id": "xxx",
"openapp_info": {
"appid": "bbb",
"openid": "ccc",
"unionid": "ddd",
"headimgurl": "HEADIMGURL",
"nickname": "NICKNAME"
},
"phone_info": {
"phone": "137xxxxxxx"
},
"apple_info": {
"bundleid": "eee",
"apple_user_id": "fff"
},
"miniprogram_info": {
"appid": "bbb",
"openid": "ccc",
"unionid": "ddd"
}
}
}

View File

@ -0,0 +1,3 @@
{
"user_id": "bbb"
}

View File

@ -0,0 +1,3 @@
{
"user_id": "bbb"
}