-
${file.name}
-
${i18n.t('auth_files.file_size')}: ${this.formatFileSize(file.size)}
-
${i18n.t('auth_files.file_modified')}: ${new Date(file.modtime).toLocaleString(i18n.currentLanguage === 'zh-CN' ? 'zh-CN' : 'en-US')}
-
-
- ${i18n.t('stats.success')}: ${fileStats.success}
-
-
- ${i18n.t('stats.failure')}: ${fileStats.failure}
-
+
${typeBadge}${file.name}
+
+ ${i18n.t('auth_files.file_modified')}: ${new Date(file.modtime).toLocaleString(i18n.currentLanguage === 'zh-CN' ? 'zh-CN' : 'en-US')}
+ ${i18n.t('auth_files.file_size')}: ${this.formatFileSize(file.size)}
+
+
-
-
-
-
`;
}).join('');
+
+ // 绑定筛选按钮事件
+ this.bindAuthFileFilterEvents();
+ }
+
+ // 更新筛选按钮显示
+ updateFilterButtons(existingTypes) {
+ const filterContainer = document.querySelector('.auth-file-filter');
+ if (!filterContainer) return;
+
+ // 预定义的按钮顺序和显示文本
+ const predefinedTypes = [
+ { type: 'all', label: 'All' },
+ { type: 'qwen', label: 'Qwen' },
+ { type: 'gemini', label: 'Gemini' },
+ { type: 'claude', label: 'Claude' },
+ { type: 'codex', label: 'Codex' },
+ { type: 'iflow', label: 'iFlow' },
+ { type: 'empty', label: 'Empty' }
+ ];
+
+ // 获取现有按钮
+ const existingButtons = filterContainer.querySelectorAll('.filter-btn');
+ const existingButtonTypes = new Set();
+ existingButtons.forEach(btn => {
+ existingButtonTypes.add(btn.dataset.type);
+ });
+
+ // 显示/隐藏预定义按钮
+ existingButtons.forEach(btn => {
+ const btnType = btn.dataset.type;
+ if (existingTypes.has(btnType)) {
+ btn.style.display = 'inline-block';
+ } else {
+ btn.style.display = 'none';
+ }
+ });
+
+ // 为未知类型添加新按钮
+ const predefinedTypeSet = new Set(predefinedTypes.map(t => t.type));
+ existingTypes.forEach(type => {
+ if (type !== 'all' && !predefinedTypeSet.has(type) && !existingButtonTypes.has(type)) {
+ // 创建新按钮
+ const btn = document.createElement('button');
+ btn.className = 'filter-btn';
+ btn.dataset.type = type;
+ // 首字母大写
+ btn.textContent = type.charAt(0).toUpperCase() + type.slice(1);
+
+ // 插入到 Empty 按钮之前(如果存在)
+ const emptyBtn = filterContainer.querySelector('[data-type="empty"]');
+ if (emptyBtn) {
+ filterContainer.insertBefore(btn, emptyBtn);
+ } else {
+ filterContainer.appendChild(btn);
+ }
+
+ // 添加点击事件
+ btn.addEventListener('click', (e) => {
+ this.handleFilterClick(e.target);
+ });
+ }
+ });
+ }
+
+ // 处理筛选按钮点击
+ handleFilterClick(clickedBtn) {
+ const filterBtns = document.querySelectorAll('.auth-file-filter .filter-btn');
+
+ // 更新按钮状态
+ filterBtns.forEach(b => b.classList.remove('active'));
+ clickedBtn.classList.add('active');
+
+ // 获取筛选类型
+ const filterType = clickedBtn.dataset.type;
+
+ // 筛选文件
+ const fileItems = document.querySelectorAll('.file-item');
+ fileItems.forEach(item => {
+ if (filterType === 'all' || item.dataset.fileType === filterType) {
+ item.style.display = 'flex';
+ } else {
+ item.style.display = 'none';
+ }
+ });
+ }
+
+ // 绑定认证文件筛选事件
+ bindAuthFileFilterEvents() {
+ const filterBtns = document.querySelectorAll('.auth-file-filter .filter-btn');
+ filterBtns.forEach(btn => {
+ btn.addEventListener('click', (e) => {
+ this.handleFilterClick(e.target);
+ });
+ });
}
// 格式化文件大小
@@ -3198,6 +3322,104 @@ class CLIProxyManager {
event.target.value = '';
}
+ // 显示认证文件详细信息
+ async showAuthFileDetails(filename) {
+ try {
+ const response = await fetch(`${this.apiUrl}/auth-files/download?name=${encodeURIComponent(filename)}`, {
+ headers: {
+ 'Authorization': `Bearer ${this.managementKey}`
+ }
+ });
+
+ if (!response.ok) {
+ throw new Error(`HTTP ${response.status}`);
+ }
+
+ const jsonData = await response.json();
+
+ // 格式化JSON数据
+ const formattedJson = JSON.stringify(jsonData, null, 2);
+
+ // 显示模态框
+ this.showJsonModal(filename, formattedJson);
+ } catch (error) {
+ this.showNotification(`读取文件详情失败: ${error.message}`, 'error');
+ }
+ }
+
+ // 显示JSON模态框
+ showJsonModal(filename, jsonContent) {
+ // 创建模态框HTML
+ const modalHtml = `
+
+
+
+
+
${this.escapeHtml(jsonContent)}
+
+
+
+
+ `;
+
+ // 移除旧的模态框(如果存在)
+ const oldModal = document.getElementById('json-modal');
+ if (oldModal) {
+ oldModal.remove();
+ }
+
+ // 添加新模态框
+ document.body.insertAdjacentHTML('beforeend', modalHtml);
+
+ // 添加点击背景关闭功能
+ const modal = document.getElementById('json-modal');
+ modal.addEventListener('click', (e) => {
+ if (e.target === modal) {
+ this.closeJsonModal();
+ }
+ });
+ }
+
+ // 关闭JSON模态框
+ closeJsonModal() {
+ const modal = document.getElementById('json-modal');
+ if (modal) {
+ modal.remove();
+ }
+ }
+
+ // 复制JSON内容
+ copyJsonContent() {
+ const jsonContent = document.querySelector('.json-content');
+ if (jsonContent) {
+ const text = jsonContent.textContent;
+ navigator.clipboard.writeText(text).then(() => {
+ this.showNotification('内容已复制到剪贴板', 'success');
+ }).catch(() => {
+ this.showNotification('复制失败', 'error');
+ });
+ }
+ }
+
+ // HTML转义函数
+ escapeHtml(text) {
+ const div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+ }
+
// 下载认证文件
async downloadAuthFile(filename) {
try {
diff --git a/i18n.js b/i18n.js
index c9580de..391f4ec 100644
--- a/i18n.js
+++ b/i18n.js
@@ -40,6 +40,7 @@ const i18n = {
'common.alias': '别名',
'common.failure': '失败',
'common.unknown_error': '未知错误',
+ 'common.copy': '复制',
// 页面标题
'title.main': 'CLI Proxy API Management Center',
@@ -466,6 +467,7 @@ const i18n = {
'common.alias': 'Alias',
'common.failure': 'Failure',
'common.unknown_error': 'Unknown error',
+ 'common.copy': 'Copy',
// Page titles
'title.main': 'CLI Proxy API Management Center',
diff --git a/index.html b/index.html
index 885105b..223804c 100644
--- a/index.html
+++ b/index.html
@@ -418,9 +418,21 @@
-