基于阿里egg框架搭建博客(6)——浏览、发表文章
相关文章
【基于阿里egg框架搭建博客(6)——浏览、发表文章】基于阿里egg框架搭建博客(1)——开发准备
基于阿里egg框架搭建博客(2)——Hello World
基于阿里egg框架搭建博客(3)——注册与登录
基于阿里egg框架搭建博客(4)——权限控制
基于阿里egg框架搭建博客(5)——置顶导航条
基于阿里egg框架搭建博客(6)——浏览、发表文章
基于阿里egg框架搭建博客(7)——编辑文章
git
https://github.com/ZzzSimon/egg-example
喜欢就点个赞吧!
正文
浏览、发表文章简单来讲就是对article表的读/写操作。
Article表设计
文章图片
字段说明
名称 | 解释 |
---|---|
id | 主键id |
title | 文章标题 |
url | 文章访问path |
detail | 文章内容 |
author | 作者,对应username |
invisible | 是否保密,保密则不显示在文章列表 |
create_time | 文章第一次发表时间 |
update_time | 文章最后一次修改时间 |
DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
`id` varchar(20) NOT NULL,
`title` varchar(255) NOT NULL,
`url` varchar(255) NOT NULL,
`detail` varchar(4096) NOT NULL,
`author` varchar(255) NOT NULL,
`invisible` int(1) NOT NULL DEFAULT '0',
`create_time` datetime NOT NULL,
`update_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
页面设计 浏览文章
文章图片
文章图片
发表文章
文章图片
功能设计 浏览文章
- 点击文章标题查看文章详细内容
- 输入文章标题
- 选择是否保密,保密则不显示在文章列表
- 保存文章
- 支持markdown
Editor.md
。官方文档:http://pandao.github.io/editor.md/前端代码 浏览文章
list.tpl 文章列表 我们创建
app/view/article/list.tpl
文件:{% extends "parent.tpl" %}{% block head %}
文章列表 - 锐客网
{% endblock %}{% block content %}
{% for item in list %}
-
- {{ item.title }}
- {{item.author}} 最后更新于 {{helper.formatTime(item.update_time)}}
{% endfor %}
{% endblock %}
detail.tpl 文章详情 我们创建
app/view/article/detail.tpl
文件:{% extends "parent.tpl" %}{% block head %}
{{article.title}} - 锐客网
{% endblock %}{% block content %}{{article.title}} {{article.author}} 最后更新于 {{helper.formatTime(article.update_time)}}{{article.detail}}{% endblock %}{%block script%}{% endblock %}
此处需要注意1点:
md的内容先通过模板,渲染在一个隐藏的div中。之后,通过
editormd
动态渲染出来。发表文章
article.tpl 发表文章 我们创建
app/view/article/article.tpl
文件:{% extends "parent.tpl" %}{% block head %}
Markdown Editor - 锐客网
{% endblock %}{% block content %}
{% endblock %}{% block script %}{% endblock %}
此处需要注意1点:
ajax默认是不重定向的,所以当保存成功,我们需要返回文章的访问url,在回调函数里重定向。
后端代码
ArticleController 我们创建
app/controller/article.js
文件:const Controller = require('egg').Controller;
class ArticleController extends Controller {
async list() {
const ctx = this.ctx;
const articleList = await ctx.service.article.list();
await ctx.render('article/list.tpl', { list: articleList });
}async detail(){
const ctx = this.ctx;
const queryRes = await ctx.service.article.detail(ctx.params.id);
ctx.logger.info(queryRes);
await ctx.render('article/detail.tpl', { article: queryRes[0] });
}
}module.exports = ArticleController;
EditController 我们创建
app\controller\edit.js
文件:const Controller = require('egg').Controller;
const fs = require('mz/fs');
class EditController extends Controller{
async editHtm(){
await this.ctx.render('article/edit.tpl');
}
async save(){
const ctx = this.ctx;
const article = ctx.request.body.article;
article.id = ctx.helper.uuid();
article.url = '/article/'+article.id+'.htm';
article.author = ctx.session.user.username;
const nowTime = new Date();
article.create_time = nowTime;
article.update_time = nowTime;
const result = await ctx.service.article.save(article);
if (result) {
ctx.body = {flag:'1',msg:'保存成功',url:article.url}
}else {
ctx.body = {flag:'0',msg:'保存失败'}
}
}async uploadPic(){
const { ctx } = this;
const file = ctx.request.files[0];
let filenameNew = ctx.helper.uuid() +'.'+file.filename.split('.').pop();
let filepathNew = this.config.baseDir+'\\app\\public\\mdPic\\'+filenameNew;
//把临时文件剪切到新目录去
await fs.rename(file.filepath, filepathNew);
//按editormd要求格式返回
ctx.body = {
success : 1, //0表示上传失败;
1表示上传成功
message : "上传成功",
url: filepathNew.split(this.config.baseDir+'\\app')[1] //上传成功时才返回
}
}
}module.exports = EditController;
此处需要注意1点:
-
uoloadPic
方法主要用于md编辑器的图片上传。
我们创建
app/service/article.js
文件:const Service = require('egg').Service;
class ArticleService extends Service {
async list() {
const sql = "SELECT url,title,author,update_time FROM article WHERE invisible = 0";
const list =await this.app.mysql.query(sql);
return list;
}async detail(id = 1){
const sql = "SELECT title,detail,author,update_time FROM article WHERE id = ?";
return await this.app.mysql.query(sql,[id])
}async save(article = {}){
const res = await this.app.mysql.insert('article',article);
return res.affectedRows === 1;
}}module.exports = ArticleService;
router.js
我们往
app/router.js
中添加一下内容:router.get('/edit.htm',controller.edit.editHtm);
router.get('/article/:id.htm',controller.article.detail);
router.get('/articleList.htm', controller.article.list);
router.post('/edit/save',controller.edit.save);
router.post('/edit/uploadPic',controller.edit.uploadPic);
结尾 如果看完觉得有用,请给作者一个喜欢吧!谢谢啦!
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 基于爱,才会有“愿望”当“要求”。2017.8.12
- javaweb|基于Servlet+jsp+mysql开发javaWeb学生成绩管理系统
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- CentOS7 阿里云镜像配置方法
- 韵达基于云原生的业务中台建设 | 实战派
- EasyOA|EasyOA 基于SSM的实现 未完成总结与自我批判
- 如何在阿里云linux上部署java项目
- 基于stm32智能风扇|基于stm32智能风扇_一款基于STM32的智能灭火机器人设计