1.建模的User.js
const mongoose = require('mongoose') //引入Mongoose
const Schema = mongoose.Schema //聲明Schema
let ObjectId = Schema.Types.ObjectId //聲明Object類型
const bcrypt = require('bcrypt')
const SALT_WORK_FACTOR = 10
//創建我們的用戶Schema
const userSchema = new Schema({
UserId: ObjectId,
userName: { unique: true, type: String },
password: String,
createAt: { type: Date, default: Date.now() },
lastLoginAt: { type: Date, default: Date.now() }
}, {
collection: 'user'
})
//每次存儲數據時都要執行
//這個是用來注冊的,可返還是否有重復的用戶名
userSchema.pre('save', function (next) {
//let user = this
// console.log(this)
bcrypt.genSalt(SALT_WORK_FACTOR, (err, salt) => {
if (err) return next(err)
bcrypt.hash(this.password, salt, (err, hash) => {
if (err) return next(err)
this.password = hash
next()
})
})
})
//用來比對用戶名相同,密碼是否正確的
userSchema.methods = {
//密碼比對的方法
comparePassword: (_password, password) => {
return new Promise((resolve, reject) => {
bcrypt.compare(_password, password, (err, isMatch) => {
if (!err) resolve(isMatch)
else reject(err)
})
})
}
}
//發布模型
mongoose.model('User', userSchema)
2.api里面的user.js 接口Js
const Router = require('koa-router')
const mongoose = require('mongoose')
let router = new Router()
router.get('/', async (ctx) => {
ctx.body = '用戶首頁'
})
router.post('/register', async (ctx) => {
const User = mongoose.model('User')
let newUser = new User({
userName: ctx.request.body.username,
password: ctx.request.body.password,
})
await newUser.save().then(() => {
ctx.body = {
code: 200,
message: '注冊成功'
}
}).catch(err => {
ctx.body = {
code: 500,
message: err
}
})
})
router.post('/login', async (ctx) => {
let userInfo = ctx.request.body
let userName = userInfo.userName
let password = userInfo.password
//引入User的model
const User = mongoose.model('User')
await User.findOne({ userName: userName }).exec().then(async (res) => {
console.log(res)
if (res) {
//當用戶名存在時,開始比對密碼
let newUser = new User() //因為是實例方法,所以要new出對象,才能調用
// comparePassword 是schema/底下User.js 下面實例化的方法
// res.password 是數據庫中的password
await newUser.comparePassword(password, res.password)
.then((isMatch) => {
//返回比對結果
ctx.body = { code: 200, message: isMatch }
})
.catch(error => {
//出現異常,返回異常
console.log(error)
ctx.body = { code: 500, message: error }
})
} else {
ctx.body = {
code: 201,
message: '用戶名不存在'
}
}
})
})
module.exports = router
3.index.js 主js 初始化
const Koa = require('koa')
const app = new Koa()
//連接數據庫初始化
const { connect,initSchemas } = require('../service/database/init')
const mongoose = require('mongoose')
const Router =require('koa-router')
// 作為post請求用 koa-bodyparser
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
// 支持跨域
const cors = require('koa2-cors')
app.use(cors())
let user = require('./appApi/user')
//裝載子路由
let router = new Router();
router.use('/user',user.routes())
//加載路由中組件
app.use(router.routes())
app.use(router.allowedMethods())
//立即執行函數
;(async () => {
// 第四個文件夾有方法
await connect()
initSchemas()
})()
app.use(async (ctx) => {
ctx.body = '<h1>Hello Koa2</h1>'
})
app.listen(3000, () => {
console.log('3000端口打開')
})
4.連接數據庫初始化文件 init.js
const mongoose = require('mongoose')
const db = 'mongodb://localhost/smile-db'
// 需要安裝glob 插件,之前筆記有設計
const glob = require('glob')
const {resolve} = require('path')
exports.initSchemas = () =>{
glob.sync(resolve(__dirname,'./schema/','**/*.js')).forEach(require)
}
mongoose.Promise = global.Promise
exports.connect = () => {
//鏈接數據庫
mongoose.connect(db)
let maxNum = 0
return new Promise((resolve, reject) => {
//增加數據庫監聽事件
//數據庫監聽斷開事件
mongoose.connection.on('disconnected', (err) => {
console.log('************數據庫已斷開***********')
if(maxNum <=3){
maxNum ++
mongoose.connect(db)
}else{
reject()
throw new Error('數據庫出現問題,程序無法搞定,請維護')
}
})
//數據庫監聽鏈接錯誤事件
mongoose.connection.on('error', (err) => {
console.log('************數據庫錯誤***********')
if(maxNum <=3){
maxNum ++
mongoose.connect(db)
}else{
reject(err)
throw new Error('數據庫出現問題,程序無法搞定,請維護')
}
})
//數據庫監聽打開
mongoose.connection.once('open', () => {
console.log('************MongoDB 連接成功***********')
resolve()
})
})
}