mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-02 19:00:49 +08:00
feat(app.js, i18n): support batch addition of Gemini API keys with enhanced UI
- Updated the Gemini API key modal to allow input of multiple keys, each on a new line. - Added a hint for users on how to input multiple keys and updated the corresponding internationalization strings. - Enhanced the key addition logic to handle success, skipped, and failed counts, providing detailed feedback to users. - Improved error handling and notifications for batch operations.
This commit is contained in:
88
app.js
88
app.js
@@ -2526,7 +2526,8 @@ class CLIProxyManager {
|
||||
<h3>${i18n.t('ai_providers.gemini_add_modal_title')}</h3>
|
||||
<div class="form-group">
|
||||
<label for="new-gemini-key">${i18n.t('ai_providers.gemini_add_modal_key_label')}</label>
|
||||
<input type="text" id="new-gemini-key" placeholder="${i18n.t('ai_providers.gemini_add_modal_key_placeholder')}">
|
||||
<textarea id="new-gemini-key" rows="6" placeholder="${i18n.t('ai_providers.gemini_add_modal_key_placeholder')}"></textarea>
|
||||
<p class="form-hint">${i18n.t('ai_providers.gemini_add_modal_key_hint')}</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="new-gemini-url">${i18n.t('ai_providers.gemini_add_modal_url_label')}</label>
|
||||
@@ -2543,35 +2544,90 @@ class CLIProxyManager {
|
||||
|
||||
// 添加Gemini密钥
|
||||
async addGeminiKey() {
|
||||
const newKey = document.getElementById('new-gemini-key').value.trim();
|
||||
const keyInput = document.getElementById('new-gemini-key');
|
||||
const baseUrlInput = document.getElementById('new-gemini-url');
|
||||
if (!keyInput) {
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = keyInput.value
|
||||
.split('\n')
|
||||
.map(line => line.trim())
|
||||
.filter(line => line.length > 0);
|
||||
const baseUrl = baseUrlInput ? baseUrlInput.value.trim() : '';
|
||||
|
||||
if (!newKey) {
|
||||
this.showNotification(i18n.t('notification.please_enter') + ' ' + i18n.t('notification.gemini_api_key'), 'error');
|
||||
if (keys.length === 0) {
|
||||
this.showNotification(i18n.t('notification.gemini_multi_input_required'), 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await this.makeRequest('/gemini-api-key');
|
||||
const currentKeys = data['gemini-api-key'] || [];
|
||||
const newConfig = { 'api-key': newKey };
|
||||
if (baseUrl) {
|
||||
newConfig['base-url'] = baseUrl;
|
||||
}
|
||||
currentKeys.push(newConfig);
|
||||
let currentKeys = Array.isArray(data['gemini-api-key']) ? data['gemini-api-key'] : [];
|
||||
const existingKeys = new Set(currentKeys.map(item => item && item['api-key']).filter(Boolean));
|
||||
const batchSeen = new Set();
|
||||
|
||||
await this.makeRequest('/gemini-api-key', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(currentKeys)
|
||||
});
|
||||
let successCount = 0;
|
||||
let skippedCount = 0;
|
||||
let failedCount = 0;
|
||||
|
||||
for (const apiKey of keys) {
|
||||
if (!apiKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (batchSeen.has(apiKey)) {
|
||||
skippedCount++;
|
||||
continue;
|
||||
}
|
||||
batchSeen.add(apiKey);
|
||||
|
||||
if (existingKeys.has(apiKey)) {
|
||||
skippedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const newConfig = { 'api-key': apiKey };
|
||||
if (baseUrl) {
|
||||
newConfig['base-url'] = baseUrl;
|
||||
} else {
|
||||
delete newConfig['base-url'];
|
||||
}
|
||||
|
||||
const nextKeys = [...currentKeys, newConfig];
|
||||
|
||||
try {
|
||||
await this.makeRequest('/gemini-api-key', {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify(nextKeys)
|
||||
});
|
||||
currentKeys = nextKeys;
|
||||
existingKeys.add(apiKey);
|
||||
successCount++;
|
||||
} catch (error) {
|
||||
failedCount++;
|
||||
console.error('Gemini key add failed:', error);
|
||||
}
|
||||
}
|
||||
|
||||
this.clearCache(); // 清除缓存
|
||||
this.closeModal();
|
||||
this.loadGeminiKeys();
|
||||
this.showNotification(i18n.t('notification.gemini_key_added'), 'success');
|
||||
|
||||
if (successCount === 1 && skippedCount === 0 && failedCount === 0) {
|
||||
this.showNotification(i18n.t('notification.gemini_key_added'), 'success');
|
||||
return;
|
||||
}
|
||||
|
||||
const summaryTemplate = i18n.t('notification.gemini_multi_summary');
|
||||
const summary = summaryTemplate
|
||||
.replace('{success}', successCount)
|
||||
.replace('{skipped}', skippedCount)
|
||||
.replace('{failed}', failedCount);
|
||||
const status = failedCount > 0 ? 'warning' : (successCount > 0 ? 'success' : 'info');
|
||||
this.showNotification(summary, status);
|
||||
} catch (error) {
|
||||
this.showNotification(`${i18n.t('notification.add_failed')}: ${error.message}`, 'error');
|
||||
this.showNotification(`${i18n.t('notification.gemini_multi_failed')}: ${error.message}`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
16
i18n.js
16
i18n.js
@@ -131,8 +131,9 @@ const i18n = {
|
||||
'ai_providers.gemini_empty_desc': '点击上方按钮添加第一个密钥',
|
||||
'ai_providers.gemini_item_title': 'Gemini密钥',
|
||||
'ai_providers.gemini_add_modal_title': '添加Gemini API密钥',
|
||||
'ai_providers.gemini_add_modal_key_label': 'API密钥:',
|
||||
'ai_providers.gemini_add_modal_key_placeholder': '请输入Gemini API密钥',
|
||||
'ai_providers.gemini_add_modal_key_label': 'API密钥列表:',
|
||||
'ai_providers.gemini_add_modal_key_placeholder': '请输入Gemini API密钥(每行一个)',
|
||||
'ai_providers.gemini_add_modal_key_hint': '可一次粘贴多个密钥,每行一个。',
|
||||
'ai_providers.gemini_add_modal_url_label': 'Base URL (可选):',
|
||||
'ai_providers.gemini_add_modal_url_placeholder': '例如: https://generativelanguage.googleapis.com',
|
||||
'ai_providers.gemini_edit_modal_title': '编辑Gemini API密钥',
|
||||
@@ -403,6 +404,9 @@ const i18n = {
|
||||
'notification.gemini_key_added': 'Gemini密钥添加成功',
|
||||
'notification.gemini_key_updated': 'Gemini密钥更新成功',
|
||||
'notification.gemini_key_deleted': 'Gemini密钥删除成功',
|
||||
'notification.gemini_multi_input_required': '请先输入至少一个Gemini密钥',
|
||||
'notification.gemini_multi_failed': 'Gemini密钥批量添加失败',
|
||||
'notification.gemini_multi_summary': 'Gemini批量添加完成:成功 {success},跳过 {skipped},失败 {failed}',
|
||||
'notification.codex_config_added': 'Codex配置添加成功',
|
||||
'notification.codex_config_updated': 'Codex配置更新成功',
|
||||
'notification.codex_config_deleted': 'Codex配置删除成功',
|
||||
@@ -580,8 +584,9 @@ const i18n = {
|
||||
'ai_providers.gemini_empty_desc': 'Click the button above to add the first key',
|
||||
'ai_providers.gemini_item_title': 'Gemini Key',
|
||||
'ai_providers.gemini_add_modal_title': 'Add Gemini API Key',
|
||||
'ai_providers.gemini_add_modal_key_label': 'API Key:',
|
||||
'ai_providers.gemini_add_modal_key_placeholder': 'Please enter Gemini API key',
|
||||
'ai_providers.gemini_add_modal_key_label': 'API Keys:',
|
||||
'ai_providers.gemini_add_modal_key_placeholder': 'Enter Gemini API keys (one per line)',
|
||||
'ai_providers.gemini_add_modal_key_hint': 'You can paste multiple keys, one per line.',
|
||||
'ai_providers.gemini_add_modal_url_label': 'Base URL (optional):',
|
||||
'ai_providers.gemini_add_modal_url_placeholder': 'e.g. https://generativelanguage.googleapis.com',
|
||||
'ai_providers.gemini_edit_modal_title': 'Edit Gemini API Key',
|
||||
@@ -851,6 +856,9 @@ const i18n = {
|
||||
'notification.gemini_key_added': 'Gemini key added successfully',
|
||||
'notification.gemini_key_updated': 'Gemini key updated successfully',
|
||||
'notification.gemini_key_deleted': 'Gemini key deleted successfully',
|
||||
'notification.gemini_multi_input_required': 'Please enter at least one Gemini key',
|
||||
'notification.gemini_multi_failed': 'Gemini bulk add failed',
|
||||
'notification.gemini_multi_summary': 'Gemini bulk add finished: {success} added, {skipped} skipped, {failed} failed',
|
||||
'notification.codex_config_added': 'Codex configuration added successfully',
|
||||
'notification.codex_config_updated': 'Codex configuration updated successfully',
|
||||
'notification.codex_config_deleted': 'Codex configuration deleted successfully',
|
||||
|
||||
Reference in New Issue
Block a user