【小雞創(chuàng)作】beego開發(fā)輕博客
本章目標:添加“文章錄入”功能
github: 打開后袜香,點擊右上角star按鈕
視頻教程: B站地址
前臺頁面
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() 就可 初始化富文本頁面 。我繼續(xù)修改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');
// 圖片不采用上傳模式,直接保存到數(shù)據庫
editor.customConfig.uploadImgShowBase64 = true;
editor.customConfig.pasteFilterStyle = false;
editor.customConfig.zIndex = 1;
editor.create();
});
</script>
定義數(shù)據庫表
新增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"` //瀏覽次數(shù)
Praise int `gorm:"default:0"` // 點贊次數(shù)
}
新增文章的頁面顯示
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()养晋。試想如果用戶打開新增文章頁面后衬吆,維護好數(shù)據,當點擊保存按鈕時候绳泉,不小心多點幾次逊抡,難道系統(tǒng)就會多新增幾個重復的文章記錄?因此零酪,我們添加了ctx.Data["key"] = uuid.NewUUID().String() 使每打開新增文章頁面都會有一個唯一的key 在當前頁面上冒嫡。當點擊保存時,會將頁面key傳回到后臺四苇,這樣后臺可以更具key開判斷用戶是新增還是修改孝凌!剛才說的情況用戶多次點擊,第一次是新增蛔琅,之后都是修改胎许。
2. 與文章調整相關的功能峻呛,必須是登陸的用戶,且登陸的用戶的必須是管理員辜窑。我們修改 NoteController控制器钩述,添加NestPrepare方法。每次發(fā)送的請求穆碎,當路由到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. 添加頁面邏輯,當保存時遍搞,我們將頁面用戶維護的文章數(shù)據用ajax發(fā)送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. 調整數(shù)據庫
3.1 我們之前定義的文章的數(shù)據庫中表結構中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 需要將文章的數(shù)據保存到數(shù)據庫垂睬,因此我們要新增方法,用來保存文章數(shù)據抗悍。代碼如下:
func SaveNote(n *Note) error {
return db.Save(n).Error
}
4. 調整控制器NoteController
4.1 將來我們需要將文章在首頁列出來驹饺,我們不能將文章的所有的內容都顯示在首頁,因此我們需要截取文章前600個字作為文章的摘要保存到數(shù)據庫缴渊。這里我們用到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 {
//存在錯誤,但是當錯誤不是查不到數(shù)據的錯誤瞧哟,那就返回錯誤
if err != gorm.ErrRecordNotFound {
ctx.Abort500(syserrors.NewError("保存失敾烨伞!", err))
}
// 查不到數(shù)據勤揩,那就做新增文章操作
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存在就更新凿傅,不存在就新增。
//上面更新操作是数苫,從數(shù)據庫查出來的文章記錄,修改數(shù)據辨液,所以是存在id的虐急。
if err := ctx.Dao.SaveNote(&n); err != nil {
ctx.Abort500(syserrors.NewError("保存失敗滔迈!", err))
}
ctx.JSONOk("成功")
}
用戶保存文章功能止吁,我們已經完成
總結
本講,我們實現(xiàn)了文章錄入的功能燎悍,我們回顧下實現(xiàn)過程共分為兩大步驟:
- 第一步 準備工作
1.1 畫出文章的新增的頁面敬惦。
1.2 設計好文章的數(shù)據庫表結構。
1.3 添加路由讓 1.1 的新增的頁面谈山,可以訪問到俄删。 - 第二步 實現(xiàn)文章保存
2.1 修改新增頁面,保存時向后臺發(fā)送請求奏路。
2.2 實現(xiàn)后臺的邏輯畴椰,保存數(shù)據到數(shù)據庫。
下一講鸽粉,我們將會實現(xiàn)文章顯示斜脂、文章修改和文章刪除的功能。下講再見??