- Run cargo fmt on all Rust crates for consistent formatting - Update CLAUDE.md with WASM plugin commands and dev.ps1 instructions - Update wiki: add WASM plugin architecture, rewrite dev environment docs - Minor frontend cleanup (unused imports)
209 lines
6.4 KiB
TypeScript
209 lines
6.4 KiB
TypeScript
import { useNavigate } from 'react-router-dom';
|
|
import { Form, Input, Button, message, Divider } from 'antd';
|
|
import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons';
|
|
import { useAuthStore } from '../stores/auth';
|
|
|
|
export default function Login() {
|
|
const navigate = useNavigate();
|
|
const login = useAuthStore((s) => s.login);
|
|
const loading = useAuthStore((s) => s.loading);
|
|
const [messageApi, contextHolder] = message.useMessage();
|
|
|
|
const onFinish = async (values: { username: string; password: string }) => {
|
|
try {
|
|
await login(values.username, values.password);
|
|
messageApi.success('登录成功');
|
|
navigate('/');
|
|
} catch (err: unknown) {
|
|
const errorMsg =
|
|
(err as { response?: { data?: { message?: string } } })?.response?.data?.message ||
|
|
'登录失败,请检查用户名和密码';
|
|
messageApi.error(errorMsg);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div style={{ display: 'flex', minHeight: '100vh' }}>
|
|
{contextHolder}
|
|
|
|
{/* 左侧品牌展示区 */}
|
|
<div
|
|
style={{
|
|
flex: 1,
|
|
background: 'linear-gradient(135deg, #312E81 0%, #4F46E5 50%, #6366F1 100%)',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
padding: '60px',
|
|
position: 'relative',
|
|
overflow: 'hidden',
|
|
}}
|
|
>
|
|
{/* 装饰性背景元素 */}
|
|
<div
|
|
style={{
|
|
position: 'absolute',
|
|
top: '-20%',
|
|
right: '-10%',
|
|
width: '500px',
|
|
height: '500px',
|
|
borderRadius: '50%',
|
|
background: 'rgba(255, 255, 255, 0.05)',
|
|
}}
|
|
/>
|
|
<div
|
|
style={{
|
|
position: 'absolute',
|
|
bottom: '-15%',
|
|
left: '-8%',
|
|
width: '400px',
|
|
height: '400px',
|
|
borderRadius: '50%',
|
|
background: 'rgba(255, 255, 255, 0.03)',
|
|
}}
|
|
/>
|
|
|
|
{/* 品牌内容 */}
|
|
<div style={{ position: 'relative', zIndex: 1, textAlign: 'center', maxWidth: '480px' }}>
|
|
<div
|
|
style={{
|
|
width: 64,
|
|
height: 64,
|
|
borderRadius: 16,
|
|
background: 'rgba(255, 255, 255, 0.15)',
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
margin: '0 auto 32px',
|
|
backdropFilter: 'blur(8px)',
|
|
border: '1px solid rgba(255, 255, 255, 0.2)',
|
|
}}
|
|
>
|
|
<SafetyCertificateOutlined style={{ fontSize: 32, color: '#fff' }} />
|
|
</div>
|
|
|
|
<h1
|
|
style={{
|
|
color: '#fff',
|
|
fontSize: 36,
|
|
fontWeight: 800,
|
|
margin: '0 0 16px',
|
|
letterSpacing: '-1px',
|
|
lineHeight: 1.2,
|
|
}}
|
|
>
|
|
ERP Platform
|
|
</h1>
|
|
<p
|
|
style={{
|
|
color: 'rgba(255, 255, 255, 0.7)',
|
|
fontSize: 16,
|
|
lineHeight: 1.6,
|
|
margin: 0,
|
|
}}
|
|
>
|
|
新一代模块化企业资源管理平台
|
|
</p>
|
|
<p
|
|
style={{
|
|
color: 'rgba(255, 255, 255, 0.5)',
|
|
fontSize: 14,
|
|
lineHeight: 1.6,
|
|
marginTop: 8,
|
|
}}
|
|
>
|
|
身份权限 · 工作流引擎 · 消息中心 · 系统配置
|
|
</p>
|
|
|
|
{/* 底部特性点 */}
|
|
<div style={{ marginTop: 48, display: 'flex', gap: 32, justifyContent: 'center' }}>
|
|
{[
|
|
{ label: '多租户架构', value: 'SaaS' },
|
|
{ label: '模块化设计', value: '可插拔' },
|
|
{ label: '事件驱动', value: '可扩展' },
|
|
].map((item) => (
|
|
<div key={item.label} style={{ textAlign: 'center' }}>
|
|
<div style={{ color: 'rgba(255, 255, 255, 0.9)', fontSize: 18, fontWeight: 700 }}>
|
|
{item.value}
|
|
</div>
|
|
<div style={{ color: 'rgba(255, 255, 255, 0.5)', fontSize: 12, marginTop: 4 }}>
|
|
{item.label}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 右侧登录表单区 */}
|
|
<main
|
|
style={{
|
|
width: 480,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
padding: '60px',
|
|
background: '#fff',
|
|
}}
|
|
>
|
|
<div style={{ maxWidth: 360, width: '100%', margin: '0 auto' }}>
|
|
<h2 style={{ marginBottom: 4, fontWeight: 700, fontSize: 24 }}>
|
|
欢迎回来
|
|
</h2>
|
|
<p style={{ fontSize: 14, color: '#64748B' }}>
|
|
请登录您的账户以继续
|
|
</p>
|
|
|
|
<Divider style={{ margin: '24px 0' }} />
|
|
|
|
<Form name="login" onFinish={onFinish} autoComplete="off" size="large" layout="vertical">
|
|
<Form.Item
|
|
name="username"
|
|
rules={[{ required: true, message: '请输入用户名' }]}
|
|
>
|
|
<Input
|
|
prefix={<UserOutlined style={{ color: '#94A3B8' }} />}
|
|
placeholder="用户名"
|
|
style={{ height: 44, borderRadius: 10 }}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="password"
|
|
rules={[{ required: true, message: '请输入密码' }]}
|
|
>
|
|
<Input.Password
|
|
prefix={<LockOutlined style={{ color: '#94A3B8' }} />}
|
|
placeholder="密码"
|
|
style={{ height: 44, borderRadius: 10 }}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item style={{ marginBottom: 0 }}>
|
|
<Button
|
|
type="primary"
|
|
htmlType="submit"
|
|
loading={loading}
|
|
block
|
|
style={{
|
|
height: 44,
|
|
borderRadius: 10,
|
|
fontSize: 15,
|
|
fontWeight: 600,
|
|
}}
|
|
>
|
|
登录
|
|
</Button>
|
|
</Form.Item>
|
|
</Form>
|
|
|
|
<div style={{ marginTop: 32, textAlign: 'center' }}>
|
|
<p style={{ fontSize: 12, color: '#64748B', margin: 0 }}>
|
|
ERP Platform v0.1.0 · Powered by Rust + React
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
);
|
|
}
|