|
- <!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>
- *,*::before,*::after{margin:0;padding:0;box-sizing:border-box;}
- :root{
- --primary:#E8751A;
- --primary-dark:#C96012;
- --primary-light:#F5A623;
- --blue:#1A3550;
- --white:#fff;
- --bg:#f0f2f5;
- --text:#303133;
- --text-secondary:#909399;
- --border:#dcdfe6;
- --danger:#f56c6c;
- --font-cn:"Source Han Sans SC","Noto Sans SC","PingFang SC","Microsoft YaHei",sans-serif;
- --font-en:"Roboto",sans-serif;
- }
- html,body{height:100%;font-family:var(--font-cn);color:var(--text);}
-
- .login-wrapper{display:flex;height:100vh;}
-
- /* 左侧品牌区 */
- .login-left{
- flex:0 0 50%;display:flex;flex-direction:column;align-items:center;justify-content:center;
- background:linear-gradient(135deg,var(--primary) 0%,var(--primary-dark) 100%);
- position:relative;overflow:hidden;
- }
- .login-left::before{
- content:"";position:absolute;width:600px;height:600px;border-radius:50%;
- background:rgba(255,255,255,.06);top:-120px;right:-180px;
- }
- .login-left::after{
- content:"";position:absolute;width:400px;height:400px;border-radius:50%;
- background:rgba(255,255,255,.04);bottom:-80px;left:-100px;
- }
- .brand{position:relative;z-index:1;text-align:center;color:var(--white);padding:0 60px;}
- .brand-logo{width:80px;height:80px;background:rgba(255,255,255,.15);border-radius:20px;
- display:flex;align-items:center;justify-content:center;margin:0 auto 28px;backdrop-filter:blur(10px);}
- .brand-logo svg{width:44px;height:44px;}
- .brand h1{font-size:28px;font-weight:700;margin-bottom:12px;letter-spacing:1px;}
- .brand p{font-size:14px;opacity:.75;line-height:1.8;max-width:360px;}
-
- /* 右侧表单区 */
- .login-right{flex:1;display:flex;align-items:center;justify-content:center;background:var(--bg);}
- .login-box{
- width:400px;background:var(--white);border-radius:12px;
- box-shadow:0 2px 12px rgba(0,0,0,.08);padding:48px 40px;
- }
- .login-box h2{font-size:22px;font-weight:600;color:var(--text);margin-bottom:6px;}
- .login-box .subtitle{font-size:13px;color:var(--text-secondary);margin-bottom:32px;}
-
- /* 表单 */
- .form-item{margin-bottom:22px;}
- .form-item label{display:block;font-size:13px;color:var(--text);font-weight:500;margin-bottom:8px;}
- .input-wrap{
- position:relative;display:flex;align-items:center;
- border:1px solid var(--border);border-radius:8px;transition:.2s;background:var(--white);
- }
- .input-wrap:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px rgba(232,117,26,.1);}
- .input-wrap .icon{position:absolute;left:12px;color:var(--text-secondary);display:flex;align-items:center;}
- .input-wrap .icon svg{width:18px;height:18px;}
- .input-wrap input{
- width:100%;border:none;outline:none;padding:11px 12px 11px 40px;
- font-size:14px;font-family:var(--font-cn);color:var(--text);background:transparent;border-radius:8px;
- }
- .input-wrap input::placeholder{color:#c0c4cc;}
- .input-wrap .toggle-pwd{
- position:absolute;right:12px;cursor:pointer;color:var(--text-secondary);
- display:flex;align-items:center;background:none;border:none;padding:0;
- }
- .input-wrap .toggle-pwd:hover{color:var(--primary);}
- .input-wrap .toggle-pwd svg{width:18px;height:18px;}
-
- .form-options{display:flex;align-items:center;justify-content:space-between;margin-bottom:28px;}
- .remember{display:flex;align-items:center;gap:6px;cursor:pointer;font-size:13px;color:var(--text-secondary);}
- .remember input[type="checkbox"]{width:16px;height:16px;accent-color:var(--primary);cursor:pointer;}
-
- .btn-login{
- width:100%;padding:12px 0;border:none;border-radius:8px;
- background:linear-gradient(135deg,var(--primary),var(--primary-dark));
- color:var(--white);font-size:15px;font-weight:600;cursor:pointer;
- transition:.25s;letter-spacing:1px;font-family:var(--font-cn);
- }
- .btn-login:hover{transform:translateY(-1px);box-shadow:0 6px 20px rgba(232,117,26,.35);}
- .btn-login:active{transform:translateY(0);}
- .btn-login:disabled{opacity:.6;cursor:not-allowed;transform:none;box-shadow:none;}
-
- .login-footer{text-align:center;margin-top:24px;font-size:12px;color:var(--text-secondary);}
-
- .error-msg{color:var(--danger);font-size:13px;margin-bottom:16px;display:none;}
- .error-msg.show{display:block;}
-
- @media(max-width:960px){
- .login-left{display:none;}
- .login-right{background:linear-gradient(135deg,#fdf0e6 0%,var(--bg) 100%);}
- }
- @media(max-width:480px){
- .login-box{width:100%;margin:0 20px;padding:36px 28px;}
- }
- </style>
- </head>
- <body>
-
- <div class="login-wrapper">
- <div class="login-left">
- <div class="brand">
- <div class="brand-logo">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
- <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
- </svg>
- </div>
- <h1>北京维康慈善基金会</h1>
- <p>官网内容管理系统<br>致力于妇幼健康、患者关爱、卫生健康促进等公益事业</p>
- </div>
- </div>
-
- <div class="login-right">
- <div class="login-box">
- <h2>欢迎回来</h2>
- <p class="subtitle">请登录您的管理员账号</p>
-
- <form id="loginForm">
- <div class="error-msg" id="errorMsg"></div>
-
- <div class="form-item">
- <label>用户名</label>
- <div class="input-wrap">
- <span class="icon">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
- </span>
- <input type="text" name="username" id="username" placeholder="请输入用户名" autocomplete="username" required>
- </div>
- </div>
-
- <div class="form-item">
- <label>密码</label>
- <div class="input-wrap">
- <span class="icon">
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
- </span>
- <input type="password" name="password" id="password" placeholder="请输入密码" autocomplete="current-password" required>
- <button type="button" class="toggle-pwd" onclick="togglePassword()" aria-label="显示密码">
- <svg id="eyeIcon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
- </button>
- </div>
- </div>
-
- <div class="form-options">
- <label class="remember">
- <input type="checkbox" name="remember" id="remember"> 记住我
- </label>
- </div>
-
- <button type="submit" class="btn-login" id="submitBtn">登 录</button>
- </form>
-
- <div class="login-footer">
- © <span id="currentYear"></span> 北京维康慈善基金会 · 内容管理系统
- </div>
- </div>
- </div>
- </div>
-
- <script>
- document.getElementById('currentYear').textContent = new Date().getFullYear();
-
- function togglePassword(){
- const input = document.getElementById('password');
- input.type = input.type === 'password' ? 'text' : 'password';
- }
-
- document.getElementById('loginForm').addEventListener('submit', async function(e) {
- e.preventDefault();
- const btn = document.getElementById('submitBtn');
- const errorMsg = document.getElementById('errorMsg');
- const username = document.getElementById('username').value.trim();
- const password = document.getElementById('password').value;
- const remember = document.getElementById('remember').checked;
-
- if (!username || !password) {
- errorMsg.textContent = '请输入用户名和密码';
- errorMsg.classList.add('show');
- return;
- }
-
- btn.disabled = true;
- btn.textContent = '登录中...';
- errorMsg.classList.remove('show');
-
- try {
- const res = await fetch('/admin/auth/login', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ username, password, remember })
- });
- const data = await res.json();
- if (data.errno === 0) {
- window.location.href = '/admin/dashboard.html';
- } else {
- errorMsg.textContent = data.errmsg || '登录失败';
- errorMsg.classList.add('show');
- }
- } catch (err) {
- errorMsg.textContent = '网络错误,请稍后重试';
- errorMsg.classList.add('show');
- } finally {
- btn.disabled = false;
- btn.textContent = '登 录';
- }
- });
- </script>
-
- </body>
- </html>
|