【小雞軟體】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> ...
頁面效果如下:image.png
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 實現背景邏輯,儲存資料到資料庫。
下一講,我們將會實現文章顯示、文章修改和文章刪除的功能。下講再見