From e6b849a6d5912573ef39b04ecda531d2c09740b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 02:54:57 +0000 Subject: [PATCH 1/3] Initial plan From 7b25283d8b5853d0002e5573510be02859e05dad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 02:59:29 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=AC=AC=E4=B8=89=E6=96=B9=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E9=83=A8=E9=97=A8=E6=88=90=E5=91=98=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=BD=BF=E7=94=A8=E9=94=99=E8=AF=AFtoken=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 WxCpTpUserService 接口中新增带 corpId 参数的 listSimpleByDepartment 方法 - 旧方法标记为 @Deprecated,Javadoc 指向新方法 - 新方法实现中通过 corpId 获取 access_token 并附加到请求参数,使用 withoutSuiteAccessToken=true 跳过自动添加 suite_access_token - 新增 WxCpTpUserServiceImplTest 单元测试验证修复 Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../cp/tp/service/WxCpTpUserService.java | 20 +++++ .../service/impl/WxCpTpUserServiceImpl.java | 26 ++++++ .../impl/WxCpTpUserServiceImplTest.java | 85 +++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImplTest.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpUserService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpUserService.java index 0f2fc5dd99..1359fa66e0 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpUserService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpUserService.java @@ -53,9 +53,29 @@ public interface WxCpTpUserService { * @param departId 必填。部门id * @param fetchChild 非必填。1/0:是否递归获取子部门下面的成员 * @param status 非必填。0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加 + * @param corpId 企业id * @return the list * @throws WxErrorException the wx error exception */ + List listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status, String corpId) + throws WxErrorException; + + /** + *
+   * 获取部门成员.
+   *
+   * http://qydev.weixin.qq.com/wiki/index.php?title=管理成员#.E8.8E.B7.E5.8F.96.E9.83.A8.E9.97.A8.E6.88.90.E5.91.98
+   * 
+ * + * @param departId 必填。部门id + * @param fetchChild 非必填。1/0:是否递归获取子部门下面的成员 + * @param status 非必填。0获取全部员工,1获取已关注成员列表,2获取禁用成员列表,4获取未关注成员列表。status可叠加 + * @return the list + * @throws WxErrorException the wx error exception + * @deprecated 第三方应用调用此接口需要使用 corpId 对应的 access_token,请使用 + * {@link #listSimpleByDepartment(Long, Boolean, Integer, String)} + */ + @Deprecated List listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status) throws WxErrorException; /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java index d992627468..423af48a9d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java @@ -97,6 +97,32 @@ public List listByDepartment(Long departId, Boolean fetchChild, Intege } @Override + public List listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status, String corpId) + throws WxErrorException { + String params = ""; + if (fetchChild != null) { + params += "&fetch_child=" + (fetchChild ? "1" : "0"); + } + if (status != null) { + params += "&status=" + status; + } else { + params += "&status=0"; + } + params += "&access_token=" + mainService.getWxCpTpConfigStorage().getAccessToken(corpId); + + String url = mainService.getWxCpTpConfigStorage().getApiUrl(USER_SIMPLE_LIST + departId); + String responseContent = this.mainService.get(url, params, true); + JsonObject tmpJsonElement = GsonParser.parse(responseContent); + return WxCpGsonBuilder.create() + .fromJson( + tmpJsonElement.getAsJsonObject().get("userlist"), + new TypeToken>() { + }.getType() + ); + } + + @Override + @Deprecated public List listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status) throws WxErrorException { String params = ""; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImplTest.java new file mode 100644 index 0000000000..1cfc7f3499 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImplTest.java @@ -0,0 +1,85 @@ +package me.chanjar.weixin.cp.tp.service.impl; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpUser; +import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; +import me.chanjar.weixin.cp.config.impl.WxCpTpDefaultConfigImpl; +import me.chanjar.weixin.cp.tp.service.WxCpTpUserService; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.util.List; + +import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.User.USER_SIMPLE_LIST; +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertNotNull; + +/** + * 企业微信-第三方开发-用户管理相关测试. + * + * @author GitHub Copilot + */ +public class WxCpTpUserServiceImplTest { + + @Mock + private WxCpTpServiceApacheHttpClientImpl wxCpTpService; + + @Mock + private WxCpTpConfigStorage configStorage; + + private WxCpTpUserService wxCpTpUserService; + + private AutoCloseable mockitoAnnotations; + + /** + * Sets up. + */ + @BeforeClass + public void setUp() { + mockitoAnnotations = MockitoAnnotations.openMocks(this); + when(wxCpTpService.getWxCpTpConfigStorage()).thenReturn(configStorage); + WxCpTpDefaultConfigImpl defaultConfig = new WxCpTpDefaultConfigImpl(); + when(configStorage.getApiUrl(contains(USER_SIMPLE_LIST))) + .thenAnswer(invocation -> defaultConfig.getApiUrl(invocation.getArgument(0))); + wxCpTpUserService = new WxCpTpUserServiceImpl(wxCpTpService); + } + + /** + * Tear down. + * + * @throws Exception the exception + */ + @AfterClass + public void tearDown() throws Exception { + mockitoAnnotations.close(); + } + + /** + * 测试使用 corpId 的 listSimpleByDepartment 方法,验证请求使用了 access_token 而非 suite_access_token. + * + * @throws WxErrorException the wx error exception + */ + @Test + public void testListSimpleByDepartmentWithCorpId() throws WxErrorException { + Long departId = 1L; + String corpId = "test_corp_id"; + String accessToken = "test_access_token"; + String result = "{\"errcode\":0,\"errmsg\":\"ok\",\"userlist\":[{\"userid\":\"zhangsan\",\"name\":\"张三\"}]}"; + + when(configStorage.getAccessToken(corpId)).thenReturn(accessToken); + String url = new WxCpTpDefaultConfigImpl().getApiUrl(USER_SIMPLE_LIST + departId); + when(wxCpTpService.get(eq(url), contains("access_token=" + accessToken), eq(true))).thenReturn(result); + + List users = wxCpTpUserService.listSimpleByDepartment(departId, true, 0, corpId); + assertNotNull(users); + + // 验证调用时传入了 withoutSuiteAccessToken=true,确保不会附加 suite_access_token + verify(wxCpTpService).get(eq(url), contains("access_token=" + accessToken), eq(true)); + } +} From 64e021017f556a04e7b7ca82e00b5db240d290d6 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 12 Mar 2026 14:34:02 +0800 Subject: [PATCH 3/3] Update weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../service/impl/WxCpTpUserServiceImpl.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java index 423af48a9d..f3d41e3ff5 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/WxCpTpUserServiceImpl.java @@ -99,19 +99,29 @@ public List listByDepartment(Long departId, Boolean fetchChild, Intege @Override public List listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status, String corpId) throws WxErrorException { - String params = ""; + StringBuilder params = new StringBuilder(); if (fetchChild != null) { - params += "&fetch_child=" + (fetchChild ? "1" : "0"); + params.append("fetch_child=").append(fetchChild ? "1" : "0"); } if (status != null) { - params += "&status=" + status; + if (params.length() > 0) { + params.append('&'); + } + params.append("status=").append(status); } else { - params += "&status=0"; + if (params.length() > 0) { + params.append('&'); + } + params.append("status=0"); } - params += "&access_token=" + mainService.getWxCpTpConfigStorage().getAccessToken(corpId); + if (params.length() > 0) { + params.append('&'); + } + params.append("access_token=") + .append(mainService.getWxCpTpConfigStorage().getAccessToken(corpId)); String url = mainService.getWxCpTpConfigStorage().getApiUrl(USER_SIMPLE_LIST + departId); - String responseContent = this.mainService.get(url, params, true); + String responseContent = this.mainService.get(url, params.toString(), true); JsonObject tmpJsonElement = GsonParser.parse(responseContent); return WxCpGsonBuilder.create() .fromJson(