【小鸡软件】beego开发轻博客
本章目标:添加文章录入功能
github: 打开后,点击右上角star按钮
码云: 打开后,点击右上角star按钮
前台页面
1. 我们采用“ wangeditor”作为 富文本编辑器 编辑器
wangEditor 是一款 轻量级 web 富文本编辑器。配置方便,使用简单。支持 IE10+ 浏览器。
2 新增 views->note_new.html 文件,核心代码如下
<body class="lay-blog">
...
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<label class="layui-form-label">标题</label>
<div class="layui-input-block">
<input type="text" name="title" required=""
value=""
lay-verify="required" placeholder="请输入标题"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">内容</label>
<div class="layui-input-block">
<div id="edit"></div>
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn" lay-submit=""
lay-filter="save">提交
</button>
</div>
</form>
...
页面效果如下:3. wangEditor使用
我们只需要引入wangEditor.min.js 文件,调用window.wangEditor("元素id").create() 就可 初始化富文本页面 。我继续修改views->note_new.html 文件。
<body>
...
<form>... <div id="edit"><div> ...</form>
...
{{template "comm/footer.html" .}}
<script type="text/javascript" src="/static/lib/wangEditor/wangEditor.min.js"></script>
<script>
layui.use([...], function () {
...
// 初始化 wangEditor
var E = window.wangEditor;
var editor = new E('#edit');
// 图片不采用上传模式,直接保存到数据库
editor.customConfig.uploadImgShowBase64 = true;
editor.customConfig.pasteFilterStyle = false;
editor.customConfig.zIndex = 1;
editor.create();
});
</script>
定义数据库表
新增models->note.go 定义文章表,代码如下
type Note struct {
gorm.Model
Key string `gorm:"unique_index;not null;"` //文章唯一标示
UserID int // 用户id
User User //用户
Title string //文章标题
Summary string `gorm:"type:text"` //概要
Content string `gorm:"type:text"` //文章内容
Visit int `gorm:"default:0"` //浏览次数
Praise int `gorm:"default:0"` // 点赞次数
}
新增文章的页面显示
1. 我们需要为文章新增页面添加路由路径,以此我们新增一个新的NoteController控制器。新增 controllers->note.go文件添加如下代码
type NoteController struct {
BaseController
}
// @router /new [get]
func (ctx *NoteController) NewPage() {
ctx.Data["key"] = uuid.NewUUID().String()
ctx.TplName = "note_new.html"
}
上面代码中有个ctx.Data["key"] = uuid.NewUUID().String()。试想如果用户打开新增文章页面后,维护好数据,当点击保存按钮时候,不小心多点几次,难道系统就会多新增几个重复的文章记录?因此,我们添加了ctx.Data["key"] = uuid.NewUUID().String() 使每打开新增文章页面都会有一个唯一的key 在当前页面上。当点击保存时,会将页面key传回到后台,这样后台可以更具key开判断用户是新增还是修改!刚才说的情况用户多次点击,第一次是新增,之后都是修改。
2. 与文章调整相关的功能,必须是登陆的用户,且登陆的用户的必须是管理员。我们修改 NoteController控制器,添加NestPrepare方法。每次发送的请求,当路由到NoteController控制器相应的方法时,都会去调用NestPrepare方法,用来添加判断用户必须登陆且为管理员。修改controllers->note.go,代码如下
func (ctx *NoteController) NestPrepare() {
ctx.MustLogin()//用户必须登陆,没有登陆就返回错误
if ctx.User.Role != 0 {//不是管理员,之前返回错误
ctx.Abort500(syserrors.NewError("您没有权限修改文章", nil))
}
}
3. 我们采用的beego的注解路由,我需要将NoteController控制器 注入beego的Include上。修改routers->router.go文件,修改如下:
func init() {
...
beego.AddNamespace(
beego.NewNamespace(
"note",
beego.NSInclude(&controllers.NoteController{}),
),
)
}
到此,新增文章的路由路径为:note/new
4. 添加新增文章的操作入口->修改用户管理页面(views->user.html) 添加按钮,点击跳转到文章新增页面。修改views->user.html文件,修改代码如下:
...
{{if .IsLogin}}
...
{{if eq .User.Role 0}}
<h4 class="item-title">
<p>
<a href="/note/new"><i class="layui-icon layui-icon-add-1"></i><span>新增文章</span></a>
</p>
</h4>
{{end}}
...
新增文章的页面保存功能
1. 我们新约定 文章新增的路由路径为:/note/save/:key
2. 添加页面逻辑,当保存时,我们将页面用户维护的文章数据用ajax发送post请求到后台服务,服务对于的路径为/note/save/:key,我们需要修改views->note_new.html文件,添加如下代码
...
<script>
layui.use(['form', 'jquery', 'layer', 'sysn'], function () {
...
form.on('submit(save)', function (fromdata) {
sysn.post("/note/save/{{.key}}", fdata)
.success(function (data) {
layer.msg("保存成功!");
if (data.action) {
setTimeout(function () {
window.location.href = data.action;
}, 300)
}
}).run();
}
}
</script>
...
3. 调整数据库
3.1 我们之前定义的文章的数据库中表结构中key是不能重复的,是作为文章的唯一标示。因此我们新增的时候都需要先判断 key是否存在,如果存在就更新不存在就新增。我们修改models->note.go 添加按key查询文章的方法。
func QueryNoteByKeyAndUserId(key string, userid int) (note Note, err error) {
return note, db.Model(&Note{}).Where("key = ? and user_id = ?", key, userid).Take(¬e).Error
}
3.2 需要将文章的数据保存到数据库,因此我们要新增方法,用来保存文章数据。代码如下:
func SaveNote(n *Note) error {
return db.Save(n).Error
}
4. 调整控制器NoteController
4.1 将来我们需要将文章在首页列出来,我们不能将文章的所有的内容都显示在首页,因此我们需要截取文章前600个字作为文章的摘要保存到数据库。这里我们用到golang的第三方库github.com/PuerkitoBio/goquery,用来解析文章的html文档。修改controllers->note.go 添加截取文章摘要的方法,代码如下。
// 截取content摘要
//content >文章 > html文档
func getSummary(content string) (string, error) {
// bytes.Buffer,非常常用。
var buf bytes.Buffer
buf.Write([]byte(content))
// 用goquery来解析content
doc, err := goquery.NewDocumentFromReader(&buf)
if err != nil {
return "", err
}
// Text() 得到body元素下的文本内容(去掉html元素)
str := doc.Find("body").Text()
// 截取字符串
if len(str) > 600 {
str = str[0:600] + "..."
}
return str, nil
}
4.1 新增保存文章的方法 ,修改controllers->note.go ,代码如下
// @router /save/:key [post]
func (ctx *NoteController) Save() {
//得到页面的传过来 key
key := ctx.Ctx.Input.Param(":key")
// 判空,为空就返回错误。
title := ctx.GetMustString("title", "标题不能为空!")
content := ctx.GetMustString("content", "内容不能为空!")
//获取文章摘要
summary, _ := getSummary(content)
// 根据key查询文章
note, err := ctx.Dao.QueryNoteByKeyAndUserId(key, int(ctx.User.ID))
var n models.Note
if err != nil {
//存在错误,但是当错误不是查不到数据的错误,那就返回错误
if err != gorm.ErrRecordNotFound {
ctx.Abort500(syserrors.NewError("保存失败!", err))
}
// 查不到数据,那就做新增文章操作
n = models.Note{
Key: key,
Summary: summary,
Title: title,
Files: files,
Content: content,
UserID: int(ctx.User.ID),
}
} else {
//查询不报错,这存在文章,那就做更新文章操作
n = note
n.Title = title
n.Content = content
n.Summary = summary
n.Files = files
n.UpdatedAt = time.Now()
}
//保存文章 SaveNote 是根据id来判断是更新还是新增,id存在就更新,不存在就新增。
//上面更新操作是,从数据库查出来的文章记录,修改数据,所以是存在id的。
if err := ctx.Dao.SaveNote(&n); err != nil {
ctx.Abort500(syserrors.NewError("保存失败!", err))
}
ctx.JSONOk("成功")
}
用户保存文章功能,我们已经完成
总结
本讲,我们实现了文章录入的功能,我们回顾下实现过程共分为两大步骤:
- 第一步 准备工作
1.1 画出文章的新增的页面。
1.2 设计好文章的数据库表结构。
1.3 添加路由让 1.1 的新增的页面,可以访问到。 - 第二步 实现文章保存
2.1 修改新增页面,保存时向后台发送请求。
2.2 实现后台的逻辑,保存数据到数据库。
下一讲,我们将会实现文章显示、文章修改和文章删除的功能。下讲再见????
有疑问加站长微信联系(非本文作者)