一、首先要连接数据库,准备一个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');
});