<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MCP工具 - API Key</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: #333;
}
.container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
border-radius: 20px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
text-align: center;
max-width: 600px;
width: 90%;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.logo {
font-size: 3em;
margin-bottom: 20px;
}
h1 {
color: #2c3e50;
margin-bottom: 30px;
font-size: 2.5em;
font-weight: 700;
}
.api-key-section {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 15px;
padding: 30px;
margin: 30px 0;
border: 2px dashed #6c757d;
}
.api-key-label {
color: #495057;
font-size: 1.2em;
margin-bottom: 15px;
font-weight: 600;
}
.api-key-display {
background: #212529;
color: #00ff88;
padding: 15px;
border-radius: 10px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
font-size: 0.9em;
letter-spacing: 1px;
word-break: break-all;
margin-bottom: 15px;
border: 2px solid #00ff88;
box-shadow: 0 0 20px rgba(0, 255, 136, 0.3);
}
.key-info {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-top: 20px;
}
.info-card {
background: white;
padding: 15px;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.info-label {
color: #6c757d;
font-size: 0.9em;
margin-bottom: 5px;
}
.info-value {
color: #2c3e50;
font-weight: 600;
font-size: 1.1em;
}
.countdown {
color: #e74c3c;
font-weight: bold;
}
.button-group {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 30px;
}
.btn {
padding: 12px 25px;
border: none;
border-radius: 25px;
font-size: 1.1em;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-block;
}
.btn-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 12px 25px rgba(102, 126, 234, 0.6);
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn-secondary:hover {
background: #5a6268;
transform: translateY(-2px);
}
.btn-success {
background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
color: white;
}
.btn-success:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(40, 167, 69, 0.4);
}
.features {
text-align: left;
margin-top: 30px;
background: rgba(248, 249, 250, 0.8);
padding: 20px;
border-radius: 15px;
}
.features h3 {
color: #2c3e50;
margin-bottom: 15px;
text-align: center;
}
.features ul {
list-style: none;
padding: 0;
}
.features li {
padding: 8px 0;
border-bottom: 1px solid rgba(108, 117, 125, 0.2);
color: #495057;
}
.features li:before {
content: "✨ ";
margin-right: 10px;
}
.copy-btn {
background: #17a2b8;
color: white;
border: none;
padding: 8px 15px;
border-radius: 5px;
cursor: pointer;
font-size: 0.9em;
margin-top: 10px;
transition: all 0.3s ease;
}
.copy-btn:hover {
background: #138496;
}
.status-indicator {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
background: #28a745;
margin-right: 8px;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
@media (max-width: 768px) {
.key-info {
grid-template-columns: 1fr;
}
.button-group {
flex-direction: column;
}
h1 {
font-size: 2em;
}
}
</style>
</head>
<body>
<div class="container">
<div class="logo">🔑</div>
<h1>MCP 工具平台</h1>
<div class="api-key-section">
<div class="api-key-label">
<span class="status-indicator"></span>
您的 API Key
</div>
<div class="api-key-display" id="apiKeyDisplay">
加载中...
</div>
<button class="copy-btn" onclick="copyApiKey()">📋 复制 API Key</button>
<div class="key-info">
<div class="info-card">
<div class="info-label">过期时间</div>
<div class="info-value" id="expiryTime">--</div>
</div>
<div class="info-card">
<div class="info-label">剩余时间</div>
<div class="info-value countdown" id="timeRemaining">--</div>
</div>
</div>
</div>
<div class="features">
<h3>🚀 平台功能</h3>
<ul>
<li>为Cursor等IDE提供MCP工具调用服务</li>
<li>实时天气查询,支持全国主要城市</li>
<li>强大的数学计算引擎</li>
<li>Word文档自动创建和格式化</li>
<li>表格数据处理和生成</li>
<li>15个专业工具,满足开发需求</li>
</ul>
</div>
<div class="button-group">
<a href="/" class="btn btn-primary">💬 测试对话</a>
<button class="btn btn-secondary" onclick="regenerateApiKey()">🔄 重新生成</button>
<a href="/mcp" class="btn btn-success">🔧 MCP工具</a>
</div>
</div>
<script>
let apiKeyData = null;
let countdownInterval = null;
// 加载API Key信息
async function loadApiKey() {
try {
const response = await fetch('/api/key');
apiKeyData = await response.json();
document.getElementById('apiKeyDisplay').textContent = apiKeyData.apiKey;
document.getElementById('expiryTime').textContent =
new Date(apiKeyData.expiry).toLocaleString('zh-CN');
startCountdown();
} catch (error) {
console.error('加载API Key失败:', error);
document.getElementById('apiKeyDisplay').textContent = '加载失败';
}
}
// 倒计时显示
function startCountdown() {
if (countdownInterval) {
clearInterval(countdownInterval);
}
countdownInterval = setInterval(() => {
const now = Date.now();
const expiry = new Date(apiKeyData.expiry).getTime();
const remaining = expiry - now;
if (remaining <= 0) {
document.getElementById('timeRemaining').textContent = '已过期';
clearInterval(countdownInterval);
loadApiKey(); // 重新加载,服务器会自动生成新的
return;
}
const hours = Math.floor(remaining / (1000 * 60 * 60));
const minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((remaining % (1000 * 60)) / 1000);
document.getElementById('timeRemaining').textContent =
`${hours}小时 ${minutes}分钟 ${seconds}秒`;
}, 1000);
}
// 复制API Key
async function copyApiKey() {
try {
await navigator.clipboard.writeText(apiKeyData.apiKey);
const btn = event.target;
const originalText = btn.textContent;
btn.textContent = '✅ 已复制';
btn.style.background = '#28a745';
setTimeout(() => {
btn.textContent = originalText;
btn.style.background = '#17a2b8';
}, 2000);
} catch (error) {
alert('复制失败,请手动复制');
}
}
// 重新生成API Key
async function regenerateApiKey() {
if (!confirm('确定要重新生成API Key吗?旧的Key将立即失效。')) {
return;
}
try {
const response = await fetch('/api/key/regenerate', {
method: 'POST'
});
if (response.ok) {
await loadApiKey();
alert('✅ API Key已重新生成');
} else {
alert('❌ 重新生成失败');
}
} catch (error) {
console.error('重新生成API Key失败:', error);
alert('❌ 重新生成失败');
}
}
// 页面加载时初始化
document.addEventListener('DOMContentLoaded', loadApiKey);
</script>
</body>
</html>