|
@ -6,256 +6,144 @@ import SHA1 from 'crypto-js/sha1'; |
|
|
import Hex from 'crypto-js/enc-hex'; |
|
|
import Hex from 'crypto-js/enc-hex'; |
|
|
import { ApiTable } from '$utils' |
|
|
import { ApiTable } from '$utils' |
|
|
import { Request } from '@peace/utils' |
|
|
import { Request } from '@peace/utils' |
|
|
import { Button, Input, Form, Row, Col, message, Tabs } from 'antd'; |
|
|
import { Button, Input, Form, Row, Col, message, Tabs, Tooltip } from 'antd'; |
|
|
import { login, LOGIN_ERROR } from '../actions/auth'; |
|
|
import { login, LOGIN_ERROR } from '../actions/auth'; |
|
|
import { ExclamationCircleOutlined } from '@ant-design/icons'; |
|
|
import { ExclamationCircleOutlined } from '@ant-design/icons'; |
|
|
import { Uploads } from '$components' |
|
|
import { Uploads } from '$components' |
|
|
|
|
|
import { LockOutlined, UserOutlined } from '@ant-design/icons'; |
|
|
import '../style.less'; |
|
|
import '../style.less'; |
|
|
|
|
|
|
|
|
const FormItem = Form.Item; |
|
|
const FormItem = Form.Item; |
|
|
|
|
|
|
|
|
let codCountDownInterval = null |
|
|
let codCountDownInterval = null |
|
|
const Login = props => { |
|
|
const Login = props => { |
|
|
const { dispatch, user, error, isRequesting } = props |
|
|
const { dispatch, user, error, isRequesting } = props |
|
|
const [username, setUserName] = useState('') |
|
|
const [username, setUserName] = useState('') |
|
|
const [password, setPassword] = useState('') |
|
|
const [password, setPassword] = useState('') |
|
|
const [phone, setPhone] = useState('') |
|
|
const [phone, setPhone] = useState('') |
|
|
const [code, setCode] = useState('') |
|
|
const [code, setCode] = useState('') |
|
|
const [inputChanged, setInputChanged] = useState(false) |
|
|
const [inputChanged, setInputChanged] = useState(false) |
|
|
const [curTabKey, setCurTabKey] = useState(1) |
|
|
const [curTabKey, setCurTabKey] = useState(1) |
|
|
const [codSending, setCodSending] = useState(false) |
|
|
const [codSending, setCodSending] = useState(false) |
|
|
const [codCountDown, setCodeCountDown] = useState(60) |
|
|
const [codCountDown, setCodeCountDown] = useState(60) |
|
|
const codCountDownRef = useRef(0) |
|
|
const codCountDownRef = useRef(0) |
|
|
|
|
|
const [form] = Form.useForm(); |
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
}, []) |
|
|
|
|
|
|
|
|
}, []) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
if (user && user.authorized) { |
|
|
|
|
|
dispatch(push('/projectRegime/information')); |
|
|
|
|
|
} |
|
|
|
|
|
}, [user]) |
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
useEffect(() => { |
|
|
if (user && user.authorized) { |
|
|
if (codSending) { |
|
|
dispatch(push('/projectRegime/information')); |
|
|
setCodeCountDown(59) |
|
|
} |
|
|
codCountDownRef.current = 59 |
|
|
}, [user]) |
|
|
codCountDownInterval = setInterval(() => { |
|
|
|
|
|
codCountDownRef.current -= 1 |
|
|
useEffect(() => { |
|
|
if (codCountDownRef.current == 0) { |
|
|
if (codSending) { |
|
|
setCodSending(false) |
|
|
setCodeCountDown(59) |
|
|
setCodeCountDown(60) |
|
|
codCountDownRef.current = 59 |
|
|
clearInterval(codCountDownInterval) |
|
|
codCountDownInterval = setInterval(() => { |
|
|
codCountDownInterval = null |
|
|
codCountDownRef.current -= 1 |
|
|
} else { |
|
|
if (codCountDownRef.current == 0) { |
|
|
setCodeCountDown(codCountDownRef.current) |
|
|
setCodSending(false) |
|
|
|
|
|
setCodeCountDown(60) |
|
|
|
|
|
clearInterval(codCountDownInterval) |
|
|
|
|
|
codCountDownInterval = null |
|
|
|
|
|
} else { |
|
|
|
|
|
setCodeCountDown(codCountDownRef.current) |
|
|
|
|
|
} |
|
|
|
|
|
}, 1000); |
|
|
|
|
|
} else { |
|
|
|
|
|
if (codCountDownInterval) { |
|
|
|
|
|
clearInterval(codCountDownInterval) |
|
|
|
|
|
codCountDownInterval = null |
|
|
|
|
|
setCodeCountDown(60) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
}, 1000); |
|
|
}, [codSending]) |
|
|
} else { |
|
|
|
|
|
if (codCountDownInterval) { |
|
|
|
|
|
clearInterval(codCountDownInterval) |
|
|
|
|
|
codCountDownInterval = null |
|
|
|
|
|
setCodeCountDown(60) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}, [codSending]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
<div |
|
|
|
|
|
id='loginContainer' |
|
|
|
|
|
style={{ |
|
|
|
|
|
height: '100vh', |
|
|
|
|
|
display: 'flex', |
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
justifyContent: 'center', |
|
|
|
|
|
color: 'aliceblue', |
|
|
|
|
|
backgroundImage: 'url(/assets/images/login/login_b.png)', |
|
|
|
|
|
backgroundSize: 'cover', |
|
|
|
|
|
position: 'relative', |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
{/* <img src='/assets/images/logo.png' style={{ height: 42, borderRadius: 4, position: 'fixed', top: 32, left: 32 }} /> */} |
|
|
|
|
|
|
|
|
const doLogin = () => { |
|
|
<div style={{ |
|
|
if (curTabKey == 1) { |
|
|
width: 556, height: 434, backgroundColor: '#rgba(255,255,255,0.50)', |
|
|
if (!username || !password) |
|
|
borderRadius: '2px 2px 0 0', boxShadow: 'inset 0 0 8px 0 rgba(50,131,255,0.25)', |
|
|
dispatch({ |
|
|
display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'absolute', right: 150, top: 'calc(50% - 217px)' |
|
|
type: LOGIN_ERROR, |
|
|
}}> |
|
|
payload: { error: '请输入账号名和密码' } |
|
|
<div style={{ |
|
|
}); |
|
|
width: 410, |
|
|
setInputChanged(false) |
|
|
height: 322, |
|
|
dispatch(login({ username, password })); |
|
|
backgroundColor: '' |
|
|
} else { |
|
|
}}> |
|
|
if (!phone || !code) |
|
|
<img src={'/assets/images/login/login_a.png'} style={{ width: 124, height: 37, display: 'inline-block', marginBottom: 40 }} /> |
|
|
dispatch({ |
|
|
|
|
|
type: LOGIN_ERROR, |
|
|
|
|
|
payload: { error: '请输入手机号和验证码' } |
|
|
|
|
|
}); |
|
|
|
|
|
dispatch(login({ phone, code })); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const enterHandler = e => { |
|
|
<Form |
|
|
if (e.key === 'Enter') { |
|
|
form={form} |
|
|
doLogin() |
|
|
onFinish={r => { |
|
|
} |
|
|
form.validateFields().then(r => { |
|
|
}; |
|
|
dispatch(login({ username: r.username, password: r.password })); |
|
|
|
|
|
}) |
|
|
|
|
|
.catch(err => { |
|
|
|
|
|
dispatch({ |
|
|
|
|
|
type: LOGIN_ERROR, |
|
|
|
|
|
payload: { error: '请输入账号名和密码' } |
|
|
|
|
|
}) |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<Form.Item label='' name="username" rules={[{ required: true, message: '请输入用户名' },]}> |
|
|
|
|
|
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="用户名" /> |
|
|
|
|
|
</Form.Item> |
|
|
|
|
|
|
|
|
|
|
|
<Form.Item label='' name="password" rules={[{ required: true, message: '请输入密码' },]}> |
|
|
|
|
|
<Input prefix={<LockOutlined className="site-form-item-icon" />} placeholder="密码" /> |
|
|
|
|
|
</Form.Item> |
|
|
|
|
|
<Tooltip title='请联系管理员'> |
|
|
|
|
|
<a style={{ position: 'relative', left: 348, top: -17 }}>忘记密码</a> |
|
|
|
|
|
</Tooltip> |
|
|
|
|
|
<Form.Item |
|
|
|
|
|
> |
|
|
|
|
|
<Button type="primary" htmlType="submit" style={{ width: 410, height: 50 }}> |
|
|
|
|
|
登录 |
|
|
|
|
|
</Button> |
|
|
|
|
|
</Form.Item> |
|
|
|
|
|
</Form> |
|
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
<div |
|
|
|
|
|
id='loginContainer' |
|
|
|
|
|
style={{ |
|
|
|
|
|
height: '100vh', |
|
|
|
|
|
display: 'flex', |
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
justifyContent: 'center', |
|
|
|
|
|
color: 'aliceblue', |
|
|
|
|
|
backgroundImage: 'url(/assets/images/login_bg.png)' |
|
|
|
|
|
}} |
|
|
|
|
|
> |
|
|
|
|
|
<img src='/assets/images/logo.png' style={{ height: 42, borderRadius: 4, position: 'fixed', top: 32, left: 32 }} /> |
|
|
|
|
|
|
|
|
|
|
|
<div style={{ width: 1000, backgroundColor: '#01316d', borderRadius: 24 }}> |
|
|
|
|
|
<Row> |
|
|
|
|
|
<Col span={12} style={{}}> |
|
|
|
|
|
<img src='/assets/images/login.png' width={'100%'} /> |
|
|
|
|
|
</Col> |
|
|
|
|
|
<Col span={12}> |
|
|
|
|
|
<div style={{ |
|
|
|
|
|
width: '100%', |
|
|
|
|
|
height: '100%', |
|
|
|
|
|
padding: 30, |
|
|
|
|
|
display: 'flex', |
|
|
|
|
|
flexDirection: 'column', |
|
|
|
|
|
justifyContent: 'space-around' |
|
|
|
|
|
}}> |
|
|
|
|
|
<p style={{ fontSize: 30, fontWeight: 'bold', textAlign: 'center' }}> |
|
|
|
|
|
中鼎国际工程项目指挥调度系统 |
|
|
|
|
|
</p> |
|
|
|
|
|
<Tabs defaultActiveKey="1" animated={true} onChange={(k) => { |
|
|
|
|
|
setCurTabKey(k) |
|
|
|
|
|
}}> |
|
|
|
|
|
<Tabs.TabPane tab="用户名登录" key="1"> |
|
|
|
|
|
<Form onKeyDown={enterHandler}> |
|
|
|
|
|
<div style={{ fontSize: 10, fontWeight: 'bold' }}> |
|
|
|
|
|
用户名 |
|
|
|
|
|
</div> |
|
|
|
|
|
<FormItem name="username"> |
|
|
|
|
|
<Input |
|
|
|
|
|
type="text" |
|
|
|
|
|
size="large" |
|
|
|
|
|
value={username} |
|
|
|
|
|
placeholder="用户名" |
|
|
|
|
|
onChange={e => { |
|
|
|
|
|
setUserName(e.target.value) |
|
|
|
|
|
setInputChanged(true) |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
|
|
|
</FormItem> |
|
|
|
|
|
<div style={{ fontSize: 10, fontWeight: 'bold' }}> |
|
|
|
|
|
密码 |
|
|
|
|
|
</div> |
|
|
|
|
|
<FormItem name="password"> |
|
|
|
|
|
<Input |
|
|
|
|
|
type="password" |
|
|
|
|
|
size="large" |
|
|
|
|
|
value={password} |
|
|
|
|
|
placeholder="密码" |
|
|
|
|
|
onChange={e => { |
|
|
|
|
|
setPassword(e.target.value) |
|
|
|
|
|
setInputChanged(true) |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
|
|
|
</FormItem> |
|
|
|
|
|
</Form> |
|
|
|
|
|
</Tabs.TabPane> |
|
|
|
|
|
<Tabs.TabPane tab="手机登录" key="2" disabled> |
|
|
|
|
|
<Form onKeyDown={enterHandler}> |
|
|
|
|
|
<div style={{ fontSize: 10, fontWeight: 'bold' }}> |
|
|
|
|
|
手机号 |
|
|
|
|
|
</div> |
|
|
|
|
|
<FormItem name="phone" rules={[{ pattern: /^1[3|4|5|7|8|9]\d{9}$/, message: '请输入正确的手机号码' }]}> |
|
|
|
|
|
<Input |
|
|
|
|
|
type="text" |
|
|
|
|
|
size="large" |
|
|
|
|
|
value={username} |
|
|
|
|
|
onChange={e => { |
|
|
|
|
|
setPhone(e.target.value) |
|
|
|
|
|
setInputChanged(true) |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
|
|
|
</FormItem> |
|
|
|
|
|
<div style={{ fontSize: 10, fontWeight: 'bold' }}> |
|
|
|
|
|
验证码 |
|
|
|
|
|
</div> |
|
|
|
|
|
<FormItem name="code"> |
|
|
|
|
|
<Input.Group compact> |
|
|
|
|
|
<Input |
|
|
|
|
|
size="large" |
|
|
|
|
|
style={{ width: 'calc(100% - 112px)' }} |
|
|
|
|
|
onChange={e => { |
|
|
|
|
|
setCode(e.target.value) |
|
|
|
|
|
setInputChanged(true) |
|
|
|
|
|
}} |
|
|
|
|
|
/> |
|
|
|
|
|
<Button |
|
|
|
|
|
size="large" |
|
|
|
|
|
onClick={() => { |
|
|
|
|
|
setCodSending(true) |
|
|
|
|
|
const random = Math.floor(Math.random() * Math.pow(10, 4)); |
|
|
|
|
|
const sig = Hex.stringify(SHA1(phone + random)); |
|
|
|
|
|
setInputChanged(false) |
|
|
|
|
|
Request.post(ApiTable.validatePhone, { |
|
|
|
|
|
phone: phone, |
|
|
|
|
|
r: random, |
|
|
|
|
|
sig: sig |
|
|
|
|
|
}).then(res => { |
|
|
|
|
|
|
|
|
|
|
|
}, err => { |
|
|
|
|
|
let message = err.response.body?.message |
|
|
|
|
|
console.log(message); |
|
|
|
|
|
dispatch({ |
|
|
|
|
|
type: LOGIN_ERROR, |
|
|
|
|
|
payload: { error: message || '获取验证码失败' } |
|
|
|
|
|
}); |
|
|
|
|
|
setCodSending(false) |
|
|
|
|
|
}); |
|
|
|
|
|
}} |
|
|
|
|
|
loading={codSending} |
|
|
|
|
|
style={{ width: 112 }} |
|
|
|
|
|
> |
|
|
|
|
|
{codSending ? codCountDown + ' s' : '发送验证码'} |
|
|
|
|
|
</Button> |
|
|
|
|
|
</Input.Group> |
|
|
|
|
|
</FormItem> |
|
|
|
|
|
</Form> |
|
|
|
|
|
</Tabs.TabPane> |
|
|
|
|
|
</Tabs> |
|
|
|
|
|
|
|
|
|
|
|
<Row style={{ |
|
|
|
|
|
textAlign: 'left' |
|
|
|
|
|
}}> |
|
|
|
|
|
{ |
|
|
|
|
|
inputChanged || !error ? |
|
|
|
|
|
<span style={{ |
|
|
|
|
|
visibility: 'hidden' |
|
|
|
|
|
}}>-</span> : |
|
|
|
|
|
<span> |
|
|
|
|
|
<ExclamationCircleOutlined style={{ color: 'red' }} />{error} |
|
|
|
|
|
</span> |
|
|
|
|
|
} |
|
|
|
|
|
</Row> |
|
|
|
|
|
<Button |
|
|
|
|
|
shape="round" |
|
|
|
|
|
size="large" |
|
|
|
|
|
style={{ width: '100%' }} |
|
|
|
|
|
loading={isRequesting} |
|
|
|
|
|
onClick={doLogin} |
|
|
|
|
|
> |
|
|
|
|
|
登录 |
|
|
|
|
|
</Button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</Col> |
|
|
|
|
|
</Row> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div > |
|
|
|
|
|
); |
|
|
</div> |
|
|
|
|
|
</div > |
|
|
|
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function mapStateToProps (state) { |
|
|
function mapStateToProps (state) { |
|
|
const { auth } = state; |
|
|
const { auth } = state; |
|
|
console.log(auth.error); |
|
|
console.log(auth.error); |
|
|
return { |
|
|
return { |
|
|
user: auth.user, |
|
|
user: auth.user, |
|
|
error: auth.error, |
|
|
error: auth.error, |
|
|
isRequesting: auth.isRequesting |
|
|
isRequesting: auth.isRequesting |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
export default connect(mapStateToProps)(Login); |
|
|
export default connect(mapStateToProps)(Login); |