添加了 退出登录 登录用户名
This commit is contained in:
parent
8e839c28f8
commit
505c187eb7
6
package-lock.json
generated
6
package-lock.json
generated
|
@ -17,6 +17,7 @@
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
|
"jwt-decode": "^3.1.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-player": "^2.12.0",
|
"react-player": "^2.12.0",
|
||||||
|
@ -11506,6 +11507,11 @@
|
||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jwt-decode": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/jwt-decode/-/jwt-decode-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
|
||||||
|
},
|
||||||
"node_modules/kind-of": {
|
"node_modules/kind-of": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
|
"jwt-decode": "^3.1.2",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-player": "^2.12.0",
|
"react-player": "^2.12.0",
|
||||||
|
|
77
src/App.js
77
src/App.js
|
@ -1,19 +1,22 @@
|
||||||
// App.js
|
import React, { useState, useEffect } from 'react';
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import AppBar from '@mui/material/AppBar';
|
import AppBar from '@mui/material/AppBar';
|
||||||
|
import Avatar from '@mui/material/Avatar';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import Toolbar from '@mui/material/Toolbar';
|
import Toolbar from '@mui/material/Toolbar';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
|
import ExitToAppIcon from '@mui/icons-material/ExitToApp';
|
||||||
import { Route, Router, Routes } from 'react-router-dom';
|
import { Route, Router, Routes } from 'react-router-dom';
|
||||||
import ConfigContext, { config } from './Config';
|
import ConfigContext, { config } from './Config';
|
||||||
import LoginForm from './LoginForm';
|
import LoginForm from './LoginForm';
|
||||||
import Main from './Main';
|
import Main from './Main';
|
||||||
import VideoPlayer from './VideoPlayer'; // 导入我们将创建的VideoPlayer组件
|
import VideoPlayer from './VideoPlayer';
|
||||||
import { default as VuetifyLogo, default as VuetifyName } from './logo.svg';
|
import { default as VuetifyLogo, default as VuetifyName } from './logo.svg';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
|
import jwtDecode from 'jwt-decode';
|
||||||
|
|
||||||
axios.interceptors.request.use((config) => {
|
axios.interceptors.request.use((config) => {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
|
@ -24,51 +27,69 @@ axios.interceptors.request.use((config) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const navigate = useNavigate(); // 将 navigate 声明移动到组件内部
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
axios.interceptors.response.use(
|
const [username, setUsername] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
if (token) {
|
||||||
|
const decodedToken = jwtDecode(token);
|
||||||
|
setUsername(decodedToken.username);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
axios.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
|
|
||||||
(error) => {
|
(error) => {
|
||||||
|
|
||||||
|
|
||||||
if (error.response.status === 401) {
|
if (error.response.status === 401) {
|
||||||
sessionStorage.setItem('previousLocation', location.pathname); // 使用 window.location.pathname 获取当前路径
|
sessionStorage.setItem('previousLocation', location.pathname);
|
||||||
navigate('/login'); // 使用 window.location.assign() 进行导航
|
navigate('/login');
|
||||||
}
|
}
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleLogout = () => {
|
||||||
|
localStorage.removeItem('token');
|
||||||
|
setUsername('');
|
||||||
|
navigate('/login');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
|
||||||
<ConfigContext.Provider value={config}>
|
<ConfigContext.Provider value={config}>
|
||||||
|
<div>
|
||||||
<div>
|
<AppBar position="static">
|
||||||
<AppBar position="static">
|
<Toolbar>
|
||||||
<Toolbar>
|
<Box display="flex" alignItems="center" flexGrow={1}>
|
||||||
<IconButton edge="start" color="inherit" aria-label="menu">
|
<IconButton edge="start" color="inherit" aria-label="menu">
|
||||||
<img src={VuetifyLogo} alt="Vuetify Logo" width="40" />
|
<img src={VuetifyLogo} alt="Vuetify Logo" width="40" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Typography variant="h3" style={{ flexGrow: 1 }}>
|
|
||||||
<img src={VuetifyName} alt="Vuetify Name" width="40" />
|
|
||||||
</Typography>
|
|
||||||
</Toolbar>
|
|
||||||
</AppBar>
|
|
||||||
</div>
|
|
||||||
<Routes>
|
|
||||||
<Route path="/login" element={<LoginForm />} />
|
|
||||||
<Route path="/" element={<Main />} />
|
|
||||||
<Route path="/res/:filename" element={<VideoPlayer />} />
|
|
||||||
</Routes>
|
|
||||||
|
|
||||||
|
</Box>
|
||||||
|
{username && (
|
||||||
|
<Box display="flex" alignItems="center" marginRight="1rem">
|
||||||
|
<Avatar>{username.charAt(0).toUpperCase()}</Avatar>
|
||||||
|
<Typography variant="subtitle1" style={{ marginLeft: '1rem' }}>
|
||||||
|
{username}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<IconButton edge="end" color="inherit" aria-label="logout" onClick={handleLogout}>
|
||||||
|
<ExitToAppIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
</div>
|
||||||
|
<Routes>
|
||||||
|
<Route path="/login" element={<LoginForm />} />
|
||||||
|
<Route path="/" element={<Main />} />
|
||||||
|
<Route path="/res/:filename" element={<VideoPlayer />} />
|
||||||
|
</Routes>
|
||||||
</ConfigContext.Provider>
|
</ConfigContext.Provider>
|
||||||
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user