import store from '@/store' // 现有权限指令 const permissions = { inserted(element, binding) { const { value } = binding const permissions = store.getters['user/permissions'] if (value && value instanceof Array && value.length > 0) { const hasPermission = permissions.some((role) => value.includes(role)) if (!hasPermission) element.parentNode && element.parentNode.removeChild(element) } }, } // 权限处理逻辑封装为函数,方便inserted和update钩子复用 function handlePermission(element, binding) { // 获取用户信息 const userInfo = store.state.user.userInfo || {} const user = userInfo.user || {} // 更加健壮的管理员权限判断,接受布尔值true、字符串'true'等真值 const isAdmin = !!user.admin const dataScope = user.dataScope ?? 999 // 默认无权限 // 权限级别定义 const PERMISSION_LEVEL = { PROVINCE: 0, // 省级 CITY: 1, // 市级 COUNTY: 2, // 县级 } // 分类权限定义 - 基于表格结构 const PERMISSION_CATEGORIES = { // 第一类:省级维护,市县查看 ADMIN_PROVINCE_VIEW_OTHERS: [ 'catalogManage', // 监审目录管理 'auditEntityManage', // 被监审单位管理 'costFormManage', // 成本监审表模板管理 'financeSheetManage', // 财务数据表模板管理 'costVerifyManage', // 成本核定表模板管理 'auditReviewDocManage', // 监审文书管理 'auditDocNoManage', // 监审文号管理 'auditDocManage', // 监审资料管理 'annualReviewPlan', // 年度审计计划 'auditInitiation', // 监审立项管理 ], // 第二类:省市县可查看添加本级及下级,同级不可查看添加 // LEVEL_BASED_MANAGE: [ // 'annualReviewPlan', // 年度审计计划 // 'auditInitiation', // 监审立项管理 // ], // 第三类:跟着数据权限走 // DATA_BASED_MANAGE: [ // 'auditProject', // 监审项目管理 // 'taskManagement', // 任务管理 // 'superviseMatters' // 督办管理 // ], } // 解析绑定值 const options = binding.value || {} const action = options.action || 'view' // 默认只有查看权限 const category = options.category || '' // 权限分类标识 const targetData = options.targetData || {} // 目标数据,用于判断同级等场景 const displayMode = options.displayMode || 'hidden' // 无权限时的显示模式:'hidden'(隐藏)或 'disabled'(禁用) // 判断是否拥有权限 let hasPermission = false // 管理员拥有所有权限 if (isAdmin) { hasPermission = true } else { // 基于分类的权限判断逻辑 // 第一类权限:省级维护,市县查看 if (PERMISSION_CATEGORIES.ADMIN_PROVINCE_VIEW_OTHERS.includes(category)) { if (action === 'view') { // 所有级别都可查看 hasPermission = true } else { // 新增、编辑、删除操作只有省级可执行 // 确保dataScope为0的省级用户有正确权限 hasPermission = dataScope === PERMISSION_LEVEL.PROVINCE } } } // 根据displayMode决定无权限时的处理方式 if (!hasPermission) { if (displayMode === 'disabled') { // 禁用模式:保留元素但禁用交互 element.setAttribute('disabled', 'disabled') element.style.cursor = 'not-allowed' element.style.opacity = '0.6' element.style.pointerEvents = 'none' // 禁用所有指针事件 // 添加提示类名,可用于自定义样式 element.classList.add('permission-disabled') // 对于a标签的特殊处理 if (element.tagName === 'A') { // 移除href属性或设置为无效值 if (element.hasAttribute('href')) { element.setAttribute( 'data-original-href', element.getAttribute('href') ) element.removeAttribute('href') } element.setAttribute('tabindex', '-1') // 从Tab键序列中移除 } // 阻止所有事件冒泡和默认行为,确保元素真正不可交互 const preventEvent = (e) => { e.stopPropagation() e.preventDefault() return false } // 使用捕获模式添加所有可能的交互事件阻止 const events = [ 'click', 'mousedown', 'mouseup', 'dblclick', 'touchstart', 'touchend', 'touchmove', 'touchcancel', 'keydown', 'keypress', 'keyup', 'focus', 'blur', ] events.forEach((event) => { element.addEventListener(event, preventEvent, true) }) // 重写元素上可能存在的onclick等属性 element.onclick = null element.onmousedown = null element.onmouseup = null element.ondblclick = null } else { // 默认隐藏模式:移除元素 element.parentNode && element.parentNode.removeChild(element) } } } // 区域权限指令定义 - 同时使用inserted和update钩子确保动态元素也能正确应用权限 const regionPermission = { inserted: handlePermission, update: handlePermission, } // 安装函数 const install = function (Vue) { Vue.directive('permissions', permissions) Vue.directive('region-permission', regionPermission) } // 全局安装 if (window.Vue) { window['permissions'] = permissions window['regionPermission'] = regionPermission Vue.use(install) } // 导出 permissions.install = install export default permissions