Files
chat-one-admin-web/src/pages/login/index.tsx
alboped c4872891f8 feat: 实现大模型模型列表与供应商管理,并接入 Playwright 测试
补齐 LLM 子菜单路由,落地模型列表与供应商管理页面交互,同时引入功能与视觉回归用例以便后续页面持续验证。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 02:01:40 +08:00

217 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { LockOutlined, MobileOutlined, UserOutlined } from '@ant-design/icons';
import {
LoginFormPage,
ProConfigProvider,
ProFormCaptcha,
ProFormCheckbox,
ProFormText,
} from '@ant-design/pro-components';
import { Tabs, message, theme } from 'antd';
import { useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { login, getUserInfo } from '@/api/auth';
import { useUserStore } from '@/stores/user';
import type { LoginType } from '@/api/types/auth';
import type { LoginAccountParams } from '@/api/types/auth';
import logo from '@/assets/logo.png';
const LoginFrom = () => {
const [loginType, setLoginType] = useState<LoginType>('account');
const { token } = theme.useToken();
const setToken = useUserStore(s => s.setToken);
const setUserInfo = useUserStore(s => s.setUserInfo);
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const onFinish = async (values: LoginAccountParams) => {
console.log(values);
if (loginType !== 'account') {
message.warning('暂不支持短信登录');
return;
}
const res = await login(values);
if (res.code !== 200) {
message.error(res.message);
return;
}
const userInfo = await getUserInfo();
if (userInfo.code !== 200) {
message.error(userInfo.message);
return;
}
setToken(res.data.token);
setUserInfo(userInfo.data);
message.success('登录成功');
const redirect = searchParams.get('redirect') || '/dashboard';
navigate(redirect, { replace: true });
};
return (
<div
style={{
backgroundColor: 'white',
height: '100vh',
}}
>
<LoginFormPage
backgroundImageUrl="https://mdn.alipayobjects.com/huamei_gcee1x/afts/img/A*y0ZTS6WLwvgAAAAAAAAAAAAADml6AQ/fmt.webp"
logo={logo}
backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr"
title="ChatOne"
containerStyle={{
backgroundColor: 'rgba(0, 0, 0,0.65)',
backdropFilter: 'blur(4px)',
}}
subTitle="整合AI聊天管理平台"
onFinish={onFinish}
>
<Tabs
items={[
{ key: 'account', label: '账号密码登录' },
{ key: 'phone', label: '手机号登录' },
]}
onChange={key => setLoginType(key as LoginType)}
activeKey={loginType}
/>
{loginType === 'account' && (
<>
<ProFormText
name="username"
fieldProps={{
size: 'large',
prefix: (
<UserOutlined
style={{
color: token.colorText,
}}
className={'prefixIcon'}
/>
),
}}
placeholder={'用户名: admin or user'}
rules={[
{
required: true,
message: '请输入用户名!',
},
]}
/>
<ProFormText.Password
name="password"
fieldProps={{
size: 'large',
prefix: (
<LockOutlined
style={{
color: token.colorText,
}}
className={'prefixIcon'}
/>
),
}}
placeholder={'密码: 123456'}
rules={[
{
required: true,
message: '请输入密码!',
},
]}
/>
</>
)}
{loginType === 'phone' && (
<>
<ProFormText
fieldProps={{
size: 'large',
prefix: (
<MobileOutlined
style={{
color: token.colorText,
}}
className={'prefixIcon'}
/>
),
}}
name="mobile"
placeholder={'手机号'}
rules={[
{
required: true,
message: '请输入手机号!',
},
{
pattern: /^1\d{10}$/,
message: '手机号格式错误!',
},
]}
/>
<ProFormCaptcha
fieldProps={{
size: 'large',
prefix: (
<LockOutlined
style={{
color: token.colorText,
}}
className={'prefixIcon'}
/>
),
}}
captchaProps={{
size: 'large',
}}
placeholder={'请输入验证码'}
captchaTextRender={(timing, count) => {
if (timing) {
return `${count} ${'获取验证码'}`;
}
return '获取验证码';
}}
name="captcha"
rules={[
{
required: true,
message: '请输入验证码!',
},
]}
onGetCaptcha={async () => {
message.success('获取验证码成功验证码为1234');
}}
/>
</>
)}
<div
style={{
marginBlockEnd: 24,
}}
>
<ProFormCheckbox noStyle name="autoLogin">
</ProFormCheckbox>
<a
style={{
float: 'right',
}}
>
</a>
</div>
</LoginFormPage>
</div>
);
};
export default function Login() {
return (
<ProConfigProvider dark>
<LoginFrom />
</ProConfigProvider>
);
}