(三)项目功能的实现之新增用户
BLOG -- 源码目录
└── model -- 数据库操作
└── user.js --用户管理
├── public -- 静态资源
└── route -- 路由
└── admin --博客管理
├── user-edit-fn.js --用户添加页面路由
└── user-edit.js --用户编辑页面路由
└── admin.js --博客管理页面路由
└── views -- 模板
└── admin --博客管理页面art模板
├── user-edit.art --用户编辑页面
└── user.art --用户列表页
├── app.js -- 创建网站服务
└──joi.js -- JavaScript对象的规则描述语言和验证器
1.user.art
- 为新增用户添加跳转链接到user-edit.art
{{extend './common/layout.art'}}
{{block 'main'}}
<!-- 子模板的相对路径相对的就是当前文件 因为它是由模板引擎解析的 而不是浏览器 -->
{{include './common/header.art'}}
<!-- 主体内容 -->
<div class="content">
{{include './common/aside.art'}}
<div class="main">
<!-- 分类标题 -->
<div class="title">
<h4>用户</h4>
<span>找到1个用户</span>
<a href="/admin/user-edit" class="btn btn-primary new">新增用户</a>
</div>
{{/block}}
2.user-edit.art
- 为新增用户表单指定请求地址、请求方式、为表单项添加name属性(method\value\name\action)
<p class="tips">{{message}}</p>
表示用户提交的错误信息的显示
{{extend './common/layout.art'}}
{{block 'main'}}
{{include './common/header.art'}}
<!-- /头部 -->
<!-- 主体内容 -->
<div class="content">
{{include './common/aside.art'}}
<div class="main">
<!-- 分类标题 -->
<div class="title">
<h4 style="display: {{button == '修改' ? 'block' : 'none'}}">{{@user && user._id}}</h4>
<p class="tips">{{message}}</p>
</div>
<!-- /分类标题 -->
<form class="form-container" action="{{link}}" method="post">
<div class="form-group">
<label>用户名</label>
<input name="username" type="text" class="form-control" placeholder="请输入用户名" value="{{user && user.username}}">
</div>
<div class="form-group">
<label>邮箱</label>
<input type="email" class="form-control" placeholder="请输入邮箱地址" name="email" value="{{user && user.email}}">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" class="form-control" placeholder="请输入密码" name="password">
</div>
<div class="form-group">
<label>角色</label>
<select class="form-control" name="role">
<option value="normal" {{user && user.role == 'normal' ? 'selected' : ''}}>普通用户</option>
<option value="admin" {{user && user.role == 'admin' ? 'selected' : ''}}>超级管理员</option>
</select>
</div>
<div class="form-group">
<label>状态</label>
<select class="form-control" name="state">
<option value="0" {{user && user.state == '0' ? 'selected' : ''}}>启用</option>
<option value="1" {{user && user.state == '1' ? 'selected' : ''}}>禁用</option>
</select>
</div>
<div class="buttons">
<input type="submit" class="btn btn-primary" value="{{button}}">
</div>
</form>
</div>
</div>
{{/block}}
admin.js
- 创建用户编辑页面路由,渲染user-edit
- 增加实现添加用户的功能路由,user-edit-fn
// 引用expess框架
const express = require('express');
// 创建博客展示页面路由
const admin = express.Router();
// 渲染登录页面
admin.get('/login', require('./admin/loginPage'));
// 实现登录功能
admin.post('/login', require('./admin/login'));
// 创建用户列表路由
admin.get('/user', require('./admin/userPage'));
// 实现退出功能
admin.get('/logout', require('./admin/logout'));
// 创建用户编辑页面路由
admin.get('/user-edit', require('./admin/user-edit'));
// 创建实现用户添加功能路由
admin.post('/user-edit', require('./admin/user-edit-fn'));
// 将路由对象做为模块成员进行导出
module.exports = admin;
user.js
- 引入joi模块,定义验证规则,将模块对象抛出
// 创建用户集合
// 引入mongoose第三方模块
const mongoose = require('mongoose');
// 导入bcrypt
const bcrypt = require('bcrypt');
// 引入joi模块
const Joi = require('joi');
// 创建用户集合规则
const userSchema = new mongoose.Schema({
username: {
type: String,
required: true,
minlength: 2,
maxlength: 20
},
email: {
type: String,
// 保证邮箱地址在插入数据库时不重复
unique: true,
required: true
},
password: {
type: String,
required: true
},
// admin 超级管理员
// normal 普通用户
role: {
type: String,
required: true
},
// 0 启用状态
// 1 禁用状态
state: {
type: Number,
default: 0
}
});
// 创建集合
const User = mongoose.model('User', userSchema);
async function createUser () {
const salt = await bcrypt.genSalt(10);
const pass = await bcrypt.hash('123456', salt);
const user = await User.create({
username: 'iteheima',
email: 'itheima@itcast.cn',
password: pass,
role: 'admin',
state: 0
});
}
// createUser();
// 验证用户信息
const validateUser = user => {
// 定义对象的验证规则
const schema = {
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('状态值非法'))
};
// 实施验证
return Joi.validate(user, schema);
}
// 将用户集合做为模块成员进行导出
module.exports = {
User,
validateUser
}
5.joi.js
- JavaScript对象的规则描述语言和验证器
npm install joi
// 引入joi模块
const Joi = require('joi');
// 定义对象的验证规则
const schema = {
username: Joi.string().min(2).max(5).required().error(new Error('username属性没有通过验证')),
birth: Joi.number().min(1900).max(2020).error(new Error('birth没有通过验证'))
};
async function run () {
try {
// 实施验证
await Joi.validate({username: 'ab', birth: 1800}, schema);
}catch (ex) {
console.log(ex.message);
return;
}
console.log('验证通过')
}
run();
7、user-edit.js
- 通过req.query获取message并渲染到user-edit.art中
module.exports = async (req, res) => {
// 获取到地址栏中的id参数
const { message } = req.query;
//进行渲染
res.render('admin/user-edit', {
message: message,
});
8、user-edit-fn.js
- 通过引入validateUser构造函数,验证没有通过,获取e.message并重定向回用户添加页面
- 根据邮箱地址查询用户是否存在,如果用户已经存在 邮箱地址已经被别人占用重定向回用户添加页面
- 如果都没有问题,说明可以添加用户,则进行密码加密,引入bcrypt,将用户信息添加到数据库中,完成用户添加后重定向回用户列表页面
// 引入用户集合的构造函数
const { User, validateUser } = require('../../model/user');
// 引入加密模块
const bcrypt = require('bcrypt');
module.exports = async (req, res, next) => {
try {
await validateUser(req.body)
}catch (e) {
// 验证没有通过
// e.message
// 重定向回用户添加页面
// return res.redirect(`/admin/user-edit?message=${e.message}`);
// JSON.stringify() 将对象数据类型转换为字符串数据类型
return next(JSON.stringify({path: '/admin/user-edit', message: e.message}))
}
// 根据邮箱地址查询用户是否存在
let user = await User.findOne({email: req.body.email});
// 如果用户已经存在 邮箱地址已经被别人占用
if (user) {
// 重定向回用户添加页面
// return res.redirect(`/admin/user-edit?message=邮箱地址已经被占用`);
return next(JSON.stringify({path: '/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');
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。