You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

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_COMPLETED
  • DATA_EXPORT_DOWNLOADED / DATA_EXPORT_FAILED / DATA_EXPORT_EXPIRED

details 仅记录:taskId / userId / format / status / sizeBytes 等;禁止写入文件内容、storageKey、手机号、邮箱、密码、Token、绝对路径。