Login.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import React, { useState } from 'react';
  2. import {
  3. Form,
  4. Input,
  5. Button,
  6. Card,
  7. message,
  8. } from 'antd';
  9. import {
  10. UserOutlined,
  11. } from '@ant-design/icons';
  12. import { useNavigate } from 'react-router';
  13. import {
  14. useAuth,
  15. } from '../hooks/AuthProvider';
  16. // 登录页面
  17. export const LoginPage = () => {
  18. const { login } = useAuth();
  19. const [form] = Form.useForm();
  20. const [loading, setLoading] = useState(false);
  21. const navigate = useNavigate();
  22. const handleSubmit = async (values: { username: string; password: string }) => {
  23. try {
  24. setLoading(true);
  25. // 获取地理位置
  26. let latitude: number | undefined;
  27. let longitude: number | undefined;
  28. try {
  29. if (navigator.geolocation) {
  30. const position = await new Promise<GeolocationPosition>((resolve, reject) => {
  31. navigator.geolocation.getCurrentPosition(resolve, reject);
  32. });
  33. latitude = position.coords.latitude;
  34. longitude = position.coords.longitude;
  35. }
  36. } catch (geoError) {
  37. console.warn('获取地理位置失败:', geoError);
  38. }
  39. await login(values.username, values.password, latitude, longitude);
  40. // 登录成功后跳转到管理后台首页
  41. navigate('/admin/dashboard');
  42. } catch (error: any) {
  43. message.error(error.response?.data?.error || '登录失败');
  44. } finally {
  45. setLoading(false);
  46. }
  47. };
  48. return (
  49. <div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
  50. <div className="max-w-md w-full space-y-8">
  51. <div>
  52. <h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
  53. 登录管理后台
  54. </h2>
  55. </div>
  56. <Card>
  57. <Form
  58. form={form}
  59. name="login"
  60. onFinish={handleSubmit}
  61. autoComplete="off"
  62. layout="vertical"
  63. >
  64. <Form.Item
  65. name="username"
  66. rules={[{ required: true, message: '请输入用户名' }]}
  67. >
  68. <Input
  69. prefix={<UserOutlined />}
  70. placeholder="用户名"
  71. size="large"
  72. />
  73. </Form.Item>
  74. <Form.Item
  75. name="password"
  76. rules={[{ required: true, message: '请输入密码' }]}
  77. >
  78. <Input.Password
  79. placeholder="密码"
  80. size="large"
  81. />
  82. </Form.Item>
  83. <Form.Item>
  84. <Button
  85. type="primary"
  86. htmlType="submit"
  87. size="large"
  88. block
  89. loading={loading}
  90. >
  91. 登录
  92. </Button>
  93. </Form.Item>
  94. </Form>
  95. <div className="mt-4 text-center text-gray-500">
  96. <p>测试账号: admin / admin123</p>
  97. {/* <p>普通账号: user1 / 123456</p> */}
  98. </div>
  99. </Card>
  100. </div>
  101. </div>
  102. );
  103. };