/** * auth: 允许的权限 * authExclude: 排除的权限 * * auth的几种传值方式 * 1.String * 例: auth="sysApp:page" * 直接传入字符串,对单项权限进行验证 * * 2.Array * 2.1.单项权限 * 例: :auth="['sysApp:page']" * 2.2.并且关系多项权限 * 例: :auth="['sysApp:page', 'sysApp:add']" * 数组中传入多个字符串 * 此时验证的是同时拥有"sysApp:page"和"sysApp:add"两项权限才会渲染 * 2.3.或者关系多项权限 * 例: :auth="[['sysApp:page', 'sysApp:add'], ['sysApp:edit']]" * 二维数组结构,内部数组之间为并且关系 * 此时验证的是"sysApp:page"&"sysApp:add"||"sysApp:edit" * 注意:或者的条件必须包括在数组中,暴露在外则判定为并且 * 2.4.可直接传入布尔值 * 例: :auth="['sysApp:page', 1 === 1]" * :auth="[['sysApp:page', 'sysApp:add'], [1 === 1]]" * * 3.Json * 如果觉得多项权限时每次都要写应用编号比较繁琐,可对Array形式进行简化 * 3.1.单项权限 * 例: :auth="{ sysApp: 'page' }" * 3.2.并且关系多项权限 * 例: :auth="{ sysApp: ['page', 'add'] }" * 3.3.或者关系多项权限 * 例: :auth="{ sysApp: [['page', 'add'], ['edit']]}" * 3.4.可直接传入布尔值 * 例: :auth="{ sysApp: ['page', 1 === 1] }" * :auth="{ sysApp: [['page', 'add'], [1 === 1]] }" * */ import app from '@/main' const authByArray = (auth, permissions) => { const flags = [] auth.forEach(p => { switch (p.constructor) { case String: flags.push([permissions.indexOf(p) > -1, '&&']) break case Array: flags.push([authByArray(p, permissions), '||']) break case Boolean: flags.push([p, '&&']) break } }) let result flags.forEach((p, i) => { if (p[1] === '&&') { if (i === 0) { result = true } if (result) { result = p[0] } } else { if (i === 0) { result = false } if (!result) { result = p[0] } } //result = p[1] === '&&' ? result && p[0] : result || p[0] }) return result } const authByJson = (auth, permissions) => { let result = true const flags = [] const deepName = (arr, key) => { arr.forEach((p, i) => { switch (p.constructor) { case String: arr[i] = `${key}:${p}` break case Array: p = deepName(p, key) break default: p = p break } }) return arr } for (let key in auth) { const app = auth[key] switch (app.constructor) { case String: flags.push(permissions.indexOf(`${key}:${p}`) > -1) break case Array: flags.push(authByArray(deepName(app, key), permissions)) break } } flags.forEach(p => { result = result && p }) return result } export const auth = (auth) => { const { info } = app.global if (!info) { return false } /** * 超级管理员 */ if (info.adminType === 1) { return true } const permissions = info.permissions let flag = false if (auth) { switch (auth.constructor) { case String: flag = permissions.indexOf(auth) > -1 break case Array: flag = authByArray(auth, permissions) break case Object: flag = authByJson(auth, permissions) break } } return flag } export default { functional: true, props: { auth: { default() { return new Array() }, type: [Array, Object, String], }, authExclude: { default() { return new Array() }, type: Array, }, }, render(h, context) { const { props, scopedSlots } = context const authExclude = props.authExclude let flag = auth(props.auth) if (flag) { return scopedSlots.default && scopedSlots.default() } return false }, }