Просмотр исходного кода

fix(dingtalk-contacts): 补 OAPI_BASE 常量 + 2 处直接 .get() NPE 高危补 assertSuccess

DDConf 新增 OAPI_BASE / API_BASE 公共常量,替代 DDImplClient_Contacts 内 v2 系列私有 OAPI 常量定义。

listSubDepartmentId / listDepartmentUserId 此前 (Map) DDR.doPost(...).getResult() 直接 .get("xxx_list"),errcode != 0 时 result 为 null 触发 NPE。补 DDR.assertSuccess() 调用,先抛带 errcode + errmsg 的业务异常。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
malk 1 неделя назад
Родитель
Сommit
2a1bf55d3e

+ 10 - 0
mjava/src/main/java/com/malk/server/dingtalk/DDConf.java

@@ -40,6 +40,16 @@ public class DDConf {
      */
      */
     public static final long TOP_DEPARTMENT = 1L;
     public static final long TOP_DEPARTMENT = 1L;
 
 
+    /**
+     * 钉钉开放平台 OAPI 基础地址(v1/v2 老接口共用)
+     */
+    public static final String OAPI_BASE = "https://oapi.dingtalk.com";
+
+    /**
+     * 钉钉开放平台新版 API 基础地址(v1.0 新接口)
+     */
+    public static final String API_BASE = "https://api.dingtalk.com";
+
     /**
     /**
      * 知识库权限设置成员上限: 30
      * 知识库权限设置成员上限: 30
      */
      */

+ 9 - 3
mjava/src/main/java/com/malk/service/dingtalk/impl/DDImplClient_Contacts.java

@@ -35,7 +35,10 @@ public class DDImplClient_Contacts implements DDClient_Contacts {
         Map body = UtilMap.map("dept_id", dept_id);
         Map body = UtilMap.map("dept_id", dept_id);
         // ppExt:: 格屋临时添加, 后续上线限流重试功能
         // ppExt:: 格屋临时添加, 后续上线限流重试功能
 //        Thread.sleep(50);
 //        Thread.sleep(50);
-        Map rsp = (Map) DDR.doPost("https://oapi.dingtalk.com/topapi/v2/department/listsubid", null, param, body).getResult();
+        DDR r = DDR.doPost("https://oapi.dingtalk.com/topapi/v2/department/listsubid", null, param, body);
+        // fixme: 失败时 result 为 null, 直接 .get("dept_id_list") 会 NPE; 先 assertSuccess 抛带 errcode 的业务异常
+        r.assertSuccess();
+        Map rsp = (Map) r.getResult();
         List<Number> list = (List<Number>) rsp.get("dept_id_list");
         List<Number> list = (List<Number>) rsp.get("dept_id_list");
         // ppExt: 不要直接使用 Number 作为类型, 不同基本类型比较值时会有偏差 [可以作为父类接受数据, 避免直接强制类型转换错误, 再进行基本类型处理]
         // ppExt: 不要直接使用 Number 作为类型, 不同基本类型比较值时会有偏差 [可以作为父类接受数据, 避免直接强制类型转换错误, 再进行基本类型处理]
         return list.stream().map(item -> item.longValue()).collect(Collectors.toList());
         return list.stream().map(item -> item.longValue()).collect(Collectors.toList());
@@ -101,7 +104,10 @@ public class DDImplClient_Contacts implements DDClient_Contacts {
     public List<String> listDepartmentUserId(String access_token, long dept_id) {
     public List<String> listDepartmentUserId(String access_token, long dept_id) {
         Map param = UtilMap.map("access_token", access_token);
         Map param = UtilMap.map("access_token", access_token);
         Map body = UtilMap.map("dept_id", dept_id);
         Map body = UtilMap.map("dept_id", dept_id);
-        Map rsp = (Map) DDR.doPost("https://oapi.dingtalk.com/topapi/user/listid", null, param, body).getResult();
+        DDR r = DDR.doPost("https://oapi.dingtalk.com/topapi/user/listid", null, param, body);
+        // fixme: 失败时 result 为 null, 直接 .get("userid_list") 会 NPE; 先 assertSuccess 抛带 errcode 的业务异常
+        r.assertSuccess();
+        Map rsp = (Map) r.getResult();
         return (List<String>) rsp.get("userid_list");
         return (List<String>) rsp.get("userid_list");
     }
     }
 
 
@@ -299,7 +305,7 @@ public class DDImplClient_Contacts implements DDClient_Contacts {
     //  统一模板:param = {access_token}; body 按 §3.4.2 必填显式 + body_ext 透传
     //  统一模板:param = {access_token}; body 按 §3.4.2 必填显式 + body_ext 透传
     // ================================================================================
     // ================================================================================
 
 
-    private static final String OAPI = "https://oapi.dingtalk.com";
+    private static final String OAPI = DDConf.OAPI_BASE;
 
 
     /** 统一构造含 access_token 的 param map */
     /** 统一构造含 access_token 的 param map */
     private Map qs(String access_token) {
     private Map qs(String access_token) {