明确整份覆盖、交集预选、batch-shares 事务与 Web 弹窗扩展范围,供实现对照。 Co-authored-by: Cursor <cursoragent@cursor.com>
4.9 KiB
4.9 KiB
文档库多选批量设置分享(工单 #25)
工单:#25
背景与问题
Web 文档库管理(/#/doclib/enter)工具栏「设置分享」当前仅在恰好选中 1 份且可管理的文档时可用(actionsFor.share),弹窗与接口均为单文档。用户需要多选文档后统一设置分享人员。
已确认决策
| 项 | 结论 |
|---|---|
| 保存语义 | 整份覆盖:弹窗所选 userIds 写入每一份所选文档,替换原分享人;空列表表示全部收回 |
| 弹窗初始勾选 | 所选文档现有分享人的交集;无共同人员则为空 |
| 修改端 | Web 管理端 + 后端批量 API |
| 失败策略 | 整批事务:全部成功或全部回滚 |
| 实现方案 | 新增 batch-shares + 扩展现有 ShareDialog(方案 A) |
范围
包含
web-admin:doclib/enter列表工具栏、ShareDialog、actionsFor、API 封装与单测backend:批量分享路由、schema、服务层事务与单文件写入逻辑复用
不包含
- 小程序 / 移动 H5
- 「只追加不收回」、部分成功返回清单
- 文件夹级分享
后端设计
接口
POST /web/doclib/files/batch-shares
请求体(extra=forbid):
{
"ids": ["file-id-1", "file-id-2"],
"userIds": ["user-id-a", "user-id-b"]
}
约束:
ids:min_length=1,max_length=100(对齐DeleteFilesBody)userIds:max_length=500(对齐ShareBody)- 去重后的
ids均须当前用户可管理;任一份不可管理则 4xx,整批不写 - 人员须同租户且启用;自动排除各文档上传人(与现
set_shares一致:requested - {create_by}) - 非法 / 停用 / 跨租户人员 → 400,整批回滚
响应:成功后返回更新后的文档列表(字段与现有单文档分享成功返回一致的序列化)。
事务与复用
- 现有
DoclibService.set_shares在单文件路径末尾commit。批量路径须在全部文件写入完成前不 commit。 - 抽取内部方法(名称示例:
_apply_shares(file_id, user_ids))完成单文件差量更新(含 lock);set_shares=_apply_shares+commit+ 返回序列化;set_shares_batch= 校验全部可管理 → 校验人员 → 对每个 id 调用_apply_shares→ 一次commit→ 返回列表。 - 任一步抛错依赖会话回滚,不留下部分文档已改的状态。
路由注册位置:与现有 PUT /web/doclib/files/{file_id}/shares、POST .../batch-delete 同模块(backend/app/api/doclib.py)。
前端设计
工具栏与权限
actionsFor.share:rows.length > 0 && rows.every((row) => row.canManage)(与删除多选门槛一致,取消「仅 1 条」限制)。- 工具栏「设置分享」对
selected全量打开弹窗,不再只取selected[0]。 - 详情抽屉单文档「设置分享」仍传入单元素数组或单文档,行为不变。
ShareDialog
- Props 改为支持多文档(例如
documents: DoclibDocument[]);打开时:- 摘要列出所选文档名称(数量较多时可截断并注明总数)
userIds初始 = 分享人 id 交集- 候选人员:交集中的人员 ∪ 远程搜索结果;排除各文档上传人(多文档时排除所有相关
ownerId)
- 保存:统一调用批量接口
saveDoclibBatchShares(ids, userIds)(单文档也走批量,少分支);成功提示后关闭并刷新列表 / 更新详情。
纯函数(便于单测)
shareUserIntersection(documents): string[]— 交集;空文档列表返回[]- 可选:
canShareSelection(rows)与actionsFor共用语义
API
在 web-admin/src/api/doclib.ts 增加:
saveDoclibBatchShares(ids: string[], userIds: string[]) → POST .../files/batch-shares
单文档 saveDoclibShares 可保留供兼容/测试,页面路径以批量为准。
UI 规范
- 沿用现有
doclib-dialog dialog-form-layout、Fresh Mint、P12 类弹窗;不新造布局与主色。 - 按钮图标规则与现页一致(Close / Check 等已有用法)。
验收
- 多选可管理文档后可打开「设置分享」;含不可管理项时按钮禁用。
- 打开时勾选为交集;无共同分享人时为空。
- 保存后所选文档分享人员均等于弹窗所选集合(含清空)。
- 故意混入无权限文档(若后端被直接调用)→ 整批不改。
- 详情页单文档分享仍可用。
- 单测覆盖交集函数与
actionsFor.share;后端/服务层覆盖批量成功与权限失败回滚(按项目既有测试方式)。
风险
set_shares重构时须保证单文档路径回归(commit 时机、上传人排除、软删恢复历史 share 行)。- 批量上限 100 与删除一致;超大选区依赖现有表格多选,不另做分片 UI。
状态
设计已获用户确认(会话中「按照推荐」方案 A,「OK,请继续」批准落盘)。待用户审阅本文件后进入实现计划。