一、首先要连接数据库,准备一个db.js
module.exports = app =>{ const mongoose = require('mongoose') //数据库连接,允许新连接生成 mongoose.connect('mongodb://127.0.0.1:27017/vue_moba',{ useNewUrlParser:true }) //加载所有模块 require('require-all')(__dirname + '/../models') }
二、准备各个模块的数据类型
- Ad模块
const mongoose = require("mongoose") const schema = new mongoose.Schema({ name:{type:String}, items:[{ image:{type:String}, url:{type:String}, }] }) module.exports = mongoose.model('Ad',schema)
- AdminUser模块
const mongoose = require("mongoose") const schema = new mongoose.Schema({ username:{type:String}, password:{ type:String, select:false, set(val){ return require('bcrypt').hashSync(val,10) }}, }) module.exports = mongoose.model('AdminUser',schema)
-
Article模块
const mongoose = require("mongoose") const schema = new mongoose.Schema({ title:{type:String}, categories:[{type:mongoose.Schema.Types.ObjectId,ref:'Category'}], body:{type:String}, },{ timestamps:true }) module.exports = mongoose.model('Article',schema)
-
Category模块
const mongoose = require('mongoose') const schema = new mongoose.Schema({ name: { type: String }, parent: { type: mongoose.SchemaTypes.ObjectId, ref: 'Category' }, }) schema.virtual('children', { localField: '_id', foreignField: 'parent', justOne: false, ref: 'Category' }) schema.virtual('newsList', { localField: '_id', foreignField: 'categories', justOne: false, ref: 'Article' }) module.exports = mongoose.model('Category', schema)
-
Hero模块
const mongoose = require("mongoose") const schema = new mongoose.Schema({ name:{type:String}, avatar:{type:String}, title:{type:String}, categories:[{type:mongoose.Schema.Types.ObjectId,ref:'Category'}], scores:{ difficult:{type:Number}, skills:{type:Number}, attack:{type:Number}, survive:{type:Number} }, skills:[{ icon:{type:String}, name:{type:String}, description:{type:String}, tips:{type:String} }], items1:[{ type:mongoose.Schema.Types.ObjectId,ref:'Item' }], items2:[{ type:mongoose.Schema.Types.ObjectId,ref:'Item' }], usageTips:{type:String}, battleTips:{type:String}, teamTips:{type:String}, partners:[{ hero:{type:mongoose.Schema.Types.ObjectId,ref:'Hero'}, description:{type:String} }] }) module.exports = mongoose.model('Hero',schema)
-
Item模块
const mongoose = require("mongoose") const schema = new mongoose.Schema({ name:{type:String}, icon:{type:String} }) module.exports = mongoose.model('Item',schema)
三、准备数据连接接口
module.exports = app => { const express = require('express') const jwt = require('jsonwebtoken') const AdminUser = require('../../models/AdminUser') const assert = require('http-assert') const router = express.Router({ mergeParams: true }) //const Category = require('../../models/Category') //创建资源 router.post('/', async (req, res) => { //因为模块有很多个,不能一一为每一个模块设置接口,则使用统一的接口调用 const model = await req.Model.create(req.body) res.send(model) }) //修改 router.put('/:id', async (req, res) => { const model = await req.Model.findByIdAndUpdate(req.params.id, req.body) res.send(model) }) router.delete('/:id', async (req, res) => { await req.Model.findByIdAndDelete(req.params.id, req.body) res.send({ success: true }) }) //资源列表 router.get('/',async (req, res) => { const queryOptions = {} if (req.Model.modelName === 'Category') { queryOptions.populate = 'parent' //关联查询parent } const items = await req.Model.find().setOptions(queryOptions).limit(100) res.send(items) }) //资源详情 router.get('/:id', async (req, res) => { const model = await req.Model.findById(req.params.id) res.send(model) }) //登陆校验中间件 const authMiddleware = require('../../middleware/auth') const resourceMiddleware =require("../../middleware/resource") app.use('/admin/api/rest/:resource',authMiddleware(), resourceMiddleware() , router) //处理上传 const multer = require('multer') //上传 const upload = multer({ dest: __dirname + '/../../uploads' }) //允许该接口上传文件 app.post('/admin/api/upload',authMiddleware(), upload.single('file'), async (req, res) => { //在req中加入一个属性file const file = req.file file.url = `http://localhost:3037/uploads/${file.filename}` res.send(file) }) app.post('/admin/api/login', async (req, res) => { const { username, password } = req.body //找用户 const user = await AdminUser.findOne({ username }).select('+password') assert(user,422,"用户不存在") //校验密码 const isValid = require('bcrypt').compareSync(password, user.password) assert(isValid,422,"密码错误") //返回token const token = jwt.sign({ id: user._id, }, app.get('secret')) res.send({token}) }) //错误处理 app.use(async(err,req,res,next) =>{ res.status(err.statusCode || 500).send({ message:err.message }) }) }
四、在index在引入上述模块
const express = require("express") const app = express() app.set('secret', 'i2u34y12oi3u4y8') app.use(require('cors')()) app.use(express.json()) app.use('/', express.static(__dirname + '/web')) app.use('/admin', express.static(__dirname + '/admin'))
//上传文件模块 app.use('/uploads', express.static(__dirname + '/uploads')) require('./plugins/db')(app) require('./routes/admin')(app) app.listen(3000, () => { console.log('http://localhost:3000'); });