From f4d9a54abef58cbc6d2e3587c800067cf3676031 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Fri, 11 Jun 2021 21:58:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(wxads):=20=E6=96=B0=E5=A2=9E=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=20API=20=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WechatAdsClientExecuteImagesExtensions.cs | 100 ++++++++++++++++++ .../Models/Abstractions/CommonFilter.cs | 40 +++++++ .../Models/Abstractions/CommonPagination.cs | 39 +++++++ .../Models/Images/ImagesAddRequest.cs | 39 +++++++ .../Models/Images/ImagesAddResponse.cs | 25 +++++ .../Models/Images/ImagesGetRequest.cs | 39 +++++++ .../Models/Images/ImagesGetResponse.cs | 93 ++++++++++++++++ 7 files changed, 375 insertions(+) create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonFilter.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonPagination.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddResponse.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetRequest.cs create mode 100644 src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetResponse.cs diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs new file mode 100644 index 00000000..4d3dd2a7 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Web; +using Flurl; +using Flurl.Http; + +namespace SKIT.FlurlHttpClient.Wechat.Ads +{ + public static class WechatAdsClientExecuteImagesExtensions + { + /// + /// 异步调用 [POST] /images/add 接口。 + /// + /// + /// + /// + /// + public static async Task ExecuteImagesAddAsync(this WechatAdsClient client, Models.ImagesAddRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + if (string.IsNullOrEmpty(request.FileName)) + { + request.FileName = Guid.NewGuid().ToString("N").ToLower(); + } + + if (string.IsNullOrEmpty(request.FileContentType)) + { + if (request.FileName!.EndsWith(".swf", StringComparison.OrdinalIgnoreCase)) + request.FileContentType = "application/x-shockwave-flash"; + else if (request.FileName!.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)) + request.FileContentType = "image/jpeg"; + else if (request.FileName!.EndsWith(".jpeg", StringComparison.OrdinalIgnoreCase)) + request.FileContentType = "image/jpeg"; + else if (request.FileName!.EndsWith(".gif", StringComparison.OrdinalIgnoreCase)) + request.FileContentType = "image/gif"; + else + request.FileContentType = "image/png"; + } + + if (string.IsNullOrEmpty(request.FileHash)) + { + request.FileHash = Security.MD5Utility.Hash(request.FileBytes ?? new byte[0]); + } + + string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); + using var fileContent = new ByteArrayContent(request.FileBytes ?? new byte[0]); + using var httpContent = new MultipartFormDataContent(boundary); + httpContent.Add(fileContent, "\"media\"", "\"" + HttpUtility.UrlEncode(request.FileName) + "\""); + httpContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data; boundary=" + boundary); + fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(request.FileContentType); + fileContent.Headers.ContentLength = request.FileBytes?.Length ?? 0; + IFlurlRequest flurlReq = client + .CreateRequest(HttpMethod.Post, "images", "add") + .SetOptions(request) + .SetQueryParam("access_token", request.AccessToken); + + return await client.SendRequestAsync(flurlReq, content: httpContent, cancellationToken: cancellationToken); + } + + /// + /// 异步调用 [GET] /images/get 接口。 + /// + /// + /// + /// + /// + public static async Task ExecuteImagesGetAsync(this WechatAdsClient client, Models.ImagesGetRequest 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(HttpMethod.Get, "images", "get") + .SetOptions(request) + .SetQueryParam("access_token", request.AccessToken); + + if (!string.IsNullOrEmpty(request.ImageId)) + flurlReq.SetQueryParam("image_id", request.ImageId); + + if (request.Filters != null && request.Filters.Any()) + flurlReq.SetQueryParam("filtering", client.JsonSerializer.Serialize(request.Filters)); + + if (request.PageSize.HasValue) + flurlReq.SetQueryParam("page_size", request.PageSize.Value); + + if (request.Page.HasValue) + flurlReq.SetQueryParam("page", request.Page.Value); + + return await client.SendRequestAsync(flurlReq, cancellationToken: cancellationToken); + } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonFilter.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonFilter.cs new file mode 100644 index 00000000..a9e12cdb --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonFilter.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SKIT.FlurlHttpClient.Wechat.Ads.Models.Abstractions +{ + public sealed class CommonFilter + { + public const string OPERATOR_EQUALS = "EQUALS"; + public const string OPERATOR_CONTAINS = "CONTAINS"; + public const string OPERATOR_LESS = "LESS"; + public const string OPERATOR_LESSEQUALS = "LESS_EQUALS"; + public const string OPERATOR_GREATER = "GREATER"; + public const string OPERATOR_GREATEREQUALS = "GREATER_EQUALS"; + + /// + /// 获取或设置过滤字段。 + /// + [Newtonsoft.Json.JsonProperty("field")] + [System.Text.Json.Serialization.JsonPropertyName("field")] + public string Field { get; set; } = string.Empty; + + /// + /// 获取或设置操作符。 + /// 默认值:EQUALS + /// + [Newtonsoft.Json.JsonProperty("operator")] + [System.Text.Json.Serialization.JsonPropertyName("operator")] + public string Operator { get; set; } = OPERATOR_EQUALS; + + /// + /// 获取或设置字段取值。 + /// + [Newtonsoft.Json.JsonProperty("values")] + [System.Text.Json.Serialization.JsonPropertyName("values")] + public string[] Values { get; set; } = new string[0]; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonPagination.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonPagination.cs new file mode 100644 index 00000000..b13fdea9 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Abstractions/CommonPagination.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SKIT.FlurlHttpClient.Wechat.Ads.Models.Abstractions +{ + public sealed class CommonPagination + { + /// + /// 获取或设置总数量。 + /// + [Newtonsoft.Json.JsonProperty("total_number")] + [System.Text.Json.Serialization.JsonPropertyName("total_number")] + public int TotalNumber { get; set; } + + /// + /// 获取或设置总页数。 + /// + [Newtonsoft.Json.JsonProperty("total_page")] + [System.Text.Json.Serialization.JsonPropertyName("total_page")] + public int TotalPage { get; set; } + + /// + /// 获取或设置页大小。 + /// + [Newtonsoft.Json.JsonProperty("page_size")] + [System.Text.Json.Serialization.JsonPropertyName("page_size")] + public int PageSize { get; set; } + + /// + /// 获取或设置页码。 + /// + [Newtonsoft.Json.JsonProperty("page")] + [System.Text.Json.Serialization.JsonPropertyName("page")] + public int Page { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddRequest.cs new file mode 100644 index 00000000..f69ee2f5 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddRequest.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.Ads.Models +{ + /// + /// 表示 [POST] /images/add 接口的请求。 + /// + public class ImagesAddRequest : WechatAdsRequest + { + /// + /// 获取或设置图片文件字节数组。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public byte[] FileBytes { get; set; } = new byte[0]; + + /// + /// 获取或设置图片文件名。如果不指定将由系统自动生成。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? FileName { get; set; } + + /// + /// 获取或设置图片文件 Conent-Type。如果不指定将由系统自动生成。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? FileContentType { get; set; } + + /// + /// 获取或设置图片文件的哈希值。如果不指定将由系统自动生成。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string? FileHash { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddResponse.cs new file mode 100644 index 00000000..f999141e --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesAddResponse.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.Ads.Models +{ + /// + /// 表示 [POST] /images/add 接口的响应。 + /// + public class ImagesAddResponse : WechatAdsResponse + { + public static class Types + { + public class Data : ImagesGetResponse.Types.Data.Types.Image + { + } + } + + /// + /// 获取或设置返回数据。 + /// + [Newtonsoft.Json.JsonProperty("data")] + [System.Text.Json.Serialization.JsonPropertyName("data")] + public Types.Data Data { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetRequest.cs new file mode 100644 index 00000000..1924a3a8 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetRequest.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.Ads.Models +{ + /// + /// 表示 [GET] /images/get 接口的请求。 + /// + public class ImagesGetRequest : WechatAdsRequest + { + /// + /// 获取或设置图片 ID。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string ImageId { get; set; } = string.Empty; + + /// + /// 获取或设置过滤条件。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public IList? Filters { get; set; } + + /// + /// 获取或设置页大小。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? PageSize { get; set; } + + /// + /// 获取或设置页码。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public int? Page { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetResponse.cs new file mode 100644 index 00000000..b27fcb52 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Images/ImagesGetResponse.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; + +namespace SKIT.FlurlHttpClient.Wechat.Ads.Models +{ + /// + /// 表示 [GET] /images/get 接口的响应。 + /// + public class ImagesGetResponse : WechatAdsResponse + { + public static class Types + { + public class Data + { + public static class Types + { + public class Image + { + /// + /// 获取或设置图片 ID。 + /// + [Newtonsoft.Json.JsonProperty("image_id")] + [System.Text.Json.Serialization.JsonPropertyName("image_id")] + public string ImageId { get; set; } = default!; + + /// + /// 获取或设置图片类型。 + /// + [Newtonsoft.Json.JsonProperty("type")] + [System.Text.Json.Serialization.JsonPropertyName("type")] + public string Type { get; set; } = default!; + + /// + /// 获取或设置图片宽度(单位:像素)。 + /// + [Newtonsoft.Json.JsonProperty("width")] + [System.Text.Json.Serialization.JsonPropertyName("width")] + public int Width { get; set; } + + /// + /// 获取或设置图片高度(单位:像素)。 + /// + [Newtonsoft.Json.JsonProperty("height")] + [System.Text.Json.Serialization.JsonPropertyName("height")] + public int Height { get; set; } + + /// + /// 获取或设置图片文件大小(单位:字节)。 + /// + [Newtonsoft.Json.JsonProperty("file_size")] + [System.Text.Json.Serialization.JsonPropertyName("file_size")] + public int FileSize { get; set; } + + /// + /// 获取或设置图片文件的哈希值。 + /// + [Newtonsoft.Json.JsonProperty("signature")] + [System.Text.Json.Serialization.JsonPropertyName("signature")] + public string FileHash { get; set; } = default!; + + /// + /// 获取或设置图片预览地址 URL。 + /// + [Newtonsoft.Json.JsonProperty("preview_url")] + [System.Text.Json.Serialization.JsonPropertyName("preview_url")] + public string PreviewUrl { get; set; } = default!; + } + } + + /// + /// 获取或设置图片列表。 + /// + [Newtonsoft.Json.JsonProperty("list")] + [System.Text.Json.Serialization.JsonPropertyName("list")] + public Types.Image[] ImageList { get; set; } = default!; + + /// + /// 获取或设置分页信息。 + /// + [Newtonsoft.Json.JsonProperty("page_info")] + [System.Text.Json.Serialization.JsonPropertyName("page_info")] + public Abstractions.CommonPagination Pagination { get; set; } = default!; + } + } + + /// + /// 获取或设置返回数据。 + /// + [Newtonsoft.Json.JsonProperty("data")] + [System.Text.Json.Serialization.JsonPropertyName("data")] + public Types.Data Data { get; set; } = default!; + } +}