使用脚手架生成项目
cnpm i egg-init -g
egg-init zhangximufengblog-api --type simple
cd zhangximufengblog-api
cnpm i
cnpm run dev
opoen localhost:7001
2. 编写用户注册功能 [#](#t12. 编写用户注册功能)
-
2.1 使用egg-mongoose [#](#t22.1 使用egg-mongoose)
3.1.1 安装 [#](#t33.1.1 安装)
cnpm i egg-mongoose --save
3.1.2 启用插件 [#](#t43.1.2 启用插件)
// {app_root}config\plugin.js
exports.mongoose = {
enable: true,
package: 'egg-mongoose'
}
3.1.3 配置插件 [#](#t53.1.3 配置插件)
// {app_root}/config/config.default.js
exports.mongoose = {
client: {
url: 'mongodb://127.0.0.1/zhangximufengblog',
options: {},
},
};
2.2 配置模型 [#](#t62.2 配置模型)
// {app_root}/app/model/user.js
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const ObjectId = Schema.Types.ObjectId;
const UserSchema = new Schema({
username: { type: String, required: true },
password: { type: String, required: true },
email: String
});
return mongoose.model('User', UserSchema);
}
2.3 控制器中使用 [#](#t72.3 控制器中使用)
const BaseControler = require('./base');
class UserController extends BaseControler {
//用户注册
async signup() {
let { ctx, app } = this;
let user = ctx.request.body;
try {
user = await ctx.model.User.create(user);
this.success(user);
} catch (error) {
this.error(error);
}
}
}
2.4 配置路由 [#](#t82.4 配置路由)
module.exports = app => {
const { router, controller } = app;
router.post('/api/users/signup', controller.users.signup);
};
2.5 暂时禁用CSRF [#](#t92.5 暂时禁用CSRF)
config\config.default.js
config.security = {
csrf: false
}
3. 编写用户登录功能 [#](#t103. 编写用户登录功能)
3.1 控制器上增加方法 [#](#t113.1 控制器上增加方法)
//用户登录
async signin() {
let { ctx, app } = this;
let user = ctx.request.body;
try {
user = await ctx.model.User.findOne(user);
if (user) {
ctx.session.user = user;//保持会话
this.success({ user });
} else {
this.error('用户名或密码错误');
}
} catch (error) {
this.error(error);
}
}
3.2 配置路由 [#](#t123.2 配置路由)
router.post('/api/users/signin', controller.users.signin);
4. 编写用户退出功能 [#](#t134. 编写用户退出功能)
4.1 控制器上增加方法 [#](#t144.1 控制器上增加方法)
async signout() {
let { ctx } = this;
ctx.session.user = null;
this.success('success');
}
4.2 配置路由 [#](#t154.2 配置路由)
router.get('/api/users/signout', controller.users.signout);
5. 分类管理 [#](#t165. 分类管理)
Method | Path | Controller.Action |
---|---|---|
POST | /posts | app.controllers.posts.create |
GET | /posts | app.controllers.posts.index |
PUT | /posts/:id | app.controllers.posts.update |
DELETE | /posts/:id | app.controllers.posts.destroy |
\app\router.js
router.resources('categories', '/api/categories', controller.categories);
app\model\category.js
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const ObjectId = Schema.Types.ObjectId;
const CategorySchema = new Schema({
name: { type: String, required: true }
});
return mongoose.model('Category', CategorySchema);
}
5.1 添加分类 [#](#t175.1 添加分类)
async create() {
let { ctx } = this;
let category = ctx.request.body;
try {
let doc = await ctx.model.Category.create(category);
this.success('success');
} catch (err) {
this.error(error);
}
}
5.2 查看分类列表 [#](#t185.2 查看分类列表)
//查询分类列表
async index() {
let { ctx } = this;
let { pageNum = 1, pageSize = 10, keyword } = ctx.query;
pageNum = isNaN(pageNum) ? 1 : parseInt(pageNum);
pageSize = isNaN(pageSize) ? 1 : parseInt(pageSize);
let query = {};
if (keyword) {
query.name = new RegExp(keyword);
}
let total = await ctx.model.Category.count(query);
let items = await ctx.model.Category.find(query).skip((pageNum - 1) * pageSize).limit(pageSize);
this.success({
items,
pageNum,
pageSize,
total,
pageCount: Math.ceil(total / pageSize)
});
}
5.3 修改分类 [#](#t195.3 修改分类)
//修改分类
async update() {
let { ctx } = this;
let id = ctx.params.id;
let category = ctx.request.body;
try {
let result = await ctx.model.Category.findByIdAndUpdate(id, category);
this.success('success');
} catch (err) {
this.error(error);
}
}
5.4 删除分类 [#](#t205.4 删除分类)
//删除分类
async destroy() {
let { ctx } = this;
let id = ctx.params.id;
let { ids = [] } = ctx.request.body;
ids.push(id);
try {
await ctx.model.Category.remove({ _id: { $in: ids } });
this.success('success');
} catch (error) {
this.error(error);
}
}
6. 文章管理 [#](#t216. 文章管理)
\app\router.js
router.resources('articles', '/api/articles', controller.articles);
router.get('/api/articles/pv/:id', controller.articles.updatePv);
router.post('/api/articles/comment/:id', controller.articles.comment);
app\model\article.js
module.exports=app => {
const mongoose=app.mongoose;
const Schema=mongoose.Schema;
const ObjectId=Schema.Types.ObjectId;
const ArticleSchema=new Schema({
user: {type: ObjectId,ref: 'User'},
category: { type: ObjectId, ref: 'Category' },
title: String,
content: String,
pv: { type: Number, default: 0 },
comments: [{ user: { type: ObjectId, ref: 'User' }, content: String, createAt: { type: Date, default: Date.now } }],
createAt: { type: Date, default: Date.now }
});
return mongoose.model('Article',ArticleSchema);
}
6.1 添加文章 [#](#t226.1 添加文章)
async create() {
let { ctx } = this;
let article = ctx.request.body;
article.user = this.user._id;
try {
let doc = await ctx.model.Article.create(article);
this.success('success');
} catch (error) {
this.error(error);
}
}
6.2 查看文章列表 [#](#t236.2 查看文章列表)
async index() {
let { ctx } = this;
let { pageNum = 1, pageSize = 10, keyword } = ctx.query;
pageNum = isNaN(pageNum) ? 1 : parseInt(pageNum);
pageSize = isNaN(pageSize) ? 1 : parseInt(pageSize);
let query = {};
if (keyword) {
query.title = new RegExp(keyword);
}
let total = await ctx.model.Article.count(query);
let items = await ctx.model.Article.find(query).populate('category').populate('comments').skip((pageNum - 1) * pageSize).limit(pageSize);
this.success({
items,
pageNum,
pageSize,
total,
pageCount: Math.ceil(total / pageSize)
});
}
6.3 修改文章 [#](#t246.3 修改文章)
async update() {
let { ctx } = this;
let id = ctx.params.id;
let article = ctx.request.body;
try {
let result = await ctx.model.Article.findByIdAndUpdate(id, article);
this.success('success');
} catch (err) {
this.error(error);
}
}
6.4 删除文章 [#](#t256.4 删除文章)
async destroy() {
let { ctx } = this;
let { ids } = ctx.request.body;
try {
await ctx.model.Article.remove({ _id: { $in: ids } });
this.success('success');
} catch (error) {
this.error(error);
}
}
6.5 修改阅读量 [#](#t266.5 修改阅读量)
async updatePv() {
let { ctx } = this;
let id = ctx.params.id;
try {
let result = await ctx.model.Article.findByIdAndUpdate(id, { $inc: { pv: 1 } });
this.success('success');
} catch (error) {
this.error(error);
}
}
6.6 评论文章 [#](#t276.6 评论文章)
async comment() {
let { ctx } = this;
let id = ctx.params.id;
let comment = ctx.request.body;
comment.user = this.user._id;;
try {
let result = await ctx.model.Article.findByIdAndUpdate(id, { $push: { comments: comment } });
this.success('success');
} catch (err) {
this.error(error);
}
}
7. 处理跨域 [#](#t287. 处理跨域)
npm i egg-cors --save
// {app_root}/config/plugin.js
exports.cors = {
enable: true,
package: 'egg-cors',
};
//{app_root}/config/config.default.js
exports.security = {
domainWhiteList: [ 'http://localhost:4200' ],
};
8. 会话持久化 [#](#t298. 会话持久化)
-
cnpm i egg-session-redis egg-redis -S
// {app_root}/config/plugin.js
exports.sessionRedis = {
enable: true,
package: 'egg-session-redis',
};
exports.redis = {
enable: true,
package: 'egg-redis',
}
// {app_root}/config/config.default.js
exports.redis = {
client: {
host: '127.0.0.1',
port: '6379',
password: 'zxmf',
db: '0',
},
agent:true
};
9. 开发 [#](#t309. 开发)
9.1 指定运行环境 [#](#t319.1 指定运行环境)
EGG_SERVER_ENV=prod
app.config.env
config
|- config.default.js
|- config.test.js
|- config.prod.js
|- config.unittest.js
`- config.local.js
Gitalking ...
Be the first guy leaving a comment!