123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- import React, { useRef, useEffect } from 'react';
- import { Row, Col, Form, Input, Button, Card, message, Image } from 'antd';
- import type { InputRef } from 'antd';
- import { useSelector } from 'react-redux';
- import { RootState } from '../../states/store';
- import { SystemMode } from '../../states/systemModeSlice';
- import loginBrand from 'src/assets/imgs/login-brand.jpeg';
- import { useDispatch } from 'react-redux';
- import {
- login as loginApi,
- LoginApiResponse,
- } from '../../API/security/userActions';
- import { setUserInfo, type UserInfoState } from '../../states/user_info'; // 同时导入 setUserInfo 和类型 UserInfoState
- import handleEmergencyOperation from '../../domain/patient/handleEmergencyOperation';
- import { setSystemMode } from '../../states/systemModeSlice';
- const Login: React.FC = () => {
- const [form] = Form.useForm();
- const dispatch = useDispatch();
- const systemMode = useSelector((state: RootState) => state.systemMode.mode);
- const userInfo = useSelector((state: RootState) => state.userInfo);
- const usernameInputRef = useRef<InputRef>(null);
- console.log(`========${systemMode}`);
- // 自动聚焦到用户名输入框
- useEffect(() => {
- if (usernameInputRef.current) {
- usernameInputRef.current.focus();
- }
- }, []);
- if (systemMode === SystemMode.Emergency) {
- return null;
- }
- //非急诊,但已经登录,不显示login
- if (systemMode === SystemMode.Normal && !!userInfo && userInfo.uid !== 0) {
- return null;
- }
- // 2. 登录请求函数
- const loginRequest = async (values: {
- username: string;
- password: string;
- }): Promise<LoginApiResponse> => {
- const res = await loginApi(values.username, values.password);
- return res.data;
- };
- // 3. handleFinish 处理流程
- const handleFinish = async (values: {
- username: string;
- password: string;
- }): Promise<void> => {
- try {
- const result = await loginRequest(values);
- if (result.code === '0x000000') {
- // 4. 转换为 UserInfoState 类型
- const userInfo: UserInfoState = {
- token: result.data.token,
- expire: result.data.expire,
- uid: result.data.uid,
- name: result.data.name,
- avatar: result.data.avatar,
- };
- // 5. 分发 redux action
- dispatch(setUserInfo(userInfo));
- dispatch(setSystemMode(SystemMode.Normal));
- message.success('登录成功'); //todo 更详细的提示与异步过程
- } else {
- message.error(`登录失败,详情:${result.description}`);
- }
- } catch (e) {
- message.error(
- `登录失败,网络错误: ${e instanceof Error ? e.message : '未知错误'}`
- );
- }
- };
- // 急诊操作处理流程
- const handleEmergencyClick = async (
- e: React.MouseEvent<HTMLElement>
- ): Promise<void> => {
- e.preventDefault(); // 阻止表单提交
- try {
- await handleEmergencyOperation();
- message.success('急诊模式启动成功');
- } catch (e) {
- dispatch(setSystemMode(SystemMode.Normal));
- message.error(
- `急诊操作失败: ${e instanceof Error ? e.message : '未知错误'}`
- );
- console.error('Emergency operation failed:', e);
- }
- };
- return (
- <Row
- className="fixed inset-0 z-50 bg-white bg-opacity-100 w-full h-full flex items-center justify-center"
- justify="center"
- align="middle"
- >
- <Col
- xs={24}
- sm={24}
- md={14}
- lg={12}
- xl={12}
- className="flex items-center justify-center h-full"
- >
- <Card className="max-w-md shadow-lg w-[480px] max-auto">
- <Form
- form={form}
- layout="vertical"
- onFinish={handleFinish}
- className="space-y-6 "
- >
- <Form.Item
- label="用户名"
- name="username"
- rules={[{ required: true, message: '请输入用户名' }]}
- >
- <Input
- ref={usernameInputRef}
- size="large"
- placeholder="请输入用户名"
- data-testid="login-username-input"
- />
- </Form.Item>
- <Form.Item
- label="密码"
- name="password"
- rules={[{ required: true, message: '请输入密码' }]}
- >
- <Input.Password
- size="large"
- placeholder="请输入密码"
- className="py-0 px-[11px]"
- data-testid="login-password-input"
- />
- </Form.Item>
- <Form.Item>
- <Row gutter={16}>
- <Col span={12}>
- <Button
- type="primary"
- htmlType="submit"
- size="large"
- className="w-full"
- data-testid="login-submit-button"
- >
- 登录
- </Button>
- </Col>
- <Col span={12}>
- <Button
- type="primary"
- size="large"
- className="w-full"
- onClick={handleEmergencyClick}
- >
- 急诊
- </Button>
- </Col>
- </Row>
- </Form.Item>
- </Form>
- </Card>
- </Col>
- <Col
- xs={0}
- sm={0}
- md={10}
- lg={12}
- xl={12}
- className="h-full flex items-center justify-center"
- >
- {/* 右侧区域可用于展示插画或品牌信息,当前留空 */}
- <Image
- src={loginBrand}
- alt="Brand Logo"
- className="max-w-full h-auto"
- />
- </Col>
- </Row>
- );
- };
- export default Login;
|