751 lines
29 KiB
JavaScript
751 lines
29 KiB
JavaScript
/**
|
||
* =============================================
|
||
* 权限管理模块 - Layui版本
|
||
* Auth + RBAC 权限控制完整实现
|
||
* =============================================
|
||
*
|
||
* 使用说明:
|
||
* 1. 放置在layui的modules目录下
|
||
* 2. 使用:layui.use('permission', function(mod){...})
|
||
* 3. 或者直接:var permission = layui.permission;
|
||
*
|
||
* @version 2.0.0 - Layui Module
|
||
* @author Permission Module
|
||
* @date 2024-01-01
|
||
*/
|
||
|
||
layui.define(function (exports) {
|
||
'use strict';
|
||
|
||
/**
|
||
* =============================================
|
||
* 权限配置管理器
|
||
* =============================================
|
||
*/
|
||
const PermissionConfig = (function () {
|
||
// 私有变量
|
||
const _defaultToolbar = {
|
||
create: { title: '创建资源', layEvent: 'dataCreate', icon: 'layui-icon-add-1', permission: 'create', color: 'layui-btn-normal', size: '', show: true },
|
||
recycle: { title: '回收站', layEvent: 'dataRecycle', icon: 'layui-icon-refresh', permission: 'recycle', color: 'layui-btn-warm', size: '', show: true },
|
||
filter: { title: '筛选', layEvent: 'filter', icon: 'layui-icon-search', permission: 'filter', color: 'layui-btn-primary', size: '', show: true },
|
||
export: { title: '导出', layEvent: 'export', icon: 'layui-icon-download-circle', permission: 'export', color: 'layui-btn-primary', size: '', show: true },
|
||
print: { title: '打印', layEvent: 'print', icon: 'layui-icon-print', permission: 'print', color: 'layui-btn-primary', size: '', show: true },
|
||
refresh: { title: '刷新', layEvent: 'refresh', icon: 'layui-icon-refresh', permission: 'refresh', color: 'layui-btn-primary', size: '', show: true },
|
||
batchDelete: { title: '批量删除', layEvent: 'batchDelete', icon: 'layui-icon-delete', permission: 'batch_delete', color: 'layui-btn-danger', size: '', show: true },
|
||
import: { title: '导入', layEvent: 'import', icon: 'layui-icon-upload-circle', permission: 'import', color: 'layui-btn-primary', size: '', show: true }
|
||
};
|
||
|
||
const _rowToolbar = {
|
||
view: { title: '查看', layEvent: 'dataView', icon: 'layui-icon-eye', permission: 'view', color: 'layui-btn-primary layui-btn-xs', size: 'layui-btn-xs', show: true },
|
||
edit: { title: '编辑', layEvent: 'dataEdit', icon: 'layui-icon-edit', permission: 'edit', color: 'layui-btn-normal layui-btn-xs', size: 'layui-btn-xs', show: true },
|
||
delete: { title: '删除', layEvent: 'dataDelete', icon: 'layui-icon-delete', permission: 'delete', color: 'layui-btn-danger layui-btn-xs', size: 'layui-btn-xs', show: true },
|
||
copy: { title: '复制', layEvent: 'dataCopy', icon: 'layui-icon-file-b', permission: 'copy', color: 'layui-btn-warm layui-btn-xs', size: 'layui-btn-xs', show: true },
|
||
enable: { title: '启用', layEvent: 'dataEnable', icon: 'layui-icon-play', permission: 'enable', color: 'layui-btn-normal layui-btn-xs', size: 'layui-btn-xs', show: true },
|
||
disable: { title: '禁用', layEvent: 'dataDisable', icon: 'layui-icon-pause', permission: 'disable', color: 'layui-btn-warm layui-btn-xs', size: 'layui-btn-xs', show: true },
|
||
audit: { title: '审核', layEvent: 'dataAudit', icon: 'layui-icon-ok-circle', permission: 'audit', color: 'layui-btn-normal layui-btn-xs', size: 'layui-btn-xs', show: true },
|
||
unaudit: { title: '取消审核', layEvent: 'dataUnaudit', icon: 'layui-icon-close', permission: 'unaudit', color: 'layui-btn-warm layui-btn-xs', size: 'layui-btn-xs', show: true }
|
||
};
|
||
|
||
const _customButtons = {
|
||
toolbar: {},
|
||
row: {}
|
||
};
|
||
|
||
// 工具函数
|
||
const _isArray = function (obj) {
|
||
return Object.prototype.toString.call(obj) === '[object Array]';
|
||
};
|
||
|
||
// 公共方法
|
||
return {
|
||
/**
|
||
* 获取默认工具条配置
|
||
*/
|
||
getDefaultToolbar: function () {
|
||
return Object.assign({}, _defaultToolbar);
|
||
},
|
||
|
||
/**
|
||
* 获取行工具条配置
|
||
*/
|
||
getRowToolbar: function () {
|
||
return Object.assign({}, _rowToolbar);
|
||
},
|
||
|
||
/**
|
||
* 注册自定义按钮
|
||
* @param {String} type - 按钮类型 (toolbar/row)
|
||
* @param {String} key - 按钮唯一标识
|
||
* @param {Object} config - 按钮配置
|
||
*/
|
||
registerButton: function (type, key, config) {
|
||
if (!['toolbar', 'row'].includes(type)) {
|
||
console.error('按钮类型必须是 toolbar 或 row');
|
||
return false;
|
||
}
|
||
|
||
if (!_customButtons[type]) {
|
||
_customButtons[type] = {};
|
||
}
|
||
|
||
_customButtons[type][key] = Object.assign({
|
||
title: key,
|
||
layEvent: key,
|
||
icon: 'layui-icon-more',
|
||
permission: key,
|
||
color: 'layui-btn-primary',
|
||
size: '',
|
||
show: true
|
||
}, config);
|
||
|
||
return true;
|
||
},
|
||
|
||
/**
|
||
* 获取工具条配置
|
||
* @param {String} type - toolbar/row
|
||
* @param {Array} keys - 需要的按钮key列表
|
||
* @param {Object} customConfig - 自定义配置(覆盖默认配置)
|
||
* @returns {Array} 配置数组
|
||
*/
|
||
getToolbarConfig: function (type, keys = [], customConfig = {}) {
|
||
const baseConfig = type === 'toolbar' ? _defaultToolbar : _rowToolbar;
|
||
const customBtns = _customButtons[type] || {};
|
||
|
||
// 合并基础配置和自定义配置
|
||
const allConfig = Object.assign({}, baseConfig, customBtns);
|
||
|
||
// 应用自定义配置覆盖
|
||
Object.keys(customConfig).forEach(key => {
|
||
if (allConfig[key]) {
|
||
allConfig[key] = Object.assign(allConfig[key], customConfig[key]);
|
||
}
|
||
});
|
||
|
||
// 如果指定了keys,只返回指定的按钮
|
||
if (keys.length > 0) {
|
||
return keys.map(key => allConfig[key]).filter(Boolean);
|
||
}
|
||
|
||
// 返回所有配置
|
||
return Object.values(allConfig).filter(btn => btn.show !== false);
|
||
},
|
||
|
||
/**
|
||
* 获取单个按钮配置
|
||
* @param {String} type - toolbar/row
|
||
* @param {String} key - 按钮key
|
||
* @returns {Object} 按钮配置
|
||
*/
|
||
getButtonConfig: function (type, key) {
|
||
const config = this.getToolbarConfig(type);
|
||
return config.find(btn => btn.layEvent === key || (btn.permission && btn.permission.includes(key)));
|
||
},
|
||
|
||
/**
|
||
* 批量注册按钮
|
||
* @param {String} type - 按钮类型
|
||
* @param {Object} buttons - 按钮配置对象
|
||
*/
|
||
registerButtons: function (type, buttons) {
|
||
Object.keys(buttons).forEach(key => {
|
||
this.registerButton(type, key, buttons[key]);
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 清除自定义按钮
|
||
* @param {String} type - 按钮类型
|
||
* @param {String} key - 按钮key,不传则清除所有
|
||
*/
|
||
clearCustomButtons: function (type, key) {
|
||
if (key) {
|
||
delete _customButtons[type]?.[key];
|
||
} else {
|
||
_customButtons[type] = {};
|
||
}
|
||
}
|
||
};
|
||
})();
|
||
|
||
/**
|
||
* =============================================
|
||
* 权限验证工具类
|
||
* =============================================
|
||
*/
|
||
const Auth = (function () {
|
||
// 私有变量
|
||
let _permissions = [];
|
||
let _permissionCache = {};
|
||
let _user = null;
|
||
let _controller = null; // 当前页面对应的控制器(用于裸动作 token 解析)
|
||
|
||
// 工具函数
|
||
const _isArray = function (obj) {
|
||
return Object.prototype.toString.call(obj) === '[object Array]';
|
||
};
|
||
|
||
const _isString = function (obj) {
|
||
return typeof obj === 'string';
|
||
};
|
||
|
||
// 前端短词 → 后端动作 同义词(按钮配置常用 create,权限 key 用 add)
|
||
const _synonyms = {
|
||
create: 'add',
|
||
recycle: 'recyclebin',
|
||
batch_delete: 'delete',
|
||
batchDelete: 'delete'
|
||
};
|
||
|
||
const _splitPermissions = function (perm) {
|
||
if (_isArray(perm)) return perm;
|
||
if (_isString(perm)) return perm.split(',').map(p => p.trim());
|
||
return [];
|
||
};
|
||
|
||
// 公共方法
|
||
return {
|
||
/**
|
||
* 初始化权限
|
||
* @param {Array} permissions - 用户权限列表
|
||
* @param {Object} user - 用户信息
|
||
*/
|
||
init: function (permissions = [], user = null) {
|
||
_permissions = permissions || [];
|
||
_user = user;
|
||
_controller = null;
|
||
this.clearCache();
|
||
},
|
||
|
||
/**
|
||
* 获取当前用户
|
||
* @returns {Object} 用户信息
|
||
*/
|
||
getUser: function () {
|
||
return _user;
|
||
},
|
||
|
||
/**
|
||
* 设置当前用户
|
||
* @param {Object} user - 用户信息
|
||
*/
|
||
setUser: function (user) {
|
||
_user = user;
|
||
},
|
||
|
||
/**
|
||
* 获取权限列表
|
||
* @returns {Array} 权限列表
|
||
*/
|
||
getPermissions: function () {
|
||
return _permissions;
|
||
},
|
||
|
||
/**
|
||
* 设置当前页面对应的控制器(用于裸动作 token 解析,如 has('view') → admin:view)
|
||
*/
|
||
setController: function (controller) {
|
||
_controller = controller || null;
|
||
this.clearCache();
|
||
return this;
|
||
},
|
||
|
||
/**
|
||
* 检查单个权限
|
||
* 支持:
|
||
* - 精确 key:admin:edit
|
||
* - 控制器通配:admin:*(覆盖该控制器下所有动作)
|
||
* - 超级管理员:* / *:*
|
||
* - 裸动作 token(结合 setController):view → admin:view,create → admin:add(同义词)
|
||
* @param {String} permission - 权限标识
|
||
* @returns {Boolean}
|
||
*/
|
||
has: function (permission) {
|
||
if (!permission) return true;
|
||
|
||
// 使用缓存
|
||
if (_permissionCache[permission] !== undefined) {
|
||
return _permissionCache[permission];
|
||
}
|
||
|
||
const perms = _splitPermissions(permission);
|
||
const result = perms.some(p => this._match(p));
|
||
_permissionCache[permission] = result;
|
||
return result;
|
||
},
|
||
|
||
/**
|
||
* 单个权限标识匹配(内部)
|
||
*/
|
||
_match: function (p) {
|
||
if (!p) return true;
|
||
|
||
// 精确匹配
|
||
if (_permissions.indexOf(p) > -1) return true;
|
||
|
||
// 超级管理员放行
|
||
if (_permissions.indexOf('*') > -1 || _permissions.indexOf('*:*') > -1) return true;
|
||
|
||
// 完整 key:controller:action / controller:*
|
||
if (p.indexOf(':') > -1) {
|
||
const parts = p.split(':');
|
||
const ctrl = parts[0];
|
||
const act = parts[1];
|
||
if (act === '*') {
|
||
return _permissions.indexOf(ctrl + ':*') > -1;
|
||
}
|
||
return _permissions.indexOf(ctrl + ':' + act) > -1
|
||
|| _permissions.indexOf(ctrl + ':*') > -1;
|
||
}
|
||
|
||
// 裸动作 token:结合当前控制器解析(含同义词)
|
||
const action = _synonyms[p] || p;
|
||
if (_controller) {
|
||
if (_permissions.indexOf(_controller + ':*') > -1) return true;
|
||
if (_permissions.indexOf(_controller + ':' + action) > -1) return true;
|
||
}
|
||
return false;
|
||
},
|
||
|
||
/**
|
||
* 检查多个权限(满足一个即可)
|
||
* @param {Array} permissions - 权限列表
|
||
* @returns {Boolean}
|
||
*/
|
||
hasAny: function (permissions) {
|
||
if (!_isArray(permissions) || permissions.length === 0) return false;
|
||
return permissions.some(p => this.has(p));
|
||
},
|
||
|
||
/**
|
||
* 检查所有权限
|
||
* @param {Array} permissions - 权限列表
|
||
* @returns {Boolean}
|
||
*/
|
||
hasAll: function (permissions) {
|
||
if (!_isArray(permissions) || permissions.length === 0) return false;
|
||
return permissions.every(p => this.has(p));
|
||
},
|
||
|
||
/**
|
||
* 检查权限并返回权限标识
|
||
* @param {String|Array} permissions - 权限标识
|
||
* @returns {String|Boolean} 有权限返回权限标识,无权限返回false
|
||
*/
|
||
check: function (permissions) {
|
||
if (_isArray(permissions)) {
|
||
for (let p of permissions) {
|
||
if (this.has(p)) {
|
||
return p;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
return this.has(permissions) ? permissions : false;
|
||
},
|
||
|
||
/**
|
||
* 过滤有权限的按钮
|
||
* @param {Array} buttons - 按钮配置数组
|
||
* @returns {Array} 有权限的按钮数组
|
||
*/
|
||
filterButtons: function (buttons) {
|
||
if (!_isArray(buttons)) return [];
|
||
return buttons.filter(btn => {
|
||
// 如果没有设置permission,默认显示
|
||
if (!btn.permission) return true;
|
||
// 支持多个权限,用逗号分隔
|
||
const perms = _splitPermissions(btn.permission);
|
||
return this.hasAny(perms);
|
||
});
|
||
},
|
||
|
||
/**
|
||
* 生成工具条HTML
|
||
* @param {Array} buttons - 按钮配置数组
|
||
* @param {String} containerClass - 容器样式类
|
||
* @param {Object} options - 额外选项
|
||
* @returns {String} HTML字符串
|
||
*/
|
||
renderToolbar: function (buttons, containerClass = 'layui-btn-container', options = {}) {
|
||
const filteredButtons = this.filterButtons(buttons);
|
||
|
||
if (filteredButtons.length === 0) return '';
|
||
console.log('🔧 渲染工具条 - 需要在项目中实现',filteredButtons);
|
||
|
||
// const html = filteredButtons.map(btn => {
|
||
// const color = btn.color || 'layui-btn-primary';
|
||
// const size = btn.size || '';
|
||
// const icon = btn.icon ? `<i class="${btn.icon}"></i>` : '';
|
||
// const disabled = btn.disabled ? 'disabled' : '';
|
||
// const style = btn.style ? `style="${btn.style}"` : '';
|
||
|
||
// return `<button class="layui-btn ${color} ${size}" lay-event="${btn.layEvent}" title="${btn.title}" ${disabled} ${style}>
|
||
// ${icon}${btn.title}
|
||
// </button>`;
|
||
// }).join('');
|
||
|
||
// const containerStyle = options.containerStyle ? `style="${options.containerStyle}"` : '';
|
||
// return `<div class="${containerClass}" ${containerStyle}>${html}</div>`;
|
||
},
|
||
|
||
/**
|
||
* 生成行工具条HTML
|
||
* @param {Array} buttons - 按钮配置数组
|
||
* @param {Object} options - 额外选项
|
||
* @returns {String} HTML字符串
|
||
*/
|
||
renderRowToolbar: function (buttons, options = {}) {
|
||
const filteredButtons = this.filterButtons(buttons);
|
||
|
||
if (filteredButtons.length === 0) return '';
|
||
|
||
const html = filteredButtons.map(btn => {
|
||
const color = btn.color || 'layui-btn-primary layui-btn-xs';
|
||
const icon = btn.icon ? `<i class="${btn.icon}"></i>` : '';
|
||
const disabled = btn.disabled ? 'disabled' : '';
|
||
const style = btn.style ? `style="${btn.style}"` : '';
|
||
|
||
return `<a class="layui-btn ${color}" lay-event="${btn.layEvent}" title="${btn.title}" ${disabled} ${style}>
|
||
${icon}
|
||
</a>`;
|
||
}).join('');
|
||
|
||
return `<div class="layui-btn-group">${html}</div>`;
|
||
},
|
||
|
||
/**
|
||
* 清除缓存
|
||
*/
|
||
clearCache: function () {
|
||
_permissionCache = {};
|
||
},
|
||
|
||
/**
|
||
* 批量检查权限
|
||
* @param {Array} permissions - 权限列表
|
||
* @returns {Object} 权限检查结果对象
|
||
*/
|
||
batchCheck: function (permissions) {
|
||
if (!_isArray(permissions)) return {};
|
||
|
||
return permissions.reduce((result, perm) => {
|
||
result[perm] = this.has(perm);
|
||
return result;
|
||
}, {});
|
||
},
|
||
|
||
/**
|
||
* 预加载常用权限
|
||
* @param {Array} permissions - 常用权限列表
|
||
*/
|
||
preload: function (permissions = ['create', 'edit', 'delete', 'view']) {
|
||
permissions.forEach(perm => this.has(perm));
|
||
}
|
||
};
|
||
})();
|
||
|
||
/**
|
||
* =============================================
|
||
* 动态权限更新管理器
|
||
* =============================================
|
||
*/
|
||
const PermissionManager = (function () {
|
||
// 私有变量
|
||
const _listeners = [];
|
||
let _refreshTimeout = null;
|
||
|
||
// 公共方法
|
||
return {
|
||
/**
|
||
* 添加权限变更监听器
|
||
* @param {Function} callback - 回调函数
|
||
* @param {String} id - 监听器ID(用于移除)
|
||
*/
|
||
onPermissionChange: function (callback, id = null) {
|
||
_listeners.push({ callback, id });
|
||
},
|
||
|
||
/**
|
||
* 移除权限变更监听器
|
||
* @param {String} id - 监听器ID
|
||
*/
|
||
offPermissionChange: function (id) {
|
||
const index = _listeners.findIndex(l => l.id === id);
|
||
if (index !== -1) {
|
||
_listeners.splice(index, 1);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 触发权限变更
|
||
* @param {Array} newPermissions - 新的权限列表
|
||
* @param {Object} user - 用户信息
|
||
*/
|
||
triggerChange: function (newPermissions, user = null) {
|
||
// 更新权限
|
||
Auth.init(newPermissions, user);
|
||
|
||
// 保存到localStorage
|
||
if (typeof localStorage !== 'undefined') {
|
||
localStorage.setItem('permissions', JSON.stringify(newPermissions));
|
||
if (user) {
|
||
localStorage.setItem('user', JSON.stringify(user));
|
||
}
|
||
}
|
||
|
||
// 通知所有监听器
|
||
_listeners.forEach(({ callback }) => {
|
||
try {
|
||
callback(newPermissions, user);
|
||
} catch (e) {
|
||
console.error('权限变更监听器执行出错:', e);
|
||
}
|
||
});
|
||
|
||
// 防抖刷新表格
|
||
clearTimeout(_refreshTimeout);
|
||
_refreshTimeout = setTimeout(() => {
|
||
this.refreshTables();
|
||
}, 100);
|
||
},
|
||
|
||
/**
|
||
* 刷新所有表格
|
||
*/
|
||
refreshTables: function () {
|
||
console.log('🔄 刷新表格 - 需要在项目中实现');
|
||
|
||
// 触发自定义事件
|
||
const event = new CustomEvent('permissionChanged', {
|
||
detail: { permissions: Auth.getPermissions() }
|
||
});
|
||
|
||
if (typeof window !== 'undefined') {
|
||
window.dispatchEvent(event);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 从服务器同步最新权限
|
||
* @param {String} url - 权限接口地址
|
||
* @returns {Promise} 同步结果
|
||
*/
|
||
syncPermissions: function (url = '/api/user/permissions') {
|
||
// return new Promise((resolve, reject) => {
|
||
// if (typeof $ !== 'undefined' && $.ajax) {
|
||
// $.get(url, function (res) {
|
||
// if (res.code === 200 || res.success) {
|
||
// this.triggerChange(res.data.permissions || res.data, res.data.user);
|
||
// resolve(true);
|
||
// } else {
|
||
// reject(new Error(res.msg || '同步权限失败'));
|
||
// }
|
||
// }.bind(this)).fail(function (xhr) {
|
||
// reject(new Error('网络请求失败: ' + xhr.statusText));
|
||
// });
|
||
// } else if (typeof fetch !== 'undefined') {
|
||
// fetch(url)
|
||
// .then(res => res.json())
|
||
// .then(res => {
|
||
// if (res.code === 200 || res.success) {
|
||
// this.triggerChange(res.data.permissions || res.data, res.data.user);
|
||
// resolve(true);
|
||
// } else {
|
||
// reject(new Error(res.msg || '同步权限失败'));
|
||
// }
|
||
// })
|
||
// .catch(err => reject(err));
|
||
// } else {
|
||
// reject(new Error('不支持的HTTP请求方式'));
|
||
// }
|
||
// }.bind(this));
|
||
},
|
||
|
||
/**
|
||
* 清除所有监听器
|
||
*/
|
||
clearListeners: function () {
|
||
_listeners.length = 0;
|
||
}
|
||
};
|
||
})();
|
||
|
||
/**
|
||
* =============================================
|
||
* 权限按钮组件
|
||
* =============================================
|
||
*/
|
||
class AuthButton extends HTMLElement {
|
||
constructor() {
|
||
super();
|
||
this.attachShadow({ mode: 'open' });
|
||
this._clickHandler = this._handleClick.bind(this);
|
||
}
|
||
|
||
static get observedAttributes() {
|
||
return ['permission', 'text', 'icon', 'type', 'size', 'disabled'];
|
||
}
|
||
|
||
connectedCallback() {
|
||
this.render();
|
||
}
|
||
|
||
disconnectedCallback() {
|
||
this.shadowRoot.removeEventListener('click', this._clickHandler);
|
||
}
|
||
|
||
attributeChangedCallback(name, oldValue, newValue) {
|
||
if (oldValue !== newValue) {
|
||
this.render();
|
||
}
|
||
}
|
||
|
||
_handleClick(e) {
|
||
if (!this.hasAttribute('disabled')) {
|
||
this.dispatchEvent(new CustomEvent('auth-click', {
|
||
bubbles: true,
|
||
composed: true,
|
||
detail: { button: this }
|
||
}));
|
||
}
|
||
}
|
||
|
||
render() {
|
||
const permission = this.getAttribute('permission');
|
||
const text = this.getAttribute('text') || '按钮';
|
||
const icon = this.getAttribute('icon') || '';
|
||
const type = this.getAttribute('type') || 'primary';
|
||
const size = this.getAttribute('size') || '';
|
||
const disabled = this.hasAttribute('disabled');
|
||
const hasPermission = !permission || Auth.has(permission);
|
||
|
||
// 无权限时隐藏
|
||
if (!hasPermission) {
|
||
this.shadowRoot.innerHTML = '';
|
||
this.style.display = 'none';
|
||
return;
|
||
}
|
||
|
||
this.style.display = '';
|
||
const iconHtml = icon ? `<i class="${icon}"></i>` : '';
|
||
const btnClass = `layui-btn layui-btn-${type} ${size}`;
|
||
const disabledAttr = disabled ? 'disabled' : '';
|
||
|
||
this.shadowRoot.innerHTML = `
|
||
<style>
|
||
:host {
|
||
display: inline-block;
|
||
}
|
||
.layui-btn {
|
||
display: inline-block;
|
||
height: 38px;
|
||
line-height: 38px;
|
||
padding: 0 18px;
|
||
background-color: #009688;
|
||
color: #fff;
|
||
white-space: nowrap;
|
||
text-align: center;
|
||
font-size: 14px;
|
||
border: none;
|
||
border-radius: 2px;
|
||
cursor: pointer;
|
||
box-sizing: border-box;
|
||
text-decoration: none;
|
||
}
|
||
.layui-btn:hover {
|
||
opacity: 0.9;
|
||
}
|
||
.layui-btn[disabled] {
|
||
opacity: 0.5;
|
||
cursor: not-allowed;
|
||
}
|
||
.layui-btn-xs {
|
||
height: 26px;
|
||
line-height: 26px;
|
||
padding: 0 10px;
|
||
font-size: 12px;
|
||
}
|
||
.layui-btn-sm {
|
||
height: 30px;
|
||
line-height: 30px;
|
||
padding: 0 10px;
|
||
font-size: 12px;
|
||
}
|
||
.layui-btn-lg {
|
||
height: 44px;
|
||
line-height: 44px;
|
||
padding: 0 25px;
|
||
font-size: 16px;
|
||
}
|
||
.layui-btn-primary {
|
||
background-color: #fff;
|
||
color: #333;
|
||
border: 1px solid #d2d2d2;
|
||
}
|
||
.layui-btn-normal {
|
||
background-color: #1E9FFF;
|
||
}
|
||
.layui-btn-warm {
|
||
background-color: #FFB800;
|
||
}
|
||
.layui-btn-danger {
|
||
background-color: #FF5722;
|
||
}
|
||
i {
|
||
margin-right: 5px;
|
||
}
|
||
</style>
|
||
<button class="${btnClass}" ${disabledAttr}>
|
||
${iconHtml}${text}
|
||
</button>
|
||
`;
|
||
|
||
// 添加点击事件
|
||
const btn = this.shadowRoot.querySelector('button');
|
||
btn.removeEventListener('click', this._clickHandler);
|
||
btn.addEventListener('click', this._clickHandler);
|
||
}
|
||
}
|
||
|
||
// 注册自定义元素
|
||
if (typeof customElements !== 'undefined' && !customElements.get('auth-button')) {
|
||
customElements.define('auth-button', AuthButton);
|
||
}
|
||
|
||
/**
|
||
* =============================================
|
||
* 导出模块
|
||
* =============================================
|
||
*/
|
||
exports('auth', {
|
||
// 核心对象auth
|
||
Auth: Auth,
|
||
PermissionConfig: PermissionConfig,
|
||
PermissionManager: PermissionManager,
|
||
|
||
// 便捷方法(直接暴露常用方法)
|
||
init: Auth.init.bind(Auth),
|
||
setController: Auth.setController.bind(Auth),
|
||
has: Auth.has.bind(Auth),
|
||
hasAny: Auth.hasAny.bind(Auth),
|
||
hasAll: Auth.hasAll.bind(Auth),
|
||
getPermissions: Auth.getPermissions.bind(Auth),
|
||
renderToolbar: Auth.renderToolbar.bind(Auth),
|
||
renderRowToolbar: Auth.renderRowToolbar.bind(Auth),
|
||
filterButtons: Auth.filterButtons.bind(Auth),
|
||
|
||
// 配置方法
|
||
getToolbarConfig: PermissionConfig.getToolbarConfig.bind(PermissionConfig),
|
||
registerButton: PermissionConfig.registerButton.bind(PermissionConfig),
|
||
registerButtons: PermissionConfig.registerButtons.bind(PermissionConfig),
|
||
|
||
// 管理器方法
|
||
onPermissionChange: PermissionManager.onPermissionChange.bind(PermissionManager),
|
||
triggerChange: PermissionManager.triggerChange.bind(PermissionManager),
|
||
syncPermissions: PermissionManager.syncPermissions.bind(PermissionManager),
|
||
|
||
// 按钮组件
|
||
AuthButton: AuthButton
|
||
});
|
||
}); |