fix(web-admin): 修复 Excel 查看因工作表权限未 protect 误报加载失败

工作表 setPoint 须先 protect;表格已渲染成功后权限步骤抛错不再判定为整体加载失败。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-11-14 23:31:26 +08:00
1 parent cd94ebc56d
commit a327ccf69a
1 file changed
+52 -29
@@ -52,7 +52,6 @@
getActiveWorkbook: () => any
Enum: {
WorkbookPermissionPoint: Record<string, string>
WorksheetPermissionPoint: Record<string, string>
}
}
@@ -65,47 +64,61 @@
univerRef.value = null
}
/**
* 工作表 setPoint 必须先 protect(),否则会抛
* "Cannot set … because worksheet protection does not exist"。
* 工作簿 setEditable / setMode 不依赖 protect。
*/
async function applyReadonlyPermissions(univerAPI: UniverAPI) {
const workbook = univerAPI.getActiveWorkbook()
if (!workbook) return
const workbookPermission = workbook.getWorkbookPermission()
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.CopyContent, true)
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.CreateSheet, false)
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.DeleteSheet, false)
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.InsertRow, false)
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.InsertColumn, false)
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.DeleteRow, false)
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.DeleteColumn, false)
// 本地关闭编辑(不依赖 Authz / protect)
if (typeof workbook.setEditable === 'function') {
workbook.setEditable(false)
}
const sheet = workbook.getActiveSheet()
if (!sheet) return
const sheetPermission = sheet.getWorksheetPermission()
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.SetCellValue, false)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.SetCellStyle, false)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.InsertRow, false)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.InsertColumn, false)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.DeleteRow, false)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.DeleteColumn, false)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Filter, true)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Sort, true)
await sheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Copy, true)
try {
const workbookPermission = workbook.getWorkbookPermission?.()
if (workbookPermission?.setMode) {
await workbookPermission.setMode('viewer')
}
const copyPoint = univerAPI.Enum?.WorkbookPermissionPoint?.CopyContent
if (workbookPermission?.setPoint && copyPoint) {
await workbookPermission.setPoint(copyPoint, true)
}
} catch (error) {
console.warn('[ListExcelViewer] workbook permission skipped', error)
}
const sheet = workbook.getActiveSheet?.()
if (!sheet?.getWorksheetPermission) return
try {
const sheetPermission = sheet.getWorksheetPermission()
// filterOnly = View + Sort + Filter;须先 protect
if (!sheetPermission.isProtected?.()) {
await sheetPermission.protect?.({ name: 'list-excel-readonly' })
}
if (sheetPermission.setMode) {
await sheetPermission.setMode('filterOnly')
}
} catch (error) {
console.warn('[ListExcelViewer] worksheet filterOnly skipped', error)
}
}
function mountFilter(univerAPI: UniverAPI, snapshot: ListExcelSnapshot) {
const sheet = univerAPI.getActiveWorkbook()?.getActiveSheet()
if (!sheet) return
const sheet = univerAPI.getActiveWorkbook()?.getActiveSheet?.()
if (!sheet?.getRange) return
const colCount = Math.max(snapshot.headers.length, 1)
const rowCount = Math.max(snapshot.rows.length + 1, 1)
const range = sheet.getRange(0, 0, rowCount, colCount)
try {
sheet.getFilter()?.remove()
sheet.getFilter?.()?.remove?.()
} catch {
// no existing filter
}
range.createFilter()
range.createFilter?.()
}
async function loadUniverModules() {
@@ -198,11 +211,21 @@
}
})
await applyReadonlyPermissions(api)
mountFilter(api, snapshot)
// 权限/筛选失败不应让整页判定为加载失败(表格数据已就绪)
try {
await applyReadonlyPermissions(api)
} catch (error) {
console.warn('[ListExcelViewer] readonly setup skipped', error)
}
try {
mountFilter(api, snapshot)
} catch (error) {
console.warn('[ListExcelViewer] filter setup skipped', error)
}
} catch (error) {
console.error(error)
ElMessage.error('Excel 查看加载失败,请稍后重试')
disposeUniver()
} finally {
booting.value = false
}