feat(doclib): 允许多选可管理文档分享并计算分享人交集。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-11-12 17:41:48 +08:00
1 parent bb75f98582
commit 522ef36e7a
2 files changed
+40 -3

No files matched your search

+22 -2
View File
@@ -14,7 +14,7 @@ const node = (id: string, scope: 'mine' | 'shared', children: any[] = []) => ({
children
})
test('分享接收人只能下载,混合选择不能批量删除', () => {
test('可管理文档可多选分享,混合选择不能分享', () => {
assert.deepEqual(actionsFor([{ canManage: false }]), {
share: false,
download: true,
@@ -25,10 +25,30 @@ test('分享接收人只能下载,混合选择不能批量删除', () => {
download: true,
delete: false
})
assert.deepEqual(actionsFor([{ canManage: true }]), { share: true, download: true, delete: true })
assert.deepEqual(actionsFor([{ canManage: true }]), {
share: true,
download: true,
delete: true
})
assert.deepEqual(actionsFor([{ canManage: true }, { canManage: true }]), {
share: true,
download: true,
delete: true
})
assert.deepEqual(actionsFor([]), { share: false, download: false, delete: false })
})
test('分享人初始勾选取所选文档交集', async () => {
const { shareUserIntersection } = await import('./model')
const docs = [
{ shares: [{ id: 'a' }, { id: 'b' }] },
{ shares: [{ id: 'b' }, { id: 'c' }] }
]
assert.deepEqual(shareUserIntersection(docs), ['b'])
assert.deepEqual(shareUserIntersection([{ shares: [{ id: 'a' }] }, { shares: [] }]), [])
assert.deepEqual(shareUserIntersection([]), [])
})
test('同一个目录在不同范围有独立树节点,已删除目录不再命中', () => {
const mine = node('root', 'mine', [node('child', 'mine')])
const shared = node('root', 'shared')
+18 -1
View File
@@ -2,12 +2,29 @@ import type { DoclibFolder } from '@/api/doclib'
export function actionsFor(rows: Array<{ canManage: boolean }>) {
return {
share: rows.length === 1 && rows[0].canManage,
share: rows.length > 0 && rows.every((row) => row.canManage),
download: rows.length > 0,
delete: rows.length > 0 && rows.every((row) => row.canManage)
}
}
/** 多选打开分享弹窗时,初始勾选为各文档现有分享人的交集。 */
export function shareUserIntersection(
documents: Array<{ shares?: Array<{ id: string }> | null }>
): string[] {
if (!documents.length) return []
let ids = new Set(
(documents[0].shares || []).map((person) => String(person.id || '').trim()).filter(Boolean)
)
for (const doc of documents.slice(1)) {
const next = new Set(
(doc.shares || []).map((person) => String(person.id || '').trim()).filter(Boolean)
)
ids = new Set([...ids].filter((id) => next.has(id)))
}
return [...ids]
}
export function findFolder(nodes: DoclibFolder[], id: string): DoclibFolder | undefined {
for (const node of nodes) {
if (node.id === id) return node