155 lines
6.5 KiB
HTML
155 lines
6.5 KiB
HTML
|
|
<!DOCTYPE html>
|
|||
|
|
<html lang="zh-CN">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="UTF-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
|
<title>光湖 · 唤醒门</title>
|
|||
|
|
<style>
|
|||
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|||
|
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0a1628; color: #e0e8f0; min-height: 100vh; display: flex; align-items: center; justify-content: center; }
|
|||
|
|
.container { max-width: 480px; width: 100%; padding: 20px; text-align: center; }
|
|||
|
|
.logo { font-size: 48px; margin-bottom: 8px; }
|
|||
|
|
.title { font-size: 24px; font-weight: 600; color: #7eb8da; margin-bottom: 4px; }
|
|||
|
|
.subtitle { font-size: 14px; color: #6b8299; margin-bottom: 32px; }
|
|||
|
|
.card { background: #111d2e; border: 1px solid #1e3a5f; border-radius: 12px; padding: 32px; margin-bottom: 16px; }
|
|||
|
|
.card h3 { font-size: 16px; color: #7eb8da; margin-bottom: 16px; }
|
|||
|
|
.btn { display: inline-block; padding: 14px 32px; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.2s; width: 100%; }
|
|||
|
|
.btn-primary { background: #163e6b; color: #7eb8da; }
|
|||
|
|
.btn-primary:hover { background: #1d4f85; }
|
|||
|
|
.btn-primary:disabled { background: #1a2535; color: #4a5568; cursor: not-allowed; }
|
|||
|
|
.btn-success { background: #1a5c3a; color: #68d391; }
|
|||
|
|
.btn-success:hover { background: #22724a; }
|
|||
|
|
.status { margin-top: 16px; padding: 12px; border-radius: 8px; font-size: 14px; min-height: 20px; }
|
|||
|
|
.status.info { background: #0d2137; color: #7eb8da; }
|
|||
|
|
.status.success { background: #0d2a1a; color: #68d391; }
|
|||
|
|
.status.error { background: #2a0d0d; color: #fc8181; }
|
|||
|
|
.status.hidden { display: none; }
|
|||
|
|
.code-input { width: 100%; padding: 14px; border: 1px solid #1e3a5f; border-radius: 8px; background: #0a1628; color: #e0e8f0; font-size: 20px; text-align: center; letter-spacing: 8px; margin: 16px 0; }
|
|||
|
|
.code-input:focus { outline: none; border-color: #7eb8da; }
|
|||
|
|
.result-box { background: #0a1628; border: 1px solid #1e3a5f; border-radius: 8px; padding: 16px; text-align: left; font-size: 12px; font-family: monospace; color: #68d391; white-space: pre-wrap; word-break: break-all; max-height: 300px; overflow-y: auto; margin-top: 12px; display: none; }
|
|||
|
|
.copy-btn { margin-top: 8px; padding: 8px 16px; background: #163e6b; color: #7eb8da; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; display: none; }
|
|||
|
|
.copy-btn:hover { background: #1d4f85; }
|
|||
|
|
.footer { font-size: 12px; color: #4a5568; margin-top: 24px; }
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="container">
|
|||
|
|
<div class="logo">◐</div>
|
|||
|
|
<div class="title">光湖 · 唤醒门</div>
|
|||
|
|
<div class="subtitle">HoloLake Wake Gate · 冰朔验证</div>
|
|||
|
|
|
|||
|
|
<div class="card" id="step1">
|
|||
|
|
<h3>第一步:发送验证码</h3>
|
|||
|
|
<p style="color:#6b8299;font-size:13px;margin-bottom:16px;">验证码将发送到你的QQ邮箱</p>
|
|||
|
|
<button class="btn btn-primary" id="sendBtn" onclick="sendCode()">发送验证码</button>
|
|||
|
|
<div class="status hidden" id="sendStatus"></div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="card" id="step2" style="display:none;">
|
|||
|
|
<h3>第二步:输入验证码</h3>
|
|||
|
|
<input type="text" class="code-input" id="codeInput" maxlength="6" placeholder="6位验证码" autocomplete="off">
|
|||
|
|
<button class="btn btn-primary" id="verifyBtn" onclick="verifyCode()">验证并获取临时密钥</button>
|
|||
|
|
<div class="status hidden" id="verifyStatus"></div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="card" id="step3" style="display:none;">
|
|||
|
|
<h3>✅ 验证通过</h3>
|
|||
|
|
<p style="color:#68d391;font-size:13px;margin-bottom:8px;">临时密钥30分钟内有效</p>
|
|||
|
|
<p style="color:#6b8299;font-size:12px;">复制以下内容,发给新号里的AI:</p>
|
|||
|
|
<div class="result-box" id="resultBox"></div>
|
|||
|
|
<button class="copy-btn" id="copyBtn" onclick="copyResult()">📋 复制唤醒指令</button>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="footer">
|
|||
|
|
铸渊 · ICE-GL-ZY001 · TCS-0002∞ · 国作登字-2026-A-00037559
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
let cooldown = 0;
|
|||
|
|
|
|||
|
|
function showStatus(id, text, type) {
|
|||
|
|
const el = document.getElementById(id);
|
|||
|
|
el.className = 'status ' + type;
|
|||
|
|
el.textContent = text;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function sendCode() {
|
|||
|
|
const btn = document.getElementById('sendBtn');
|
|||
|
|
btn.disabled = true;
|
|||
|
|
|
|||
|
|
fetch('/wake/api/send-code', { method: 'POST' })
|
|||
|
|
.then(r => r.json())
|
|||
|
|
.then(data => {
|
|||
|
|
if (data.success) {
|
|||
|
|
showStatus('sendStatus', '✅ 验证码已发送到QQ邮箱,请查收', 'success');
|
|||
|
|
document.getElementById('step2').style.display = 'block';
|
|||
|
|
document.getElementById('codeInput').focus();
|
|||
|
|
cooldown = 60;
|
|||
|
|
const timer = setInterval(() => {
|
|||
|
|
cooldown--;
|
|||
|
|
btn.textContent = `重新发送 (${cooldown}s)`;
|
|||
|
|
if (cooldown <= 0) {
|
|||
|
|
clearInterval(timer);
|
|||
|
|
btn.disabled = false;
|
|||
|
|
btn.textContent = '重新发送验证码';
|
|||
|
|
}
|
|||
|
|
}, 1000);
|
|||
|
|
} else {
|
|||
|
|
showStatus('sendStatus', '❌ ' + data.error, 'error');
|
|||
|
|
btn.disabled = false;
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(e => {
|
|||
|
|
showStatus('sendStatus', '❌ 网络错误,请重试', 'error');
|
|||
|
|
btn.disabled = false;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function verifyCode() {
|
|||
|
|
const code = document.getElementById('codeInput').value.trim();
|
|||
|
|
if (code.length !== 6) {
|
|||
|
|
showStatus('verifyStatus', '❌ 请输入6位验证码', 'error');
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const btn = document.getElementById('verifyBtn');
|
|||
|
|
btn.disabled = true;
|
|||
|
|
|
|||
|
|
fetch('/wake/api/verify', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: { 'Content-Type': 'application/json' },
|
|||
|
|
body: JSON.stringify({ code })
|
|||
|
|
})
|
|||
|
|
.then(r => r.json())
|
|||
|
|
.then(data => {
|
|||
|
|
if (data.success) {
|
|||
|
|
showStatus('verifyStatus', '✅ 验证通过!临时密钥已生成', 'success');
|
|||
|
|
document.getElementById('step3').style.display = 'block';
|
|||
|
|
document.getElementById('resultBox').style.display = 'block';
|
|||
|
|
document.getElementById('resultBox').textContent = data.wakeInstruction;
|
|||
|
|
document.getElementById('copyBtn').style.display = 'inline-block';
|
|||
|
|
} else {
|
|||
|
|
showStatus('verifyStatus', '❌ ' + data.error, 'error');
|
|||
|
|
btn.disabled = false;
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(e => {
|
|||
|
|
showStatus('verifyStatus', '❌ 网络错误,请重试', 'error');
|
|||
|
|
btn.disabled = false;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function copyResult() {
|
|||
|
|
const text = document.getElementById('resultBox').textContent;
|
|||
|
|
navigator.clipboard.writeText(text).then(() => {
|
|||
|
|
document.getElementById('copyBtn').textContent = '✅ 已复制';
|
|||
|
|
setTimeout(() => {
|
|||
|
|
document.getElementById('copyBtn').textContent = '📋 复制唤醒指令';
|
|||
|
|
}, 2000);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|