|
<!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="/tokeninfo">Token 信息页面 (/tokeninfo)</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> |
|
</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="enable_stream_check"> |
|
<option value="">保持不变</option> |
|
<option value="true">启用</option> |
|
<option value="false">禁用</option> |
|
</select> |
|
</div> |
|
|
|
<div class="form-group"> |
|
<label>包含停止流:</label> |
|
<select id="include_stop_stream"> |
|
<option value="">保持不变</option> |
|
<option value="true">启用</option> |
|
<option value="false">禁用</option> |
|
</select> |
|
</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="check_usage_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="check_usage_models_list" placeholder="模型列表,以逗号分隔" style="display: none;"> |
|
</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="result" class="message"></div> |
|
|
|
<script> |
|
async function fetchConfig() { |
|
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('enable_stream_check').value = |
|
parseStringFromBoolean(data.data.enable_stream_check, ''); |
|
document.getElementById('include_stop_stream').value = |
|
parseStringFromBoolean(data.data.include_stop_stream, ''); |
|
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('check_usage_models_type').value = data.data.check_usage_models?.type || ''; |
|
document.getElementById('check_usage_models_list').value = data.data.check_usage_models?.type === 'list' ? data.data.check_usage_models?.content || '' : document.getElementById('check_usage_models_list').value; |
|
} |
|
} |
|
|
|
async function updateConfig(action) { |
|
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('enable_stream_check').value && { |
|
enable_stream_check: parseBooleanFromString(document.getElementById('enable_stream_check').value) |
|
}), |
|
...(document.getElementById('include_stop_stream').value && { |
|
include_stop_stream: parseBooleanFromString(document.getElementById('include_stop_stream').value) |
|
}), |
|
...(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('check_usage_models_type').value && { |
|
check_usage_models: { |
|
type: document.getElementById('check_usage_models_type').value, |
|
...(document.getElementById('check_usage_models_type').value === 'list' && { |
|
content: document.getElementById('check_usage_models_list').value |
|
}) |
|
} |
|
}) |
|
}; |
|
|
|
const result = await makeAuthenticatedRequest('/config', { |
|
body: JSON.stringify(data) |
|
}); |
|
|
|
if (result) { |
|
showMessage('result', result.message, false); |
|
if (action === 'update' || action === 'reset') { |
|
await fetchConfig(); |
|
} |
|
} |
|
} |
|
|
|
function showSuccess(message) { |
|
showMessage('result', message, false); |
|
} |
|
|
|
function showError(message) { |
|
showMessage('result', 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('check_usage_models_type').addEventListener('change', function() { |
|
const input = document.getElementById('check_usage_models_list'); |
|
input.style.display = this.value === 'list' ? 'inline-block' : 'none'; |
|
}); |
|
</script> |
|
</body> |
|
|
|
</html> |