添加了相关测试文件,引入Tailwindcss

Change-Id: I12054143571bb688590af0357125a0ed26ff2050
diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx
new file mode 100644
index 0000000..f27ac02
--- /dev/null
+++ b/src/pages/Login.jsx
@@ -0,0 +1,114 @@
+import React, { useState } from 'react';
+import { useNavigate, Link } from 'react-router-dom';
+import { Form, Input, Button, Checkbox, Card, message, Typography, Space, Divider } from 'antd';
+import { UserOutlined, LockOutlined } from '@ant-design/icons';
+import request from '../utils/request'; // 替换为我们的请求工具
+
+const { Title, Text } = Typography;
+
+const Login = () => {
+  const [loading, setLoading] = useState(false);
+  const navigate = useNavigate();
+
+  const onFinish = async (values) => {
+    setLoading(true);
+    try {
+      const response = await request.post('/api/auth/login', {
+        username: values.username,
+        password: values.password
+      });
+      
+      if (response.data.code === 200) {
+        // 登录成功
+        localStorage.setItem('token', response.data.data.token);
+        localStorage.setItem('user', JSON.stringify(response.data.data.user));
+        
+        // 存储用户权限信息
+        if (response.data.data.permissions) {
+          localStorage.setItem('permissions', JSON.stringify(response.data.data.permissions));
+        }
+        
+        message.success('登录成功');
+        navigate('/');
+      } else {
+        message.error(response.data.message || '登录失败');
+      }
+    } catch (error) {
+      console.error('登录错误:', error);
+      // 错误处理已在拦截器中完成,这里不需要额外处理
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  return (
+    <div className="flex justify-center items-center min-h-screen bg-gray-100 p-4">
+      <Card className="w-full max-w-md shadow-lg">
+        <div className="text-center mb-6">
+          <Title level={2} className="mb-2">PT网站登录</Title>
+          <Text type="secondary">欢迎回来,请登录您的账号</Text>
+        </div>
+        
+        <Form
+          name="login"
+          initialValues={{ remember: true }}
+          onFinish={onFinish}
+          size="large"
+          layout="vertical"
+        >
+          <Form.Item
+            name="username"
+            rules={[{ required: true, message: '请输入用户名!' }]}
+          >
+            <Input prefix={<UserOutlined />} placeholder="用户名" />
+          </Form.Item>
+          
+          <Form.Item
+            name="password"
+            rules={[{ required: true, message: '请输入密码!' }]}
+          >
+            <Input.Password prefix={<LockOutlined />} placeholder="密码" />
+          </Form.Item>
+          
+          <Form.Item>
+            <div className="flex justify-between items-center">
+              <Form.Item name="remember" valuePropName="checked" noStyle>
+                <Checkbox>记住我</Checkbox>
+              </Form.Item>
+              <a className="text-blue-500 hover:text-blue-700" href="#">
+                忘记密码
+              </a>
+            </div>
+          </Form.Item>
+
+          <Form.Item>
+            <Button type="primary" htmlType="submit" className="w-full" loading={loading}>
+              登录
+            </Button>
+          </Form.Item>
+          
+          <Divider plain>或者</Divider>
+          
+          <div className="text-center">
+            <Text type="secondary" className="mr-2">还没有账号?</Text>
+            <Link to="/register" className="text-blue-500 hover:text-blue-700">立即注册</Link>
+          </div>
+        </Form>
+        
+        <div className="mt-6 p-4 bg-gray-50 rounded-md">
+          <Text type="secondary" className="block mb-2">提示:测试账号</Text>
+          <ul className="space-y-1 text-sm text-gray-600">
+            <li>管理员: admin / admin123</li>
+            <li>普通用户: user / user123</li>
+            <li>版主: moderator / mod123</li>
+            <li>老手: veteran / vet123</li>
+            <li>新人: newbie / new123</li>
+            <li>黑户: blacklisted / black123</li>
+          </ul>
+        </div>
+      </Card>
+    </div>
+  );
+};
+
+export default Login;
\ No newline at end of file