Files
military-tech-voice3.0/frontend/login.html
T
lanhao 223761e717 feat: 登录验证 + 邀请码注册 + 用量监控后台
- 新增用户认证系统(登录/登出/邀请码注册)
- 新增管理后台(邀请码管理/用户管理/使用记录/用量统计)
- 合成接口加登录验证,每次调用记录用户和稿件内容
- SQLite存储用户数据和使用日志
- 默认admin账号: simonkoson

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-02 18:51:23 +08:00

136 lines
5.8 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>登录 - 军事科技AI配音</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="auth-container">
<div class="auth-card">
<div class="auth-header">
<svg class="auth-logo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/>
<polygon points="10,8 16,12 10,16"/>
</svg>
<h1>军事科技 <span>AI配音</span></h1>
</div>
<!-- 登录表单 -->
<form id="loginForm" class="auth-form">
<h2>登录</h2>
<div class="form-group">
<label>用户名</label>
<input type="text" id="loginUsername" required autocomplete="username">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" id="loginPassword" required autocomplete="current-password">
</div>
<button type="submit" class="btn btn-primary btn-full">登 录</button>
<p class="auth-switch">有邀请码?<a href="#" id="showRegister">点击注册</a></p>
<div class="auth-error" id="loginError"></div>
</form>
<!-- 注册表单 -->
<form id="registerForm" class="auth-form" style="display:none">
<h2>邀请码注册</h2>
<div class="form-group">
<label>邀请码</label>
<input type="text" id="regInviteCode" required placeholder="请输入管理员提供的邀请码">
</div>
<div class="form-group">
<label>用户名</label>
<input type="text" id="regUsername" required placeholder="自定义登录用户名" autocomplete="username">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" id="regPassword" required placeholder="至少6位" autocomplete="new-password">
</div>
<div class="form-group">
<label>显示名称(选填)</label>
<input type="text" id="regDisplayName" placeholder="不填则使用邀请码绑定的姓名">
</div>
<button type="submit" class="btn btn-primary btn-full">注 册</button>
<p class="auth-switch"><a href="#" id="showLogin">返回登录</a></p>
<div class="auth-error" id="registerError"></div>
</form>
</div>
</div>
<script>
const loginForm = document.getElementById('loginForm');
const registerForm = document.getElementById('registerForm');
document.getElementById('showRegister').addEventListener('click', (e) => {
e.preventDefault();
loginForm.style.display = 'none';
registerForm.style.display = 'block';
});
document.getElementById('showLogin').addEventListener('click', (e) => {
e.preventDefault();
registerForm.style.display = 'none';
loginForm.style.display = 'block';
});
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
const errorEl = document.getElementById('loginError');
errorEl.textContent = '';
try {
const res = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: document.getElementById('loginUsername').value,
password: document.getElementById('loginPassword').value
})
});
const data = await res.json();
if (res.ok && data.success) {
window.location.href = '/';
} else {
errorEl.textContent = data.error || '登录失败';
}
} catch (err) {
errorEl.textContent = '网络错误,请重试';
}
});
registerForm.addEventListener('submit', async (e) => {
e.preventDefault();
const errorEl = document.getElementById('registerError');
errorEl.textContent = '';
try {
const res = await fetch('/api/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
invite_code: document.getElementById('regInviteCode').value,
username: document.getElementById('regUsername').value,
password: document.getElementById('regPassword').value,
display_name: document.getElementById('regDisplayName').value
})
});
const data = await res.json();
if (res.ok && data.success) {
alert(data.message + '\n请使用新账号登录');
registerForm.style.display = 'none';
loginForm.style.display = 'block';
} else {
errorEl.textContent = data.error || '注册失败';
}
} catch (err) {
errorEl.textContent = '网络错误,请重试';
}
});
// 如果已登录,直接跳主页
fetch('/api/me').then(res => {
if (res.ok) window.location.href = '/';
});
</script>
</body>
</html>