mirror of
https://github.com/PlayEdu/backend
synced 2025-06-15 17:57:01 +08:00
登录跳转以及登录相关store
This commit is contained in:
parent
5a677f3302
commit
bfda92dd3a
@ -18,6 +18,7 @@
|
|||||||
"react-router-dom": "^6.8.2",
|
"react-router-dom": "^6.8.2",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
"redux": "^4.2.1",
|
"redux": "^4.2.1",
|
||||||
|
"redux-thunk": "^2.4.2",
|
||||||
"typescript": "^4.4.2",
|
"typescript": "^4.4.2",
|
||||||
"web-vitals": "^2.1.0"
|
"web-vitals": "^2.1.0"
|
||||||
},
|
},
|
||||||
|
25
src/App.tsx
25
src/App.tsx
@ -3,9 +3,25 @@ import styles from "./App.module.css";
|
|||||||
import { useLocation, useRoutes, useNavigate } from "react-router-dom";
|
import { useLocation, useRoutes, useNavigate } from "react-router-dom";
|
||||||
import routes from "./router/routes";
|
import routes from "./router/routes";
|
||||||
import { getToken } from "./utils/index";
|
import { getToken } from "./utils/index";
|
||||||
|
import { login } from "./api/index";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import {
|
||||||
|
IsLoginActionCreator,
|
||||||
|
SetUserActionCreator,
|
||||||
|
SetPermisssionsActionCreator,
|
||||||
|
} from "./store/user/userActions";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const Views = () => useRoutes(routes);
|
const Views = () => useRoutes(routes);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const getUser = () => {
|
||||||
|
login.getUser().then((res: any) => {
|
||||||
|
const data = res.data;
|
||||||
|
dispatch(IsLoginActionCreator());
|
||||||
|
dispatch(SetUserActionCreator(data.user));
|
||||||
|
dispatch(SetPermisssionsActionCreator(data.permissions));
|
||||||
|
});
|
||||||
|
};
|
||||||
// const CheckLogin = () => {
|
// const CheckLogin = () => {
|
||||||
// const navigate = useNavigate();
|
// const navigate = useNavigate();
|
||||||
// const location = useLocation();
|
// const location = useLocation();
|
||||||
@ -13,10 +29,11 @@ function App() {
|
|||||||
// navigate("/login");
|
// navigate("/login");
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
// const token = getToken();
|
const token = getToken();
|
||||||
// if (!token) {
|
if (token) {
|
||||||
// CheckLogin();
|
getUser();
|
||||||
// }
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.App}>
|
<div className={styles.App}>
|
||||||
<Views />
|
<Views />
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.main-header {
|
.main-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: white !important;
|
background-color: white !important;
|
||||||
@ -24,8 +23,3 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
|
||||||
line-height: 64px !important;
|
|
||||||
display: inline;
|
|
||||||
color: #03a9f4 !important;
|
|
||||||
}
|
|
||||||
|
@ -1,22 +1,44 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import styles from "./Header.module.css";
|
import styles from "./Header.module.css";
|
||||||
import logo from "../../assets/logo.png";
|
import { Layout, Typography, Button, Dropdown, MenuProps } from "antd";
|
||||||
import { Layout, Typography, Menu, Button, Dropdown, MenuProps } from "antd";
|
import { useSelector } from "../../store/hooks";
|
||||||
import { Link } from "react-router-dom";
|
import { useDispatch } from "react-redux";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { LoginOutActionCreator } from "../../store/user/userActions";
|
||||||
|
|
||||||
export const Header: React.FC = () => {
|
export const Header: React.FC = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const user = useSelector((state: any) => state.user);
|
||||||
|
const onClick: MenuProps["onClick"] = ({ key }) => {
|
||||||
|
if (key === "login_out") {
|
||||||
|
dispatch(LoginOutActionCreator());
|
||||||
|
navigate("/login");
|
||||||
|
} else if (key === "edit_password") {
|
||||||
|
navigate("/editPasswor");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const items: MenuProps["items"] = [
|
||||||
|
{
|
||||||
|
label: "修改密码",
|
||||||
|
key: "edit_password",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "退出登录",
|
||||||
|
key: "login_out",
|
||||||
|
},
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<div className={styles["app-header"]}>
|
<div className={styles["app-header"]}>
|
||||||
<Layout.Header className={styles["main-header"]}>
|
<Layout.Header className={styles["main-header"]}>
|
||||||
<div></div>
|
<div></div>
|
||||||
<Button.Group className={styles["button-group"]}>
|
<Button.Group className={styles["button-group"]}>
|
||||||
<Link style={{ textDecoration: "none" }} to={`/login`}>
|
<Dropdown menu={{ items, onClick }} placement="bottomRight">
|
||||||
<Button>登录</Button>
|
<Button type="link" danger>
|
||||||
</Link>
|
{user.name}
|
||||||
|
</Button>
|
||||||
|
</Dropdown>
|
||||||
</Button.Group>
|
</Button.Group>
|
||||||
</Layout.Header>
|
</Layout.Header>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { Typography, Input, Select, Button, Space, Table } from "antd";
|
import { Typography, Input, Select, Button, Space, Table } from "antd";
|
||||||
import type { ColumnsType } from "antd/es/table";
|
import type { ColumnsType } from "antd/es/table";
|
||||||
import styles from "./Index.module.css";
|
import styles from "./Vod.module.css";
|
||||||
import { PlusOutlined, ReloadOutlined } from "@ant-design/icons";
|
import { PlusOutlined, ReloadOutlined } from "@ant-design/icons";
|
||||||
import { login } from "../../../api/index";
|
import { login } from "../../../api/index";
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
export * from "./Vod";
|
export * from "./Vod"
|
@ -3,8 +3,17 @@ import styles from "./Login.module.css";
|
|||||||
import { Typography, Spin, Input, Button, message } from "antd";
|
import { Typography, Spin, Input, Button, message } from "antd";
|
||||||
import { login, system } from "../../api/index";
|
import { login, system } from "../../api/index";
|
||||||
import { setToken } from "../../utils/index";
|
import { setToken } from "../../utils/index";
|
||||||
|
import { useDispatch } from "react-redux";
|
||||||
|
import {
|
||||||
|
IsLoginActionCreator,
|
||||||
|
SetUserActionCreator,
|
||||||
|
SetPermisssionsActionCreator,
|
||||||
|
} from "../../store/user/userActions";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
export const Login: React.FC = () => {
|
export const Login: React.FC = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
const [image, setImage] = useState<string>("");
|
const [image, setImage] = useState<string>("");
|
||||||
const [email, setEmail] = useState<string>("");
|
const [email, setEmail] = useState<string>("");
|
||||||
@ -57,8 +66,12 @@ export const Login: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getUser = () => {
|
const getUser = () => {
|
||||||
login.getUser().then((res) => {
|
login.getUser().then((res: any) => {
|
||||||
console.log(res);
|
const data = res.data;
|
||||||
|
dispatch(IsLoginActionCreator());
|
||||||
|
dispatch(SetUserActionCreator(data.user));
|
||||||
|
dispatch(SetPermisssionsActionCreator(data.permissions));
|
||||||
|
navigate("/");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
7
src/store/hooks.ts
Normal file
7
src/store/hooks.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import {
|
||||||
|
useSelector as useReduxSelector,
|
||||||
|
TypedUseSelectorHook,
|
||||||
|
} from "react-redux";
|
||||||
|
import { RootState } from "./store";
|
||||||
|
|
||||||
|
export const useSelector: TypedUseSelectorHook<RootState> = useReduxSelector;
|
@ -1,30 +1,7 @@
|
|||||||
|
import { createStore, applyMiddleware } from "redux";
|
||||||
|
import userReducer from "./user/userReducer";
|
||||||
|
import thunk from "redux-thunk";
|
||||||
|
|
||||||
import { createStore } from "redux";
|
const store = createStore(userReducer, applyMiddleware(thunk));
|
||||||
interface IAction {
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
type: string;
|
|
||||||
payload?: any;
|
|
||||||
}
|
|
||||||
interface IState {
|
|
||||||
isshow: boolean;
|
|
||||||
}
|
|
||||||
const reducer = (
|
|
||||||
preState: IState = {
|
|
||||||
isshow: false,
|
|
||||||
},
|
|
||||||
action: IAction
|
|
||||||
) => {
|
|
||||||
const { type } = action;
|
|
||||||
const newState = { ...preState };
|
|
||||||
switch (type) {
|
|
||||||
case "show":
|
|
||||||
newState.isshow = true;
|
|
||||||
return newState;
|
|
||||||
case "hidden":
|
|
||||||
newState.isshow = false;
|
|
||||||
return newState;
|
|
||||||
default:
|
|
||||||
return preState;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const store = createStore(reducer);
|
|
||||||
export default store;
|
export default store;
|
||||||
|
59
src/store/user/userActions.ts
Normal file
59
src/store/user/userActions.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { message } from "antd";
|
||||||
|
|
||||||
|
export const IS_LOGIN = "IS_LOGIN";
|
||||||
|
export const LOGIN_OUT = "LOGIN_OUT";
|
||||||
|
export const SET_USER = "SET_USER";
|
||||||
|
export const SET_PERMISSSIONS = "SET_PERMISSSIONS";
|
||||||
|
|
||||||
|
interface IsLoginAction {
|
||||||
|
type: typeof IS_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LoginOutAction {
|
||||||
|
type: typeof LOGIN_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SetUserAction {
|
||||||
|
type: typeof SET_USER;
|
||||||
|
payload: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SetPermisssionsAction {
|
||||||
|
type: typeof SET_PERMISSSIONS;
|
||||||
|
payload: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UserLoginAction =
|
||||||
|
| IsLoginAction
|
||||||
|
| LoginOutAction
|
||||||
|
| SetUserAction
|
||||||
|
| SetPermisssionsAction;
|
||||||
|
|
||||||
|
export const IsLoginActionCreator = (): IsLoginAction => {
|
||||||
|
return {
|
||||||
|
type: IS_LOGIN,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LoginOutActionCreator = (): LoginOutAction => {
|
||||||
|
message.success("已退出登录");
|
||||||
|
return {
|
||||||
|
type: LOGIN_OUT,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SetUserActionCreator = (data: any): SetUserAction => {
|
||||||
|
return {
|
||||||
|
type: SET_USER,
|
||||||
|
payload: data,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SetPermisssionsActionCreator = (
|
||||||
|
data: any
|
||||||
|
): SetPermisssionsAction => {
|
||||||
|
return {
|
||||||
|
type: SET_PERMISSSIONS,
|
||||||
|
payload: data,
|
||||||
|
};
|
||||||
|
};
|
33
src/store/user/userReducer.ts
Normal file
33
src/store/user/userReducer.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import {
|
||||||
|
UserLoginAction,
|
||||||
|
IS_LOGIN,
|
||||||
|
LOGIN_OUT,
|
||||||
|
SET_USER,
|
||||||
|
SET_PERMISSSIONS,
|
||||||
|
} from "./userActions";
|
||||||
|
|
||||||
|
interface UserState {
|
||||||
|
permisssions: any[];
|
||||||
|
user: any[];
|
||||||
|
isLogin: boolean;
|
||||||
|
}
|
||||||
|
export const defaultState: UserState = {
|
||||||
|
isLogin: false,
|
||||||
|
permisssions: [],
|
||||||
|
user: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (state = defaultState, action: UserLoginAction) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case IS_LOGIN:
|
||||||
|
return { ...state, isLogin: true };
|
||||||
|
case LOGIN_OUT:
|
||||||
|
return { ...state, isLogin: false, user: [], permisssions: [] };
|
||||||
|
case SET_USER:
|
||||||
|
return { ...state, user: action.payload };
|
||||||
|
case SET_PERMISSSIONS:
|
||||||
|
return { ...state, permisssions: action.payload };
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user