${typeBadge}${file.name}
@@ -3842,6 +3884,9 @@ class CLIProxyManager {
// 绑定认证文件操作按钮事件(使用事件委托)
this.bindAuthFileActionEvents();
+
+ // Reapply current filter state
+ this.applyAuthFileFilterState();
}
// 更新筛选按钮显示
@@ -3924,6 +3969,7 @@ class CLIProxyManager {
// 获取筛选类型
const filterType = clickedBtn.dataset.type;
+ this.currentAuthFileFilter = filterType || 'all';
// 筛选文件
const fileItems = document.querySelectorAll('.file-item');
@@ -3975,6 +4021,65 @@ class CLIProxyManager {
this.refreshFilterButtonTexts();
}
+ // Apply current filter selection to the list
+ applyAuthFileFilterState() {
+ const filterContainer = document.querySelector('.auth-file-filter');
+ if (!filterContainer) return;
+
+ const currentType = this.currentAuthFileFilter || 'all';
+ const buttons = filterContainer.querySelectorAll('.filter-btn');
+ if (buttons.length === 0) return;
+
+ let targetButton = null;
+ buttons.forEach(btn => {
+ if (btn.dataset.type === currentType) {
+ targetButton = btn;
+ }
+ });
+
+ if (!targetButton) {
+ targetButton = filterContainer.querySelector('.filter-btn[data-type="all"]') || buttons[0];
+ if (targetButton) {
+ this.currentAuthFileFilter = targetButton.dataset.type || 'all';
+ }
+ }
+
+ if (targetButton) {
+ this.handleFilterClick(targetButton);
+ }
+ }
+
+ // Remove deleted auth files from cache and DOM instantly
+ removeAuthFileElements(filenames = []) {
+ if (!Array.isArray(filenames) || filenames.length === 0) {
+ return;
+ }
+
+ const removalSet = new Set(filenames);
+ this.cachedAuthFiles = (this.cachedAuthFiles || []).filter(file => file && !removalSet.has(file.name));
+
+ const container = document.getElementById('auth-files-list');
+ if (!container) return;
+
+ const fileItems = container.querySelectorAll('.file-item');
+ fileItems.forEach(item => {
+ const fileNameAttr = item.getAttribute('data-file-name');
+ if (fileNameAttr && removalSet.has(fileNameAttr)) {
+ item.remove();
+ }
+ });
+
+ if (!container.querySelector('.file-item')) {
+ container.innerHTML = `
+
+
+
${i18n.t('auth_files.empty_title')}
+
${i18n.t('auth_files.empty_desc')}
+
+ `;
+ }
+ }
+
// 刷新筛选按钮文本(根据 data-i18n-text)
refreshFilterButtonTexts() {
document.querySelectorAll('.auth-file-filter .filter-btn[data-i18n-text]').forEach(btn => {
@@ -4234,23 +4339,86 @@ class CLIProxyManager {
try {
await this.makeRequest(`/auth-files?name=${encodeURIComponent(filename)}`, { method: 'DELETE' });
+ this.removeAuthFileElements([filename]);
this.clearCache(); // 清除缓存
- this.loadAuthFiles();
+ await this.loadAuthFiles();
this.showNotification(i18n.t('auth_files.delete_success'), 'success');
} catch (error) {
this.showNotification(`${i18n.t('notification.delete_failed')}: ${error.message}`, 'error');
}
}
- // 删除所有认证文件
+ // Delete auth files (respect current filter)
async deleteAllAuthFiles() {
- if (!confirm(i18n.t('auth_files.delete_all_confirm'))) return;
+ const filterType = (this.currentAuthFileFilter || 'all').toLowerCase();
+ const isFiltered = filterType !== 'all';
+ const typeLabel = this.generateDynamicTypeLabel(filterType);
+ const confirmMessage = isFiltered
+ ? i18n.t('auth_files.delete_filtered_confirm').replace('{type}', typeLabel)
+ : i18n.t('auth_files.delete_all_confirm');
+
+ if (!confirm(confirmMessage)) return;
try {
- const response = await this.makeRequest('/auth-files?all=true', { method: 'DELETE' });
+ if (!isFiltered) {
+ const response = await this.makeRequest('/auth-files?all=true', { method: 'DELETE' });
+ const currentNames = (this.cachedAuthFiles || []).map(file => file.name).filter(Boolean);
+ if (currentNames.length > 0) {
+ this.removeAuthFileElements(currentNames);
+ }
+ this.clearCache(); // 清除缓存
+ this.currentAuthFileFilter = 'all';
+ await this.loadAuthFiles();
+ this.showNotification(`${i18n.t('auth_files.delete_all_success')} ${response.deleted} ${i18n.t('auth_files.files_count')}`, 'success');
+ return;
+ }
+
+ const deletableFiles = (this.cachedAuthFiles || []).filter(file => {
+ if (!file || file.runtime_only) return false;
+ const fileType = (file.type || 'unknown').toLowerCase();
+ return fileType === filterType;
+ });
+
+ if (deletableFiles.length === 0) {
+ this.showNotification(i18n.t('auth_files.delete_filtered_none').replace('{type}', typeLabel), 'info');
+ return;
+ }
+
+ let success = 0;
+ let failed = 0;
+ const deletedNames = [];
+
+ for (const file of deletableFiles) {
+ try {
+ await this.makeRequest(`/auth-files?name=${encodeURIComponent(file.name)}`, { method: 'DELETE' });
+ success++;
+ deletedNames.push(file.name);
+ } catch (error) {
+ console.error('删除认证文件失败:', file?.name, error);
+ failed++;
+ }
+ }
+
+ if (deletedNames.length > 0) {
+ this.removeAuthFileElements(deletedNames);
+ }
+
this.clearCache(); // 清除缓存
- this.loadAuthFiles();
- this.showNotification(`${i18n.t('auth_files.delete_all_success')} ${response.deleted} ${i18n.t('auth_files.files_count')}`, 'success');
+ this.currentAuthFileFilter = 'all';
+ await this.loadAuthFiles();
+
+ if (failed === 0) {
+ const successMsg = i18n.t('auth_files.delete_filtered_success')
+ .replace('{count}', success)
+ .replace('{type}', typeLabel);
+ this.showNotification(successMsg, 'success');
+ } else {
+ const warningMsg = i18n.t('auth_files.delete_filtered_partial')
+ .replace('{success}', success)
+ .replace('{failed}', failed)
+ .replace('{type}', typeLabel);
+ this.showNotification(warningMsg, 'warning');
+ }
} catch (error) {
this.showNotification(`${i18n.t('notification.delete_failed')}: ${error.message}`, 'error');
}
diff --git a/i18n.js b/i18n.js
index 6d2eb44..ae07fc2 100644
--- a/i18n.js
+++ b/i18n.js
@@ -225,11 +225,15 @@ const i18n = {
'auth_files.delete_button': '删除',
'auth_files.delete_confirm': '确定要删除文件',
'auth_files.delete_all_confirm': '确定要删除所有认证文件吗?此操作不可恢复!',
+ 'auth_files.delete_filtered_confirm': '确定要删除筛选出的 {type} 认证文件吗?此操作不可恢复!',
'auth_files.upload_error_json': '只能上传JSON文件',
'auth_files.upload_success': '文件上传成功',
'auth_files.download_success': '文件下载成功',
'auth_files.delete_success': '文件删除成功',
'auth_files.delete_all_success': '成功删除',
+ 'auth_files.delete_filtered_success': '成功删除 {count} 个 {type} 认证文件',
+ 'auth_files.delete_filtered_partial': '{type} 认证文件删除完成,成功 {success} 个,失败 {failed} 个',
+ 'auth_files.delete_filtered_none': '当前筛选类型 ({type}) 下没有可删除的认证文件',
'auth_files.files_count': '个文件',
'auth_files.filter_all': '全部',
'auth_files.filter_qwen': 'Qwen',
@@ -684,11 +688,15 @@ const i18n = {
'auth_files.delete_button': 'Delete',
'auth_files.delete_confirm': 'Are you sure you want to delete file',
'auth_files.delete_all_confirm': 'Are you sure you want to delete all auth files? This operation cannot be undone!',
+ 'auth_files.delete_filtered_confirm': 'Are you sure you want to delete all {type} auth files? This operation cannot be undone!',
'auth_files.upload_error_json': 'Only JSON files are allowed',
'auth_files.upload_success': 'File uploaded successfully',
'auth_files.download_success': 'File downloaded successfully',
'auth_files.delete_success': 'File deleted successfully',
'auth_files.delete_all_success': 'Successfully deleted',
+ 'auth_files.delete_filtered_success': 'Deleted {count} {type} auth files successfully',
+ 'auth_files.delete_filtered_partial': '{type} auth files deletion finished: {success} succeeded, {failed} failed',
+ 'auth_files.delete_filtered_none': 'No deletable auth files under the current filter ({type})',
'auth_files.files_count': 'files',
'auth_files.filter_all': 'All',
'auth_files.filter_qwen': 'Qwen',