Files
realizemultiagent/shared/code/frontend/login.html
2026-04-02 00:59:42 +08:00

117 lines
4.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', Roboto, sans-serif; background: #f0f2f5; display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.container { background: #fff; border-radius: 12px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); padding: 40px 36px; width: 380px; }
.logo { text-align: center; margin-bottom: 28px; }
.logo h1 { font-size: 24px; color: #1a1a2e; font-weight: 600; }
.logo p { font-size: 13px; color: #888; margin-top: 4px; }
.form-group { margin-bottom: 18px; }
label { display: block; font-size: 14px; color: #333; margin-bottom: 6px; font-weight: 500; }
input { width: 100%; height: 44px; padding: 0 14px; border: 1px solid #ddd; border-radius: 8px; font-size: 15px; outline: none; transition: border-color 0.2s; }
input:focus { border-color: #4f46e5; }
.btn { width: 100%; height: 46px; background: #4f46e5; color: #fff; border: none; border-radius: 8px; font-size: 16px; font-weight: 600; cursor: pointer; transition: background 0.2s; margin-top: 8px; }
.btn:hover { background: #4338ca; }
.btn:disabled { background: #a5a6f6; cursor: not-allowed; }
.links { display: flex; justify-content: space-between; margin-top: 16px; font-size: 13px; }
.links a { color: #4f46e5; text-decoration: none; }
.links a:hover { text-decoration: underline; }
.msg { padding: 10px 14px; border-radius: 8px; font-size: 13px; margin-bottom: 16px; display: none; }
.msg.error { background: #fef2f2; color: #dc2626; border: 1px solid #fca5a5; display: block; }
.msg.success { background: #f0fdf4; color: #16a34a; border: 1px solid #86efac; display: block; }
.loading { display: none; text-align: center; margin-top: 10px; font-size: 13px; color: #888; }
</style>
</head>
<body>
<div class="container">
<div class="logo">
<h1>欢迎回来</h1>
<p>登录您的账户</p>
</div>
<div id="msg" class="msg"></div>
<form id="loginForm">
<div class="form-group">
<label for="phone">手机号</label>
<input type="tel" id="phone" placeholder="请输入手机号" maxlength="11" required autocomplete="tel">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" placeholder="请输入密码" required autocomplete="current-password">
</div>
<button type="submit" class="btn" id="submitBtn">登录</button>
</form>
<div class="links">
<a href="register.html">注册账号</a>
<a href="change-password.html">忘记密码?</a>
</div>
<div id="loading" class="loading">登录中...</div>
</div>
<script>
const form = document.getElementById('loginForm');
const msg = document.getElementById('msg');
const submitBtn = document.getElementById('submitBtn');
const loading = document.getElementById('loading');
function showMsg(text, type) {
msg.textContent = text;
msg.className = 'msg ' + type;
msg.style.display = 'block';
}
function hideMsg() {
msg.style.display = 'none';
}
form.addEventListener('submit', async (e) => {
e.preventDefault();
hideMsg();
const phone = document.getElementById('phone').value.trim();
const password = document.getElementById('password').value;
if (!/^1[3-9]\d{9}$/.test(phone)) {
showMsg('请输入正确的手机号', 'error');
return;
}
if (password.length < 6) {
showMsg('密码不能少于6位', 'error');
return;
}
submitBtn.disabled = true;
submitBtn.textContent = '登录中...';
loading.style.display = 'block';
try {
const res = await fetch('http://localhost:3000/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ phone, password })
});
const data = await res.json();
if (data.code === 0) {
localStorage.setItem('auth_token', data.token);
localStorage.setItem('auth_user', JSON.stringify(data.user));
showMsg('登录成功!正在跳转...', 'success');
setTimeout(() => { window.location.href = 'devices.html'; }, 800);
} else {
showMsg(data.message || '登录失败,请检查手机号和密码', 'error');
}
} catch (err) {
showMsg('网络错误,请检查服务器是否启动', 'error');
} finally {
submitBtn.disabled = false;
submitBtn.textContent = '登录';
loading.style.display = 'none';
}
});
</script>
</body>
</html>