| <!DOCTYPE html> |
| <html lang="zh"> |
|
|
| <head> |
| <meta charset="UTF-8"> |
| <link rel="icon" type="image/x-icon" href="data:image/x-icon;,"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>配置管理</title> |
| |
| <link rel="stylesheet" href="/static/shared-styles.css"> |
| <script src="/static/shared.js"></script> |
| </head> |
|
|
| <body> |
| <h1>配置管理</h1> |
|
|
| <div class="container"> |
| <div class="form-group"> |
| <label>路径:</label> |
| <select id="path"> |
| <option value="/">根路径 (/)</option> |
| <option value="/logs">日志页面 (/logs)</option> |
| <option value="/config">配置页面 (/config)</option> |
| <option value="/tokens">Token 管理页面 (/tokens)</option> |
| <option value="/static/shared-styles.css">共享样式 (/static/shared-styles.css)</option> |
| <option value="/static/shared.js">共享脚本 (/static/shared.js)</option> |
| <option value="/about">关于页面 (/about)</option> |
| <option value="/readme">ReadMe文档 (/readme)</option> |
| <option value="/api">api调用 (/api)</option> |
| <option value="/build-key">构建动态 Key (/build-key)</option> |
| </select> |
| </div> |
|
|
| <div class="form-group"> |
| <label>内容类型:</label> |
| <select id="content_type"> |
| <option value="default">默认</option> |
| <option value="text">纯文本</option> |
| <option value="html">HTML</option> |
| </select> |
| </div> |
|
|
| <div class="form-group"> |
| <label>内容:</label> |
| <textarea id="content"></textarea> |
| </div> |
|
|
| <div class="form-group"> |
| <label>图片处理能力:</label> |
| <select id="vision_ability"> |
| <option value="">保持不变</option> |
| <option value="disabled">禁用</option> |
| <option value="base64-only">仅 Base64</option> |
| <option value="base64-http">Base64 + HTTP</option> |
| </select> |
| </div> |
|
|
| <div class="form-group"> |
| <label>慢速池:</label> |
| <select id="enable_slow_pool"> |
| <option value="">保持不变</option> |
| <option value="true">启用</option> |
| <option value="false">禁用</option> |
| </select> |
| </div> |
|
|
| <div class="form-group"> |
| <label>允许所有Claude模型:</label> |
| <select id="enable_all_claude"> |
| <option value="">保持不变</option> |
| <option value="true">启用</option> |
| <option value="false">禁用</option> |
| </select> |
| </div> |
|
|
| <div class="form-group"> |
| <label>使用量检查模型规则:</label> |
| <select id="usage_check_models_type"> |
| <option value="">保持不变</option> |
| <option value="none">禁用</option> |
| <option value="default">默认</option> |
| <option value="all">所有</option> |
| <option value="list">自定义列表</option> |
| </select> |
| <input type="text" id="usage_check_models_list" placeholder="模型列表,以逗号分隔" style="display: none;"> |
| </div> |
|
|
| <div class="form-group"> |
| <label>是否允许动态配置Key:</label> |
| <select id="enable_dynamic_key"> |
| <option value="">保持不变</option> |
| <option value="true">启用</option> |
| <option value="false">禁用</option> |
| </select> |
| </div> |
|
|
| <div class="form-group"> |
| <label>代理设置:</label> |
| <select id="proxies_type" onchange="handleProxiesTypeChange()"> |
| <option value="">保持不变</option> |
| <option value="no">不使用代理</option> |
| <option value="system">使用系统代理</option> |
| <option value="list">自定义代理列表</option> |
| </select> |
| <input type="text" id="proxies_list" placeholder="代理地址列表,以逗号分隔 (例如: http://127.0.0.1:7890)" |
| style="display: none;"> |
| </div> |
|
|
| <div class="form-group"> |
| <label>包含网络引用:</label> |
| <select id="include_web_references"> |
| <option value="">保持不变</option> |
| <option value="true">启用</option> |
| <option value="false">禁用</option> |
| </select> |
| </div> |
|
|
| <div class="form-group"> |
| <label>共享令牌(空表示禁用):</label> |
| <input type="text" id="shareToken"> |
| </div> |
|
|
| <div class="form-group"> |
| <label>认证令牌:</label> |
| <input type="password" id="authToken"> |
| </div> |
|
|
| <div class="button-group"> |
| <button onclick="updateConfig('get')">获取配置</button> |
| <button onclick="updateConfig('update')">更新配置</button> |
| <button onclick="updateConfig('reset')" class="secondary">重置配置</button> |
| </div> |
| </div> |
|
|
| <div id="message"></div> |
|
|
| <script> |
| async function fetchConfig() { |
| try { |
| const path = document.getElementById('path').value; |
| const data = await makeAuthenticatedRequest('/config', { |
| body: JSON.stringify({ action: 'get', path }) |
| }); |
| |
| if (data) { |
| let content = ''; |
| |
| |
| const pageContent = data.data.page_content; |
| |
| |
| if (pageContent?.type === 'default') { |
| |
| const response = await fetch(path); |
| content = await response.text(); |
| } else if (pageContent?.type === 'text' || pageContent?.type === 'html') { |
| content = pageContent.content; |
| } |
| |
| |
| document.getElementById('content').value = content || ''; |
| document.getElementById('content_type').value = pageContent?.type || 'default'; |
| let visionValue = data.data.vision_ability || ''; |
| |
| switch (visionValue) { |
| case 'none': |
| visionValue = 'disabled'; |
| break; |
| case 'base64': |
| visionValue = 'base64-only'; |
| break; |
| case 'all': |
| visionValue = 'base64-http'; |
| break; |
| } |
| document.getElementById('vision_ability').value = visionValue; |
| document.getElementById('enable_slow_pool').value = |
| parseStringFromBoolean(data.data.enable_slow_pool, ''); |
| document.getElementById('enable_all_claude').value = |
| parseStringFromBoolean(data.data.enable_all_claude, ''); |
| document.getElementById('usage_check_models_type').value = data.data.usage_check_models?.type || ''; |
| document.getElementById('usage_check_models_list').value = data.data.usage_check_models?.type === 'list' ? data.data.usage_check_models?.content || '' : document.getElementById('usage_check_models_list').value; |
| document.getElementById('enable_dynamic_key').value = |
| parseStringFromBoolean(data.data.enable_dynamic_key, ''); |
| document.getElementById('include_web_references').value = |
| parseStringFromBoolean(data.data.include_web_references, ''); |
| |
| |
| const proxies = data.data.proxies || ''; |
| let proxiesType = ''; |
| let proxiesList = ''; |
| |
| if (proxies === '') { |
| proxiesType = 'no'; |
| } else if (proxies === 'system') { |
| proxiesType = 'system'; |
| } else { |
| proxiesType = 'list'; |
| proxiesList = proxies; |
| } |
| |
| document.getElementById('proxies_type').value = proxiesType; |
| document.getElementById('proxies_list').value = proxiesList; |
| handleProxiesTypeChange(); |
| |
| document.getElementById('shareToken').value = data.data.share_token || ''; |
| |
| |
| showGlobalMessage(`成功获取 ${path} 的配置`, false); |
| } |
| } catch (error) { |
| showGlobalMessage(error.message || '获取配置失败', true); |
| } |
| } |
| |
| async function updateConfig(action) { |
| try { |
| if (action === 'get') { |
| await fetchConfig(); |
| return; |
| } |
| |
| const contentType = document.getElementById('content_type').value; |
| const content = document.getElementById('content').value; |
| |
| |
| let contentObj = { type: 'default' }; |
| if (action === 'update' && contentType !== 'default') { |
| contentObj = { |
| type: contentType, |
| content: content |
| }; |
| } |
| |
| const data = { |
| action, |
| path: document.getElementById('path').value, |
| ...(contentObj && { content: contentObj }), |
| ...(document.getElementById('vision_ability').value && { |
| vision_ability: document.getElementById('vision_ability').value |
| }), |
| ...(document.getElementById('enable_slow_pool').value && { |
| enable_slow_pool: parseBooleanFromString(document.getElementById('enable_slow_pool').value) |
| }), |
| ...(document.getElementById('enable_all_claude').value && { |
| enable_all_claude: parseBooleanFromString(document.getElementById('enable_all_claude').value) |
| }), |
| ...(document.getElementById('usage_check_models_type').value && { |
| usage_check_models: { |
| type: document.getElementById('usage_check_models_type').value, |
| ...(document.getElementById('usage_check_models_type').value === 'list' && { |
| content: document.getElementById('usage_check_models_list').value |
| }) |
| } |
| }), |
| ...(document.getElementById('enable_dynamic_key').value && { |
| enable_dynamic_key: parseBooleanFromString(document.getElementById('enable_dynamic_key').value) |
| }), |
| ...(document.getElementById('proxies_type').value && { |
| proxies: (() => { |
| const type = document.getElementById('proxies_type').value; |
| switch (type) { |
| case 'no': |
| return ''; |
| case 'system': |
| return 'system'; |
| case 'list': |
| return document.getElementById('proxies_list').value; |
| default: |
| return undefined; |
| } |
| })() |
| }), |
| ...(document.getElementById('include_web_references').value && { |
| include_web_references: parseBooleanFromString(document.getElementById('include_web_references').value) |
| }), |
| share_token: document.getElementById('shareToken').value.trim(), |
| }; |
| |
| const result = await makeAuthenticatedRequest('/config', { |
| body: JSON.stringify(data) |
| }); |
| |
| if (result) { |
| showGlobalMessage(result.message, false); |
| if (action === 'update' || action === 'reset') { |
| await fetchConfig(); |
| } |
| } |
| } catch (error) { |
| showGlobalMessage(error.message || '操作失败', true); |
| } |
| } |
| |
| |
| document.getElementById('path').addEventListener('change', fetchConfig); |
| |
| |
| document.getElementById('content_type').addEventListener('change', function () { |
| const textarea = document.getElementById('content'); |
| textarea.disabled = this.value === 'default'; |
| }); |
| |
| |
| initializeTokenHandling('authToken'); |
| |
| |
| document.getElementById('usage_check_models_type').addEventListener('change', function () { |
| const input = document.getElementById('usage_check_models_list'); |
| input.style.display = this.value === 'list' ? 'inline-block' : 'none'; |
| }); |
| |
| |
| function handleProxiesTypeChange() { |
| const type = document.getElementById('proxies_type').value; |
| const list = document.getElementById('proxies_list'); |
| list.style.display = type === 'list' ? 'inline-block' : 'none'; |
| } |
| |
| |
| document.addEventListener('DOMContentLoaded', async () => { |
| try { |
| await fetchConfig(); |
| showGlobalMessage('页面加载完成', false); |
| } catch (error) { |
| showGlobalMessage('初始化配置加载失败', true); |
| } |
| }); |
| </script> |
| </body> |
|
|
| </html> |