feat: 路由登录 动态路由重定向

This commit is contained in:
2026-01-26 17:59:52 +08:00
parent 502c236b0d
commit a5d3342d93
3 changed files with 102 additions and 194 deletions

View File

@@ -1,4 +1,3 @@
import { getTenantIdByName, login } from "@/services/login";
import {
AlipayOutlined,
LockOutlined,
@@ -6,34 +5,36 @@ import {
TaobaoOutlined,
UserOutlined,
WeiboOutlined,
} from "@ant-design/icons";
} from '@ant-design/icons';
import {
LoginFormPage,
ProConfigProvider,
ProFormCaptcha,
ProFormCheckbox,
ProFormText,
} from "@ant-design/pro-components";
import { history, useModel, useNavigate } from "@umijs/max";
import { Button, Divider, Space, Tabs, theme, message } from "antd";
import type { CSSProperties } from "react";
import { useState } from "react";
import * as authUtil from "@/utils/auth";
import { flushSync } from "react-dom";
type LoginType = "phone" | "account";
} from '@ant-design/pro-components';
import { history, useModel, useNavigate } from '@umijs/max';
import { Button, Divider, message, Space, Tabs, theme } from 'antd';
import type { CSSProperties } from 'react';
import { useState } from 'react';
import { flushSync } from 'react-dom';
import { getTenantIdByName, login } from '@/services/login';
import * as authUtil from '@/utils/auth';
type LoginType = 'phone' | 'account';
const iconStyles: CSSProperties = {
color: "rgba(0, 0, 0, 0.2)",
fontSize: "18px",
verticalAlign: "middle",
cursor: "pointer",
color: 'rgba(0, 0, 0, 0.2)',
fontSize: '18px',
verticalAlign: 'middle',
cursor: 'pointer',
};
const Page = () => {
const [loginType, setLoginType] = useState<LoginType>("account");
const [loginType, setLoginType] = useState<LoginType>('account');
const { token } = theme.useToken();
const [messageApi, contextHolder] = message.useMessage();
const { initialState, setInitialState } = useModel("@@initialState");
const { initialState, setInitialState } = useModel('@@initialState');
const navigate = useNavigate();
// 获取租户 ID
const getTenantId = async (name: string) => {
@@ -57,7 +58,7 @@ const Page = () => {
try {
// 根据登录类型处理不同的参数
const params = {
tenantName: "芋道源码",
tenantName: '芋道源码',
...values,
};
@@ -71,21 +72,22 @@ const Page = () => {
// 调用登录接口
const data = await login(params);
// 登录成功
messageApi.success("登录成功!");
messageApi.success('登录成功!');
// 跳转到首页
authUtil.setToken(data);
await fetchUserInfo();
const urlParams = new URL(window.location.href).searchParams;
navigate(urlParams.get("redirect") || "/");
// navigate(urlParams.get("redirect") || "/");
window.location.href = urlParams.get('redirect') || '/';
} catch (error) {
messageApi.error("登录失败,请检查网络或稍后重试!");
messageApi.error('登录失败,请检查网络或稍后重试!');
}
};
return (
<div
style={{
backgroundColor: "white",
height: "100vh",
backgroundColor: 'white',
height: '100vh',
}}
>
{contextHolder}
@@ -95,8 +97,8 @@ const Page = () => {
backgroundVideoUrl="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr"
// title="BY"
containerStyle={{
backgroundColor: "rgb(0 0 0 / 51%)",
backdropFilter: "blur(4px)",
backgroundColor: 'rgb(0 0 0 / 51%)',
backdropFilter: 'blur(4px)',
}}
onFinish={handleSubmit}
subTitle="百业到家云控台"
@@ -127,17 +129,17 @@ const Page = () => {
actions={
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Divider plain>
<span
style={{
color: token.colorTextPlaceholder,
fontWeight: "normal",
fontWeight: 'normal',
fontSize: 14,
}}
>
@@ -147,48 +149,48 @@ const Page = () => {
<Space align="center" size={24}>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
height: 40,
width: 40,
border: "1px solid " + token.colorPrimaryBorder,
border: '1px solid ' + token.colorPrimaryBorder,
background: token.colorBgContainer,
borderRadius: "50%",
borderRadius: '50%',
}}
>
<AlipayOutlined style={{ ...iconStyles, color: "#1677FF" }} />
<AlipayOutlined style={{ ...iconStyles, color: '#1677FF' }} />
</div>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
height: 40,
width: 40,
border: "1px solid " + token.colorPrimaryBorder,
border: '1px solid ' + token.colorPrimaryBorder,
background: token.colorBgContainer,
borderRadius: "50%",
borderRadius: '50%',
}}
>
<TaobaoOutlined style={{ ...iconStyles, color: "#FF6A10" }} />
<TaobaoOutlined style={{ ...iconStyles, color: '#FF6A10' }} />
</div>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
height: 40,
width: 40,
background: token.colorBgContainer,
border: "1px solid " + token.colorPrimaryBorder,
borderRadius: "50%",
border: '1px solid ' + token.colorPrimaryBorder,
borderRadius: '50%',
}}
>
<WeiboOutlined style={{ ...iconStyles, color: "#1890ff" }} />
<WeiboOutlined style={{ ...iconStyles, color: '#1890ff' }} />
</div>
</Space>
</div>
@@ -199,125 +201,125 @@ const Page = () => {
activeKey={loginType}
onChange={(activeKey) => setLoginType(activeKey as LoginType)}
>
<Tabs.TabPane key={"account"} tab={"账号密码登录"} />
<Tabs.TabPane key={"phone"} tab={"手机号登录"} />
<Tabs.TabPane key={'account'} tab={'账号密码登录'} />
<Tabs.TabPane key={'phone'} tab={'手机号登录'} />
</Tabs>
{loginType === "account" && (
{loginType === 'account' && (
<>
<ProFormText
name="username"
fieldProps={{
size: "large",
size: 'large',
prefix: (
<UserOutlined
style={{
color: token.colorText,
}}
className={"prefixIcon"}
className={'prefixIcon'}
/>
),
style: {
backgroundColor: "rgb(0 0 0 / 77%)",
color: "white",
backgroundColor: 'rgb(0 0 0 / 77%)',
color: 'white',
},
}}
placeholder={"用户名: admin or user"}
placeholder={'用户名: admin or user'}
rules={[
{
required: true,
message: "请输入用户名!",
message: '请输入用户名!',
},
]}
/>
<ProFormText.Password
name="password"
fieldProps={{
size: "large",
size: 'large',
prefix: (
<LockOutlined
style={{
color: token.colorText,
}}
className={"prefixIcon"}
className={'prefixIcon'}
/>
),
style: {
backgroundColor: "rgb(0 0 0 / 77%)",
color: "white",
backgroundColor: 'rgb(0 0 0 / 77%)',
color: 'white',
},
}}
placeholder={"密码: ant.design"}
placeholder={'密码: ant.design'}
rules={[
{
required: true,
message: "请输入密码!",
message: '请输入密码!',
},
]}
/>
</>
)}
{loginType === "phone" && (
{loginType === 'phone' && (
<>
<ProFormText
fieldProps={{
size: "large",
size: 'large',
prefix: (
<MobileOutlined
style={{
color: token.colorText,
}}
className={"prefixIcon"}
className={'prefixIcon'}
/>
),
style: {
backgroundColor: "rgb(0 0 0 / 77%)",
color: "white",
backgroundColor: 'rgb(0 0 0 / 77%)',
color: 'white',
},
}}
name="mobile"
placeholder={"手机号"}
placeholder={'手机号'}
rules={[
{
required: true,
message: "请输入手机号!",
message: '请输入手机号!',
},
{
pattern: /^1\d{10}$/,
message: "手机号格式错误!",
message: '手机号格式错误!',
},
]}
/>
<ProFormCaptcha
fieldProps={{
size: "large",
size: 'large',
prefix: (
<LockOutlined
style={{
color: token.colorText,
}}
className={"prefixIcon"}
className={'prefixIcon'}
/>
),
}}
captchaProps={{
size: "large",
size: 'large',
}}
placeholder={"请输入验证码"}
placeholder={'请输入验证码'}
captchaTextRender={(timing, count) => {
if (timing) {
return `${count} ${"获取验证码"}`;
return `${count} ${'获取验证码'}`;
}
return "获取验证码";
return '获取验证码';
}}
name="captcha"
rules={[
{
required: true,
message: "请输入验证码!",
message: '请输入验证码!',
},
]}
onGetCaptcha={async () => {
message.success("获取验证码成功验证码为1234");
message.success('获取验证码成功验证码为1234');
}}
/>
</>
@@ -332,7 +334,7 @@ const Page = () => {
</ProFormCheckbox>
<a
style={{
float: "right",
float: 'right',
}}
>