DingdingAuthtimeController(钉钉集成管理)¶
管理企业域与钉钉(DingTalk)集成的全流程:钉钉企业 corpId / AppKey / AppSecret / AgentId / 服务器回调地址 / 扫码登录应用配置的查询与保存;外网访问地址可达性验证;企业域组织架构与钉钉组织架构的双向同步;按软件生成钉钉免登跳转链接;按软件单独保存钉钉应用 AgentId / AppSecret / AppKey。
- 类级基址:
${myapps.context-path.manager:}/api/authtime(完整路径:{manager-context}/api/authtime<相对路径>) - Tag:钉钉集成模块(控制器源码未声明类级
@Tag,本文档按所属业务域命名) - 控制器源码:
obpm-manager/src/main/java/cn/myapps/manager/authtime/controller/dingding/DingdingAuthtimeController.java - 公共说明:
- 类继承
BaseAuthTimeController,通过其success(errmsg, data)/error(errcode, errmsg, errors)返回统一Resource(字段errcode/errmsg/data/errors,结构见 ../index.md「统一响应结构」)。 - 多数端点在
try/catch内捕获Exception并e.printStackTrace()后返回errcode=500、errmsg=e.getMessage()、data=null(HTTP 状态码 200);外网验证失败常用errcode=1。 synch2Dingding/synchFromDingding未捕获异常,方法签名throws Exception,异常向上抛由 Spring 默认异常处理(HTTP 500,无统一Resource体)。- 鉴权说明见 index.md「鉴权说明」(adminToken JWT)。
- 路径变量:
domainid为企业域 id;applicationid为软件 id;appkey/appsecret为钉钉应用的 Key/Secret。
1. 钉钉配置¶
按企业域 id 查询钉钉集成配置:企业 corpId、应用 AppKey/AppSecret/AgentId、服务器外网地址、扫码登录 AppId/AppSecret/回调地址;同时返回企业域已绑定软件列表(含每个软件的钉钉应用 AgentId/AppSecret/AppKey)。dingdingProxyType 为空时返回 "none"。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/domain/{domainid}/dingding(完整:{manager-context}/api/authtime/domain/{domainid}/dingding) - 鉴权:是(需管理员 adminToken,详见 index.md「鉴权说明」)
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
请求示例¶
响应¶
结构:统一 Resource(见 ../index.md「统一响应结构」)。
data:JSONObject,字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| dingdingProxyType | string | 钉钉代理类型(域对象为空时返回 none) |
| dingdingCorpID | string | 钉钉企业 corpId |
| dingdingAppSecret | string | 钉钉企业默认 AppSecret |
| dingdingAppKey | string | 钉钉企业默认 AppKey |
| dingdingAgentId | string | 钉钉企业默认 AgentId |
| dingdingServerHost | string | 服务器外网访问地址 |
| dingdingQrCodeAppId | string | 扫码登录 AppId |
| dingdingQrCodeAppSecret | string | 扫码登录 AppSecret |
| dingdingQrCodeCallbackUrl | string | 扫码登录回调地址 |
| apps | array\<JSONObject> | 企业域已绑定软件的钉钉应用配置列表 |
apps 元素字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 软件 id |
| name | string | 软件名称 |
| description | string | 软件描述 |
| dingdingAgentId | string | 该软件的钉钉应用 AgentId |
| dingdingAppSecret | string | 该软件的钉钉应用 AppSecret |
| dingdingAppKey | string | 该软件的钉钉应用 AppKey |
成功示例:
{
"errcode": 0,
"errmsg": "ok",
"data": {
"dingdingProxyType": "dingding",
"dingdingCorpID": "dingxxxxxxxx",
"dingdingAppSecret": "secret-xxx",
"dingdingAppKey": "appkey-xxx",
"dingdingAgentId": "123456789",
"dingdingServerHost": "https://example.com",
"dingdingQrCodeAppId": "",
"dingdingQrCodeAppSecret": "",
"dingdingQrCodeCallbackUrl": "",
"apps": [
{ "id": "__APP01", "name": "协同办公", "description": "", "dingdingAgentId": "1000001", "dingdingAppSecret": "secret-xxx", "dingdingAppKey": "appkey-xxx" }
]
},
"errors": null
}
2. 保存钉钉配置¶
按企业域 id 保存钉钉集成配置(覆盖企业 corpId、应用 AppKey/AppSecret/AgentId、服务器外网地址、扫码登录 AppId/AppSecret/回调地址中**非空且与现状不同**的字段)。任一字段变更即触发 needUpdate=true,调用 doCreateOrUpdate 持久化并清理钉钉 secret 缓存。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/dingding(完整:{manager-context}/api/authtime/domain/{domainid}/dingding) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| jsonObject | body | JSON | 是 | 配置包体(字段见下) |
请求体¶
JSON 对象(application/json):
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| dingdingProxyType | string | 否 | 钉钉代理类型,非空且与现状不同才更新 |
| dingdingCorpID | string | 否 | 钉钉企业 corpId,非空且与现状不同才更新 |
| dingdingAgentId | string | 否 | 钉钉企业默认 AgentId,非空且与现状不同才更新 |
| dingdingAppSecret | string | 否 | 钉钉企业默认 AppSecret,非空且与现状不同才更新 |
| dingdingAppKey | string | 否 | 钉钉企业默认 AppKey,非空且与现状不同才更新 |
| dingdingServerHost | string | 否 | 服务器外网访问地址,非空且与现状不同才更新 |
| dingdingQrCodeAppId | string | 否 | 扫码登录 AppId,非空且与现状不同才更新 |
| dingdingQrCodeAppSecret | string | 否 | 扫码登录 AppSecret,非空且与现状不同才更新 |
| dingdingQrCodeCallbackUrl | string | 否 | 扫码登录回调地址,非空且与现状不同才更新 |
注:源码先
doUpdate(domain)写库,再判断needUpdate决定是否doCreateOrUpdate并清缓存;空值字段不覆盖现有配置。
请求示例¶
PUT /api/authtime/domain/__P1UD2yVWpnFpUedONr/dingding HTTP/1.1
Content-Type: application/json
{
"dingdingProxyType": "dingding",
"dingdingCorpID": "dingxxxxxxxx",
"dingdingAppKey": "appkey-xxx",
"dingdingAppSecret": "secret-xxx",
"dingdingAgentId": "123456789",
"dingdingServerHost": "https://example.com"
}
响应¶
结构:统一 Resource。
data:字符串 "保存成功"。
成功示例:
失败示例:3. 钉钉外网访问地址验证¶
用钉钉应用 AppKey / AppSecret 调用 DingdingService.getAccessToken 校验钉钉开放平台可达性与应用凭据有效性。getAccessToken 返回非空视为成功,返回 null 视为验证失败(errcode=1)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/domain/{domainid}/dingding/appkey/{appkey}/appsecret/{appsecret}(完整:{manager-context}/api/authtime/domain/{domainid}/dingding/appkey/{appkey}/appsecret/{appsecret}) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id(路径变量,方法签名持有但实际逻辑未直接使用) |
| appkey | path | string | 是 | 钉钉应用 AppKey |
| appsecret | path | string | 是 | 钉钉应用 AppSecret |
注:将 AppSecret 放在 URL 路径中存在泄露风险,建议生产环境配合 HTTPS / 网关日志脱敏使用。
请求示例¶
GET /api/authtime/domain/__P1UD2yVWpnFpUedONr/dingding/appkey/appkey-xxx/appsecret/secret-xxx HTTP/1.1
响应¶
结构:统一 Resource。
data:字符串 "验证成功"。
| 条件 | errcode | errmsg | data |
|---|---|---|---|
getAccessToken 返回 null |
1 | 验证失败 |
null |
| 验证成功 | 0 | ok | 验证成功 |
| 抛异常 | 500 | <异常信息> |
null |
成功示例:
失败示例:4. 同步企业域组织架构到钉钉¶
按企业域 id 取出域对象,调用 DingdingService.synch2Dingding 将企业域下的部门 / 用户推送到钉钉,返回同步结果。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/synch2dingding(完整:{manager-context}/api/authtime/domain/{domainid}/synch2dingding) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
请求示例¶
响应¶
结构:统一 Resource。
data:net.sf.json.JSONObject(由 DingdingService.synch2Dingding 返回,结构由同步逻辑决定,通常含成功 / 失败计数)。
注:本端点方法签名
throws Exception,未捕获异常,失败时由 Spring 默认异常处理(HTTP 500,无统一Resource体)。
成功示例:
失败示例:5. 同步钉钉组织架构到企业域¶
按企业域 id 取出域对象,调用 DingdingService.synchFromDingding 将钉钉通讯录拉取到企业域(部门 / 用户)。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/synchfromdingding(完整:{manager-context}/api/authtime/domain/{domainid}/synchfromdingding) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
请求示例¶
响应¶
结构:统一 Resource。
data:net.sf.json.JSONObject(由 DingdingService.synchFromDingding 返回)。
注:方法名
synchFromDingding,方法签名throws Exception,未捕获异常,失败时由 Spring 默认异常处理(HTTP 500,无统一Resource体)。
成功示例:
失败示例:6. 生成跳转链接¶
按企业域 + 软件生成钉钉免登跳转链接:拼接服务器外网地址 + dingding.html + domainid + corpid + appid(appid 即软件 id)。软件不存在时返回 errcode=1(查不对应的软件,源码原样拼写)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/domain/{domainid}/application/{applicationid}/getdingdingurl(完整:{manager-context}/api/authtime/domain/{domainid}/application/{applicationid}/getdingdingurl) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| applicationid | path | string | 是 | 软件 id |
请求示例¶
响应¶
结构:统一 Resource。
data:Map<String, String>,键固定为 "进入系统",值为拼好的跳转 URL。
| 条件 | errcode | errmsg | data |
|---|---|---|---|
| 软件不存在 | 1 | 查不对应的软件 |
null |
| 成功 | 0 | ok | { "进入系统": "<跳转 URL>" } |
| 抛异常 | 500 | <异常信息> |
null |
注:源码额外把
uris写入request属性(疑似为视图渲染保留),但作为@RestController端点,最终响应体即上述Resource。
成功示例:
{
"errcode": 0,
"errmsg": "ok",
"data": { "进入系统": "https://example.com/dingding.html?domainid=__P1UD2yVWpnFpUedONr&corpid=dingxxxxxxxx&appid=__APP01" },
"errors": null
}
7. 保存钉钉应用 AgentId¶
按企业域 + 软件保存该软件的钉钉应用 AgentId(写入 DomainVO 中按软件 id 维度的 AgentId 映射),并持久化(doCreateOrUpdate)。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/application/{applicationid}/updatedingdingagentid(完整:{manager-context}/api/authtime/domain/{domainid}/application/{applicationid}/updatedingdingagentid) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| applicationid | path | string | 是 | 软件 id |
| id | query | string | 是 | 钉钉应用 AgentId |
请求示例¶
PUT /api/authtime/domain/__P1UD2yVWpnFpUedONr/application/__APP01/updatedingdingagentid?id=1000001 HTTP/1.1
响应¶
结构:统一 Resource。
data:字符串 "保存成功"。
成功示例:
失败示例:8. 保存钉钉应用 AppSecret¶
按企业域 + 软件保存该软件的钉钉应用 AppSecret(写入 DomainVO 中按软件 id 维度的 AppSecret 映射),并持久化。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/application/{applicationid}/updatedingdingappsecret(完整:{manager-context}/api/authtime/domain/{domainid}/application/{applicationid}/updatedingdingappsecret) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| applicationid | path | string | 是 | 软件 id |
| appsecret | query | string | 是 | 钉钉应用 AppSecret |
请求示例¶
PUT /api/authtime/domain/__P1UD2yVWpnFpUedONr/application/__APP01/updatedingdingappsecret?appsecret=secret-xxx HTTP/1.1
响应¶
结构:统一 Resource。
data:字符串 "保存成功"。
成功示例:
失败示例:9. 保存钉钉应用 AppKey¶
按企业域 + 软件保存该软件的钉钉应用 AppKey(写入 DomainVO 中按软件 id 维度的 AppKey 映射),并持久化。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/domain/{domainid}/application/{applicationid}/updatedingdingappkey(完整:{manager-context}/api/authtime/domain/{domainid}/application/{applicationid}/updatedingdingappkey) - 鉴权:是
- Tag:钉钉集成模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainid | path | string | 是 | 企业域 id |
| applicationid | path | string | 是 | 软件 id |
| appkey | query | string | 是 | 钉钉应用 AppKey |
请求示例¶
PUT /api/authtime/domain/__P1UD2yVWpnFpUedONr/application/__APP01/updatedingdingappkey?appkey=appkey-xxx HTTP/1.1
响应¶
结构:统一 Resource。
data:字符串 "保存成功"。
成功示例:
失败示例: