feat(doclib): 文档库支持多选文档后批量设置分享。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-11-12 17:43:16 +08:00
1 parent dd4fdf1e6e
commit 0baa6880f7
3 files changed
+55 -20

No files matched your search

@@ -11,11 +11,13 @@
:close-on-press-escape="!saving"
:show-close="!saving"
>
<p class="doclib-summary">{{ document?.name }}</p>
<p class="doclib-summary">{{ summaryText }}</p>
<el-form label-position="top">
<el-form-item>
<template #label
>分享给<span class="form-label-tip">可多选,取消选择即收回访问权限</span></template
>分享给<span class="form-label-tip"
>可多选,取消选择即收回访问权限;保存后对所选文档整份覆盖</span
></template
>
<el-select
v-model="userIds"
@@ -56,15 +58,15 @@
import { Close, Check } from '@element-plus/icons-vue'
import {
fetchDoclibUsers,
saveDoclibShares,
saveDoclibBatchShares,
type DoclibDocument,
type DoclibPerson
} from '@/api/doclib'
import { createLatestRequest } from './model'
const props = defineProps<{ modelValue: boolean; document: DoclibDocument | null }>()
import { createLatestRequest, shareUserIntersection } from './model'
const props = defineProps<{ modelValue: boolean; documents: DoclibDocument[] }>()
const emit = defineEmits<{
'update:modelValue': [value: boolean]
saved: [document: DoclibDocument]
saved: [documents: DoclibDocument[]]
}>()
const visible = computed({
get: () => props.modelValue,
@@ -77,17 +79,31 @@
const userIds = ref<string[]>([])
const people = ref<DoclibPerson[]>([])
const requests = createLatestRequest()
const ownerIds = computed(
() => new Set(props.documents.map((doc) => doc.ownerId).filter(Boolean))
)
const summaryText = computed(() => {
const names = props.documents.map((doc) => doc.name).filter(Boolean)
if (!names.length) return '未选择文档'
if (names.length === 1) return names[0]
const shown = names.slice(0, 5)
const more = names.length > 5 ? `等 ${names.length} 个` : ''
return `已选 ${names.length} 个文档:${shown.join('、')}${more ? ` ${more}` : ''}`
})
const options = computed(() => {
const candidates = new Map((props.document?.shares || []).map((person) => [person.id, person]))
const candidates = new Map<string, DoclibPerson>()
for (const doc of props.documents) {
for (const person of doc.shares || []) candidates.set(person.id, person)
}
people.value.forEach((person) => candidates.set(person.id, person))
return [...candidates.values()].filter((person) => person.id !== props.document?.ownerId)
return [...candidates.values()].filter((person) => !ownerIds.value.has(person.id))
})
watch(
() => props.modelValue,
(value) => {
requests.invalidate()
if (!value) return
userIds.value = (props.document?.shares || []).map((person) => person.id)
userIds.value = shareUserIntersection(props.documents)
people.value = []
void searchUsers('')
}
@@ -109,12 +125,17 @@
}
}
async function save() {
if (!props.document?.canManage || saving.value) return
if (!props.documents.length || props.documents.some((doc) => !doc.canManage) || saving.value) {
return
}
saving.value = true
try {
const updated = await saveDoclibShares(props.document.id, userIds.value)
const updated = await saveDoclibBatchShares(
props.documents.map((doc) => doc.id),
userIds.value
)
ElMessage.success('分享设置已保存')
emit('saved', updated)
emit('saved', updated || [])
emit('update:modelValue', false)
} catch {
/* 请求层统一展示错误 */