用户信息修改功能
当点击用户后面的按钮时,要跳转到用户信息修改页面。而修改和添加实际上是同一个页面。
要区分跳转后是添加操作还是修改操作,在于携带的参数。
如果是添加操作,那就直接跳转过去;如果是修改操作,那就携带当前用户的id,通过get的方式传递过去。这样,在跳转到用户编辑页面的时候,可以通过get方式中是否有id参数,来区分到底是添加操作还是修改操作。如果是修改操作,还需要将要修改的用户信息从数据库中查询出来,并显示在页面中。
当用户在页面中修改完信息以后,点击提交表单按钮,向服务器发送修改用户信息的请求。
修改界面表单的上方显示的是要修改用户的id值,如果是添加用户,这个地方是不需要显示的。所以在模板中需要判断。
为用户列表页面为修改按钮添加链接
修改链接是admin/user-edit
在views/user.art中
<a href="/admin/user-edit?id={{@$value._id}}" class="glyphicon glyphicon-edit"></a>
此时点击即可跳转,并且地址栏携带id参数。
找到编辑页面所对应的路由user-edit.js,在这里,要获取到地址栏中的id参数,从而判断是添加还是修改操作。
因为无论是message还是id参数,都是存放在req.query当中,所以可以继续解构。
引入User模块,
通过id获取到用户信息,并将user传递给模板user-edit.art。
由于这个页面就是一个表单,所以要通过表单value属性把用户的信息显示在表单的控件里面。
但是,当是添加用户操作时,并没有传递给模板user,如果模板中还是用到了User,那么将会报错。所以要先判断user存不存在,再获取它的属性。
密码不可以直接修改,要在单独的地方进行修改密码操作。有两种做法:
- 直接隐藏密码,不让用户修改
- 让用户填写密码,但是密码错误则不让用户修改
在user-edit.js中,渲染页面时,为添加和修改页面设置自己的提交页面和按钮。
if (id) {//修改操作let user = await User.findOne({_id: id});//res.send(user);//return;//渲染用户编辑页面res.render('admin/user-edit', {message: message,user: user,link: '/admin/user-add',button: '修改'});} else {//添加操作res.render('admin/user-edit', {message: message,link: '/admin/user-edit',button: '添加'});}
<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 name="email" type="email" class="form-control" placeholder="请输入邮箱地址" value="{{user && user.email}}"></div><div class="form-group"><label>密码</label><input name="password" type="password" class="form-control" placeholder="请输入密码"></div><div class="form-group"><label>角色</label><select name="role" class="form-control"><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 name="state" class="form-control"><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>
修改数据库中的用户信息
- 将要修改的用户id传递到服务器端(
link: '/admin/user-modify?id=' + id
) - 建立用户信息修改功能对应的路由
- 接收客户端表单传递过来的请求参数
- 根据id查询用户信息,并将客户端传递过来的密码和数据库中的密码进行比对
- 如果比对失败,直接对客户端做出响应
- 如果比对成功,则将用户信息更新到数据库中
如果比对失败,要给请求处理函数传一个next,然后失败后调用next,传一个字符串类型的对象过去。并且需要携带id信息。
let obj = {path: '/admin/user-edit', message: '密码比对失败,无法修改信息', id : id};return next(JSON.stringify(obj));
但此时,app中的中间件代码是写死的,需要改善一下这个代码,把所有传递的参数拼接到地址后面。
app.js
app.use((err, req, res, next) => {//将字符串对象转换为对象类型//JSON.parse()const result = JSON.parse(err);//console.log(err);let params = [];for(let attr in result) {if(attr != 'path'){params.push(attr + '=' + result[attr]);}}return res.redirect(`${result.path}?${params.join('&')}`);
})
输入错误密码,将得到这样的提示
而地址栏是这样的
如果比对成功,把从req.body中解构出用户的属性,并更新到数据库中。其中密码是不能更新的。
//不包括idconst { username, email, role, state, password } = req.body; await User.updateOne({_id: id}, {username: username,email: email,role: role,state: state});
通过重定向
res.redirect('/admin/user');
提交成功后,页面重定向到user页面了。
此时,用户信息修改功能完成。