feat: 接入文档权限批量接口

This commit is contained in:
xy
2026-09-03 14:15:38 +08:00
parent 925d8c9202
commit 6d56bc0075
7 changed files with 437 additions and 75 deletions
@@ -84,7 +84,11 @@ function deletePermission(permissionId: string | undefined) {
}
}
function formatSubject(subjectType: PermissionSubjectOption['type'], subjectId: string) {
function formatSubject(subjectType: PermissionSubjectOption['type'], subjectId: string | null) {
if (!subjectId) {
return '系统默认继承规则'
}
const subject = props.subjects.find((item) => item.type === subjectType && item.id === subjectId)
return subject?.label ?? subjectId
}
@@ -3,11 +3,11 @@ import { computed, onMounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { getAllDepartments } from '@/api/management/organization'
import { getDocuments } from '@/api/management/documents'
import { getTemplatePermissionConfig } from '@/api/management/documents'
import {
createTemplatePermission,
deleteTemplatePermission,
batchSaveTemplatePermissions,
getTemplatePermissions,
getTemplatePermissionMatrix,
isPermissionMockEnabled,
} from '@/api/management/document-permissions'
import { getUsers } from '@/api/management/users'
@@ -16,6 +16,7 @@ import type {
DepartmentRecord,
DocumentRecord,
RoleRecord,
TemplatePermissionBatchItemRequest,
TemplatePermissionRecord,
UserRecord,
} from '@/api/management/types'
@@ -146,7 +147,7 @@ function syncPermissionRows() {
}
async function getAllTemplatesForPermission() {
const firstPage = await getDocuments({ page: 1, pageSize: 200, status: 'all' })
const firstPage = await getTemplatePermissionConfig({ page: 1, pageSize: 200, status: 'all' })
const pageCount = Math.ceil(firstPage.total / firstPage.pageSize)
if (pageCount <= 1) {
@@ -155,13 +156,69 @@ async function getAllTemplatesForPermission() {
const remainingPages = await Promise.all(
Array.from({ length: pageCount - 1 }, (_, index) =>
getDocuments({ page: index + 2, pageSize: firstPage.pageSize, status: 'all' }),
getTemplatePermissionConfig({
page: index + 2,
pageSize: firstPage.pageSize,
status: 'all',
}),
),
)
return [firstPage, ...remainingPages].flatMap((page) => page.records)
}
async function getAllTemplatePermissionMatrix(templateId: string) {
const firstPage = await getTemplatePermissionMatrix({
page: 1,
pageSize: 200,
templateId,
})
const pageCount = Math.ceil(firstPage.total / firstPage.pageSize)
if (pageCount <= 1) {
return firstPage.records
}
const remainingPages = await Promise.all(
Array.from({ length: pageCount - 1 }, (_, index) =>
getTemplatePermissionMatrix({
page: index + 2,
pageSize: firstPage.pageSize,
templateId,
}),
),
)
return [firstPage, ...remainingPages].flatMap((page) => page.records)
}
function mergeTemplatePermissions(
matrixRecords: TemplatePermissionRecord[],
effectiveRecords: TemplatePermissionRecord[],
) {
const seen = new Set<string>()
return [...matrixRecords, ...effectiveRecords.filter((record) => record.inherited)].filter(
(record) => {
const key = [
record.templateId,
record.subjectType,
record.subjectId ?? '',
record.permissionLevel,
record.effect,
record.inherited,
].join('|')
if (seen.has(key)) {
return false
}
seen.add(key)
return true
},
)
}
async function getRolesForPermission(): Promise<{
records: RoleRecord[]
usedFallback: boolean
@@ -281,17 +338,28 @@ async function loadTemplatePermissions() {
permissionError.value = false
try {
const records = await getTemplatePermissions(
templateId,
permissionPreviewUserId.value || undefined,
)
const [matrixResult, effectiveResult] = await Promise.allSettled([
getAllTemplatePermissionMatrix(templateId),
getTemplatePermissions(templateId, permissionPreviewUserId.value || undefined),
])
if (matrixResult.status === 'rejected') {
throw matrixResult.reason
}
if (requestId !== permissionRequestId || templateId !== selectedTemplateId.value) {
return
}
templatePermissions.value = records
templatePermissions.value = mergeTemplatePermissions(
matrixResult.value,
effectiveResult.status === 'fulfilled' ? effectiveResult.value : [],
)
syncPermissionRows()
if (effectiveResult.status === 'rejected') {
ElMessage.warning('用户继承权限预览加载失败,当前仅展示矩阵权限数据')
}
} catch {
if (requestId !== permissionRequestId) {
return
@@ -341,6 +409,7 @@ async function applyTemplatePermission(
permission: PermissionKey,
enabled: boolean,
) {
const operations: TemplatePermissionBatchItemRequest[] = []
const matchingRecords = templatePermissions.value.filter(
(record) =>
record.subjectType === subjectType &&
@@ -362,34 +431,49 @@ async function applyTemplatePermission(
if (!binding.id) {
throw new Error('该直接拒绝权限缺少绑定 ID,无法撤销')
}
await deleteTemplatePermission(templateId, binding.id)
operations.push({
templateId,
action: 'REVOKE',
permissionId: binding.id,
})
}
if (!directAllows.length && !inheritedAllows) {
await createTemplatePermission(templateId, {
operations.push({
templateId,
action: 'ADD',
subjectType,
subjectId,
permissionLevel: permission,
effect: 'ALLOW',
})
}
return
}
for (const binding of directAllows) {
if (!binding.id) {
throw new Error('该直接允许权限缺少绑定 ID,无法撤销')
} else {
for (const binding of directAllows) {
if (!binding.id) {
throw new Error('该直接允许权限缺少绑定 ID,无法撤销')
}
operations.push({
templateId,
action: 'REVOKE',
permissionId: binding.id,
})
}
if (!directDenies.length && inheritedAllows) {
operations.push({
templateId,
action: 'ADD',
subjectType,
subjectId,
permissionLevel: permission,
effect: 'DENY',
})
}
await deleteTemplatePermission(templateId, binding.id)
}
if (!directDenies.length && inheritedAllows) {
await createTemplatePermission(templateId, {
subjectType,
subjectId,
permissionLevel: permission,
effect: 'DENY',
})
if (operations.length) {
await batchSaveTemplatePermissions({ operations })
}
}
@@ -437,7 +521,15 @@ async function addTemplatePermission(form: TemplatePermissionForm) {
permissionSaving.value = true
try {
await createTemplatePermission(selectedTemplateId.value, form)
await batchSaveTemplatePermissions({
operations: [
{
templateId: selectedTemplateId.value,
action: 'ADD',
...form,
},
],
})
await loadTemplatePermissions()
ElMessage.success('模板权限已添加')
} catch (error) {
@@ -455,7 +547,15 @@ async function removeTemplatePermission(permissionId: string) {
permissionSaving.value = true
try {
await deleteTemplatePermission(selectedTemplateId.value, permissionId)
await batchSaveTemplatePermissions({
operations: [
{
templateId: selectedTemplateId.value,
action: 'REVOKE',
permissionId,
},
],
})
await loadTemplatePermissions()
ElMessage.success('模板权限已删除')
} catch (error) {