egg(77)–egg之文章curd,文章与文章分类相关联

82次阅读

共计 13413 个字符,预计需要花费 34 分钟才能阅读完成。

model

app/model/article.js
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
var d=new Date();
const ArticleSchema = new Schema({
title: {type: String},
cate_id:{type:Schema.Types.ObjectId},
article_img: {type: String},
link:{
type: String
},
content: {type: String},
keywords: {type: String},
description: {type: String},
sort: {type: Number,default:100},
add_time: {
type:Number,
default: d.getTime()
},
status: {type: Number,default:1}
});
return mongoose.model(‘Article’,ArticleSchema,’article’);
}

router.js
router.get(‘/admin/article’, controller.admin.article.index);
router.get(‘/admin/article/add’, controller.admin.article.add);
router.get(‘/admin/article/edit’, controller.admin.article.edit);
router.post(‘/admin/article/doEdit’, controller.admin.article.doEdit);
router.post(‘/admin/article/doAdd’, controller.admin.article.doAdd);
controller.js
aggregate 聚合管道分页

const fs=require(‘fs’);

const pump = require(‘mz-modules/pump’);

var BaseController =require(‘./base.js’);
class ArticleController extends BaseController {
async index() {

var page=this.ctx.request.query.page || 1;

var pageSize=3;

// 总数量
var totalNum=await this.ctx.model.Article.find({}).count();

/*

var goodsResult=await this.ctx.model.Goods.find({}).skip((page-1)*pageSize).limit(pageSize);

*/

// 让文章和分类进行关联

var result=await this.ctx.model.Article.aggregate([

{
$lookup:{
from:’article_cate’,
localField:’cate_id’,
foreignField:’_id’,
as:’catelist’
}
},
{
$skip:(page-1)*pageSize
},
{
$limit:pageSize
}

])

console.log(result);

await this.ctx.render(‘admin/article/index’,{
list:result,
totalPages:Math.ceil(totalNum/pageSize),
page:page
});

}
async add() {

// 获取所有的分类
var cateResult=await this.ctx.model.ArticleCate.aggregate([

{
$lookup:{
from:’article_cate’,
localField:’_id’,
foreignField:’pid’,
as:’items’
}
},
{
$match:{
“pid”:’0′
}
}

])

await this.ctx.render(‘admin/article/add’,{

cateList:cateResult
});

}

async doAdd() {

let parts = this.ctx.multipart({autoFields: true});
let files = {};
let stream;
while ((stream = await parts()) != null) {
if (!stream.filename) {
break;
}
let fieldname = stream.fieldname; //file 表单的名字

// 上传图片的目录
let dir=await this.service.tools.getUploadFile(stream.filename);
let target = dir.uploadDir;
let writeStream = fs.createWriteStream(target);

await pump(stream, writeStream);

files=Object.assign(files,{
[fieldname]:dir.saveDir
})

// 生成缩略图
this.service.tools.jimpImg(target);

}

let article =new this.ctx.model.Article(Object.assign(files,parts.field));
await article.save();

await this.success(‘/admin/article’,’ 增加文章成功 ’);

}

async edit() {

var id=this.ctx.request.query.id;

// 当前 id 对应的数据
var result=await this.ctx.model.Article.find({“_id”:id});

// 获取所有的分类
var cateResult=await this.ctx.model.ArticleCate.aggregate([

{
$lookup:{
from:’article_cate’,
localField:’_id’,
foreignField:’pid’,
as:’items’
}
},
{
$match:{
“pid”:’0′
}
}

]);

await this.ctx.render(‘admin/article/edit’,{
cateList:cateResult,
list:result[0]
});

}

async doEdit() {

let parts = this.ctx.multipart({autoFields: true});
let files = {};
let stream;
while ((stream = await parts()) != null) {
if (!stream.filename) {
break;
}
let fieldname = stream.fieldname; //file 表单的名字

// 上传图片的目录
let dir=await this.service.tools.getUploadFile(stream.filename);
let target = dir.uploadDir;
let writeStream = fs.createWriteStream(target);

await pump(stream, writeStream);

files=Object.assign(files,{
[fieldname]:dir.saveDir
})

// 生成缩略图
this.service.tools.jimpImg(target);

}

var id=parts.field.id;

var updateResult=Object.assign(files,parts.field);

await this.ctx.model.Article.updateOne({“_id”:id},updateResult);

await this.success(‘/admin/article’,’ 修改数据成功 ’);

}

}
module.exports = ArticleController;
view
增加
<%- include ../public/page_header.html %>

<!– 富文本编辑器 –>
<link href=”/public/admin/wysiwyg-editor/css/font-awesome.min.css” rel=”stylesheet” type=”text/css” />

<!– Include Editor style. –>
<link href=”/public/admin/wysiwyg-editor/css/froala_editor.pkgd.min.css” rel=”stylesheet” type=”text/css” />
<link href=”/public/admin/wysiwyg-editor/css/froala_style.min.css” rel=”stylesheet” type=”text/css” />
<!– 引入 jquery –>
<!– Include Editor JS files. –>
<script type=”text/javascript” src=”/public/admin/wysiwyg-editor/js/froala_editor.pkgd.min.js”></script>

<script type=”text/javascript” src=”/public/admin/wysiwyg-editor/js/zh_cn.js”></script>

<div class=”panel panel-default”>
<div class=”panel-heading”>
增加文章
</div>
<div class=”panel-body”>
<div class=”table-responsive input-form”>
<form action=”/admin/article/doAdd?_csrf=<%=csrf%>” method=”post” enctype=”multipart/form-data” class=”news_content”>

<!– Nav tabs –>
<ul class=”nav nav-tabs” role=”tablist”>
<li role=”presentation” class=”active”><a href=”#general” role=”tab” data-toggle=”tab”> 通用信息 </a></li>
<li role=”presentation”><a href=”#detail” role=”tab” data-toggle=”tab”> 详细描述 </a></li>
</ul>

<!– Tab panes –>
<div class=”tab-content”>
<div role=”tabpanel” class=”tab-pane active” id=”general”>

<ul class=”form_input”>

<li> <span> 文章标题:</span> <input type=”text” name=”title” class=”input”/></li>

<li> <span> 所属分类:</span>
<select name=”cate_id” id=”cate_id”>

<%for(var i=0;i<cateList.length;i++){%>

<option value=”<%=cateList[i]._id%>”><%=cateList[i].title%></option>

<%for(var j=0;j<cateList[i].items.length;j++){%>

<option value=”<%=cateList[i].items[j]._id%>”>—-<%=cateList[i].items[j].title%></option>

<%}%>

<%}%>

</select>
</li>

<li> <span> 封面图片:</span> <input type=”file” name=”article_img”/></li>

<li> <span> 跳转地址:</span> <input type=”text” name=”link” class=”input”/></li>

<li> <span>Seo 关键词: </span><input type=”text” name=”keywords” class=”input”/></li>

<li> <span>Seo 描述:</span> <textarea name=”description” id=”description” cols=”84″ rows=”4″></textarea></li>

<li> <span> 排 序:</span> <input type=”text” name=”sort” value=”100″/></li>

<li> <span> 状 态:</span> <input type=”radio” name=”status” checked value=”1″ id=”a”/> <label for=”a”> 显示 </label> <input type=”radio” name=”status” value=”0″ id=”b”/><label for=”b”> 隐藏 </label> </li>

</ul>

</div>
<div role=”tabpanel” class=”tab-pane” id=”detail”>

<textarea name=”content” id=”content” cols=”100″ rows=”8″></textarea>
</div>

<br />

<button type=”submit” class=”btn btn-success goods_content_btn”> 提交 </button>

</div>

</form>
</div>
</div>

<script>
$(function() {
$(‘#content’).froalaEditor({
height: 300, // 给编辑器设置默认的高度
language: ‘zh_cn’,
imageUploadURL: ‘/admin/goods/goodsUploadImage’,
// 根据不同的分辨率加载不同的配置
toolbarButtons: [‘fullscreen’, ‘bold’, ‘italic’, ‘underline’, ‘strikeThrough’, ‘subscript’, ‘superscript’, ‘|’, ‘fontFamily’, ‘fontSize’, ‘color’, ‘inlineStyle’, ‘paragraphStyle’, ‘|’, ‘paragraphFormat’, ‘align’, ‘formatOL’, ‘formatUL’, ‘outdent’, ‘indent’, ‘quote’, ‘-‘, ‘insertLink’, ‘insertImage’, ‘insertVideo’, ’embedly’, ‘insertFile’, ‘insertTable’, ‘|’, ’emoticons’, ‘specialCharacters’, ‘insertHR’, ‘selectAll’, ‘clearFormatting’, ‘|’, ‘print’, ‘spellChecker’, ‘help’, ‘html’, ‘|’, ‘undo’, ‘redo’],
toolbarButtonsMD: [‘fullscreen’, ‘bold’, ‘italic’, ‘underline’, ‘strikeThrough’, ‘subscript’, ‘superscript’, ‘|’, ‘fontFamily’, ‘fontSize’, ‘color’, ‘inlineStyle’, ‘paragraphStyle’, ‘|’, ‘paragraphFormat’, ‘align’, ‘formatOL’, ‘formatUL’, ‘outdent’, ‘indent’, ‘quote’, ‘-‘, ‘insertLink’, ‘insertImage’, ‘insertVideo’, ’embedly’, ‘insertFile’, ‘insertTable’, ‘|’, ’emoticons’, ‘specialCharacters’, ‘insertHR’, ‘selectAll’, ‘clearFormatting’, ‘|’, ‘print’, ‘spellChecker’, ‘help’, ‘html’, ‘|’, ‘undo’, ‘redo’],
toolbarButtonsSM: [‘fullscreen’, ‘bold’, ‘italic’, ‘underline’, ‘strikeThrough’, ‘subscript’, ‘superscript’, ‘|’, ‘fontFamily’, ‘fontSize’, ‘color’, ‘inlineStyle’, ‘paragraphStyle’, ‘|’, ‘paragraphFormat’, ‘align’, ‘formatOL’, ‘formatUL’, ‘outdent’, ‘indent’, ‘quote’, ‘-‘, ‘insertLink’, ‘insertImage’, ‘insertVideo’, ’embedly’, ‘insertFile’, ‘insertTable’, ‘|’, ’emoticons’, ‘specialCharacters’, ‘insertHR’, ‘selectAll’, ‘clearFormatting’, ‘|’, ‘print’, ‘spellChecker’, ‘help’, ‘html’, ‘|’, ‘undo’, ‘redo’]
});
});

</script>
</div>

</body>
</html>

查找
<%- include ../public/page_header.html %>

<!– 分页插件 –>
<script src=”/public/admin/js/jqPaginator.js”></script>

<div class=”panel panel-default”>
<div class=”panel-heading clear”>
<span> 文章分类列表 </span> <a href=”/admin/article/add” class=”btn btn-primary fr”> 增加文章 </a>
</div>
<div class=”panel-body”>
<!–
列表展示
–>
<div class=”table-responsive”>
<table class=”table table-bordered”>
<thead>
<tr class=”th”>
<th> 文章名称 </th>
<th> 文章图片 </th>
<th> 所属分类 </th>
<th> 增加日期 </th>
<th class=”text-center”> 排序 </th>
<th class=”text-center”> 状态 </th>
<th class=”text-center”> 操作 </th>
</tr>
</thead>
<tbody>
<%for(var i=0;i<list.length;i++){%>
<tr>
<td><%=list[i].title%></td>
<td><img class=”pic” src=”<%=list[i].article_img%>” /></td>

<td><%=list[i].catelist[0].title%></td>
<td><%=helper.formatTime(list[i].add_time)%></td>
<td class=”text-center”><span onclick=”app.editNum(this,’Article’,’sort’,'<%=list[i]._id%>’)”><%=list[i].sort%></span></td>
<td class=”text-center”>

<%if(list[i].status==1){%>

<img src=”/public/admin/images/yes.gif” onclick=”app.changeStatus(this,’Article’,’status’,'<%=list[i]._id%>’)” />

<%}else{%>
<img src=”/public/admin/images/no.gif” onclick=”app.changeStatus(this,’Article’,’status’,'<%=list[i]._id%>’)” />
<%}%>
</td>
<td class=”text-center”> <a href=”/admin/article/edit?id=<%=list[i]._id%>”> 修改 </a> <a class=”delete” href=”/admin/delete?model=Article&id=<%=list[i]._id%>”> 删除 </a></td>
</tr>
<%}%>

</tbody>
</table>

<div id=”page” class=”pagination fr”></div>
</div>
</div>
</div>

<script>

$(‘#page’).jqPaginator({
totalPages: <%=totalPages%>,
visiblePages: 8,
currentPage: <%=page%>,
onPageChange: function (num, type) {
console.log(‘ 当前第 ’ + num + ‘ 页 ’,type);

if(type==’change’){

location.href=”/admin/article?page=”+num;
}
}
});

</script>

</body>
</html>

编辑
<%- include ../public/page_header.html %>

<!– 富文本编辑器 –>
<link href=”/public/admin/wysiwyg-editor/css/font-awesome.min.css” rel=”stylesheet” type=”text/css” />

<!– Include Editor style. –>
<link href=”/public/admin/wysiwyg-editor/css/froala_editor.pkgd.min.css” rel=”stylesheet” type=”text/css” />
<link href=”/public/admin/wysiwyg-editor/css/froala_style.min.css” rel=”stylesheet” type=”text/css” />
<!– 引入 jquery –>
<!– Include Editor JS files. –>
<script type=”text/javascript” src=”/public/admin/wysiwyg-editor/js/froala_editor.pkgd.min.js”></script>

<script type=”text/javascript” src=”/public/admin/wysiwyg-editor/js/zh_cn.js”></script>

<div class=”panel panel-default”>
<div class=”panel-heading”>
修改文章
</div>
<div class=”panel-body”>
<div class=”table-responsive input-form”>
<form action=”/admin/article/doEdit?_csrf=<%=csrf%>” method=”post” enctype=”multipart/form-data” class=”news_content”>

<!– Nav tabs –>
<ul class=”nav nav-tabs” role=”tablist”>
<li role=”presentation” class=”active”><a href=”#general” role=”tab” data-toggle=”tab”> 通用信息 </a></li>
<li role=”presentation”><a href=”#detail” role=”tab” data-toggle=”tab”> 详细描述 </a></li>
</ul>

<!– Tab panes –>
<div class=”tab-content”>
<div role=”tabpanel” class=”tab-pane active” id=”general”>

<input type=”hidden” name=”id” class=”input” value=”<%=list._id%>”/>

<ul class=”form_input”>

<li> <span> 文章标题:</span> <input type=”text” name=”title” class=”input” value=”<%=list.title%>”/></li>

<li> <span> 所属分类:</span>
<select name=”cate_id” id=”cate_id”>

<%for(var i=0;i<cateList.length;i++){%>

<option value=”<%=cateList[i]._id%>” <%if(list.cate_id.toString()==cateList[i]._id.toString()){%>selected<%}%> ><%=cateList[i].title%></option>

<%for(var j=0;j<cateList[i].items.length;j++){%>

<option value=”<%=cateList[i].items[j]._id%>” <%if(list.cate_id.toString()==cateList[i].items[j]._id.toString()){%>selected<%}%>>—-<%=cateList[i].items[j].title%></option>

<%}%>

<%}%>

</select>
</li>

<li> <span> 封面图片:</span> <input type=”file” name=”article_img”/>
<br />

<span> </span> <img class=”pic” src=”<%=list.article_img%>” />

</li>

<li> <span> 跳转地址:</span> <input type=”text” name=”link” class=”input” value=”<%=list.link%>”/></li>

<li> <span>Seo 关键词: </span><input type=”text” name=”keywords” class=”input” value=”<%=list.keywords%>”/></li>

<li> <span>Seo 描述:</span> <textarea name=”description” id=”description” cols=”84″ rows=”4″><%=list.description%></textarea></li>

<li> <span> 排 序:</span> <input type=”text” name=”sort” value=”<%=list.sort%>”/></li>

<li> <span> 状 态:</span> <input type=”radio” name=”status” <%if(list.status==1){%> checked <%}%> value=”1″ id=”a”/> <label for=”a”> 显示 </label> <input type=”radio” <%if(list.status==0){%> checked <%}%> name=”status” value=”0″ id=”b”/><label for=”b”> 隐藏 </label> </li>

</ul>

</div>
<div role=”tabpanel” class=”tab-pane” id=”detail”>

<textarea name=”content” id=”content” cols=”100″ rows=”8″><%=list.content%></textarea>
</div>

<br />

<button type=”submit” class=”btn btn-success goods_content_btn”> 提交 </button>

</div>

</form>
</div>
</div>

<script>
$(function() {
$(‘#content’).froalaEditor({
height: 300, // 给编辑器设置默认的高度
language: ‘zh_cn’,
imageUploadURL: ‘/admin/goods/goodsUploadImage’,
// 根据不同的分辨率加载不同的配置
toolbarButtons: [‘fullscreen’, ‘bold’, ‘italic’, ‘underline’, ‘strikeThrough’, ‘subscript’, ‘superscript’, ‘|’, ‘fontFamily’, ‘fontSize’, ‘color’, ‘inlineStyle’, ‘paragraphStyle’, ‘|’, ‘paragraphFormat’, ‘align’, ‘formatOL’, ‘formatUL’, ‘outdent’, ‘indent’, ‘quote’, ‘-‘, ‘insertLink’, ‘insertImage’, ‘insertVideo’, ’embedly’, ‘insertFile’, ‘insertTable’, ‘|’, ’emoticons’, ‘specialCharacters’, ‘insertHR’, ‘selectAll’, ‘clearFormatting’, ‘|’, ‘print’, ‘spellChecker’, ‘help’, ‘html’, ‘|’, ‘undo’, ‘redo’],
toolbarButtonsMD: [‘fullscreen’, ‘bold’, ‘italic’, ‘underline’, ‘strikeThrough’, ‘subscript’, ‘superscript’, ‘|’, ‘fontFamily’, ‘fontSize’, ‘color’, ‘inlineStyle’, ‘paragraphStyle’, ‘|’, ‘paragraphFormat’, ‘align’, ‘formatOL’, ‘formatUL’, ‘outdent’, ‘indent’, ‘quote’, ‘-‘, ‘insertLink’, ‘insertImage’, ‘insertVideo’, ’embedly’, ‘insertFile’, ‘insertTable’, ‘|’, ’emoticons’, ‘specialCharacters’, ‘insertHR’, ‘selectAll’, ‘clearFormatting’, ‘|’, ‘print’, ‘spellChecker’, ‘help’, ‘html’, ‘|’, ‘undo’, ‘redo’],
toolbarButtonsSM: [‘fullscreen’, ‘bold’, ‘italic’, ‘underline’, ‘strikeThrough’, ‘subscript’, ‘superscript’, ‘|’, ‘fontFamily’, ‘fontSize’, ‘color’, ‘inlineStyle’, ‘paragraphStyle’, ‘|’, ‘paragraphFormat’, ‘align’, ‘formatOL’, ‘formatUL’, ‘outdent’, ‘indent’, ‘quote’, ‘-‘, ‘insertLink’, ‘insertImage’, ‘insertVideo’, ’embedly’, ‘insertFile’, ‘insertTable’, ‘|’, ’emoticons’, ‘specialCharacters’, ‘insertHR’, ‘selectAll’, ‘clearFormatting’, ‘|’, ‘print’, ‘spellChecker’, ‘help’, ‘html’, ‘|’, ‘undo’, ‘redo’]
});
});

</script>
</div>

</body>
</html>

正文完
 0