| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- 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 }
|