文件夹(FolderController)¶
提供 KMS 知识管理模块「文件夹/目录域」的核心能力:目录树查询、目录创建/置顶/取消置顶/重命名/移动/删除、按 folderId 查询路径与路径文件夹集合、获取父级目录、解析或创建企业网盘相对路径目录、创建归档目录。本控制器共 12 个端点。所有端点均返回 JSON 资源。
企业网盘相对路径解析(
resolve-or-create)供 Runtime 表单附件filePattern=02经 Feign(KmsApi)先解析/建目录再调file-upload.md上传。设计说明见仓库docs/superpowers/specs/2026-08-06-upload-field-store-place-design.md。
- 接口类型:REST 资源(
@RestController,类级与所有方法级produces = MediaType.APPLICATION_JSON_VALUE) - 基址:
${myapps.context-path.kms:}/api/kms(类级@RequestMapping仅声明单一前缀,无/kms备用前缀;与 TeamController 一致,与 FileController/CategoryController 不同) - Tag:kms文件夹模块
- 源码:
cn.myapps.kms.controller.FolderController;企业盘路径解析服务EnterpriseFolderResolveService
公共说明¶
- 鉴权(据源码
KmsMvcConfig+KmsSecurityFilter):KmsMvcConfig注册全局 Servlet 过滤器KmsSecurityFilter(URL 模式/*,context-path 为/时为/kms/*)。本控制器路径/api/kms/disks/**、/api/kms/archive/folder均不在KmsSecurityFilter.isExcludeURI的豁免名单内(豁免仅覆盖/login.*、/admin、/domain.*、/tray/service、/authtime、service/OfficeServer、.*outsideshare/.*/preview、静态资源后缀、actuator/health等)。过滤器调用Security.getUserIdFromToken(request),取不到用户则返回 HTTP401。因此所有端点均需 accessToken,可通过以下任一方式传递(据Security.getUserIdFromToken):query 参数accessToken、query 参数access_token(移动端)、请求头accessToken、CookieaccessToken、请求头Authorization: Bearer <token>。完整鉴权机制见 index.md「鉴权说明」。 - 执行用户:控制器内
getUser()(继承自AbstractBaseController)调用Security.getUserIdFromToken(request)还原当前用户 id,再经 Feign(UserAPI.getUserById)装载KmsUser。无userCode参数。 - 响应结构:统一
Resource(见 ../index.md「统一响应结构」),字段为errcode/errmsg/data/errors。KMS 的Resource为AbstractBaseController内部类,其构造器对data执行ESAPI.encode(data)做 XSS 编码,故data中的 HTML 特殊字符会被转义。 - HTTP 状态码与错误码(据源码
AbstractBaseController全局异常处理):成功默认 HTTP 200;InvalidRequestException→ HTTP 400 / errcode=400;UnauthorizedException→ HTTP 403 / errcode=403;ForbiddenException→ HTTP 403 / errcode=403;ResourceNotFoundException→ HTTP 404 / errcode=404;其他Exception→ HTTP 500 / errcode=500。 - 路径变量:
diskId、folderId、destFolderId均为 KMS 内部主键(明文 id),非 DES 加密密文。
1. 获取目录结构树¶
按网盘 Id 获取该网盘下的目录结构树(可限制仅返回指定文件夹子树)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/disks/{diskId}/foldersTree(完整:{kms-context}/api/kms/disks/{diskId}/foldersTree) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 网盘Id |
| folderIds | query | array(string) | 否 | 指定文件夹Id数组(仅返回这些文件夹的子树);不传则返回整棵目录树 |
请求示例¶
响应¶
结构:统一 Resource(见 ../index.md「统一响应结构」)。
data:String,由 folderService.getFolderTreeSetByDiskId 构造的目录树结构(JSON 序列化字符串)。
2. 创建目录¶
在指定网盘下创建一个新目录(文件夹)。服务端会自动填充 creator/creatorId/domainId(取自当前登录用户)、type=TYPE_NORMAL、创建/修改时间,并继承父目录的 diskType。部门网盘的根目录下新建文件夹时,自动为全公司部门赋「浏览/预览/收藏」权限。
- 接口类型:REST 资源
- 请求方式:
POST - 请求路径:
/disks/{diskId}/folders(完整:{kms-context}/api/kms/disks/{diskId}/folders) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 网盘Id |
| body | body | object | 是 | FolderEntity 对象 JSON,见下方请求体 |
请求体¶
folderId为父目录Id(必传,用于回溯父目录的diskType);name为新目录名称。
请求示例¶
POST /api/kms/disks/__DISKID__/folders?accessToken=__TOKEN__ HTTP/1.1
Content-Type: application/json
{ "folderId": "__PARENTFOLDERID__", "name": "新建文件夹" }
响应¶
结构:统一 Resource。
data:由 dataBuilder.buildFolderEntityReturnData(folder, user) 构造的新建文件夹返回对象(含文件夹实体与当前用户的操作权限)。
3. 置顶目录¶
将指定目录置顶。目录不存在时抛 InvalidRequestException(HTTP 400)。
- 接口类型:REST 资源
- 请求方式:
PATCH - 请求路径:
/disks/{diskId}/folders/{folderId}/top(完整:{kms-context}/api/kms/disks/{diskId}/folders/{folderId}/top) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 网盘Id(路径占位,方法体内未直接使用) |
| folderId | path | string | 是 | 待置顶文件夹Id |
请求示例¶
响应¶
结构:统一 Resource。
data:置顶后的 FolderEntity。
失败示例(目录不存在):
4. 取消目录置顶¶
取消指定目录的置顶状态。目录不存在时抛 InvalidRequestException(HTTP 400)。
- 接口类型:REST 资源
- 请求方式:
DELETE - 请求路径:
/disks/{diskId}/folders/{folderId}/top(完整:{kms-context}/api/kms/disks/{diskId}/folders/{folderId}/top) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 网盘Id(路径占位,方法体内未直接使用) |
| folderId | path | string | 是 | 待取消置顶文件夹Id |
请求示例¶
响应¶
结构:统一 Resource。
data:取消置顶后的 FolderEntity。
失败示例(目录不存在):
5. 重命名目录¶
修改指定目录的名称。目录不存在或新名称为空时抛 InvalidRequestException(HTTP 400)。
- 接口类型:REST 资源
- 请求方式:
PATCH - 请求路径:
/disks/{diskId}/folders/{folderId}/rename(完整:{kms-context}/api/kms/disks/{diskId}/folders/{folderId}/rename) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 网盘Id(路径占位,方法体内未直接使用) |
| folderId | path | string | 是 | 待重命名文件夹Id |
| body | body | string(JSON) | 是 | JSON 字符串,含字段 name |
请求体¶
请求示例¶
PATCH /api/kms/disks/__DISKID__/folders/__FOLDERID__/rename?accessToken=__TOKEN__ HTTP/1.1
Content-Type: application/json
{ "name": "新文件夹名" }
响应¶
结构:统一 Resource。
data:重命名后的 FolderEntity。
失败示例(参数有误):
6. 移动目录¶
将指定目录移动到目标目录下。
- 接口类型:REST 资源
- 请求方式:
PATCH - 请求路径:
/disks/{diskId}/folders/{folderId}/moveto/folderId/{destFolderId}(完整:{kms-context}/api/kms/disks/{diskId}/folders/{folderId}/moveto/folderId/{destFolderId}) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 网盘Id(路径占位,方法体内未直接使用) |
| folderId | path | string | 是 | 待移动文件夹Id |
| destFolderId | path | string | 是 | 目标父文件夹Id |
请求示例¶
PATCH /api/kms/disks/__DISKID__/folders/__FOLDERID__/moveto/folderId/__DESTFOLDERID__?accessToken=__TOKEN__ HTTP/1.1
响应¶
结构:统一 Resource。
data:boolean,固定为 true(移动由 folderService.moveFolder(folderId, destFolderId) 完成,过程中抛出的异常由全局处理器映射)。
7. 删除目录¶
按文件夹 Id 删除目录(含其下子内容)。删除以当前用户 Id 标记。
- 接口类型:REST 资源
- 请求方式:
DELETE - 请求路径:
/disks/{diskId}/folders/{folderId}(完整:{kms-context}/api/kms/disks/{diskId}/folders/{folderId}) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | path | string | 是 | 网盘Id(路径占位,方法体内未直接使用) |
| folderId | path | string | 是 | 待删除文件夹Id |
请求示例¶
响应¶
结构:统一 Resource。
data:boolean,固定为 true(删除由 folderService.remove(folderId, getUser().getId()) 完成)。
8. 根据 folderId 得到路径¶
按文件夹 Id 拼接出自网盘根目录到该文件夹的完整路径(以 / 分隔,末尾为该文件夹自身名称)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/disks/folders/{folderId}(完整:{kms-context}/api/kms/disks/folders/{folderId}) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| folderId | path | string | 是 | 文件夹Id |
请求示例¶
响应¶
结构:统一 Resource。
data:String,路径字符串(如 部门A/子目录/目标文件夹);文件夹不存在时返回空串 ""。
9. 根据 folderId 得到路径文件夹集合¶
按文件夹 Id 返回自网盘根目录到该文件夹路径上的所有文件夹实体列表(按层级从上到下排序)。若该 Id 实际为网盘根,则以网盘的根文件夹为起点。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/disks/folders/{folderId}/path/list(完整:{kms-context}/api/kms/disks/folders/{folderId}/path/list) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| folderId | path | string | 是 | 文件夹Id(或网盘Id) |
请求示例¶
响应¶
结构:统一 Resource。
data:由 dataBuilder.buildFolderEntityReturnData(folderList, getUser()) 构造的文件夹列表返回对象(含文件夹实体数组与当前用户操作权限)。文件夹与对应网盘均不存在时返回空列表。
10. 获取父级目录¶
返回指定文件夹的父文件夹Id(folderId 字段值)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/disks/folders/{folderId}/parent(完整:{kms-context}/api/kms/disks/folders/{folderId}/parent) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| folderId | path | string | 是 | 文件夹Id |
请求示例¶
响应¶
结构:统一 Resource。
data:String父文件夹Id(取自 folder.getFolderId())。
据源码:未对
folder == null做空值判断,文件夹不存在时会抛NullPointerException(被全局异常处理器映射为 HTTP 500)。
11. 解析或创建企业网盘目录¶
按相对企业网盘根的路径解析目标文件夹 Id;路径中缺失的目录段**自动逐级创建**。用于 Runtime 附件上传 filePattern=02:先本接口得 folderId,再调 POST /kms/upload。
约束摘要:
- 取当前用户域下
Disk.TYPE_DEPARTMENT(企业盘)列表;数量必须恰好为 1,否则 HTTP 400 relativePath空、空白或/表示网盘根目录- 路径规范化:统一
/、去首尾空白与多余/、忽略.段;含..段 → 400(路径不允许包含..) -
网盘根目录不存在 → 400
-
接口类型:REST 资源
- 请求方式:
POST - 请求路径:
/disks/enterprise/folders/resolve-or-create(完整:{kms-context}/api/kms/disks/enterprise/folders/resolve-or-create) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| relativePath | query | string | 否 | 相对企业网盘根的路径(如 docs/2026);空或 / 表示根目录 |
请求示例¶
POST /api/kms/disks/enterprise/folders/resolve-or-create?relativePath=docs/2026&accessToken=__TOKEN__ HTTP/1.1
根目录:
响应¶
结构:统一 Resource。
data:
| 字段 | 类型 | 说明 |
|---|---|---|
| diskId | string | 唯一企业网盘 Id |
| folderId | string | 解析(或新建)得到的目标文件夹 Id |
| relativePath | string | 规范化后的相对路径(根目录为空字符串 "") |
成功示例:
{
"errcode": 0,
"errmsg": "ok",
"data": {
"diskId": "__DISKID__",
"folderId": "__FOLDERID__",
"relativePath": "docs/2026"
},
"errors": null
}
常见失败:
| 场景 | HTTP / errcode | 说明 |
|---|---|---|
| 企业盘 0 个或多个 | 400 | 企业网盘数量异常,期望唯一企业盘 |
路径含 .. |
400 | 路径不允许包含.. |
| 网盘根目录不存在 | 400 | 网盘根目录不存在 |
12. 创建归档目录¶
按上传归档信息创建一条归档目录(type=TYPE_ARCHIVE)。若该 folderId 已存在则直接返回既有文件夹实体。
- 接口类型:REST 资源
- 请求方式:
POST - 请求路径:
/archive/folder(完整:{kms-context}/api/kms/archive/folder) - 鉴权:是(需 accessToken,据源码)
- Tag:kms文件夹模块
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| diskId | query | string | 是 | 网盘Id(同时作为新建文件夹的 folderId/diskId) |
| body | body | object | 是 | JSON 对象,含 folderId、folderName |
请求体¶
请求示例¶
POST /api/kms/archive/folder?diskId=__DISKID__&accessToken=__TOKEN__ HTTP/1.1
Content-Type: application/json
{ "folderId": "__FOLDERID__", "folderName": "归档文件夹" }
响应¶
结构:统一 Resource。
data:FolderEntity(既有或新建的归档文件夹;新建时 creator/creatorId 固定为 "archive")。