8.1 KiB
个人数据导出 API(V30)
本文档描述「个人数据导出」模块。这与简历导出(/resume-export-tasks)是两套完全独立的机制,请勿混淆:
- 简历导出:面向单个简历文件/快照的导出,走既有
/resume-export-tasks接口,语义保持不变。 - 个人数据导出:把当前登录用户的全量业务数据打包成一个异步 ZIP 文件下载,走下面的新接口。
只实现当前登录用户「本人」数据的导出;任务创建是异步的:先返回一个 PENDING 任务,后台 Worker 收集并打包,完成后才能下载。
一、接口总览
| 操作 | 路径 | 说明 |
|---|---|---|
| POST | /profile/me/data-export-tasks |
创建导出任务(异步 ZIP) |
| GET | /profile/me/data-export-tasks |
查询本人任务列表(分页) |
| GET | /profile/me/data-export-tasks/{taskId} |
查询本人某个任务详情 |
| GET | /profile/me/data-export-tasks/{taskId}/download |
下载已完成 ZIP |
新增 3 个 path、4 个 operation。OpenAPI 路径总数 110 → 113(详情接口已覆盖状态查询,未单独新增 /status)。
身份与权限
- 所有接口都需要登录(JWT);身份只从 JWT/SecurityContext 获取,不接受
userId/candidateId参数。 STUDENT、COMPANY、ADMIN均可导出自己的任务。- 只能查询/下载自己的任务;访问他人任务返回
403/2002,任务不存在返回404/9401。
二、创建任务
POST /profile/me/data-export-tasks
请求体(均可选):
{ "format": "ZIP", "idempotencyKey": "optional-client-key" }
约束:
format当前仅允许ZIP(非法值返回400/1001)。idempotencyKey可选,最大 64 字符;用于创建幂等重放。- 同一用户存在未完成任务(
PENDING/PROCESSING)时:- 相同
idempotencyKey重放 → 返回原任务; - 不同 key → 返回
409/9402。
- 相同
- 已完成且未过期的旧任务 → 直接返回该任务;若旧任务已过期则可创建新任务。
- 账号注销
PENDING/COMPLETED时禁止创建(见第八节)。
成功响应:
{
"code": 200,
"message": "ok",
"data": {
"taskId": 1,
"status": "PENDING",
"format": "ZIP",
"requestedAt": "2026-08-25T10:00:00",
"startedAt": null,
"completedAt": null,
"expiresAt": null,
"sizeBytes": null,
"downloadAvailable": false
}
}
响应绝不包含
storageKey、服务器绝对路径、内部异常堆栈等字段。
三、查询任务列表 / 详情
GET /profile/me/data-export-tasks?page=0&size=20&status=
page默认 0,不得小于 0。size默认 20,范围 1–100(越界返回400/1001)。status可选:PENDING/PROCESSING/COMPLETED/FAILED/EXPIRED/CANCELLED。- 按
createdAt倒序,返回标准分页结构。
GET /profile/me/data-export-tasks/{taskId}
- 任务不存在 →
404/9401。 - 任务属于他人 →
403/2002。 - 响应不返回
storageKey、绝对路径、内部字段。
四、下载
GET /profile/me/data-export-tasks/{taskId}/download
- 仅任务本人可下载。
- 仅
COMPLETED且未过期可下载。 PENDING/PROCESSING→409/9403(文件尚未准备好了)。FAILED→409/9405。EXPIRED/CANCELLED→409/9404。- 文件不存在 →
409/9406(不会返回 500)。 - 返回
Content-Disposition: attachment,Content-Type: application/octet-stream(内容为 ZIP)。 - 下载凭证不可脱离 JWT;不返回任何公开 URL。
- 下载成功会记录
downloadedAt并写审计事件DATA_EXPORT_DOWNLOADED(留有接口;服务记录 downloadedAt)。
五、任务状态机
PENDING ─→ PROCESSING ─→ COMPLETED
PENDING ─→ PROCESSING ─→ FAILED
PENDING ─→ FAILED
PROCESSING ─→ FAILED
COMPLETED ─→ EXPIRED
COMPLETED/CANCELLED(账号注销清理)
- 创建后默认
PENDING;后台 Worker 用@Version乐观锁抢占(只有一个 Worker 能把PENDING→PROCESSING,并发后到者跳过)。 - 完成后写入
completedAt、expiresAt、sizeBytes、checksumSha256。 - 默认文件有效期 24 小时,过期由定时任务把
COMPLETED→EXPIRED并删除本地导出文件;不删除任何业务数据库数据。 - 失败仅记录安全的
errorCode/errorMessage,不记录密码、Token、手机号等敏感内容。
六、导出数据范围
ZIP 内部结构(personal-data/ 根目录):
personal-data/
manifest.json # schemaVersion/format/requestedAt/fileCount/sections
profile.json # 基本资料 + 学生资料
preferences.json # 求职偏好
resumes/<文件> # 用户自己上传的简历文件 + resumes.json 元数据
applications.json # 投递记录
application-timelines.json
interviews.json # 本人参与/发起的面试
interview-timelines.json
offers.json # 本人收到或创建(COMPANY)的 Offer
offer-timelines.json
feedback.json # 本人候选人反馈
favorites.json # 本人岗位收藏
notifications.json # 本人通知
conversations.json # 本人会话
messages.json # 本人会话消息
candidate-scoring.json # 本人评分快照/趋势
scoring-appeals.json # 本人评分申诉及历史
以上为当前实现实际包含的 section(
manifest.json的sections字段会列出全部 section 名称);resumes/目录下同时附带用户自己上传的简历文件二进制。
允许导出(本人)
- 基本资料:
userId / nickname / avatarUrl / email(如业务允许)/ 账号创建时间等;不含 passwordHash。 - 学生资料与求职偏好。
- 简历版本及用户自己上传的简历文件。
COMPANY用户自己创建的企业/岗位资料。- 自己的投递记录与状态时间线、自己参与的面试、自己收到/创建的 Offer、自己的候选人反馈、岗位收藏、通知、会话与消息、评分快照/趋势/申诉及历史。
脱敏与禁止导出
- 禁止:
passwordHash、JWT、短信验证码、JWT_SECRET、deletedPhoneHash、数据库密码、管理员内部审核备注、内部风控规则、系统异常堆栈、服务器绝对路径、RabbitMQ/Redis/MySQL 连接信息。 - 不得导出其他用户的手机号、邮箱、密码、简历地址。
- 会话消息:只导出当前用户参与的消息;对方仅保留
participantId(脱敏显示名),不导出对方完整资料。
七、错误码
| 错误码 | 含义 | HTTP |
|---|---|---|
| 1001 | 参数错误(非法 format、page/size 越界) | 400 |
| 2001 | 未认证 | 401 |
| 2002 | 无权限(访问他人任务) | 403 |
| 9401 | 任务不存在 | 404 |
| 9402 | 存在未完成任务 | 409 |
| 9403 | 文件尚未生成 | 409 |
| 9404 | 导出文件已过期 | 409 |
| 9405 | 导出失败 | 409 |
| 9406 | 导出文件不存在 | 409 |
| 9302 | 注销进行中禁止操作 | 409 |
| 9303 | 账号已注销 | 409 |
错误响应统一格式(ApiResponse):{ "code": <码>, "message": "...", "requestId": "..." }。
八、账号注销兼容
- 注销 PENDING 用户:不允许创建新导出任务;已创建但未执行的任务会被 Worker 阻止并标记
FAILED(不再生成含个人信息的新文件)。 - 注销 COMPLETED 用户:所有导出接口返回
409/9303(创建/查询/详情/下载均被拦截),不能看到或下载新任务。 - 注销完成清理:账号注销完成(脱敏)流程会删除该用户的导出文件,将未完成任务标记为
CANCELLED或EXPIRED,写入审计事件;不删除任何原业务数据库数据。
九、审计
复用 AuditService,新增 action:
DATA_EXPORT_REQUESTED/DATA_EXPORT_PROCESSING/DATA_EXPORT_COMPLETEDDATA_EXPORT_DOWNLOADED/DATA_EXPORT_FAILED/DATA_EXPORT_EXPIRED
details 仅记录:taskId / userId / format / status / sizeBytes 等;禁止写入文件内容、storageKey、手机号、邮箱、密码、Token、绝对路径。