Skip to content

Commit 65e7a5b

Browse files
authored
Merge pull request #3329 from JeffreySu/Developer
fix #3326: update Weixin.Work API to support new pagination fields an…
2 parents b5b9f0c + 867f0c6 commit 65e7a5b

7 files changed

Lines changed: 125 additions & 7 deletions

File tree

src/Senparc.Weixin.All/Senparc.Weixin.All.net10.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<TargetFramework>net10.0</TargetFramework>
44
<ImplicitUsings>enable</ImplicitUsings>
55
<Nullable>enable</Nullable>
6-
<Version>2026.8.5</Version>
6+
<Version>2026.8.6</Version>
77
<LangVersion>10.0</LangVersion>
88
<AssemblyName>Senparc.Weixin.All</AssemblyName>
99
<RootNamespace>Senparc.Weixin.All</RootNamespace>
@@ -109,6 +109,8 @@
109109
1、聚合包同步纳入海关报关、商家转账授权、智慧商圈和安全探测接口
110110
[2026-07-31] v2026.7.31 Dependency update from Senparc.WebSocket to 1.2.4; Senparc.Weixin.AspNet to 1.6.7; Senparc.Weixin.Cache.CsRedis to 1.3.5; Senparc.Weixin.Cache.Memcached to 2.19.6; Senparc.Weixin.Cache.Redis to 2.21.5; Senparc.Weixin.Cache.Dapr to 0.3.5; Senparc.Weixin.MP.Middleware to 1.5.6; Senparc.Weixin.MP.MvcExtension to 7.17.5; Senparc.Weixin.MP to 16.25.2; Senparc.Weixin.Open to 4.24.5; Senparc.Weixin.TenPayV3 to 2.6.1; Senparc.Weixin.TenPay to 1.20.1; Senparc.Weixin.Work.Middleware to 1.5.6; Senparc.Weixin.Work to 3.32.2; Senparc.Weixin.WxOpen.Middleware to 1.5.6; Senparc.Weixin.WxOpen to 3.28.2; Senparc.Weixin to 6.25.1
111111
[2026-08-05] v2026.8.5 Dependency update from Senparc.Weixin.MP.Middleware to 1.5.7; Senparc.Weixin.MP.MvcExtension to 7.17.6; Senparc.Weixin.MP to 16.25.3; Senparc.Weixin.WxOpen.Middleware to 1.5.7; Senparc.Weixin.WxOpen to 3.28.3
112+
[2026-08-06] v2026.8.6 Work v3.32.2 fix: 修复企业微信审批单号新版分页游标字段及分页结束判断
113+
1、聚合 Work 的 new_cursor/new_next_cursor 官方审批分页协议,并保留旧字段兼容
112114
</PackageReleaseNotes>
113115
<RepositoryUrl>https://github.com/JeffreySu/WeiXinMPSDK</RepositoryUrl>
114116
</PropertyGroup>

src/Senparc.Weixin.Work/Senparc.Weixin.Work.Test/AdvancedAPIs/OA/ApprovalContractTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,44 @@ public void TemplateModelsCoverCurrentConfigsAndRichTips()
267267
}
268268
}
269269

270+
[TestMethod]
271+
public void GetApprovalInfoModelsSupportCurrentAndLegacyPagination()
272+
{
273+
var request = new GetApprovalInfoRequest
274+
{
275+
starttime = "1569546000",
276+
endtime = "1569718800",
277+
new_cursor = string.Empty,
278+
size = 100
279+
};
280+
var requestJson = JsonSerializer.Serialize(request);
281+
using (var requestDocument = JsonDocument.Parse(requestJson))
282+
{
283+
Assert.AreEqual(string.Empty,
284+
requestDocument.RootElement.GetProperty("new_cursor").GetString());
285+
Assert.AreEqual(100, requestDocument.RootElement.GetProperty("size").GetInt32());
286+
}
287+
288+
var result = JsonSerializer.Deserialize<GetApprovalInfoResult>(
289+
"{\"errcode\":0,\"errmsg\":\"ok\",\"sp_no_list\":[\"202608050001\"]," +
290+
"\"new_next_cursor\":\"opaque-next-cursor\"}");
291+
Assert.IsNotNull(result);
292+
Assert.AreEqual(1, result.sp_no_list.Count);
293+
Assert.AreEqual("202608050001", result.sp_no_list[0]);
294+
Assert.AreEqual("opaque-next-cursor", result.new_next_cursor);
295+
296+
var lastPage = JsonSerializer.Deserialize<GetApprovalInfoResult>(
297+
"{\"errcode\":0,\"errmsg\":\"ok\",\"sp_no_list\":[\"202608050002\"]}");
298+
Assert.IsNotNull(lastPage);
299+
Assert.AreEqual(1, lastPage.sp_no_list.Count);
300+
Assert.IsNull(lastPage.new_next_cursor);
301+
302+
var legacyResult = JsonSerializer.Deserialize<GetApprovalInfoResult>(
303+
"{\"errcode\":0,\"errmsg\":\"ok\",\"sp_no_list\":[],\"next_cursor\":100}");
304+
Assert.IsNotNull(legacyResult);
305+
Assert.AreEqual(100, legacyResult.next_cursor.Value);
306+
}
307+
270308
private static int CountOccurrences(string source, string value)
271309
=> source.Split(new[] { value }, StringSplitOptions.None).Length - 1;
272310

src/Senparc.Weixin.Work/Senparc.Weixin.Work.Test/Senparc.Weixin.Work.Test.net10.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
1、显式标记测试项目,确保企业微信契约测试被测试运行器加载
8787
[2026-07-31] v1.0.5 Dependency update from Senparc.Weixin.Cache.CsRedis to 1.3.5; Senparc.Weixin.MP to 16.25.2; Senparc.WeixinTests to 1.0.5; Senparc.Weixin to 6.25.1; Senparc.Weixin.Work to 3.32.2
8888
[2026-08-05] v1.0.6 Dependency update from Senparc.Weixin.MP to 16.25.3 and Senparc.WeixinTests to 1.0.6
89+
[2026-08-05] v1.0.6 补充企业微信审批新版分页协议契约测试
90+
1、验证 new_cursor 和 new_next_cursor 字段
91+
2、覆盖最后一页仍有审批单号但没有下一页游标的情况
8992
</PackageReleaseNotes>
9093

9194
<IsPackable>false</IsPackable>

src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/OA/OAJson/GetApprovalInfoRequest.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1-
using System;
1+
/*----------------------------------------------------------------
2+
Copyright (C) 2026 Senparc
3+
4+
文件名:GetApprovalInfoRequest.cs
5+
文件功能描述:批量获取审批单号请求参数
6+
7+
8+
创建标识:Senparc - 20230224
9+
10+
修改标识:Senparc - 20260805
11+
修改描述:v3.32.2 修复企业微信审批分页字段并兼容新版游标
12+
13+
----------------------------------------------------------------*/
14+
15+
using System;
216
using System.Collections.Generic;
317
using System.Linq;
418
using System.Text;
@@ -23,12 +37,18 @@ public class GetApprovalInfoRequest
2337
public string endtime { get; set; }
2438

2539
/// <summary>
26-
/// 分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取
40+
/// 新版分页查询游标,首次请求传空字符串,后续使用返回的new_next_cursor进行分页拉取。
41+
/// </summary>
42+
public string new_cursor { get; set; }
43+
44+
/// <summary>
45+
/// 旧版分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取。
46+
/// 当前企业微信官方文档已推荐使用new_cursor。
2747
/// </summary>
2848
public int cursor { get; set; }
2949

3050
/// <summary>
31-
/// 一次请求拉取审批单数量,默认值为100,上限值为100。若accesstoken为自建应用,仅允许获取在应用可见范围内申请人提交的表单,返回的sp_no_list个数可能和size不一致,开发者需用next_cursor判断表单记录是否拉取完
51+
/// 一次请求拉取审批单数量,默认值为100,上限值为100。若accesstoken为自建应用,仅允许获取在应用可见范围内申请人提交的表单,返回的sp_no_list个数可能和size不一致,开发者需用new_next_cursor判断表单记录是否拉取完。
3252
/// </summary>
3353
public int size { get; set; }
3454

src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/OA/OAJson/GetApprovalInfoResult.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-

1+
/*----------------------------------------------------------------
2+
Copyright (C) 2026 Senparc
3+
4+
文件名:GetApprovalInfoResult.cs
5+
文件功能描述:批量获取审批单号返回结果
6+
7+
8+
创建标识:Senparc - 20230224
9+
10+
修改标识:Senparc - 20260805
11+
修改描述:v3.32.2 修复企业微信审批分页字段并兼容新版游标
12+
13+
----------------------------------------------------------------*/
14+
215

316
using Senparc.Weixin.Entities;
417
using System.Collections.Generic;
@@ -14,5 +27,15 @@ public class GetApprovalInfoResult : WorkJsonResult
1427
///
1528
/// </summary>
1629
public List<string> sp_no_list { get; set; }
30+
31+
/// <summary>
32+
/// 新版分页查询游标;返回结果没有该字段时表示审批单已经拉取完。
33+
/// </summary>
34+
public string new_next_cursor { get; set; }
35+
36+
/// <summary>
37+
/// 旧版分页查询游标,兼容官方待废弃的旧协议字段。
38+
/// </summary>
39+
public int? next_cursor { get; set; }
1740
}
1841
}

src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/OA/OaApi.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@ and limitations under the License.
3232
3333
修改标识:Senparc - 20260725
3434
修改描述:v3.32.1 补齐复制第三方应用审批模板接口
35+
36+
修改标识:Senparc - 20260805
37+
修改描述:v3.32.2 修复企业微信审批分页字段并兼容新版游标
3538
3639
----------------------------------------------------------------*/
3740

41+
using Senparc.CO2NET.Helpers.Serializers;
3842
using Senparc.NeuChar;
3943
using Senparc.Weixin.CommonAPIs;
4044
using Senparc.Weixin.Entities;
@@ -54,6 +58,25 @@ namespace Senparc.Weixin.Work.AdvancedAPIs.OA
5458
[NcApiBind(NeuChar.PlatformType.WeChat_Work, true)]
5559
public static class OaApi
5660
{
61+
private static readonly JsonSetting IgnoreNullJsonSetting = new JsonSetting(true);
62+
63+
private static object GetApprovalInfoRequestData(GetApprovalInfoRequest data)
64+
{
65+
if (data?.new_cursor == null)
66+
{
67+
return data;
68+
}
69+
70+
return new
71+
{
72+
data.starttime,
73+
data.endtime,
74+
data.new_cursor,
75+
data.size,
76+
data.filters
77+
};
78+
}
79+
5780
#region 同步方法
5881
/// <summary>
5982
/// 获取审批模板详情
@@ -85,6 +108,7 @@ public static ApplyEventResult ApplyEvent(string accessToken, ApplyEventRequest
85108

86109
/// <summary>
87110
/// 批量获取审批单号
111+
/// 当前分页协议使用请求字段 new_cursor 和返回字段 new_next_cursor;返回结果没有 new_next_cursor 时表示已拉取完。
88112
/// https://developer.work.weixin.qq.com/document/path/91816
89113
/// </summary>
90114
/// <param name="accessToken"> 调用接口凭证。必须使用审批应用或企业内自建应用的secret获取</param>
@@ -94,7 +118,9 @@ public static ApplyEventResult ApplyEvent(string accessToken, ApplyEventRequest
94118
public static GetApprovalInfoResult GetApprovalInfo(string accessToken, GetApprovalInfoRequest data, int timeOut = Config.TIME_OUT)
95119
{
96120
var urlFormat = Config.ApiWorkHost + "/cgi-bin/oa/getapprovalinfo?access_token={0}";
97-
return CommonJsonSend.Send<GetApprovalInfoResult>(accessToken, urlFormat, data, CommonJsonSendType.POST, timeOut);
121+
return CommonJsonSend.Send<GetApprovalInfoResult>(accessToken, urlFormat,
122+
GetApprovalInfoRequestData(data), CommonJsonSendType.POST, timeOut,
123+
jsonSetting: IgnoreNullJsonSetting);
98124
}
99125

100126
/// <summary>
@@ -236,6 +262,7 @@ public static async Task<ApplyEventResult> ApplyEventAsync(string accessToken, A
236262

237263
/// <summary>
238264
/// 批量获取审批单号
265+
/// 当前分页协议使用请求字段 new_cursor 和返回字段 new_next_cursor;返回结果没有 new_next_cursor 时表示已拉取完。
239266
/// https://developer.work.weixin.qq.com/document/path/91816
240267
/// </summary>
241268
/// <param name="accessToken"> 调用接口凭证。必须使用审批应用或企业内自建应用的secret获取</param>
@@ -245,7 +272,9 @@ public static async Task<ApplyEventResult> ApplyEventAsync(string accessToken, A
245272
public static async Task<GetApprovalInfoResult> GetApprovalInfoAsync(string accessToken, GetApprovalInfoRequest data, int timeOut = Config.TIME_OUT)
246273
{
247274
var urlFormat = Config.ApiWorkHost + "/cgi-bin/oa/getapprovalinfo?access_token={0}";
248-
return await CommonJsonSend.SendAsync<GetApprovalInfoResult>(accessToken, urlFormat, data, CommonJsonSendType.POST, timeOut);
275+
return await CommonJsonSend.SendAsync<GetApprovalInfoResult>(accessToken, urlFormat,
276+
GetApprovalInfoRequestData(data), CommonJsonSendType.POST, timeOut,
277+
jsonSetting: IgnoreNullJsonSetting);
249278
}
250279

251280
/// <summary>

src/Senparc.Weixin.Work/Senparc.Weixin.Work/Senparc.Weixin.Work.net10.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@
299299
77、补齐会话内容存档 Finance 原生 SDK,会话拉取、消息解密、媒体分片下载及跨平台资源释放
300300
78、为官方正文无权访问的开放硬件访客数据 2 项接口保留同步/异步占位入口,调用时抛出包含文档编号的明确异常
301301
[2026-07-31] v3.32.2 Dependency update from Senparc.Weixin to 6.25.1
302+
[2026-08-05] v3.32.2 修复企业微信审批单号分页游标协议
303+
1、补齐官方当前协议的 new_cursor 请求字段和 new_next_cursor 返回字段,并保留旧字段兼容性
304+
2、修正新版分页请求序列化,避免发送已废弃的旧 cursor 字段
302305
</PackageReleaseNotes>
303306
<RepositoryUrl>https://github.com/JeffreySu/WeiXinMPSDK</RepositoryUrl>
304307
<SignAssembly>False</SignAssembly>

0 commit comments

Comments
 (0)