modelapp/model/article.jsmodule.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.jsaggregate聚合管道分页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>
...