diff --git a/package.json b/package.json index bc6efbb..2f44883 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "axios": "^0.21.1", "cra-template": "1.1.2", "dotenv": "^10.0.0", + "qs": "^6.10.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-scripts": "4.0.3", diff --git a/public/image/user.jpg b/public/image/user.jpg new file mode 100644 index 0000000..70c639e Binary files /dev/null and b/public/image/user.jpg differ diff --git a/src/App.css b/src/App.css index a3a1b19..593f7a0 100644 --- a/src/App.css +++ b/src/App.css @@ -5,6 +5,7 @@ a.btn { color: white !important; border-radius: .3em; padding: .375em 0; + line-height: 1.5em; font-size: 1.1em; cursor: pointer; transition: filter .3s ease-out; @@ -14,7 +15,7 @@ a.btn { } .btn:disabled { cursor: not-allowed; - filter: grayscale(100%); + filter: grayscale(100%) opacity(.5); } .btn:active { color: white !important; @@ -57,4 +58,19 @@ button.btn { .btn-straight { border-radius: .15em; width: 6em; -} \ No newline at end of file +} + +.sdu, +.user { + height: 100%; + display: flex; + align-items: center; +} +.sdu-logo, +.user-logo { + height: 100%; +} +.sdu-name { + height: 30px; + margin-left: 10px; +} diff --git a/src/App.js b/src/App.js index 74f0baf..62e5dcf 100644 --- a/src/App.js +++ b/src/App.js @@ -1,21 +1,43 @@ import './App.css'; -import { Route, SingleRouter } from './components/SingleRouter/SingleRouter'; +import { Redirect, Route, SingleRouter } from './components/SingleRouter/SingleRouter'; import { AppContainer } from './index/index'; import { UploadContainer } from './upload/upload'; import { LogInContainer } from './login/login'; import { ReviewContainer } from './review/review'; -import History from './helper/history'; +import { Component } from 'react'; +import { UserContext } from './helper/Context'; -function App() { - // TODO check login - return ( - - - - - - - ); +class App extends Component { + constructor(props) { + super(props); + this.state = { + name: '', + role: -1 + }; + this.setUserData = this.setUserData.bind(this); + } + + setUserData({ name, role }) { + this.setState({ name, role }); + } + + render() { + return ( + + + + + + + + + + ); + } +} + +function CheckLogIn() { + return localStorage.getItem('jwt') ? null : ; } export default App; diff --git a/src/components/Spinner/spinner.css b/src/components/Spinner/spinner.css index daab551..92481c2 100644 --- a/src/components/Spinner/spinner.css +++ b/src/components/Spinner/spinner.css @@ -1,6 +1,6 @@ .spinner { - width: 20px; - height: 20px; + width: 1.5em; + height: 1.5em; margin: 0 auto; } .spinner > svg { diff --git a/src/components/UserControl/UserControl.js b/src/components/UserControl/UserControl.js new file mode 100644 index 0000000..bda17fc --- /dev/null +++ b/src/components/UserControl/UserControl.js @@ -0,0 +1,53 @@ +import './userControl.css'; +import { images } from '../../resources.json'; +import { UserContext } from '../../helper/Context'; +import Spinner from '../Spinner/Spinner'; +import { get } from '../../helper/axios'; +import { apis } from '../../helper/apis'; +import { alert } from '../../helper/alert'; + +export default function UserControl(props) { + return ( + + {({ userData, setUserData }) => ( + userData.role === 2 + ? ( +
+ +
+ ) : ( +
+ { + userData.role === -1 + ? ( + + ) : ( +
+ user avatar +
+ ) + } +
{userData.name || "加载中"}
+ { + (() => { + if (userData.role !== -1) return null; + get(apis.getProfile).then(({ data, status, networkStatus }) => { + if (networkStatus !== 200) return; + if (!status) return alert('获取用户信息失败:' + data + ',请稍候刷新再试'); + setUserData({ + name: data.realName, + role: data.role + }); + }); + return null; + })() + } +
+ ) + )} +
+ ); +} \ No newline at end of file diff --git a/src/components/UserControl/userControl.css b/src/components/UserControl/userControl.css new file mode 100644 index 0000000..b014fe7 --- /dev/null +++ b/src/components/UserControl/userControl.css @@ -0,0 +1,19 @@ +.user-name { + height: 100%; + font-size: 18px; + height: 50px; + line-height: 50px; + color: white; + margin-left: 10px; +} + +.user-avatar { + width: 40px; + height: 40px; +} + +.user-avatar > img { + border-radius: 50%; + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/src/helper/Context.js b/src/helper/Context.js new file mode 100644 index 0000000..92e7865 --- /dev/null +++ b/src/helper/Context.js @@ -0,0 +1,3 @@ +import { createContext } from "react"; + +export const UserContext = createContext({}); \ No newline at end of file diff --git a/src/helper/axios.js b/src/helper/axios.js index ef983ff..454c358 100644 --- a/src/helper/axios.js +++ b/src/helper/axios.js @@ -1,11 +1,13 @@ import axios from 'axios'; import { failed } from './alert'; +import qs from 'qs'; +import History from './history'; export function get(url) { return send( axios.get(url, { headers: { - Authorization: 'Bearer ' + localStorage.getItem('jwt'), + Authorization: localStorage.getItem('jwt'), "Allow-Control-Allow-Origin": "*" } }), @@ -14,9 +16,9 @@ export function get(url) { } export function post(url, data) { return send( - axios.post(url, data, { + axios.post(url, qs.stringify(data), { headers: { - Authorization: 'Bearer ' + localStorage.getItem('jwt'), + Authorization: localStorage.getItem('jwt'), "Allow-Control-Allow-Origin": "*" } }), @@ -33,6 +35,7 @@ async function send(xhr, retryFunc) { } try { const { data } = await xhr; + console.log("recv: ", data); return { ...data, networkStatus: 200 @@ -43,16 +46,16 @@ async function send(xhr, retryFunc) { networkStatus: err?.response?.status ?? -1, status: false }; + if (err?.response?.status === 401) { + History.force('/login'); + return failData; + } waitToSend.push(retryFunc); if (err.message === 'Network Error') return await failed('您的设备似乎断网了,请检查网络后重试或刷新', flushWaitList) || failData; - else if (err?.response?.status === 401) - History.force('/login'); - else if (err?.response?.status === 504) + if (err?.response?.status === 504) return await failed('请求超时,请耐心等待几秒后重试或刷新', flushWaitList) || failData; - else - return await failed('服务器出现问题,请稍后重试或刷新', flushWaitList) || failData; - return failData; + return await failed('服务器出现问题,请稍后重试或刷新', flushWaitList) || failData; } } diff --git a/src/login/login.js b/src/login/login.js index fc20626..d3f5b7d 100644 --- a/src/login/login.js +++ b/src/login/login.js @@ -1,4 +1,8 @@ import { Component } from 'react'; +import { apis } from '../helper/apis'; +import { post } from '../helper/axios'; +import History from '../helper/history'; +import Spinner from '../components/Spinner/Spinner'; import './login.css'; export class LogInContainer extends Component { @@ -7,6 +11,7 @@ export class LogInContainer extends Component { this.state = { username: '', password: '', + processing: false, error: false, errorMessage: '', }; @@ -20,40 +25,57 @@ export class LogInContainer extends Component { handleSubmit(e) { e.preventDefault(); const { username, password } = this.state; - this.props.login(username, password); + if (!username) + return this.setState({ error: true, errorMessage: '学号不能为空' }); + if (!password) + return this.setState({ error: true, errorMessage: '密码不能为空' }); + if (!username.match(/^\d*$/)) + return this.setState({ error: true, errorMessage: '学号必须为数字' }); + this.setState({ processing: true }); + post(apis.login, { username, password }).then(({ data, status, networkStatus }) => { + this.setState({ processing: false }); + if (networkStatus !== 200) return; + if (!status) return this.setState({ error: true, errorMessage: data }); + localStorage.setItem('jwt', data); + History.replace('/'); + }); } render() { - const { error, errorMessage } = this.state; + const { error, errorMessage, processing } = this.state; return (
-

Login

+

登录

-
-
- {error && -
+
{errorMessage}
} diff --git a/src/resources.json b/src/resources.json index b43a718..a1589c4 100644 --- a/src/resources.json +++ b/src/resources.json @@ -2,6 +2,7 @@ "images": { "poster": "image/poster.jpg", "icon": "image/sdu_icon.png", - "name": "image/sdu_name.png" + "name": "image/sdu_name.png", + "avatar": "image/user.jpg" } } \ No newline at end of file diff --git a/src/upload/upload.css b/src/upload/upload.css index f565873..e4c367c 100644 --- a/src/upload/upload.css +++ b/src/upload/upload.css @@ -8,26 +8,6 @@ background-color: #9D0004; } -.sdu, -.user { - height: 100%; - display: flex; - align-items: center; -} -.sdu-logo, -.user-logo { - height: 100%; -} -.sdu-name { - height: 40px; - margin-left: 10px; -} -.user-name { - height: 100%; - line-height: 60px; - font-size: 24px; -} - .content { width: 800px; margin: 0 auto; diff --git a/src/upload/upload.js b/src/upload/upload.js index f4e87b5..3e2d832 100644 --- a/src/upload/upload.js +++ b/src/upload/upload.js @@ -7,6 +7,7 @@ import { alert } from '../helper/alert'; import { images } from '../resources.json'; import './upload.css'; +import UserControl from '../components/UserControl/UserControl'; export class UploadContainer extends Component { constructor(props) { @@ -60,10 +61,7 @@ export class UploadContainer extends Component { logo
-
- avatar -
-
+