diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientExecuteStatisticsExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientExecuteStatisticsExtensions.cs
new file mode 100644
index 00000000..2d1d7bfe
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Extensions/WechatOpenAIClientExecuteStatisticsExtensions.cs
@@ -0,0 +1,52 @@
+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.OpenAI
+{
+ public static class WechatOpenAIClientExecuteStatisticsExtensions
+ {
+ ///
+ /// 异步调用 [POST] /v2/dialog_user_specified_date 接口。
+ /// REF: https://developers.weixin.qq.com/doc/aispeech/openapi/api/v2/statistic/dialog_user_specified_date.html
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteDialogUserSpecifiedDateAsync(this WechatOpenAIClient client, Models.DialogUserSpecifiedDateRequest 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, "v2", "dialog_user_specified_date");
+
+ return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken);
+ }
+
+ ///
+ /// 异步调用 [POST] /v2/user_query_yesterday_data 接口。
+ /// REF: https://developers.weixin.qq.com/doc/aispeech/openapi/api/v2/statistic/user_query_yesterday_data.html
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task ExecuteUserQueryYesterdayDataAsync(this WechatOpenAIClient client, Models.UserQueryYesterdayDataRequest 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, "v2", "user_query_yesterday_data");
+
+ return await client.SendRequestWithJsonAsync(flurlReq, data: request, cancellationToken: cancellationToken);
+ }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/DialogUserSpecifiedDateRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/DialogUserSpecifiedDateRequest.cs
new file mode 100644
index 00000000..f062043b
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/DialogUserSpecifiedDateRequest.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /v2/dialog_user_specified_date 接口的请求。
+ ///
+ public class DialogUserSpecifiedDateRequest : WechatOpenAIRequest
+ {
+ ///
+ /// 获取或设置起始日期字符串(格式:yyyy-MM-dd)。
+ ///
+ [Newtonsoft.Json.JsonProperty("start_date")]
+ [System.Text.Json.Serialization.JsonPropertyName("start_date")]
+ public string StartDateString { get; set; } = string.Empty;
+
+ ///
+ /// 获取或设置结束日期字符串(格式:yyyy-MM-dd)。
+ ///
+ [Newtonsoft.Json.JsonProperty("end_date")]
+ [System.Text.Json.Serialization.JsonPropertyName("end_date")]
+ public string EndDateString { get; set; } = string.Empty;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/DialogUserSpecifiedDateResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/DialogUserSpecifiedDateResponse.cs
new file mode 100644
index 00000000..211c62ef
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/DialogUserSpecifiedDateResponse.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /v2/dialog_user_specified_date 接口的响应。
+ ///
+ public class DialogUserSpecifiedDateResponse : WechatOpenAIResponse
+ {
+ public static class Types
+ {
+ public class Data
+ {
+ ///
+ /// 获取或设置日期字符串(格式:yyyy-MM-dd)。
+ ///
+ [Newtonsoft.Json.JsonProperty("date")]
+ [System.Text.Json.Serialization.JsonPropertyName("date")]
+ public string DateString { get; set; } = default!;
+
+ ///
+ /// 获取或设置数量。
+ ///
+ [Newtonsoft.Json.JsonProperty("count")]
+ [System.Text.Json.Serialization.JsonPropertyName("count")]
+ public int Count { get; set; }
+ }
+ }
+
+ ///
+ /// 获取或设置对话数据列表。
+ ///
+ [Newtonsoft.Json.JsonProperty("q_a_count")]
+ [System.Text.Json.Serialization.JsonPropertyName("q_a_count")]
+ public Types.Data[] DialogDataList { get; set; } = default!;
+
+ ///
+ /// 获取或设置用户数据列表。
+ ///
+ [Newtonsoft.Json.JsonProperty("user_count")]
+ [System.Text.Json.Serialization.JsonPropertyName("user_count")]
+ public Types.Data[] UserDataList { get; set; } = default!;
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/UserQueryYesterdayDataRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/UserQueryYesterdayDataRequest.cs
new file mode 100644
index 00000000..11bd8265
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/UserQueryYesterdayDataRequest.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /v2/user_query_yesterday_data 接口的请求。
+ ///
+ public class UserQueryYesterdayDataRequest : WechatOpenAIRequest
+ {
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/UserQueryYesterdayDataResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/UserQueryYesterdayDataResponse.cs
new file mode 100644
index 00000000..be8396a7
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Models/Statistics/UserQueryYesterdayDataResponse.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+
+namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Models
+{
+ ///
+ /// 表示 [POST] /v2/user_query_yesterday_data 接口的响应。
+ ///
+ public class UserQueryYesterdayDataResponse : WechatOpenAIResponse
+ {
+ ///
+ /// 获取或设置对话数量。
+ ///
+ [Newtonsoft.Json.JsonProperty("q_a_count")]
+ [System.Text.Json.Serialization.JsonPropertyName("q_a_count")]
+ public int DialogCount { get; set; }
+
+ ///
+ /// 获取或设置用户数量。
+ ///
+ [Newtonsoft.Json.JsonProperty("user_count")]
+ [System.Text.Json.Serialization.JsonPropertyName("user_count")]
+ public int UserCount { get; set; }
+
+ ///
+ /// 获取或设置新消息总数。
+ ///
+ [Newtonsoft.Json.JsonProperty("new_news_count")]
+ [System.Text.Json.Serialization.JsonPropertyName("new_news_count")]
+ public int NewMessageCount { get; set; }
+
+ ///
+ /// 获取或设置新消息人数。
+ ///
+ [Newtonsoft.Json.JsonProperty("new_news_user_count")]
+ [System.Text.Json.Serialization.JsonPropertyName("new_news_user_count")]
+ public int NewMessageUserCount { get; set; }
+
+ ///
+ /// 获取或设置热问列表。
+ ///
+ [Newtonsoft.Json.JsonProperty("hot_query_list")]
+ [System.Text.Json.Serialization.JsonPropertyName("hot_query_list")]
+ public string[] HotQueryList { get; set; } = default!;
+
+ ///
+ /// 获取或设置命中率(范围:0~1)。
+ ///
+ [Newtonsoft.Json.JsonProperty("hit_rate")]
+ [System.Text.Json.Serialization.JsonPropertyName("hit_rate")]
+ public double HitRate { get; set; }
+
+ ///
+ /// 获取或设置错误率(范围:0~1)。
+ ///
+ [Newtonsoft.Json.JsonProperty("miss_rate")]
+ [System.Text.Json.Serialization.JsonPropertyName("miss_rate")]
+ public double MissRate { get; set; }
+
+ ///
+ /// 获取或设置用户增长率(范围:0~1)。
+ ///
+ [Newtonsoft.Json.JsonProperty("user_growth_rate")]
+ [System.Text.Json.Serialization.JsonPropertyName("user_growth_rate")]
+ public double UserGrowthRate { get; set; }
+
+ ///
+ /// 获取或设置命中增长率(范围:0~1)。
+ ///
+ [Newtonsoft.Json.JsonProperty("hit_growth_rate")]
+ [System.Text.Json.Serialization.JsonPropertyName("hit_growth_rate")]
+ public double HitGrowthRate { get; set; }
+ }
+}
diff --git a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/DialogUserSpecifiedDateRequest.json b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/DialogUserSpecifiedDateRequest.json
new file mode 100644
index 00000000..6ebf35f6
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/DialogUserSpecifiedDateRequest.json
@@ -0,0 +1,4 @@
+{
+ "start_date": "2021-08-11",
+ "end_date": "2021-08-18"
+}
\ No newline at end of file
diff --git a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/DialogUserSpecifiedDateResponse.json b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/DialogUserSpecifiedDateResponse.json
new file mode 100644
index 00000000..5d58ac5e
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/DialogUserSpecifiedDateResponse.json
@@ -0,0 +1,21 @@
+{
+ "code": 0,
+ "msg": "请求成功",
+ "request_id": "255i0ug8-l9q4-3801-44ft-w7csjn9e5142",
+ "q_a_count": [
+ {
+ "date": "2021-08-11",
+ "count": 911
+ },
+ {
+ "date": "2021-08-12",
+ "count": 1316
+ }
+ ],
+ "user_count": [
+ {
+ "date": "2021-08-11",
+ "count": 267
+ }
+ ]
+}
\ No newline at end of file
diff --git a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/UserQueryYesterdayDataRequest.json b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/UserQueryYesterdayDataRequest.json
new file mode 100644
index 00000000..22fdca1b
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/UserQueryYesterdayDataRequest.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/UserQueryYesterdayDataResponse.json b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/UserQueryYesterdayDataResponse.json
new file mode 100644
index 00000000..cc6a7f73
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.OpenAI.UnitTests/ModelSamples/Statistics/UserQueryYesterdayDataResponse.json
@@ -0,0 +1,14 @@
+{
+ "code": 0,
+ "msg": "请求成功",
+ "request_id": "255i0ug8-l9q4-3801-44ft-w7csjn9e5140",
+ "hit_rate": 0.94,
+ "q_a_count": 985,
+ "user_count": 280,
+ "hot_query_list": [ "我想看新闻", "好听的歌", "我想知道今天天气" ],
+ "miss_rate": 0.06000000000000005,
+ "new_news_count": 2021,
+ "new_news_user_count": 605,
+ "user_growth_rate": 0.16,
+ "hit_growth_rate": 0.02
+}
\ No newline at end of file