import store from '@/store' /** * 区域权限指令实现 * 用于处理基于用户级别(省级、市级、县级)的权限控制 */ // 权限判断公共工具 const permissionUtils = { /** * 获取当前登录用户信息 * @returns {Object} 用户信息对象 */ getUserInfo() { const userInfo = store.state.user.userInfo || {} return userInfo.user || {} }, /** * 判断是否为管理员账号 * @returns {Boolean} 是否为管理员 */ isAdmin() { const user = this.getUserInfo() return !!user.admin }, /** * 判断是否为省级账号 * @returns {Boolean} 是否为省级账号 */ isProvince() { const user = this.getUserInfo() return user.dataScope === PERMISSION_LEVEL.PROVINCE }, /** * 判断是否为管理员或省级账号 * @returns {Boolean} 是否为管理员或省级账号 */ isAdminOrProvince() { return this.isAdmin() || this.isProvince() }, /** * 根据操作和分类判断权限 * @param {String} action - 操作类型:'view', 'add', 'edit', 'delete' * @param {String} category - 权限分类 * @returns {Boolean} 是否有权限 */ hasPermission(action, category) { if (this.isAdmin()) { return true } const user = this.getUserInfo() const dataScope = user.dataScope ?? 999 // 对于省级维护,市县查看的分类 if (PERMISSION_CATEGORIES.ADMIN_PROVINCE_VIEW_OTHERS.includes(category)) { if (action === 'view') { return true } else { return dataScope === PERMISSION_LEVEL.PROVINCE } } return false }, } // 权限级别定义 export const PERMISSION_LEVEL = { PROVINCE: 0, // 省级 CITY: 1, // 市级 COUNTY: 2, // 县级 } // 分类权限定义 - 基于表格结构 export const PERMISSION_CATEGORIES = { // 第一类:省级维护,市县查看 ADMIN_PROVINCE_VIEW_OTHERS: [ 'catalogManage', // 监审目录管理 'auditEntityManage', // 被监审单位管理 'auditReviewDocManage', // 监审文书管理 'auditDocNoManage', // 监审文号管理 'auditDocManage', // 监审资料管理 'annualReviewPlan', // 年度审计计划 'auditInitiation', // 监审立项管理 'costFormManage', // 成本调查表模板管理 'financeSheetManage', // 财务数据表模板管理 'costVerifyManage', // 成本核定表模板管理 ], // 第二类:省市县都可添加但各维护各,省级添加的市县查看,同级不可查看 // LEVEL_BASED_MANAGE: [ // 'costFormManage', // 成本调查表模板管理 // 'financeSheetManage', // 财务数据表模板管理 // 'costVerifyManage', // 成本核定表模板管理 // ], // 第三类:跟着数据权限走 // DATA_BASED_MANAGE: [ // 'auditProject', // 监审项目管理 // 'taskManagement', // 任务管理 // 'superviseMatters' // 督办管理 // ], } /** * 权限处理逻辑封装为函数 * @param {HTMLElement} element - 要处理权限的DOM元素 * @param {Object} binding - Vue指令绑定对象 */ export 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 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 } } // 第二类权限:省市县都可添加但各维护各,省级添加的市县查看,同级不可查看 // if (PERMISSION_CATEGORIES.LEVEL_BASED_MANAGE.includes(category)) { // if (action === 'view') { // // 省级可查看所有添加的市县 // hasPermission = true // } else { // // 新增、编辑、删除操作只有数据创建者和当前用户是用一个可执行 // if ( // targetData.createBy === user.username // ) { // hasPermission = true // } // // hasPermission = dataScope === PERMISSION_LEVEL[category.split('Manage')[0]] // } // } // 第三类权限:跟着数据权限走 // if (PERMISSION_CATEGORIES.DATA_BASED_MANAGE.includes(category)) { // // 数据权限判断逻辑... // } } // 根据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钩子确保动态元素也能正确应用权限 export const regionPermission = { inserted: handlePermission, update: handlePermission, } // 安装函数 const install = function (Vue) { Vue.directive('region-permission', regionPermission) // 挂载权限判断工具到Vue原型 Vue.prototype.$permission = permissionUtils // 全局挂载regionPermission对象,方便其他地方使用 if (window.Vue) { window['regionPermission'] = regionPermission window['permissionUtils'] = permissionUtils } } // 全局安装 if (window.Vue) { window['regionPermission'] = regionPermission Vue.use(install) } // 导出 export default { regionPermission, handlePermission, PERMISSION_LEVEL, PERMISSION_CATEGORIES, permissionUtils, install, } // 同时导出permissionUtils,方便在非Vue组件中使用 export { permissionUtils }