diff --git a/web-admin/src/views/doclib/enter/ShareDialog.vue b/web-admin/src/views/doclib/enter/ShareDialog.vue
index a92ccde68..c61ba47b7 100644
--- a/web-admin/src/views/doclib/enter/ShareDialog.vue
+++ b/web-admin/src/views/doclib/enter/ShareDialog.vue
@@ -11,11 +11,13 @@
:close-on-press-escape="!saving"
:show-close="!saving"
>
-
{{ document?.name }}
+ {{ summaryText }}
分享给可多选,取消选择即收回访问权限分享给可多选,取消选择即收回访问权限;保存后对所选文档整份覆盖
()
+ 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([])
const people = ref([])
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()
+ 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 {
/* 请求层统一展示错误 */
diff --git a/web-admin/src/views/doclib/enter/browser.test.mjs b/web-admin/src/views/doclib/enter/browser.test.mjs
index 5d5f17934..334f3b313 100644
--- a/web-admin/src/views/doclib/enter/browser.test.mjs
+++ b/web-admin/src/views/doclib/enter/browser.test.mjs
@@ -95,6 +95,12 @@ await context.route('**/api/**', async (route) => {
return ok({ list, total: list.length })
}
if (path === '/web/doclib/users') return ok([{ id: 'other', name: '同事', deptName: '生产部' }])
+ if (path === '/web/doclib/files/batch-shares' && req.method() === 'POST') {
+ const body = req.postDataJSON()
+ sharedUsers = body.userIds
+ file.shares = sharedUsers.map((id) => ({ id, name: '同事', deptName: '生产部' }))
+ return ok([file])
+ }
if (path.endsWith('/shares')) {
sharedUsers = req.postDataJSON().userIds
file.shares = sharedUsers.map((id) => ({ id, name: '同事', deptName: '生产部' }))
diff --git a/web-admin/src/views/doclib/enter/index.vue b/web-admin/src/views/doclib/enter/index.vue
index b76f38c31..302a7f1ff 100644
--- a/web-admin/src/views/doclib/enter/index.vue
+++ b/web-admin/src/views/doclib/enter/index.vue
@@ -78,7 +78,7 @@
>
设置分享
-
+
(null)
- function openShare(row: DoclibDocument) {
- if (!row?.canManage) return
- shareDocument.value = row
+ const shareDocuments = ref([])
+ function openShare(rows: DoclibDocument | DoclibDocument[] | null | undefined) {
+ const list = (Array.isArray(rows) ? rows : rows ? [rows] : []).filter(
+ (row): row is DoclibDocument => !!row?.id && row.canManage
+ )
+ if (!list.length) return
+ shareDocuments.value = list
shareVisible.value = true
}
- function shareSaved(row: DoclibDocument) {
- if (detail.value?.id === row.id) detail.value = row
+ function shareSaved(rows: DoclibDocument[]) {
+ const updated = Array.isArray(rows) ? rows : []
+ const current = detail.value
+ if (current) {
+ const match = updated.find((row) => row.id === current.id)
+ if (match) detail.value = match
+ }
void refresh()
}
const detailVisible = ref(false)