diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteAdvertiserExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteAdvertiserExtensions.cs
new file mode 100644
index 00000000..f8f2705c
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteAdvertiserExtensions.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Flurl;
+using Flurl.Http;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads
+{
+ public static class WechatAdsClientExecuteAdvertiserExtensions
+ {
+ ///
+ /// 异步调用 [POST] /advertiser/add 接口。
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteAdvertiserAddAsync(this WechatAdsClient client, Models.AdvertiserAddRequest 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.Post, "advertiser", "add")
+ .SetOptions(request)
+ .SetQueryParam("access_token", request.AccessToken);
+
+ return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 异步调用 [POST] /advertiser/update 接口。
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteAdvertiserUpdateAsync(this WechatAdsClient client, Models.AdvertiserUpdateRequest 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.Post, "advertiser", "update")
+ .SetOptions(request)
+ .SetQueryParam("access_token", request.AccessToken);
+
+ return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 异步调用 [GET] /advertiser/get 接口。
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteAdvertiserGetAsync(this WechatAdsClient client, Models.AdvertiserGetRequest 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, "advertiser", "get")
+ .SetOptions(request)
+ .SetQueryParam("access_token", request.AccessToken);
+
+ return await client.SendRequestAsync(flurlReq, cancellationToken: cancellationToken);
+ }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserAddRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserAddRequest.cs
new file mode 100644
index 00000000..a6d56954
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserAddRequest.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads.Models
+{
+ ///
+ /// 表示 [POST] /advertiser/add 接口的请求。
+ ///
+ public class AdvertiserAddRequest : WechatAdsRequest
+ {
+ ///
+ /// 获取或设置行业 ID。
+ ///
+ [Newtonsoft.Json.JsonProperty("system_industry_id")]
+ [System.Text.Json.Serialization.JsonPropertyName("system_industry_id")]
+ public int IndustryId { get; set; }
+
+ ///
+ /// 获取或设置联系人姓名。
+ ///
+ [Newtonsoft.Json.JsonProperty("contact_person")]
+ [System.Text.Json.Serialization.JsonPropertyName("contact_person")]
+ public string ContactPerson { get; set; } = string.Empty;
+
+ ///
+ /// 获取或设置联系人电话号码。
+ ///
+ [Newtonsoft.Json.JsonProperty("contact_person_telephone")]
+ [System.Text.Json.Serialization.JsonPropertyName("contact_person_telephone")]
+ public string ContactTeleNumber { get; set; } = string.Empty;
+
+ ///
+ /// 获取或设置经营性质类型。
+ ///
+ [Newtonsoft.Json.JsonProperty("business_type")]
+ [System.Text.Json.Serialization.JsonPropertyName("business_type")]
+ public string? BusinessType { get; set; }
+
+ ///
+ /// 获取或设置经营内容。
+ ///
+ [Newtonsoft.Json.JsonProperty("business_content")]
+ [System.Text.Json.Serialization.JsonPropertyName("business_content")]
+ public string? BusinessContent { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserAddResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserAddResponse.cs
new file mode 100644
index 00000000..4235477c
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserAddResponse.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads.Models
+{
+ ///
+ /// 表示 [POST] /advertiser/add 接口的响应。
+ ///
+ public class AdvertiserAddResponse : WechatAdsResponse
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserGetRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserGetRequest.cs
new file mode 100644
index 00000000..a6f5f1c3
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserGetRequest.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads.Models
+{
+ ///
+ /// 表示 [GET] /advertiser/get 接口的请求。
+ ///
+ public class AdvertiserGetRequest : WechatAdsRequest
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserGetResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserGetResponse.cs
new file mode 100644
index 00000000..00d8f2d5
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserGetResponse.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads.Models
+{
+ ///
+ /// 表示 [GET] /advertiser/get 接口的响应。
+ ///
+ public class AdvertiserGetResponse : WechatAdsResponse
+ {
+ public static class Types
+ {
+ public class Data
+ {
+ ///
+ /// 获取或设置公众号名称。
+ ///
+ [Newtonsoft.Json.JsonProperty("wechat_account_name")]
+ [System.Text.Json.Serialization.JsonPropertyName("wechat_account_name")]
+ public string WechatAccountNickname { get; set; } = default!;
+
+ ///
+ /// 获取或设置系统状态。
+ ///
+ [Newtonsoft.Json.JsonProperty("system_status")]
+ [System.Text.Json.Serialization.JsonPropertyName("system_status")]
+ public string SystemStatus { get; set; } = default!;
+
+ ///
+ /// 获取或设置行业 ID。
+ ///
+ [Newtonsoft.Json.JsonProperty("industry_id")]
+ [System.Text.Json.Serialization.JsonPropertyName("industry_id")]
+ public int IndustryId { get; set; }
+
+ ///
+ /// 获取或设置联系人姓名。
+ ///
+ [Newtonsoft.Json.JsonProperty("contact_person")]
+ [System.Text.Json.Serialization.JsonPropertyName("contact_person")]
+ public string ContactPerson { get; set; } = default!;
+
+ ///
+ /// 获取或设置联系人电话号码。
+ ///
+ [Newtonsoft.Json.JsonProperty("contact_person_telephone")]
+ [System.Text.Json.Serialization.JsonPropertyName("contact_person_telephone")]
+ public string ContactTeleNumber { get; set; } = default!;
+
+ ///
+ /// 获取或设置经营性质类型。
+ ///
+ [Newtonsoft.Json.JsonProperty("business_type")]
+ [System.Text.Json.Serialization.JsonPropertyName("business_type")]
+ public string? BusinessType { get; set; }
+
+ ///
+ /// 获取或设置经营内容。
+ ///
+ [Newtonsoft.Json.JsonProperty("business_content")]
+ [System.Text.Json.Serialization.JsonPropertyName("business_content")]
+ public string? BusinessContent { get; set; }
+ }
+ }
+
+ ///
+ /// 获取或设置返回数据。
+ ///
+ [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/Advertiser/AdvertiserUpdateRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserUpdateRequest.cs
new file mode 100644
index 00000000..f9c981cb
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserUpdateRequest.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads.Models
+{
+ ///
+ /// 表示 [POST] /advertiser/update 接口的请求。
+ ///
+ public class AdvertiserUpdateRequest : WechatAdsRequest
+ {
+ ///
+ /// 获取或设置行业 ID。
+ ///
+ [Newtonsoft.Json.JsonProperty("system_industry_id")]
+ [System.Text.Json.Serialization.JsonPropertyName("system_industry_id")]
+ public int? IndustryId { get; set; }
+
+ ///
+ /// 获取或设置联系人姓名。
+ ///
+ [Newtonsoft.Json.JsonProperty("contact_person")]
+ [System.Text.Json.Serialization.JsonPropertyName("contact_person")]
+ public string? ContactPerson { get; set; }
+
+ ///
+ /// 获取或设置联系人电话号码。
+ ///
+ [Newtonsoft.Json.JsonProperty("contact_person_telephone")]
+ [System.Text.Json.Serialization.JsonPropertyName("contact_person_telephone")]
+ public string? ContactTeleNumber { get; set; }
+
+ ///
+ /// 获取或设置经营性质类型。
+ ///
+ [Newtonsoft.Json.JsonProperty("business_type")]
+ [System.Text.Json.Serialization.JsonPropertyName("business_type")]
+ public string? BusinessType { get; set; }
+
+ ///
+ /// 获取或设置经营内容。
+ ///
+ [Newtonsoft.Json.JsonProperty("business_content")]
+ [System.Text.Json.Serialization.JsonPropertyName("business_content")]
+ public string? BusinessContent { get; set; }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserUpdateResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserUpdateResponse.cs
new file mode 100644
index 00000000..77e750a1
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Models/Advertiser/AdvertiserUpdateResponse.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads.Models
+{
+ ///
+ /// 表示 [POST] /advertiser/update 接口的响应。
+ ///
+ public class AdvertiserUpdateResponse : WechatAdsResponse
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/WechatAdsEndpoints.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/WechatAdsEndpoints.cs
index 380a8b99..92743284 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.Ads/WechatAdsEndpoints.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/WechatAdsEndpoints.cs
@@ -10,6 +10,6 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads
///
/// 主域名(默认)。
///
- public const string DEFAULT = "https://api.weixin.qq.com";
+ public const string DEFAULT = "https://api.weixin.qq.com/marketing";
}
}
diff --git a/test/SKIT.FlurlHttpClient.Wechat.Ads.UnitTests/WechatAdsDeclarationTests.cs b/test/SKIT.FlurlHttpClient.Wechat.Ads.UnitTests/WechatAdsDeclarationTests.cs
new file mode 100644
index 00000000..ed6e0317
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.Ads.UnitTests/WechatAdsDeclarationTests.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace SKIT.FlurlHttpClient.Wechat.Ads.UnitTests
+{
+ public class WechatAdsDeclarationTests
+ {
+ private static readonly Assembly _assembly = Assembly.Load("SKIT.FlurlHttpClient.Wechat.Ads");
+
+ [Fact(DisplayName = "验证 API 模型命名")]
+ public void ApiModelsNamingTest()
+ {
+ TestAssertUtil.VerifyApiModelsNaming(_assembly, out var ex);
+
+ if (ex != null)
+ throw ex;
+
+ Assert.Null(ex);
+ }
+
+ [Fact(DisplayName = "验证 API 模型定义")]
+ public void ApiModelsDefinitionTest()
+ {
+ string workdir = Path.Combine(TestConfigs.ProjectTestDirectory, "ModelSamples");
+ Assert.True(Directory.Exists(workdir));
+
+ TestAssertUtil.VerifyApiModelsDefinition(_assembly, workdir, out var ex);
+
+ if (ex != null)
+ throw ex;
+
+ Assert.Null(ex);
+ }
+
+ [Fact(DisplayName = "验证 API 接口命名")]
+ public void ApiExtensionsNamingTest()
+ {
+ TestAssertUtil.VerifyApiExtensionsNaming(_assembly, out var ex);
+
+ if (ex != null)
+ throw ex;
+
+ Assert.Null(ex);
+ }
+
+ [Fact(DisplayName = "验证代码规范")]
+ public void CodeStyleTest()
+ {
+ string workdir = Path.Combine(TestConfigs.ProjectSourceDirectory);
+ Assert.True(Directory.Exists(workdir));
+
+ TestAssertUtil.VerifySourceCodeStyle(workdir, out var ex);
+
+ if (ex != null)
+ throw ex;
+
+ Assert.Null(ex);
+ }
+ }
+}