pre / templates /update_test.html
yangtb24's picture
Upload 61 files
99fc92f verified
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API密钥测试更新</title>
<link rel="stylesheet" href="/static/css/base.css">
<link rel="stylesheet" href="/static/css/style.css">
<style>
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.key-list {
margin-top: 20px;
border: 1px solid #e5e7eb;
border-radius: 8px;
overflow: hidden;
}
.key-item {
padding: 15px;
border-bottom: 1px solid #e5e7eb;
display: flex;
justify-content: space-between;
align-items: center;
}
.key-item:last-child {
border-bottom: none;
}
.key-item:hover {
background-color: #f9fafb;
}
.key-info {
flex-grow: 1;
}
.key-name {
font-weight: 500;
margin-bottom: 5px;
}
.key-value {
font-family: monospace;
color: #6b7280;
word-break: break-all;
}
.key-platform {
color: #4f46e5;
font-size: 0.875rem;
margin-bottom: 8px;
}
.key-status {
display: flex;
flex-direction: column;
align-items: flex-end;
min-width: 120px;
}
.update-btn {
padding: 6px 12px;
border-radius: 6px;
background-color: #4f46e5;
color: white;
font-size: 0.875rem;
border: none;
cursor: pointer;
transition: background-color 0.2s;
}
.update-btn:hover {
background-color: #4338ca;
}
.success-badge {
margin-top: 8px;
padding: 4px 8px;
border-radius: 9999px;
font-size: 0.75rem;
background-color: #dcfce7;
color: #16a34a;
}
.error-badge {
margin-top: 8px;
padding: 4px 8px;
border-radius: 9999px;
font-size: 0.75rem;
background-color: #fee2e2;
color: #dc2626;
}
.pending-badge {
margin-top: 8px;
padding: 4px 8px;
border-radius: 9999px;
font-size: 0.75rem;
background-color: #e0f2fe;
color: #0284c7;
}
#loading {
display: none;
margin: 20px auto;
text-align: center;
font-style: italic;
color: #6b7280;
}
.response-container {
margin-top: 15px;
background-color: #f9fafb;
border-radius: 6px;
padding: 10px;
font-family: monospace;
font-size: 0.875rem;
white-space: pre-wrap;
word-break: break-all;
display: none;
max-height: 200px;
overflow-y: auto;
}
</style>
</head>
<body>
<div class="container">
<h1>API密钥测试与更新</h1>
<p>在此页面可以测试update.py脚本的功能,验证API密钥并更新其状态。</p>
<div id="loading">正在加载API密钥列表...</div>
<div id="keyList" class="key-list"></div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
loadKeys();
// 添加回主页的按钮
const container = document.querySelector('.container');
const backButton = document.createElement('a');
backButton.href = '/';
backButton.textContent = '返回主页';
backButton.style.display = 'inline-block';
backButton.style.marginTop = '20px';
backButton.style.color = '#4f46e5';
backButton.style.textDecoration = 'none';
container.appendChild(backButton);
});
async function loadKeys() {
const loadingElement = document.getElementById('loading');
const keyListElement = document.getElementById('keyList');
loadingElement.style.display = 'block';
keyListElement.innerHTML = '';
try {
const response = await fetch('/api/keys');
const data = await response.json();
if (data && data.api_keys && data.api_keys.length > 0) {
data.api_keys.forEach(key => {
const keyElement = createKeyElement(key);
keyListElement.appendChild(keyElement);
});
} else {
keyListElement.innerHTML = '<div style="padding: 20px; text-align: center; color: #6b7280;">没有找到API密钥</div>';
}
} catch (error) {
console.error('加载API密钥失败:', error);
keyListElement.innerHTML = `<div style="padding: 20px; text-align: center; color: #dc2626;">加载API密钥失败: ${error.message}</div>`;
} finally {
loadingElement.style.display = 'none';
}
}
function createKeyElement(key) {
const keyItem = document.createElement('div');
keyItem.className = 'key-item';
keyItem.id = `key-${key.id}`;
// 密钥信息区域
const keyInfo = document.createElement('div');
keyInfo.className = 'key-info';
// 平台信息
const platformElement = document.createElement('div');
platformElement.className = 'key-platform';
platformElement.textContent = getPlatformName(key.platform);
keyInfo.appendChild(platformElement);
// 密钥名称
const nameElement = document.createElement('div');
nameElement.className = 'key-name';
nameElement.textContent = key.name;
keyInfo.appendChild(nameElement);
// 密钥值
const valueElement = document.createElement('div');
valueElement.className = 'key-value';
valueElement.textContent = key.key;
keyInfo.appendChild(valueElement);
// 如果有更新时间,显示
if (key.updated_at) {
const updatedElement = document.createElement('div');
updatedElement.style.fontSize = '0.75rem';
updatedElement.style.color = '#6b7280';
updatedElement.style.marginTop = '5px';
const date = new Date(key.updated_at);
updatedElement.textContent = `上次更新: ${date.toLocaleString()}`;
keyInfo.appendChild(updatedElement);
}
// 响应容器
const responseContainer = document.createElement('div');
responseContainer.className = 'response-container';
responseContainer.id = `response-${key.id}`;
keyInfo.appendChild(responseContainer);
keyItem.appendChild(keyInfo);
// 状态和按钮区域
const keyStatus = document.createElement('div');
keyStatus.className = 'key-status';
// 更新按钮
const updateButton = document.createElement('button');
updateButton.className = 'update-btn';
updateButton.textContent = '更新状态';
updateButton.onclick = function() {
updateKeyStatus(key.id);
};
keyStatus.appendChild(updateButton);
// 状态标签
const statusBadge = document.createElement('div');
if (key.success === true) {
statusBadge.className = 'success-badge';
statusBadge.textContent = '验证成功';
} else if (key.success === false) {
statusBadge.className = 'error-badge';
statusBadge.textContent = key.return_message || '验证失败';
} else {
statusBadge.className = 'pending-badge';
statusBadge.textContent = '等待验证';
}
keyStatus.appendChild(statusBadge);
keyItem.appendChild(keyStatus);
return keyItem;
}
async function updateKeyStatus(keyId) {
const keyElement = document.getElementById(`key-${keyId}`);
const updateButton = keyElement.querySelector('.update-btn');
const responseContainer = document.getElementById(`response-${keyId}`);
// 禁用按钮并显示加载状态
updateButton.disabled = true;
updateButton.textContent = '更新中...';
try {
const response = await fetch(`/api/keys/update/${keyId}`, {
method: 'POST'
});
const result = await response.json();
// 显示响应数据
responseContainer.textContent = JSON.stringify(result, null, 2);
responseContainer.style.display = 'block';
// 刷新密钥列表
loadKeys();
} catch (error) {
console.error(`更新密钥 ${keyId} 失败:`, error);
responseContainer.textContent = `更新失败: ${error.message}`;
responseContainer.style.display = 'block';
} finally {
// 恢复按钮状态
updateButton.disabled = false;
updateButton.textContent = '更新状态';
}
}
function getPlatformName(platformId) {
const platforms = {
'openai': 'OpenAI',
'anthropic': 'Anthropic',
'google': 'Google',
'deepseek': 'DeepSeek'
};
return platforms[platformId] || platformId;
}
</script>
</body>
</html>