86 lines
5.0 KiB
HTML
86 lines
5.0 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>
|
|
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
|
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
<script src="https://unpkg.com/axios@1/dist/axios.min.js"></script>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
html, body, #root { min-height: 100vh; width: 100%; }
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif; background: #1a1a2e; color: #fff; }
|
|
input, button { font-family: inherit; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
<script>
|
|
const { useState, useEffect } = React;
|
|
|
|
function Login({ onLogin }) {
|
|
const [username, setUsername] = useState('admin');
|
|
const [password, setPassword] = useState('admin123');
|
|
const [error, setError] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const handleLogin = async () => {
|
|
if (!username || !password) { setError('请输入用户名和密码'); return; }
|
|
setLoading(true); setError('');
|
|
try {
|
|
const res = await axios.post('/api/auth/login', new URLSearchParams({ username, password }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
|
|
if (res.data.access_token) {
|
|
localStorage.setItem('adminToken', res.data.access_token);
|
|
onLogin({ username: username });
|
|
} else if (res.data.code === 0) {
|
|
localStorage.setItem('adminToken', res.data.data.token);
|
|
onLogin(res.data.data.user || { username: username });
|
|
} else { setError(res.data.message || '登录失败'); }
|
|
} catch (e) { setError('网络错误: ' + (e.message || '请检查后端服务')); }
|
|
setLoading(false);
|
|
}
|
|
|
|
return React.createElement('div', { style: { minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'linear-gradient(135deg, #1a1a2e 0%, #16213e 100%)' } },
|
|
React.createElement('div', { style: { width: '360px', padding: '40px 30px', background: 'rgba(255,255,255,0.05)', borderRadius: '16px', border: '1px solid rgba(255,255,255,0.1)' } },
|
|
React.createElement('h1', { style: { textAlign: 'center', marginBottom: '30px', fontSize: '24px' } }, '甲辰管理后台'),
|
|
React.createElement('input', { type: 'text', placeholder: '请输入管理员账号', value: username, onChange: e => setUsername(e.target.value), style: { width: '100%', padding: '14px', marginBottom: '16px', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.2)', background: 'rgba(0,0,0,0.3)', color: '#fff', fontSize: '15px' } }),
|
|
React.createElement('input', { type: 'password', placeholder: '请输入密码', value: password, onChange: e => setPassword(e.target.value), onKeyPress: e => e.key === 'Enter' && handleLogin(), style: { width: '100%', padding: '14px', marginBottom: '20px', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.2)', background: 'rgba(0,0,0,0.3)', color: '#fff', fontSize: '15px' } }),
|
|
error && React.createElement('div', { style: { color: '#f87171', marginBottom: '16px', textAlign: 'center' } }, error),
|
|
React.createElement('button', { onClick: handleLogin, disabled: loading, style: { width: '100%', padding: '14px', borderRadius: '8px', border: 'none', background: 'linear-gradient(135deg, #f59e0b 0%, #d97706 100%)', color: '#fff', fontSize: '16px', cursor: loading ? 'not-allowed' : 'pointer' } }, loading ? '登录中...' : '登录')
|
|
)
|
|
);
|
|
}
|
|
|
|
function App() {
|
|
const [user, setUser] = useState(null);
|
|
|
|
useEffect(() => {
|
|
const token = localStorage.getItem('adminToken');
|
|
const userStr = localStorage.getItem('adminUser');
|
|
if (token && userStr) {
|
|
try { setUser(JSON.parse(userStr)); } catch (e) {}
|
|
}
|
|
}, []);
|
|
|
|
const handleLogout = () => {
|
|
localStorage.removeItem('adminToken');
|
|
localStorage.removeItem('adminUser');
|
|
setUser(null);
|
|
};
|
|
|
|
if (!user) return React.createElement(Login, { onLogin: (u) => { localStorage.setItem('adminUser', JSON.stringify(u)); setUser(u); } });
|
|
|
|
return React.createElement('div', { style: { minHeight: '100vh', background: '#1a1a2e', color: '#fff', padding: '20px' } },
|
|
React.createElement('h1', null, '甲辰管理后台 - 登录成功'),
|
|
React.createElement('p', null, '欢迎 ', user.username || '管理员'),
|
|
React.createElement('button', { onClick: handleLogout, style: { marginTop: '20px', padding: '10px 20px', borderRadius: '8px', border: '1px solid rgba(255,255,255,0.2)', background: 'transparent', color: '#fff', cursor: 'pointer' } }, '退出')
|
|
);
|
|
}
|
|
|
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
|
root.render(React.createElement(App));
|
|
</script>
|
|
</body>
|
|
</html>
|