
16 changed files with 354 additions and 95 deletions
@ -1,2 +1,3 @@
|
||||
/api_proxy/* http://www.pkuhelper.com:10301/services/pkuhole/:splat 200 |
||||
/audio_proxy/* http://www.pkuhelper.com:10301/services/pkuhole/audios/:splat 200 |
||||
/api_proxy/* http://www.pkuhelper.com/services/pkuhole/:splat 200 |
||||
/audio_proxy/* http://www.pkuhelper.com/services/pkuhole/audios/:splat 200 |
||||
/login_proxy/* http://www.pkuhelper.com/services/login/:splat 200 |
@ -0,0 +1,49 @@
|
||||
@font-face { |
||||
font-family: 'icomoon'; |
||||
src: |
||||
url('icomoon.ttf?4yzqd4') format('truetype'), |
||||
url('icomoon.woff?4yzqd4') format('woff'), |
||||
url('icomoon.svg?4yzqd4#icomoon') format('svg'); |
||||
font-weight: normal; |
||||
font-style: normal; |
||||
} |
||||
|
||||
.icon { |
||||
/* use !important to prevent issues with browser extensions that change fonts */ |
||||
/*noinspection CssNoGenericFontName*/ |
||||
font-family: 'icomoon' !important; |
||||
speak: none; |
||||
font-style: normal; |
||||
font-weight: normal; |
||||
font-variant: normal; |
||||
text-transform: none; |
||||
|
||||
/* Better Font Rendering =========== */ |
||||
-webkit-font-smoothing: antialiased; |
||||
-moz-osx-font-smoothing: grayscale; |
||||
} |
||||
|
||||
.icon-reply:before { |
||||
content: "\e96b"; |
||||
} |
||||
.icon-login-ok:before { |
||||
content: "\e975"; |
||||
} |
||||
.icon-login:before { |
||||
content: "\e98d"; |
||||
} |
||||
.icon-attention:before { |
||||
content: "\e9d3"; |
||||
} |
||||
.icon-star:before { |
||||
content: "\e9d7"; |
||||
} |
||||
.icon-star-ok:before { |
||||
content: "\e9d9"; |
||||
} |
||||
.icon-help:before { |
||||
content: "\ea09"; |
||||
} |
||||
.icon-refresh:before { |
||||
content: "\ea2e"; |
||||
} |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,8 @@
|
||||
.login-form form p { |
||||
margin: 1em 0; |
||||
text-align: center; |
||||
} |
||||
|
||||
.login-form button { |
||||
min-width: 100px; |
||||
} |
@ -0,0 +1,92 @@
|
||||
import React, {Component, PureComponent} from 'react'; |
||||
|
||||
import './UserAction.css'; |
||||
|
||||
const LOGIN_BASE=window.location.protocol==='https:' ? '/login_proxy' : 'http://www.pkuhelper.com/services/login'; |
||||
|
||||
export const TokenCtx=React.createContext({ |
||||
value: null, |
||||
set_value: ()=>{}, |
||||
}); |
||||
|
||||
export class LoginForm extends Component { |
||||
constructor(props) { |
||||
super(props); |
||||
this.state={ |
||||
loading_status: 'done', |
||||
}; |
||||
|
||||
this.username_ref=React.createRef(); |
||||
this.password_ref=React.createRef(); |
||||
} |
||||
|
||||
do_login(event,set_token) { |
||||
event.preventDefault(); |
||||
this.setState({ |
||||
loading_status: 'loading', |
||||
}); |
||||
let data=new URLSearchParams(); |
||||
data.append('uid', this.username_ref.current.value); |
||||
data.append('password', this.password_ref.current.value); |
||||
fetch(LOGIN_BASE+'/login.php?platform=hole_xmcp_ml', { |
||||
method: 'POST', |
||||
body: data, |
||||
}) |
||||
.then((res)=>res.json()) |
||||
.then((json)=>{ |
||||
if(json.code!==0) |
||||
throw new Error(json); |
||||
|
||||
set_token(json.token); |
||||
alert(`成功以 ${json.name} 的身份登录`); |
||||
this.setState({ |
||||
loading_status: 'done', |
||||
}); |
||||
}) |
||||
.catch((e)=>{ |
||||
alert('登录失败'); |
||||
this.setState({ |
||||
loading_status: 'done', |
||||
}); |
||||
console.trace(e); |
||||
}); |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<TokenCtx.Consumer>{(token)=> |
||||
<div className="login-form"> |
||||
<form onSubmit={(e)=>this.do_login(e,token.set_value)} className="box"> |
||||
<p>Token: <code>{token.value||'(null)'}</code></p> |
||||
<p> |
||||
<label> |
||||
学号: |
||||
<input ref={this.username_ref} type="tel" /> |
||||
</label> |
||||
</p> |
||||
<p> |
||||
<label> |
||||
密码: |
||||
<input ref={this.password_ref} type="password" /> |
||||
</label> |
||||
</p> |
||||
<p> |
||||
{this.state.loading_status==='loading' ? |
||||
<button disabled="disbled">正在登录……</button> : |
||||
<button type="submit">登录</button> |
||||
} |
||||
<button type="button" onClick={()=>{token.set_value(null);}}>退出</button> |
||||
</p> |
||||
</form> |
||||
<div className="box"> |
||||
<ul> |
||||
<li>我们不会记录您的密码和个人信息。</li> |
||||
<li><b>请勿泄露 Token</b>,它代表您的登录状态,与您的账户唯一对应且泄露后无法重置。</li> |
||||
<li>如果您不愿输入密码,可以直接修改 <code>localStorage['TOKEN']</code></li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
}</TokenCtx.Consumer> |
||||
) |
||||
} |
||||
} |
Loading…
Reference in new issue