/** * AuthManagerComponent - 认证授权管理组件 * * 功能特性: * - JWT Token 管理 * - API Key 生成和撤销 * - OAuth 客户端管理 * - 角色和权限管理 * - 登录日志查看 * - 会话管理 * * @example * const authManager = new AuthManagerComponent('#auth-manager-container', { * apiBaseUrl: '', // ✅ 修改为相对路径,通过同域名 nginx 转发到后端 8001 端口 * onRoleCreate: async (role) => { * await authAPIAdapter.post('/roles', role); * }, * onApiKeyGenerate: async (userId, permissions) => { * await authAPIAdapter.post('/api-keys', { user_id: userId, permissions }); * } * }); */ (function(global) { 'use strict'; class AuthManagerComponent { constructor(containerSelector, options = {}) { // 容器选择器 this.container = typeof containerSelector === 'string' ? document.querySelector(containerSelector) : containerSelector; if (!this.container) { console.error(`AuthManager: 未找到容器 ${containerSelector}`); return; } // 配置项 this.options = { apiBaseUrl: options.apiBaseUrl || '', // ✅ 修改为相对路径(通过同域名 nginx 转发到后端 8001 端口) onRoleCreate: options.onRoleCreate || null, onApiKeyGenerate: options.onApiKeyGenerate || null }; // 状态 this.roles = []; this.apiKeys = []; this.oauthClients = []; this.loginLogs = []; // DOM 元素 this.element = null; // 初始化 this.initialize(); } /** * 初始化组件 */ async initialize() { this.render(); this.bindEvents(); await this.loadRoles(); await this.loadApiKeys(); await this.loadLoginLogs(); } /** * 渲染组件 */ render() { this.container.innerHTML = `
`; this.element = this.container.querySelector('.auth-manager'); } /** * 绑定事件 */ bindEvents() { // 委托标签页切换 this.container.querySelector('.tabs-nav').addEventListener('click', (e) => { const tabBtn = e.target.closest('.tab-btn'); if (tabBtn) { this.switchTab(tabBtn.dataset.tab); } }); // 委托操作按钮 this.container.addEventListener('click', (e) => { if (e.target.classList.contains('btn-create-role')) { this.createRole(); } if (e.target.classList.contains('btn-generate-key')) { this.generateApiKey(); } if (e.target.classList.contains('btn-revoke-key')) { const keyId = e.target.dataset.keyId; this.revokeApiKey(keyId); } }); } /** * 加载角色列表 */ async loadRoles() { try { // TODO: API 调用 // const response = await authAPIAdapter.get('/roles'); // this.roles = response.data.roles; this.roles = [ { id: 1, name: '超级管理员', code: 'super_admin', users: 3, permissions: ['all'] }, { id: 2, name: '系统管理员', code: 'system_admin', users: 8, permissions: ['system.manage', 'users.view'] }, { id: 3, name: '普通用户', code: 'user', users: 156, permissions: ['dashboard.view'] }, { id: 4, name: '访客', code: 'guest', users: 45, permissions: ['public.view'] } ]; if (!this.currentTab) { this.currentTab = 'roles'; this.renderTabsNav(); this.renderRolesTab(); } } catch (error) { console.error('加载角色失败:', error); } } /** * 加载 API Keys */ async loadApiKeys() { try { // TODO: API 调用 // const response = await authAPIAdapter.get('/api-keys'); // this.apiKeys = response.data.keys; this.apiKeys = Array.from({ length: 10 }, (_, i) => ({ id: `key_${i + 1}`, name: `API Key ${i + 1}`, key_prefix: `sk_${Math.random().toString(36).substring(2, 8)}...`, owner: `用户${i + 1}`, permissions: ['read', 'write', 'delete'].slice(0, Math.floor(Math.random() * 3) + 1), created_at: `2026-03-${String(1 + i % 15).padStart(2, '0')}`, last_used: `2026-03-${String(10 + i % 6).padStart(2, '0')} 14:30:00`, status: ['active', 'revoked'][i % 2] })); if (this.currentTab === 'api-keys') { this.renderApiKeysTab(); } } catch (error) { console.error('加载 API Keys 失败:', error); } } /** * 加载登录日志 */ async loadLoginLogs() { try { // TODO: API 调用 // const response = await authAPIAdapter.get('/login-logs'); // this.loginLogs = response.data.logs; this.loginLogs = Array.from({ length: 50 }, (_, i) => ({ id: i + 1, user: `用户${i + 1}`, ip: `192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`, location: '北京', browser: ['Chrome', 'Firefox', 'Safari', 'Edge'][i % 4], os: ['Windows', 'macOS', 'Linux'][i % 3], status: ['success', 'failed'][i % 5], time: `2026-03-${String(1 + i % 15).padStart(2, '0')} ${String(8 + i % 12).padStart(2, '0')}:00:00` })); if (this.currentTab === 'login-logs') { this.renderLoginLogsTab(); } } catch (error) { console.error('加载登录日志失败:', error); } } /** * 渲染标签页导航 */ renderTabsNav() { const container = this.container.querySelector('.tabs-nav'); const tabs = [ { id: 'roles', label: '🔐 角色管理' }, { id: 'api-keys', label: '🔑 API Keys' }, { id: 'oauth', label: '🌐 OAuth 应用' }, { id: 'login-logs', label: '📋 登录日志' } ]; container.innerHTML = tabs.map(tab => ` `).join(''); } /** * 切换标签页 */ switchTab(tabName) { this.currentTab = tabName; this.renderTabsNav(); const contentContainer = this.container.querySelector('.tab-content'); contentContainer.innerHTML = ''; switch(tabName) { case 'roles': this.renderRolesTab(); break; case 'api-keys': this.renderApiKeysTab(); break; case 'oauth': this.renderOauthTab(); break; case 'login-logs': this.renderLoginLogsTab(); break; } } /** * 渲染角色管理标签页 */ renderRolesTab() { const container = this.container.querySelector('.tab-content'); container.innerHTML = `

角色列表

${this.roles.map(role => `

${role.name}

代码:${role.code}
${role.users} 人
权限:
${role.permissions.slice(0, 3).map(perm => ` ${perm} `).join('')} ${role.permissions.length > 3 ? `+${role.permissions.length - 3} 更多` : ''}
`).join('')}
`; } /** * 渲染 API Keys 标签页 */ renderApiKeysTab() { const container = this.container.querySelector('.tab-content'); container.innerHTML = `

API Keys 管理

${this.apiKeys.map(key => { const statusConfig = { 'active': { label: '有效', color: '#28a745', bg: '#d4edda' }, 'revoked': { label: '已撤销', color: '#dc3545', bg: '#f8d7da' } }; const status = statusConfig[key.status]; return ` `; }).join('')}
名称 Key 所有者 权限 创建时间 最后使用 状态 操作
${key.name} ${key.key_prefix} ${key.owner} ${key.permissions.map(p => ` ${p} `).join('')} ${key.created_at} ${key.last_used} ${status.label} ${key.status === 'active' ? ` ` : '已失效'}
`; } /** * 渲染 OAuth 应用标签页 */ renderOauthTab() { const container = this.container.querySelector('.tab-content'); container.innerHTML = `

OAuth 应用管理

🌐
暂无 OAuth 应用
点击"创建应用"开始配置第三方接入
`; } /** * 渲染登录日志标签页 */ renderLoginLogsTab() { const container = this.container.querySelector('.tab-content'); container.innerHTML = `
${this.loginLogs.map(log => { const statusConfig = { 'success': { label: '成功', color: '#28a745', bg: '#d4edda' }, 'failed': { label: '失败', color: '#dc3545', bg: '#f8d7da' } }; const status = statusConfig[log.status]; return ` `; }).join('')}
用户 IP 地址 地点 浏览器/系统 状态 时间
${log.user} ${log.ip} ${log.location} ${log.browser} / ${log.os} ${status.label} ${log.time}
`; } /** * 创建角色 */ async createRole() { if (global.Dialog) { try { await Dialog.show({ title: '创建角色', content: `
` }); if (this.options.onRoleCreate) { await this.options.onRoleCreate({}); } if (global.showToast) { showToast.success('角色创建成功!'); } } catch (error) { if (error !== 'cancelled') { console.error('创建角色失败:', error); } } } } /** * 生成 API Key */ async generateApiKey() { if (global.Dialog) { try { const result = await Dialog.prompt('请输入 Key 名称', { placeholder: '例如:生产环境 API Key' }); if (this.options.onApiKeyGenerate) { await this.options.onApiKeyGenerate(result, []); } if (global.showToast) { showToast.success('API Key 生成成功!'); } // 重新加载列表 await this.loadApiKeys(); } catch (error) { if (error !== 'cancelled') { console.error('生成 API Key 失败:', error); } } } } /** * 撤销 API Key */ async revokeApiKey(keyId) { if (confirm('确定要撤销这个 API Key 吗?撤销后将无法恢复。')) { try { // TODO: API 调用 // await authAPIAdapter.delete(`/api-keys/${keyId}`); // 更新本地状态 const key = this.apiKeys.find(k => k.id === keyId); if (key) { key.status = 'revoked'; this.renderApiKeysTab(); } if (global.showToast) { showToast.success('API Key 已撤销'); } } catch (error) { console.error('撤销 API Key 失败:', error); if (global.showToast) { showToast.error('操作失败:' + error.message); } } } } /** * 销毁组件 */ destroy() { this.container.innerHTML = ''; } } // 导出到全局 global.AuthManagerComponent = AuthManagerComponent; })(typeof window !== 'undefined' ? window : this);