dingtalk-drive-upload.md 5.6 KB

入职资料 Base64 上传接口

POST http://服务器:8104/api/tianpai/dingtalk/drive/onboarding/upload

请求头:Content-Type: application/json。

{
  "fileName": "张三-入职资料.pdf",
  "base64": "文件内容的Base64字符串"
}

fileName 和 base64 必填。base64 也可写成 fileBase64,支持纯 Base64、包含换行的 Base64,以及 data:application/pdf;base64,...。默认解码后最多 20 MiB;不接收空文件。

调用方只需传文件名和 Base64,不需要传 userId、unionId、空间ID或文件夹ID。后台默认使用钉钉员工 UserID 32600011,先查询用户详情取得 unionId,再以该用户身份操作钉盘。请求中额外传入身份字段也不会覆盖后台用户。

不再查询主管理员列表。后台分页查询该用户可见的团队空间(spaceType=org),再分页检查各空间根目录下名称完全等于“入职资料”的文件夹。找到唯一目录后,使用实际返回的空间和文件夹ID上传。未找到、多空间重名、权限不足或分页未完成时返回失败,不会任意选择第一项,也不会把个人文件空间当成团队文件。

首次部署配置

复用项目现有 AccessTokenService.getAccessToken() 的应用凭据,无需再添加 AppKey/AppSecret。

默认无需新增配置。以下配置只用于服务端指定上传用户、消除重名目录歧义或调整文件大小:

环境变量 说明
DINGTALK_DRIVE_SPACE_ID 可选,指定团队空间;留空时自动查找所有可见团队空间
DINGTALK_DRIVE_ONBOARDING_FOLDER_ID 可选,已有“入职资料”文件夹的 storage API dentry.id;指定时必须同时指定空间ID
DINGTALK_DRIVE_OPERATOR_USER_ID 默认32600011;配置为空时也回退为32600011
DINGTALK_DRIVE_MAX_FILE_BYTES 可选,默认20971520,最大104857600

也可设置同名含义的 Spring 配置 dingtalk.drive.space-id、onboarding-folder-id、operator-user-id、max-file-bytes。环境变量修改后需重启服务。指定目录时不能使用知识库 workspaceId,也不要将整个团队空间根目录误填为入职资料。

AppKey/AppSecret 用于获取应用凭据,后台通过用户详情接口解析32600011的 unionId。空间及文件夹ID来自真实查询结果,不把“团队文件”“入职资料”两个名称直接当成ID。

应用需要开通团队空间查询、文件查询、目录创建、获取上传信息、提交文件及用户详情查询(/topapi/v2/user/get)权限。用户32600011需要在通讯录授权范围内,并对目标目录有读写权限。

2026-10-19只读联调已确认:32600011可解析为钉钉用户,团队空间列表查询成功;查询空间根目录时被钉钉拒绝,错误码为 Forbidden.AccessDenied.AccessTokenPermissionDenied,明确缺少 Drive.File.Read。请在开放平台开通该应用的文件读取权限。该权限未开通前无法确认真实“入职资料”文件夹ID,也无法完成上传联调。

行为及响应

北京时间 2026-10-19 的文件保存至 团队文件/入职资料/2026/10/19/张三-入职资料.pdf。年、月、日三层目录逐层查询,不存在就创建。已有入职资料目录默认自动查找,本接口不会新建团队空间或入职资料根目录。

成功响应示意(ID均以真实返回为准):

{
  "success": true,
  "code": 200,
  "message": "上传成功",
  "data": {
    "spaceId": "实际空间ID",
    "fileId": "实际文件ID",
    "fileName": "张三-入职资料.pdf",
    "size": 12345,
    "parentId": "当天目录ID",
    "path": "团队文件/入职资料/2026/10/19/张三-入职资料.pdf"
  }
}

成功前会回读文件,验证ID、名称、空间、父目录及大小。当前日期目录已有同名文件时返回失败,请更换文件名;不同日期可使用相同文件名。不设置 overwriteDentryId,不主动覆盖已有文件。

接口沿用项目 R 响应,业务失败通过 success:false 及 message 表达。提交超时或提交后核验失败会返回 data.outcome:"unknown" 以及可获得的空间/父目录/文件ID;此时可能已经写入,先检查目录,不能盲目重试。

团队空间最多查询100个,每个目录分页有100页、5000项上限,未读完整或出现同名歧义时停止写入。本服务实例内目录创建串行化;多实例同时首次创建时会重新查询,但不保证分布式互斥。调用方需避免并发上传同日同名文件。本接口不提供幂等请求键;客户端/网关超时后也应先检查文件再决定重试。

大文件采用 JSON Base64,网关请求体限制建议至少为原文件大小的4/3再留余量。接口继承项目现有访问控制;部署时应让网关只向授权调用方开放。

PowerShell 调用

$uploadBody = @{
    fileName = '张三-入职资料.pdf'
    base64 = [Convert]::ToBase64String([IO.File]::ReadAllBytes('D:\资料\张三-入职资料.pdf'))
} | ConvertTo-Json
Invoke-RestMethod -Method Post `
    -Uri 'http://localhost:8104/api/tianpai/dingtalk/drive/onboarding/upload' `
    -ContentType 'application/json; charset=utf-8' `
    -Body ([Text.Encoding]::UTF8.GetBytes($uploadBody))

上传逻辑使用隔离单元测试;只读联调仅查询了用户及空间信息。未启动带真实同步任务的 Spring 应用,未向真实钉盘上传测试文件,未创建真实目录。真实上传验证仍需先开通钉钉返回的缺失权限。