【办公】企业云盘
企业云盘,由 yudao-module-oa 后端模块的 file 包实现,前端实现在 @/views/oa/file 目录。
企业云盘以文件节点为中心,文件夹和文件共用一张表。用户可以维护个人文件、查看共享文件,并通过用户或部门授权控制查看、下载和编辑范围。
本文涉及表如下图所示:
# 1. 文件管理
文件管理,由 OaFileNodeController 提供接口(/oa/file-node)。
# 1.1 主表表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
文件节点表 oa_file_node,用一张表保存文件夹和文件,通过 parent_id 组成目录树:
CREATE TABLE `oa_file_node` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`parent_id` bigint NOT NULL DEFAULT 0 COMMENT '父目录编号,根目录为 0',
`type` tinyint NOT NULL COMMENT '节点类型',
`name` varchar(255) NOT NULL COMMENT '节点名称',
`extension` varchar(64) DEFAULT NULL COMMENT '扩展名',
`category` tinyint DEFAULT NULL COMMENT '文件分类',
`size` bigint NOT NULL DEFAULT 0 COMMENT '文件大小,单位字节',
`url` varchar(2048) DEFAULT NULL COMMENT '文件访问地址',
`dept_id` bigint DEFAULT NULL COMMENT '所属部门编号',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '节点状态',
PRIMARY KEY (`id`),
KEY `idx_parent_id` (`tenant_id`, `parent_id`),
KEY `idx_creator` (`tenant_id`, `creator`),
KEY `idx_creator_status_category` (`tenant_id`, `creator`, `status`, `category`)
) ENGINE=InnoDB COMMENT='云盘文件节点';
① parent_id 自关联本表的 id 字段,根目录为 0(OaFileNodeDO.PARENT_ID_ROOT)。idx_parent_id 支撑按父目录列子节点;同目录同名由 OaFileNodeServiceImpl 的 validateName 校验,冲突抛出重名异常。
② 枚举 type 节点类型(OaFileNodeTypeEnum):
| 值 | 枚举 | 说明 |
|---|---|---|
0 | FOLDER | 文件夹 |
1 | FILE | 文件 |
③ 枚举 category 文件分类(OaFileCategoryEnum),对应字典 oa_file_category。文件夹的 category 为空;文件在创建 / 重命名时由 OaFileCategoryEnum.getByExtension 根据扩展名计算:
| 值 | 枚举 | 说明 |
|---|---|---|
1 | IMAGE | 图片 |
2 | DOCUMENT | 文档 |
3 | VIDEO | 视频 |
4 | AUDIO | 音频 |
5 | ARCHIVE | 压缩包 |
6 | OTHER | 其他 |
④ dept_id 关联 system_dept 表的 id 字段,创建时快照所属人当时的部门(adminUserApi.getUser(userId).getDeptId()),后续调岗不回写历史节点。账号归属仍用通用字段 creator(关联 system_users)。
⑤ status 是节点业务状态,详见 §1.2 状态流转。移入回收站改 status,彻底删除才置 deleted;彻底删除不删除 Infra 物理文件。
⑥ 列表接口不返回 url(统一置 null)。详情 getFileNode 在具备 DOWNLOAD 及以上权限时,才对文件签发临时地址(fileApi.presignGetUrl)。容量统计(get-storage / selectSumSizeByCreatorAndType)含回收站内尚未彻底删除的文件。
列表范围由 OaFileScopeEnum 区分:
| 值 | 枚举 | 说明 |
|---|---|---|
my | MY | 我的文件 |
shared | SHARED | 共享文件 |
favorite | FAVORITE | 我的收藏 |
recycle | RECYCLE | 回收站 |
该表关联两张业务表:
oa_file_permission(共享权限):在【共享设置】中维护,保存用户 / 部门授权。oa_file_favorite(文件收藏):在【收藏】中维护,保存个人收藏入口。
# 1.2 状态流转
节点状态由 OaFileNodeServiceImpl 控制,状态字段为 status,对应枚举 OaFileNodeStatusEnum:
| 状态值 | 枚举 | 说明 | 可执行操作 |
|---|---|---|---|
0 | NORMAL | 正常 | 查看、编辑、移动、回收、共享、收藏 |
1 | RECYCLED | 回收站 | 恢复、彻底删除 |
状态流转说明
创建(createFileNode) ──→ 正常(0) ──回收(recycleFileNode)──→ 回收站(1)
↑ │
└────恢复(restoreFileNode)──────┘
│
└──彻底删除(deleteFileNode)
(须先在回收站;级联权限与收藏;
不删 Infra 物理文件)
- 创建(
createFileNode):状态固定初始化为正常(0),并写入部门快照;文件分类由扩展名计算。 - 回收(
recycleFileNode):正常(0)→回收站(1)。只改当前节点,不级联改子节点状态;须本人节点(validateOwner)。 - 恢复(
restoreFileNode):回收站(1)→正常(0)。父目录必须可用(非根时validateFileNodePermission要求父目录可编辑且祖先均为正常);不改变此前单独回收的子节点。父目录仍在回收站时需先恢复父目录,否则抛出FILE_NODE_NOT_AVAILABLE等异常。 - 彻底删除(
deleteFileNode):节点必须已在回收站,否则抛出FILE_NODE_NOT_RECYCLED。按层收集整棵子树,逻辑删除节点,并级联deleteFilePermissionsByNodeIds、deleteFileFavoritesByNodeIds;不删除底层 Infra 存储文件。 - 访问正常节点时,
validateFileNodeAvailable会校验自身及全部祖先均为正常(0),防止通过收藏、搜索或直接编号访问回收目录下的文件。
# 1.3 管理后台
对应 [OA 办公协同 -> 企业云盘] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/oa/file 目录。
# 列表
在本人文件、共享文件、收藏和回收站之间切换(scope = my / shared / favorite / recycle),按名称、类型和创建时间筛选。容量统计由 GET /oa/file-node/get-storage 提供。

# 新建文件夹与上传
点击【新建文件夹】打开 OaFileNodeForm.vue,填写名称后保存。文件通过 OaFileUpload.vue 上传,再调用 POST /oa/file-node/create 保存文件节点;同目录不能存在重名节点。

# 预览与下载
点击文件进入 OaFilePreview.vue。详情接口 /oa/file-node/get 根据权限返回可用信息;具备下载权限时才显示可下载地址。

# 重命名与移动
重命名调用 PUT /oa/file-node/update-name。移动时选择目标目录,调用 PUT /oa/file-node/update-parent;仅允许移动本人节点,不能把文件夹移动到自身或其子目录中。
# 复制

# 回收、恢复与彻底删除
移入回收站调用 /oa/file-node/recycle。在回收站点击【恢复】回到原位置,若父目录也被回收,需要先恢复父目录。点击【彻底删除】会清理节点及子树、共享和收藏关系;底层存储文件不会由此接口直接删除。

# 2. 共享权限
共享权限,由 OaFilePermissionController 提供接口(/oa/file-permission)。
# 2.1 主表表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
共享权限表 oa_file_permission,保存节点授权给哪些用户或部门及其权限级别:
CREATE TABLE `oa_file_permission` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`node_id` bigint NOT NULL COMMENT '共享节点编号',
`subject_type` tinyint NOT NULL COMMENT '共享主体类型',
`subject_id` bigint NOT NULL COMMENT '共享主体编号',
`level` tinyint NOT NULL COMMENT '共享权限级别',
`inherit` bit(1) NOT NULL DEFAULT b'1' COMMENT '是否继承到子目录',
`expire_time` datetime DEFAULT NULL COMMENT '权限到期时间',
PRIMARY KEY (`id`),
KEY `idx_node_id` (`tenant_id`, `node_id`)
) ENGINE=InnoDB COMMENT='云盘共享权限';
① node_id 关联 oa_file_node 表的 id 字段。维护共享前须具备该节点的 MANAGE 权限(validateFileNodePermission(..., MANAGE))。idx_node_id 支撑按节点查授权列表。
② 枚举 subject_type 共享主体类型(OaFileSubjectTypeEnum),对应字典 oa_file_subject_type:
| 值 | 枚举 | 说明 |
|---|---|---|
1 | USER | 用户 |
2 | DEPT | 部门 |
subject_id 在 USER 时关联 system_users 表的 id 字段,在 DEPT 时关联 system_dept 表的 id 字段;保存时分别由 adminUserApi.validateUser、deptApi.validateDeptList 校验。
③ 枚举 level 共享权限级别(OaFilePermissionLevelEnum),对应字典 oa_file_permission_level:
| 值 | 枚举 | 说明 |
|---|---|---|
1 | READ | 只读 |
2 | DOWNLOAD | 下载 |
3 | EDIT | 编辑 |
4 | MANAGE | 管理 |
权限计算(getLevel)规则:本人创建的节点直接视为 MANAGE(4);他人节点取用户授权与部门授权的最高级别,祖先节点仅在 inherit = true 且未过期(expire_time)时向下传递。移动、回收、彻底删除等操作额外要求本人节点(validateOwner)。
# 2.2 管理后台
对应 [OA 办公协同 -> 企业云盘] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/oa/file 目录。共享权限没有独立菜单,在文件列表的【共享设置】弹窗中维护。
# 设置共享
在文件列表打开【共享设置】,由 OaFilePermissionList.vue 展示授权。点击【新增】打开 OaFilePermissionForm.vue,选择用户或部门、权限级别、继承设置和到期时间,调用 POST /oa/file-permission/save。

# 修改与取消共享
在共享设置中修改权限或点击【取消共享】。取消后,接收人通过该条授权获得的访问能力失效;如果仍有其他有效授权,按剩余授权计算权限。
# 3. 文件收藏
文件收藏,由 OaFileFavoriteController 提供接口(/oa/file-favorite)。
# 3.1 主表表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
收藏表 oa_file_favorite,保存「用户收藏了哪个节点」的关系:
CREATE TABLE `oa_file_favorite` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`node_id` bigint NOT NULL COMMENT '收藏节点编号',
`user_id` bigint NOT NULL COMMENT '收藏用户编号',
PRIMARY KEY (`id`),
KEY `idx_node_id` (`tenant_id`, `node_id`),
KEY `idx_user_id` (`tenant_id`, `user_id`)
) ENGINE=InnoDB COMMENT='云盘收藏';
① node_id 关联 oa_file_node 表的 id 字段,user_id 关联 system_users 表的 id 字段。收藏前须至少具备 READ 权限(createFileFavorite → validateFileNodePermission(..., READ))。
② 收藏只保存个人入口,不复制文件,也不额外增加访问权限;进入收藏列表时仍会校验节点与祖先是否可用、共享是否仍然有效。彻底删除节点时,由 deleteFileFavoritesByNodeIds 级联清理。
# 3.2 管理后台
对应 [OA 办公协同 -> 企业云盘] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/oa/file 目录。文件收藏没有独立菜单,在文件列表切换到【我的收藏】页签查看。
# 收藏与取消收藏
在可访问文件上执行收藏或取消收藏,分别调用 POST /oa/file-favorite/create、DELETE /oa/file-favorite/delete。进入收藏列表时仍需校验文件和共享权限是否有效。
