代码优化
- 把admin.js 文件变成一个路由列表,把路由处理代码分离到一个单独的文件夹下
① 依次创建以下文件用来存放路由处理代码
② 简化后的代码 - 实现功能页面展示
① 进入登录页面
② 跳转到用户列表页面
③ 退出列表页面返回登录页面
新增用户
- 为用户列表页面的新增用户按钮添加链接
- 添加一个链接对应的路由,在路由处理函数中渲染新增用户模板
- 为新增用户表单指定请求地址、请求方式、为表单项添加name属性
- 增加实现添加用户的功能路由
- 接收到客户端传递过来的请求参数
- 举例子
- 对请求参数的格式进行验证
- 验证当前要注册的邮箱地址是否已经注册过
- 对密码进行加密处理
- 将用户信息添加到数据库中
- 重定向页面到用户列表页面
→ 第三方模块Joi 知识点
① 修改以下代码
② 把以下代码添加到 user-edit-fn.js 文件中
// 引入用户集合的构造函数
const { User } = require('../../model/user');
// 引入加密模块
const bcrypt = require('bcrypt');
// 引入joi 模块
const Joi = require('joi');
module.exports = async(req, res) => {
// 定义对象的验证规则
const schema = Joi.object({
username: Joi.string().min(2).max(12).required().error(new Error('用户名不符合验证规则')),
email: Joi.string().email().required().error(new Error('邮箱格式不符合要求')),
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/).required().error(new Error('密码格式不符合要求')),
role: Joi.string().valid('normal', 'admin').required().error(new Error('角色值非法')),
state: Joi.number().valid(0,1).required().error(new Error('状态值非法'))
});
try {
// 实施验证
await schema.validateAsync(req.body);
}catch(e) {
// 验证没有通过
// e.message;
// 重定向回用户添加页面
// res.redirect('/admin/user-edit?message=' + e.message);
return res.redirect(`/admin/user-edit?message=${e.message}`);
};
// 根据邮箱地址查询用户是否存在
// req.body.email 表示用户传递过来的地址
// 通过user变量接收findOne 的返回值
let user = await User.findOne({email: req.body.email});
// 如果用户已经存在 就说明邮箱地址已经被别人占用
if (user) {
// 重定向回用户添加页面
return res.redirect(`/admin/user-edit?message=邮箱地址已经被占用`);
};
// 对密码进行加密处理
// 生成随机字符串
const salt = await bcrypt.genSalt(10);
// 对密码进行加密
const password = await bcrypt.hash(req.body.password, salt);
// 替换密码(最终我们要把数据添加到数据库中)
req.body.password = password;
// 将用户信息添加到数据库中
await User.create(req.body);
// 将页面重定向到用户列表页面
res.redirect('/admin/user');
}
③ 当新增用户后数据库中就会显示当前添加的用户信息
- 对代码进行优化处理
① 对用户数据的操作代码统一放在一个文件夹下
注: 别忘了引入joi 模块
② 修改以下代码
③ 对错误处理重定向代码进行优化处理
④ 定义错误处理中间件
拓展 – 第三方模块Joi
JavaScript对象的规则描述语言和验证器
下载第三方模块 joi npm install joi
// 引入第三方模块 joi
const Joi = require('joi');
// 定义对象的验证规则
// 声明一个schema变量用来存放验证规则
// 如果出现验证规则以外的属性 那么验证将会失败
const schema = Joi.object({
// alphanum() 表示字母字符串或数字字符串
username: Joi.string().alphanum().min(3).max(30).required().error(new Error('username属性没有通过验证')),
// 需要使用正则规则来验证password
password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
// 既可以是字符串类型,也可以是数字型
access_token: [Joi.string(), Joi.number()],
// integer() 代表整数
birthyear: Joi.number().integer().min(1933).max(2022),
email: Joi.string().email()
});
async function run() {
try {
// 实施验证
// validateAsync方法返回一个promise对象
await schema.validateAsync({username: 'aaaaa', password: 'abc123', birthyear: 2012, email: 'ithei@163.com'});
} catch(ex) {
console.log(ex.message);
return;
}
console.log('验证通过');
}
run();