|
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>登录 - 肠愈同行患者关爱</title>
- <link rel="icon" href="/static/favicon.ico" type="image/x-icon">
- <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;
- }
- 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:120px;height:120px;border-radius:50%;background:rgba(255,255,255,.95);
- display:flex;align-items:center;justify-content:center;margin:0 auto 28px;
- box-shadow:0 4px 24px rgba(0,0,0,.1);}
- .brand-logo img{width:80px;height:80px;object-fit:contain;}
- .brand-logo.no-img{background:rgba(255,255,255,.15);backdrop-filter:blur(10px);}
- .brand-logo.no-img 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;
- animation:fadeUp .5s ease both;
- }
- @keyframes fadeUp{from{opacity:0;transform:translateY(24px);}to{opacity:1;transform:translateY(0);}}
- .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;}
- </style>
- </head>
- <body>
- <div style="display:none;">
- <!-- split styles to avoid autofix issues -->
- </div>
- <style>
- .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;}
- .captcha-row{display:flex;gap:10px;align-items:center;}
- .captcha-row .input-wrap{flex:1;}
- .captcha-img{height:40px;border-radius:8px;cursor:pointer;border:1px solid var(--border);flex-shrink:0;}
- .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);
- display:flex;align-items:center;justify-content:center;gap:8px;
- }
- .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;}
- .btn-login .spinner{
- width:16px;height:16px;border:2px solid rgba(255,255,255,.3);
- border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite;display:none;
- }
- .btn-login.loading .spinner{display:block;}
- @keyframes spin{to{transform:rotate(360deg);}}
- .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>
-
- <div class="login-wrapper">
- <div class="login-left">
- <div class="brand">
- <div class="brand-logo">
- <img src="/static/images/logo.png" alt="肠愈同行患者关爱">
- </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-item">
- <label>验证码</label>
- <div class="captcha-row">
- <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="3" width="18" height="18" rx="2"/><path d="M9 9h.01M15 15h.01M9 15l6-6"/></svg>
- </span>
- <input type="text" name="captcha" id="captcha" placeholder="请输入验证码" autocomplete="off" maxlength="4" required>
- </div>
- <img class="captcha-img" id="captchaImg" src="/admin/auth/captcha" alt="验证码" title="点击刷新" onclick="this.src='/admin/auth/captcha?t='+Date.now()">
- </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">
- <span class="spinner"></span>
- <span class="btn-text">登 录</span>
- </button>
- </form>
-
- <div class="login-footer">
- © {{ now_year }} 肠愈同行患者关爱
- </div>
- </div>
- </div>
- </div>
-
- <script>
- var REMEMBER_KEY = 'cytx_admin_remember';
-
- // 页面加载时回填记住的账号密码
- (function() {
- try {
- var saved = localStorage.getItem(REMEMBER_KEY);
- if (saved) {
- var data = JSON.parse(saved);
- if (data.username) document.getElementById('username').value = data.username;
- if (data.password) document.getElementById('password').value = data.password;
- document.getElementById('remember').checked = true;
- }
- } catch(e) {}
- })();
-
- function togglePassword(){
- var input = document.getElementById('password');
- input.type = input.type === 'password' ? 'text' : 'password';
- }
-
- function refreshCaptcha(){
- document.getElementById('captchaImg').src = '/admin/auth/captcha?t=' + Date.now();
- }
-
- document.getElementById('loginForm').addEventListener('submit', function(e) {
- e.preventDefault();
- var btn = document.getElementById('submitBtn');
- var errorMsg = document.getElementById('errorMsg');
- var username = document.getElementById('username').value.trim();
- var password = document.getElementById('password').value;
- var captcha = document.getElementById('captcha').value.trim();
- var remember = document.getElementById('remember').checked;
-
- if (!username || !password) {
- errorMsg.textContent = '请输入用户名和密码';
- errorMsg.classList.add('show');
- return;
- }
- if (!captcha) {
- errorMsg.textContent = '请输入验证码';
- errorMsg.classList.add('show');
- return;
- }
-
- btn.disabled = true;
- btn.classList.add('loading');
- btn.querySelector('.btn-text').textContent = '登录中...';
- errorMsg.classList.remove('show');
-
- fetch('/admin/auth/login', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ username: username, password: password, captcha: captcha, remember: remember })
- }).then(function(res) {
- return res.json();
- }).then(function(data) {
- if (data.code === 0) {
- // 登录成功:记住我则存 localStorage,否则清除
- if (remember) {
- localStorage.setItem(REMEMBER_KEY, JSON.stringify({ username: username, password: password }));
- } else {
- localStorage.removeItem(REMEMBER_KEY);
- }
- window.location.href = '/admin/dashboard.html';
- } else {
- errorMsg.textContent = data.msg || '登录失败';
- errorMsg.classList.add('show');
- refreshCaptcha();
- document.getElementById('captcha').value = '';
- btn.disabled = false;
- btn.classList.remove('loading');
- btn.querySelector('.btn-text').textContent = '登 录';
- }
- }).catch(function() {
- errorMsg.textContent = '网络错误,请稍后重试';
- errorMsg.classList.add('show');
- refreshCaptcha();
- btn.disabled = false;
- btn.classList.remove('loading');
- btn.querySelector('.btn-text').textContent = '登 录';
- });
- });
- </script>
-
- </body>
- </html>
|