所有系统都会存在用户,包括操作记录,权限管理等。于是用户登录页面和注册页面肯定需要有。同时为了加密先简单的用MD5加个密就好了。
路由
区别于Home,单独创建目录login、register。 并在App.js 里更新路由连接,在前文也说明过。
import Login from './login/login';
import Register from './register/register';
...
export default function App () {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="login" element={<Login />} />
<Route path="register" element={<Register />} />
...
</Routes >
</Router >
);
}
登录
前文-首页中预留了登录按钮,判定是cookie中是否保存了userId(一般来说是判定是否有会话token,通过token进行数据交互)。 页面主要是账号密码的输入,以及登录注册两个按钮,当然惯例需要有一个记住我的操作框,那么就可以在操作框旁边放一个忘记密码以备不患。 整个页面是用的Antd的Form 组件。
import React from 'react';
import './login.css';
import 'antd/dist/antd.css';
import cookie from 'js-cookie'
import { useNavigate } from 'react-router-dom';
import { Form, Input, Button, Checkbox, message } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import md5 from 'js-md5'
export default function Login () {
const navigate = useNavigate();
const storeInfo = (userId) => {
let date = new Date();
date.setTime(date.getTime() + 30 * 60 * 1000);
let result = cookie.set("userId", userId, {
expires: date
});
console.log(result);
navigate('/');
}
const onFinish = (values) => {
values.password = md5(values.password);
fetch("/api/user/login", {
method: 'POST',
headers: { 'Content-Type': 'application/json', },
body: JSON.stringify(values),
})
.then(response => response.json())
.then(json => {
if (json.result === 0) {
storeInfo(json.detail.userId)
message.success('登陆成功');
} else {
message.error(json.resultNote)
}
})
.catch(e => console.log(e));
};
return (
<div className='login-page'>
<div className='login-space' />
<Form
className="login-form"
initialValues={{
remember: false,
}}
onFinish={onFinish}
>
<Form.Item
name="username"
rules={[
{
required: true,
message: '请输入用户名',
},
]}
>
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="用户名" />
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: '请输入密码!',
},
]}
>
<Input
prefix={<LockOutlined className="site-form-item-icon" />}
type="password"
placeholder="密码"
/>
</Form.Item>
<Form.Item>
<Form.Item name="remember" valuePropName="checked" noStyle>
<Checkbox>记住我</Checkbox>
</Form.Item>
<a className="login-form-forgot" href="/forget">
忘记密码?
</a>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login-form-button">
登录
</Button>
<p />
<Button type="default" htmlType="button" className="login-form-button" onClick={() => navigate('/register')}>
注册
</Button>
</Form.Item>
</Form>
<div className='login-space' />
</div>
);
}
.login-page {
display: flex;
flex-direction: row;
margin-top: 15%;
}
.login-space {
flex: 1.5;
}
.login-form {
flex: 1;
}
.login-form-forgot{
float: right;
}
.login-form-button {
width: 100%;
}
整个login 就结束了,主要是表单的处理,同理运用到注册上也差不多。
注册
import React, { useState } from 'react';
import './register.css';
import 'antd/dist/antd.css';
import cookie from 'js-cookie'
import { useNavigate } from 'react-router-dom';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import md5 from 'js-md5'
import {
Form,
Input,
Checkbox,
Button,
message
} from 'antd';
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
};
export default function Register () {
const navigate = useNavigate();
const [userState, setUserState] = useState('success')
const [emailState, setEmailState] = useState('success')
const storeInfo = (userId) => {
let date = new Date();
date.setTime(date.getTime() + 30 * 60 * 1000);
let result = cookie.set("userId", userId, {
expires: date
});
console.log(result);
navigate('/');
}
const [form] = Form.useForm();
const onFinish = (values: any) => {
setUserState('success');
setEmailState('success');
values.password = md5(values.password)
values.confirm = md5(values.confirm)
fetch("/api/user/register", {
method: 'POST',
headers: { 'Content-Type': 'application/json', },
body: JSON.stringify(values),
})
.then(response => response.json())
.then(json => {
console.log(json)
if (json.result === 0) {
storeInfo(json.detail.userId)
message.success('注册成功');
} else {
if (json.result === 2) {
setUserState('error')
} else if (json.result === 3) {
setEmailState('error')
}
message.error(json.resultNote)
}
})
.catch(e => console.log(e));
};
return (
<div className='register-page'>
<div className='register-space' />
<Form
{...formItemLayout}
form={form}
className="register"
onFinish={onFinish}
scrollToFirstError
>
<Form.Item
name="username"
label="用户名"
validateStatus={userState}
rules={[{ required: true, message: '请输入用户名~', whitespace: true }]}
>
<Input />
</Form.Item>
<Form.Item
name="email"
label="邮箱"
validateStatus={emailState}
tooltip="可用于找回密码"
rules={[
{
type: 'email',
message: '邮箱格式非法',
}
]}
>
<Input />
</Form.Item>
<Form.Item
name="password"
label="密码"
rules={[
{
required: true,
message: '密码长度至少8位~',
min: 8
},
]}
hasFeedback
>
<Input.Password />
</Form.Item>
<Form.Item
label="确认密码"
name="confirm"
dependencies={['password']}
hasFeedback
rules={[
{
required: true,
message: '请再次确认密码',
},
({ getFieldValue }) => ({
validator (_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('两次密码不一致'));
},
}),
]}
>
<Input.Password />
</Form.Item>
<Form.Item
name="agreement"
valuePropName="checked"
rules={[
{
validator: (_, value) =>
value ? Promise.resolve() : Promise.reject(new Error('请先同意相关条款')),
},
]}
{...tailFormItemLayout}
>
<Checkbox>
我已阅读并同意<a href="">《条款》</a>
</Checkbox>
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">
注册
</Button>
</Form.Item>
</Form >
<div className='register-space' />
</div>
);
}
APP管理平台–前端篇,首页(三)
|