到此,我们才真正进入具体的模块开发阶段。本章节,我们先从用户入手,谈谈如何开发用户模块。
创建用户模型
我们在web->models->admin文件夹下创建admin.js,这是用户表信息,具体如下:
'use strict';
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const adminSchema = new Schema({
user_name: String,
password: String,
id: Number,
create_time: String,
admin: {type:String,default:'管理员'},
status: Number, //1、普通管理员 2、超级管理员
avatar: {type: String, default: 'default.jpg'},
city: String,
});
adminSchema.index({id: 1}); //索引
const Admin = mongoose.model('Admin',adminSchema);
export default Admin;
用户权限判断
这个主要在用户登录的时候做判断,我们在web->middlewares文件夹下,创建check.js文件,具体如下:
/**
* Created by admin on 2017/9/28 0014.
*/
'use strict';
import AdminModel from '../models/admin/admin';
class Check {
constructor() {}
async checkAdmin(req, res, next) {
const admin_id = req.session.admin_id;
if(!admin_id || !Number(admin_id)) {
res.send({
status: 0,
type: 'ERROR_SESSION',
message: '亲,您还没有登录'
});
return
} else {
const admin = await AdminModel.findOne({id: admin_id});
if(!admin) {
res.send({
status: 0,
type: 'HAS_NO_ACCESS',
message: '权限不足,请联系管理员提升权限'
});
return
}
}
next()
};
async checkSuperAdmin(req, res, next) {
const admin_id = req.session.admin_id;
if(!admin_id || !Number(admin_id)) {
res.send({
status: 0,
type: 'ERROR_SESSION',
message: '亲,您还没有登录',
});
return
} else {
const admin = await AdminModel.findOne({id: admin_id});
if(!admin || admin.status != 2) {
res.send({
status: 0,
type:'HAS_NO_ACCESS',
message: '权限不足'
});
return
}
}
next();
};
}
export default new Check();
编写用户控制器
我们在web->controller->admin文件夹下,创建admin.js文件,具体如下:
/**
* Created by admin on 2017/9/14 0014.
*/
'use strict';
import AdminModel from '../../models/admin/admin';
import AddressComponent from '../../prototype/addressComponent';
import cryoto from 'crypto';
import formidable from 'formidable';
import dtime from 'time-formater';
class Admin extends AddressComponent {
//构造函数
constructor() {
super();
};
//登录
async login(req, res, next) {
const form = new formidable.IncomingForm(); //创建表单对象
//form.parse方法会转换请求中所包含的表单数据,callback会包含所有字段域和文件信息
form.parse(req, async(err, fields, files) => {
if(err) {
res.send({
status: 0,
type: 'FORM_DATA_ERROR',
message: '表单信息错误'
});
return;
}
const {user_name, password, status = 1} = fields;
try{
if(!user_name) {
res.send({
status: 0,
type: 'GET_ERROR_USERNAME',
message: '用户名参数错误'
});
} else if(!password) {
res.send({
status: 0,
type: 'GET_ERROR_PASSWORD',
message: '密码参数错误'
});
}
} catch(err) {
console.log(err.message,err);
res.send({
status: 0,
type: 'GET_ERROR_PARAM',
message: err.message
});
return;
}
const newpassword = this.encryption(password);
try{
const admin = await AdminModel.findOne({user_name});
if(!admin) {
const adminTip = status == 1 ? '管理员' : '超级管理员';
const admin_id = await this.getId('admin_id');
const cityInfo = await this.guessPosition(req);
const newAdmin = {user_name,password: newpassword,id: admin_id,create_time:dtime().format('YYYY-MM-DD HH:mm'),admin: adminTip,status,city:cityInfo.city
};
await AdminModel.create(newAdmin);
req.session.admin_id = admin_id;
res.send({
status: 1,
success: '注册管理员成功'
})
} else if (newpassword.toString() != admin.password.toString()) {
console.log('管理员登录密码错误');
res.send({
status: 0,
type: 'ERROR_PASSWORD',
message: '该用户已存在,密码输入错误'
})
} else {
req.session.admin_id = admin.id;
res.send({
status: 1,
success: '登录成功'
})
}
} catch(err) {
console.log('登录管理员失败',err);
res.send({
status: 0,
type: 'LOGIN_ADMIN_FAILLED',
message: '登录管理员失败'
})
}
});
}
//注册
async register(req, res, next) {
const form = new formidable.IncomingForm();
form.parse(req, async(err,fields,files) => {
if(err) {
res.send({
status: 0,
type: 'FORM_DATA_ERROR',
message: '表单信息错误'
});
return;
}
const {user_name, password, status = 1} = fields;
try{
if(!user_name) {
res.send({
status: 0,
type: 'GET_ERROR_USER_NAME',
message: '用户名错误'
})
} else if(!password) {
res.send({
status: 0,
type: 'GET_ERROR_PASSWORD',
message: '密码错误'
});
}
} catch(err) {
console.log(err.message,err);
res.send({
status: 0,
type: 'GET_ERROR_PARAM',
message: err.message
});
return;
}
try{
const admin = await AdminModel.findOne({user_name});
if(admin) {
console.log('该用户已经存在');
res.send({
status: 0,
type: 'USER_HAS_EXIST',
message: '该用户已经存在'
})
} else {
const adminTip = status == 1 ? '管理员' : '超级管理员';
const admin_id = await this.getId('admin_id');
const newpassword = this.encryption(password);
const newAdmin = {
user_name,
password: newpassword,
id: admin_id,
create_time: dtime().format('YYYY-MM-DD'),
admin: adminTip,
status,
};
await AdminModel.create(newAdmin);
req.session.admin_id = admin_id;
res.send({
status: 1,
message: '注册管理员成功'
})
}
} catch(err) {
console.log('注册管理员失败',err);
res.send({
status: 0,
type: 'REGISTER_ADMIN_FAILED',
message: '注册管理员失败'
})
}
})
};
//密码加密
encryption(password){
const newpassword = this.Md5(this.Md5(password).substr(2,7) + this.Md5(password));
return newpassword;
}
//md5加密
Md5(password) {
const md5 = cryoto.createHash('md5');
return md5.update(password).digest('base64');
}
//退出
async singout(req, res, next) {
try{
delete req.session.admin_id;
res.send({
status: 1,
success: '退出成功'
})
} catch(err) {
console.log('退出失败',err);
res.send({
status: 0,
message: '退出失败'
})
}
}
//获取用户列表
async getAllAdmin(req, res, next) {
const {limit = 20, offset = 0} = req.query;
try{
const allAdmin = await AdminModel.find({},'-_id -password').sort({id:-1}).skip(Number(offset)).limit(Number(limit));
res.send({
status: 1,
data: allAdmin,
})
} catch(err) {
console.log('获取超级管理列表失败',err);
res.send({
status: 0,
type: 'ERROR_GET_ADMIN_LIST',
message: '获取超级管理列表失败'
})
}
}
//获取用户总数
async getAdminCount(req, res, next) {
try{
const count = await AdminModel.count();
res.send({
status: 1,
count,
})
} catch(err) {
console.log('获取管理员数量失败', err);
res.send({
status: 0,
type: 'ERROR_GET_ADMIN_COUNT',
message: '获取管理员数量失败'
})
}
}
//获取用户基本信息
async getAdminInfo(req, res, next) {
const admin_id = req.session.admin_id;
if(!admin_id || !Number(admin_id)) {
console.log('获取管理员信息的SESSION失效');
res.send({
status: 0,
type:'ERROR_SESSION',
message: '获取管理员信息失败'
});
return;
}
try{
const info = await AdminModel.findOne({id:admin_id},'-_id -password');
if(!info) {
res.send({
status: 0,
type: 'GET_ERROR_ADMIN',
message: '未找到当前管理员'
});
} else {
res.send({
status: 1,
data: info
})
}
} catch(err) {
console.log('获取管理员信息失败');
res.send({
status: 0,
type: 'GET_ADMIN_INFO_FAILED',
message: '获取管理员信息失败'
})
}
}
//图片上传
async updateAvatar(req, res, next) {
const admin_id = req.params.admin_id;
if(!admin_id || !Number(admin_id))
{
console.log('admin_id参数错误:',admin_id);
res.send({
status: 0,
type: 'ERROR_ADMINID',
message: 'admin_id参数错误'
});
return;
}
try{
const image_path = await this.qiniu(req);
await AdminModel.findOneAndUpdate({id:admin_id},{$set:{avatar: image_path}});
} catch(err) {
console.log('上传图片失败',err);
res.send({
status: 0,
type: 'ERROR_UPLOAD_IMG',
message: '上传图片失败'
})
}
};
}
export default new Admin();
配置路由信息
我们在routes文件夹下创建admin.js文件,这里存放的是用户的路由信息,具体如下:
'use strict';
import express from 'express';
import Admin from '../web/controller/admin/admin';
const router = express.Router();
router.post('/login',Admin.login); //用户登录
router.get('/singout',Admin.singout); //用户退出
router.get('/all',Admin.getAllAdmin); //所有用户
router.get('/count',Admin.getAdminCount); //用户总数
router.get('/info',Admin.getAdminInfo); //用户基本信息
router.post('/update/avatar/:admin_id',Admin.updateAvatar); //修改用户信息
export default router;
然后我们在routes文件夹下创建主路由文件index.js,我们可以把分路由全部集中到主路由下,代码如下:
'use strict';
import admin from './admin';
export default app => {
app.use('/admin',admin);
};
以上配置完成后,我们就可以测试接口啦,我们先测试“用户基本信息”这个接口。先启动项目,然后在地址栏输入:http://127.0.0.1:3000/admin/info,就能看到效果。
如果看到以上内容,说明接口调用成功,否则就查看代码,看看哪里出现问题了。好啦,今天的任务就到这里吧,有问题我们可以相互交流。
相关章节
nodeJS开发一套完整的项目(1、基础配置)
nodeJS开发一套完整的项目(2、相关模块介绍)
nodeJS开发一套完整的项目(3、数据库链接和项目启动)
nodeJS开发一套完整的项目(4、编写底层功能模块)
为了更好的服务大家,请加入我们的技术交流群:(511387930),同时您也可以扫描下方的二维码关注我们的公众号,每天我们都会分享经验,谢谢大家。