# dt-java SDK 部门与用户拉取 API 调研 Label: wayfinder:research Type: research Status: resolved Blocked by: (无) ## Question 调研第三方库 `com.github.tingyugetc520:dt-java:0.1.2`(钉钉 OpenAPI 的 Java SDK,钉钉官方 dingtalk-java 的社区分支)的用法,产出票据 03 实现所需的 API 结论: 1. 如何用 Client ID/Client Secret(企业内部应用凭证)初始化 client 并获取企业级 access token 2. 拉取部门树列表的 API(部门 ID/名称/父部门/负责人 dept_manager_userid 字段) 3. 按部门拉取用户详情列表的 API(姓名/手机号/unionId/userid 字段),分页方式 4. 与现有 `DingTalkAuthClient` 手写 HTTP + Hutool 方式的关系:是否直接用 SDK 替换手写调用,还是仅在同步端点内使用 SDK(倾向后者,不动已验证的登录链路) 5. Maven 仓库可用性(中央仓库是否有 0.1.2 版本)与传递依赖冲突风险 产出:一页结论(含关键类名、调用示例、API 端点对照),供票据 03 直接照抄实现。 ## Answer 调研完成(源码已克隆到 `tmp/DtJava/` 可直接查阅)。结论如下: ### 1. 可用性与形态 - Maven Central 确认存在 `com.github.tingyugetc520:dt-java:0.1.2`(2021-03-08 发布)。封装的是**旧版 oapi.dingtalk.com** 接口(非新版 api.dingtalk.com),5 年未更新但旧版接口仍在服务。 ### 2. 初始化(凭证) ```java DtDefaultConfigImpl config = new DtDefaultConfigImpl(); config.setCorpId("xxx"); // ⚠️ yml 目前没有,需新增配置 config.setAgentId(123L); // ⚠️ yml 目前没有,需新增配置 config.setAppKey(clientId); // = 现有 crm.auth.dingtalk.client-id config.setAppSecret(clientSecret); // = 现有 client-secret DtServiceImpl dtService = new DtServiceImpl(); dtService.setDtConfigStorage(config); // SDK 自管企业 token(旧版 gettoken 接口,内部自动刷新) ``` 包名根:`com.github.tingyugetc520.ali.dingtalk.*`(注意不是 com.github.....dtjava)。 ### 3. 部门树:`DtDepartmentService` ```java List depts = dtService.getDepartmentService().list(null, true); // 递归全量 ``` `DtDepart` 字段仅 `id / name / parentId / order`——**没有 dept_manager_userid**。 ### 4. 部门负责人:从用户侧反查(关键修正) 部门负责人不在 DtDepart,而在 `DtUser.isLeaderInDeparts: Map`(获取部门用户详情接口返回)。同步逻辑应为:拉用户时聚合 `isLeaderInDeparts`,反写对应部门的负责人字段。 ### 5. 用户:`DtUserService` ```java // 部门用户详情(offset/size 分页,循环拉到不足一页为止) List users = dtService.getUserService().listByDepartment(deptId, offset, size, null); // 单个详情 DtUser u = dtService.getUserService().getById(userId); ``` `DtUser` 关键字段:`userId / unionId / name / mobile / position / jobNumber / email / avatar / departIds(多部门) / active / isAdmin / isLeaderInDeparts / hiredDate`——同步到 `auth_user`(account=userId,username=name,mobile,部门挂载 departIds,在职状态可看 active)完全够用。 ### 6. 与现有 DingTalkAuthClient 的关系 SDK 用旧版 oapi + 自管 token;现有登录链路用新版 api.dingtalk.com + 手写 HTTP。两套并存无冲突,**同步端点单独用 SDK,不动已验证的登录链路**(维持倾向结论)。 ### 7. 传递依赖风险(需在票据 03 处理) pom 传递依赖较旧:okhttp 4.5.0、httpclient、guava 29.0-jre、gson 2.8.0、**xstream 1.4.15(有已知 CVE,仅事件回调 XML 反序列化用到,同步链路不触碰)**、commons-io 2.5、commons-lang3 3.10。与 Spring Boot 3 BOM 管理的版本存在降级竞争(Maven 最近优先,Boot BOM 在父 POM 通常胜出)。建议:引入时对 xstream、guava、gson 做 exclusions 或显式锁定 Boot 版本,验证 `mvn dependency:tree` 无降级后再用。 ### 给票据 03 的落地清单 1. yml `crm.auth.dingtalk` 新增 `corp-id`、`agent-id` 两项(用户提供值) 2. crm-auth pom 引 dt-java(带 exclusions) 3. 同步:`list(null,true)` 拉部门树 → sys_dept(parentId 挂树);逐部门 `listByDepartment` 分页拉用户 → auth_user;聚合 `isLeaderInDeparts` 反写部门负责人 4. 部门循环注意钉钉限流(建议每请求间隔 ~100ms,或并发 2~3 线程 + 限流)