企业网盘本地目录同步(DiskSyncController)¶
提供 KMS 知识管理模块「企业网盘 ↔ KMS 本机本地目录」同步能力:配置/查询本地同步绝对路径、手动触发网盘→本地(全量或指定目录)、手动触发本地→网盘、查询同步任务状态。网盘侧文件/目录变更在已配置同步路径时会自动入队网盘→本地(见服务端 Hook,非本控制器端点)。
- 接口类型:REST 资源(
@RestController,类级与所有方法级produces = MediaType.APPLICATION_JSON_VALUE) - 基址:
${myapps.context-path.kms:}/api/kms(类级@RequestMapping仅声明单一前缀,无/kms备用前缀;与 DiskController 一致) - Tag:kms网盘同步
- 源码:
cn.myapps.kms.controller.DiskSyncController - 约束摘要:
- 仅企业网盘(
Disk.type == TYPE_DEPARTMENT/1) - 仅企业知识管理员(角色 Id =
RoleConstant.ID_SUPER=KMSUPERADMINROLEID) - 本地路径为 KMS 服务所在机器 的绝对路径(单机假设;进程内内存任务队列,重启丢失未完成任务)
- 指定目录不存在时抛
InvalidRequestException→ HTTP 400(非 404)
公共说明¶
- 鉴权(据源码
KmsMvcConfig+KmsSecurityFilter):路径/api/kms/disks/*/sync-local-path、/api/kms/disks/*/sync/**均不在豁免名单内,所有端点均需 accessToken。传递方式见 index.md「鉴权说明」。 - 业务权限:除 accessToken 外,本控制器(及
DiskSyncConfigService)强制校验当前用户是否持有企业知识管理员角色;否则抛ForbiddenException(HTTP 403)。 - 执行用户:
getUser()装载KmsUser。无userCode参数。 - 响应结构:统一
Resource(errcode/errmsg/data/errors)。data经ESAPI.encodeXSS 编码。 - HTTP 状态码:成功 200;
InvalidRequestException→ 400;ForbiddenException/UnauthorizedException→ 403;其他未捕获异常 → 500。 - 路径变量:
diskId、taskId为明文主键,非 DES 密文。 - 相关网盘 API:见 disk.md。设计说明见仓库内
docs/superpowers/specs/2026-08-05-kms-disk-sync-design.md(若已同步至文档仓则以本页为准)。
同步语义(调用方须知)¶
| 方向 | 触发方式 | 行为要点 |
|---|---|---|
| 网盘 → 本地 | 文件/目录变更自动入队(含 REST / S3 上传:在 事务提交后 入队);或本控制器手动全量/指定目录 | 冲突:脏本地文件移为冲突副本 {name}.conflict.{yyyyMMddHHmmss}{ext},远端内容写入原名;删除:移入 syncLocalPath/.obpm_trash/ |
| 本地 → 网盘 | **仅**本控制器手动触发 | 比较各级隐藏 .obpm_sync(MD5 快检再细比);本地删除 → 网盘软删 |
| 首次配置路径 | PUT sync-local-path 空→非空 |
自动入队全量网盘→本地 |
同盘同步任务串行;同盘同类型(DISK_TO_LOCAL / LOCAL_TO_DISK)在 PENDING/RUNNING 时去重,返回已有 taskId。
1. 设置本地同步路径¶
为企业网盘设置或清除本机同步目录绝对路径。路径须已存在、为目录且可写。path 为空字符串或空白时清除配置(关闭同步),不入队任务。从空变为非空时自动入队全量 DISK_TO_LOCAL。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/disks/{diskId}/sync-local-path(完整:{kms-context}/api/kms/disks/{diskId}/sync-local-path) - 鉴权:是(accessToken + 企业知识管理员)
- Tag:kms网盘同步
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 企业网盘 Id |
| body | body | object | 是 | SyncPathRequest |
请求体¶
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 否 | 本机绝对路径;空/空白表示清除同步配置 |
请求示例¶
PUT /api/kms/disks/__DISKID__/sync-local-path?accessToken=__TOKEN__ HTTP/1.1
Content-Type: application/json
{ "path": "D:/kms-sync/company" }
响应¶
结构:统一 Resource。
data:null。
常见失败:
| 场景 | HTTP / errcode | 说明 |
|---|---|---|
| 非知识管理员 | 403 | ForbiddenException |
| 非企业网盘 / 网盘不存在 | 400 | InvalidRequestException |
| 路径不存在、非目录或不可写 | 400 | InvalidRequestException |
2. 获取本地同步路径¶
查询指定企业网盘当前配置的本地同步路径。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/disks/{diskId}/sync-local-path(完整:{kms-context}/api/kms/disks/{diskId}/sync-local-path) - 鉴权:是(accessToken + 企业知识管理员)
- Tag:kms网盘同步
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 企业网盘 Id |
请求示例¶
响应¶
结构:统一 Resource。
data:
未配置时 path 为空字符串 ""。
3. 手动触发网盘 → 本地同步¶
将企业网盘内容同步到已配置的本地目录。请求体可省略;folderId 与 relativePath 均未传(或均为空)时为**全量**同步;否则为**指定目录子树**同步(优先使用 folderId;仅 relativePath 时从网盘根按路径分段解析)。
入队前校验:企业盘、已配置 syncLocalPath、指定目录可解析。解析失败抛 InvalidRequestException(400,非 404)。入队后立即返回 taskId(异步执行)。
- 接口类型:REST 资源
- 请求方式:
POST - 请求路径:
/disks/{diskId}/sync/disk-to-local(完整:{kms-context}/api/kms/disks/{diskId}/sync/disk-to-local) - 鉴权:是(accessToken + 企业知识管理员)
- Tag:kms网盘同步
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 企业网盘 Id |
| body | body | object | 否 | DiskToLocalRequest;可省略表示全量 |
请求体¶
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| folderId | string | 否 | 网盘文件夹 Id;与 relativePath 都不传则为全量 |
| relativePath | string | 否 | 相对网盘根的路径(如 docs/a);folderId 优先 |
请求示例(全量)¶
POST /api/kms/disks/__DISKID__/sync/disk-to-local?accessToken=__TOKEN__ HTTP/1.1
Content-Type: application/json
{}
请求示例(指定目录)¶
POST /api/kms/disks/__DISKID__/sync/disk-to-local?accessToken=__TOKEN__ HTTP/1.1
Content-Type: application/json
{ "folderId": "__FOLDERID__" }
或:
响应¶
结构:统一 Resource。
data:
同盘已有未完成的 DISK_TO_LOCAL 任务时,返回已有 taskId(去重)。
常见失败:
| 场景 | HTTP / errcode | 说明 |
|---|---|---|
| 未配置本地同步路径 | 400 | 未配置本地同步路径 |
| 指定目录不存在 / 跨盘 folderId | 400 | 指定目录不存在: ...(非 404) |
| 非企业盘 | 400 | 仅企业网盘支持本地目录同步 |
| 非知识管理员 | 403 |
4. 手动触发本地 → 网盘同步¶
比较本地同步目录与各级 .obpm_sync 清单差异,将新增/变更上传至网盘,将本地已删除项在网盘侧软删。须已配置 syncLocalPath。入队后立即返回 taskId。
- 接口类型:REST 资源
- 请求方式:
POST - 请求路径:
/disks/{diskId}/sync/local-to-disk(完整:{kms-context}/api/kms/disks/{diskId}/sync/local-to-disk) - 鉴权:是(accessToken + 企业知识管理员)
- Tag:kms网盘同步
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 企业网盘 Id |
无请求体。
请求示例¶
响应¶
结构:统一 Resource。
data:
同盘已有未完成的 LOCAL_TO_DISK 任务时,返回已有 taskId。
5. 查询同步任务状态¶
按 taskId 查询任务状态。任务必须属于路径中的 diskId,否则按任务不存在处理(400)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/disks/{diskId}/sync/tasks/{taskId}(完整:{kms-context}/api/kms/disks/{diskId}/sync/tasks/{taskId}) - 鉴权:是(accessToken + 企业知识管理员)
- Tag:kms网盘同步
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 企业网盘 Id |
| taskId | path | string | 是 | 同步任务 Id(入队接口返回) |
请求示例¶
响应¶
结构:统一 Resource。
data:SyncTaskResponse
| 字段 | 类型 | 说明 |
|---|---|---|
| taskId | string | 任务 Id |
| diskId | string | 网盘 Id |
| type | string | DISK_TO_LOCAL | LOCAL_TO_DISK |
| status | string | PENDING | RUNNING | SUCCESS | FAILED |
| message | string | 摘要消息(可空) |
| errors | string[] | 逐项错误列表(可空);有错误时任务多为 FAILED |
| createdAt | string (ISO-8601 Instant) | 创建时间 |
| finishedAt | string (ISO-8601 Instant) | 结束时间(未完成时可空) |
{
"errcode": 0,
"errmsg": "ok",
"data": {
"taskId": "__TASKID__",
"diskId": "__DISKID__",
"type": "DISK_TO_LOCAL",
"status": "SUCCESS",
"message": null,
"errors": [],
"createdAt": "2026-08-05T11:00:00Z",
"finishedAt": "2026-08-05T11:00:05Z"
},
"errors": null
}
失败示例(任务不存在或不属于该盘):
数据模型补充¶
企业网盘实体 Disk 新增字段(JPA 列 SYNC_LOCAL_PATH,VARCHAR(512),可空):
| 字段 | JSON | 说明 |
|---|---|---|
| syncLocalPath | syncLocalPath | 本机同步目录绝对路径;未配置为 null |
生产库可辅以手工脚本:obpm-kms/src/main/resources/sql/alter_kms_disk_sync_local_path_mysql.sql。