Spaces:
Running
Running
File size: 5,043 Bytes
ceb3821 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | import { t } from './i18n.js';
import { showToast, apiRequest } from './utils.js';
// 插件列表状态
let pluginsList = [];
/**
* 初始化插件管理器
*/
export function initPluginManager() {
const refreshBtn = document.getElementById('refreshPluginsBtn');
if (refreshBtn) {
refreshBtn.addEventListener('click', loadPlugins);
}
// 初始加载
loadPlugins();
}
/**
* 加载插件列表
*/
export async function loadPlugins() {
const loadingEl = document.getElementById('pluginsLoading');
const emptyEl = document.getElementById('pluginsEmpty');
const listEl = document.getElementById('pluginsList');
const totalEl = document.getElementById('totalPlugins');
const enabledEl = document.getElementById('enabledPlugins');
const disabledEl = document.getElementById('disabledPlugins');
if (loadingEl) loadingEl.style.display = 'block';
if (emptyEl) emptyEl.style.display = 'none';
if (listEl) listEl.innerHTML = '';
try {
const response = await apiRequest('/api/plugins');
if (response && response.plugins) {
pluginsList = response.plugins;
renderPluginsList();
// 更新统计信息
if (totalEl) totalEl.textContent = pluginsList.length;
if (enabledEl) enabledEl.textContent = pluginsList.filter(p => p.enabled).length;
if (disabledEl) disabledEl.textContent = pluginsList.filter(p => !p.enabled).length;
} else {
if (emptyEl) emptyEl.style.display = 'flex';
}
} catch (error) {
console.error('Failed to load plugins:', error);
showToast(t('common.error'), t('plugins.load.failed'), 'error');
if (emptyEl) emptyEl.style.display = 'flex';
} finally {
if (loadingEl) loadingEl.style.display = 'none';
}
}
/**
* 渲染插件列表
*/
function renderPluginsList() {
const listEl = document.getElementById('pluginsList');
const emptyEl = document.getElementById('pluginsEmpty');
if (!listEl) return;
if (pluginsList.length === 0) {
if (emptyEl) emptyEl.style.display = 'flex';
return;
}
if (emptyEl) emptyEl.style.display = 'none';
pluginsList.forEach(plugin => {
const card = document.createElement('div');
card.className = `plugin-card ${plugin.enabled ? 'enabled' : 'disabled'}`;
// 构建标签 HTML
let badgesHtml = '';
if (plugin.hasMiddleware) {
badgesHtml += `<span class="plugin-badge middleware" title="${t('plugins.badge.middleware.title')}">Middleware</span>`;
}
if (plugin.hasRoutes) {
badgesHtml += `<span class="plugin-badge routes" title="${t('plugins.badge.routes.title')}">Routes</span>`;
}
if (plugin.hasHooks) {
badgesHtml += `<span class="plugin-badge hooks" title="${t('plugins.badge.hooks.title')}">Hooks</span>`;
}
card.innerHTML = `
<div class="plugin-header">
<div class="plugin-title">
<h3>${plugin.name}</h3>
<span class="plugin-version">v${plugin.version}</span>
</div>
<div class="plugin-actions">
<label class="toggle-switch">
<input type="checkbox" ${plugin.enabled ? 'checked' : ''} onchange="window.togglePlugin('${plugin.name}', this.checked)">
<span class="toggle-slider"></span>
</label>
</div>
</div>
<div class="plugin-description">${plugin.description || t('plugins.noDescription')}</div>
<div class="plugin-badges">
${badgesHtml}
</div>
<div class="plugin-status">
<i class="fas fa-circle"></i> <span>${plugin.enabled ? t('plugins.status.enabled') : t('plugins.status.disabled')}</span>
</div>
`;
listEl.appendChild(card);
});
}
/**
* 切换插件启用状态
* @param {string} pluginName - 插件名称
* @param {boolean} enabled - 是否启用
*/
export async function togglePlugin(pluginName, enabled) {
try {
await apiRequest(`/api/plugins/${encodeURIComponent(pluginName)}/toggle`, {
method: 'POST',
body: JSON.stringify({ enabled })
});
showToast(t('common.success'), t('plugins.toggle.success', { name: pluginName, status: enabled ? t('common.enabled') : t('common.disabled') }), 'success');
// 重新加载列表以更新状态
loadPlugins();
// 提示需要重启
showToast(t('common.info'), t('plugins.restart.required'), 'info');
} catch (error) {
console.error(`Failed to toggle plugin ${pluginName}:`, error);
showToast(t('common.error'), t('plugins.toggle.failed'), 'error');
// 恢复开关状态
loadPlugins();
}
} |