Beego框架:部落格內容管理實現
#文章管理
在文章管理模組主要實現了文章的新增,刪除,編輯等功能。
##釋出文章
效果圖如下:
該頁面主要實現了文章的釋出,使用者在填寫相應的資訊之後點選提交按鈕將文章資訊提交到後臺,主要的儲存思路如下:
1.獲取使用者輸入的文章資訊,插入資料庫。
2.獲得使用者輸入的標籤,因為使用者輸入的標籤很可能有多個,所以我們在通過逗號切割之後,取出每個標籤之後,去除兩邊的空格,然後判斷使用者輸入的標籤是否有重複,如果有重複需要去重。
3.在標籤表判斷是否有對應的標籤,沒有對應的標籤需要建立標籤,如果有對應的標籤,更新count欄位。
4.將文章id和標籤id組成對應的記錄插入到標籤文章表中。
5.用處理後的標籤在文章表中做一個覆蓋。
func (this *ArticleController) Save() { //建立文章結構體 var post models.Post // title color istop tags posttime status content //獲取使用者輸入的標題 post.Title = strings.TrimSpace(this.GetString("title")) if post.Title == "" { this.showmsg("標題不能為空!") } //獲取使用者輸入的顏色 post.Color = strings.TrimSpace(this.GetString("color")) //獲取是否置頂 if strings.TrimSpace(this.GetString("istop")) == "1" { post.Istop = 1 } //獲取使用者輸入的標籤 tags := strings.TrimSpace(this.GetString("tags")) //獲取文章釋出時間 timestr := strings.TrimSpace(this.GetString("posttime")) //獲取文章的狀態 post.Status, _ = this.GetInt("status") post.Content = this.GetString("content") //設定使用者 post.Userid = this.userid //設定作者 post.Author = this.username //設定更新時間 post.Updated = this.getTime() //設定隨機數種子 rand.Seed(time.Now().Unix()) //長生隨機數,[0,11) var r = rand.Intn(11) // /static/images/3.jpg post.Cover = "/static/images/" + fmt.Sprintf("%d", r) + ".jpg" // Mon Jan 2 15:04:05 -0700 MST 2006 posttime, err := time.Parse("2006-01-02 15:04:05", timestr) if err == nil { post.Posttime = posttime } //插入資料庫 if err = post.Insert(); err != nil { this.showmsg("文章新增失敗!") } //go,陣列,C,C++,go //go,陣列,C,C++, //儲存使用者數的表標籤的最終結果 addtags := make([]string, 0) if tags != "" { //通過逗號切割使用者輸入的標籤 tagarr := strings.Split(tags, ",") for _, v := range tagarr { //取出使用者輸入的標籤並去除兩邊的空格 if tag := strings.TrimSpace(v); tags != "" { //標誌位 exists := false //遍歷最終結果切片 for _, vv := range addtags { //如果最終結果切片中存在當前標籤,索命有重複,將exists設定為true,並跳出迴圈 if vv == tag { exists = true break } } //如果標誌位為false,說明最終結果切片中不存在當前標籤,將當前標籤追加到最終結果切片中 if !exists { addtags = append(addtags, tag) } } } } //判斷最終結果切片長度是否大於0,如果大於0,說明使用者至少輸入了一個合法的標籤 if len(addtags) > 0 { //遍歷最終結果切片 for _, v := range addtags { //根據使用者輸入的標籤建立標籤結構體 tag := &models.Tag{Name:v} //根據標籤名稱在標籤表中讀取 if err := tag.Read("Name"); err == orm.ErrNoRows { //如果沒有對應記錄,初始化count欄位為1並插入資料庫 tag.Count = 1 tag.Insert() }else { //存在對應的記錄,更新count欄位 tag.Count += 1 tag.Update("Count") } //根據標籤id和文章id建立標籤文章結構體 tp := &models.TagPost{Tagid:tag.Id, Postid:post.Id, Poststatus:post.Status, Posttime:this.getTime()} //插入 tp.Insert() } //go 陣列 C post.Tags = "," + strings.Join(addtags, ",") + ","//,go,陣列,C, } post.Updated = this.getTime() post.Update("tags", "updated") this.Redirect("/admin/article/list", 302) }
##編輯文章
效果圖如下:
使用者在點選編輯按鈕,提交對應的博文id,在後臺獲取id,根據id在資料庫中查詢對應的文章資訊並將該系你先展示在前臺頁面(資料回顯), 使用者在修改之後點選提交按鈕,在後臺的主要修改思路如下:
分為兩種情況:
1.使用者沒有修改文章的標籤,直接獲取使用者的輸入,更新資料庫
2.使用者修改了標籤,則需要更新標籤表和文章標籤表,
如何更新標籤表?
如果使用者修改之後的標籤在標籤表中不存在,則需要在標籤表中插入對應新的記錄,
如果在標籤表中已經存在,則需要更新修改後的標籤的count欄位,以上兩步結束之後,
需要更新原標籤中的count欄位
3.在標籤文章表中將文章id和原標籤id所對應的記錄刪除,然後在標籤文章表中插入新的記錄,其成員由文章id和新的標籤id所組成。
func (this *ArticleController) Update() {
post := models.Post{}
id, err := this.GetInt("id")
//判斷是否出現了錯誤
if err == nil {
post.Id = id
//資料庫沒有對應的記錄
if post.Read() != nil {
this.Redirect("/admin/article/list", 302)
}
}
// title color istop tags posttime status content
post.Title = strings.TrimSpace(this.GetString("title"))
if post.Title == "" {
this.showmsg("標題不能為空!")
}
post.Color = strings.TrimSpace(this.GetString("color"))
if strings.TrimSpace(this.GetString("istop")) == "1" {
post.Istop = 1
}
tags := strings.TrimSpace(this.GetString("tags"))
timrstr := strings.TrimSpace(this.GetString("posttime"))
post.Status, _= this.GetInt("status")
post.Content = strings.TrimSpace(this.GetString("content"))
if posttime, err := time.Parse("2006-01-02 15:04:05", timrstr); err == nil {
post.Posttime = posttime
}
if strings.Trim(post.Tags, ",") == tags {
post.Update("title", "color", "istop", "posttime", "status", "content")
this.Redirect("/admin/article/list", 302)
}
//判斷文章原始的標籤是否為空,如果不為空,需要更新count欄位並且在
//標籤文章表中刪除對應的記錄
if post.Tags != "" {
var tagpost models.TagPost
//通過當前文章id在標籤文章表中過濾出指定的記錄
query := orm.NewOrm().QueryTable(&tagpost).Filter("postid", post.Id)
var tagpostarr []*models.TagPost
//將相關記錄存入tagpostarr中
if n, err := query.All(&tagpostarr); n > 0 && err == nil {
for i := 0; i < len(tagpostarr); i++ {
//根據標籤id建立標籤
var tag = &models.Tag{Id:tagpostarr[i].Tagid}
//更新count欄位
if err = tag.Read(); err == nil && tag.Count > 0 {
tag.Count--
tag.Update("count")
}
}
}
query.Delete()
}
//建立切片,用於儲存過濾之後的最終結果
addtags := make([]string, 0)
if tags != "" {
// go,C,C++
//通過逗號切割使用者輸入的標籤
tagarr := strings.Split(tags, ",")
//遍歷使用者輸入的標籤
for _ , v := range tagarr {
//去除每一個標籤兩邊的空格
if tag := strings.TrimSpace(v); tag != "" {
//標誌位,用於標誌是否將標籤追加到最終的結果切片中
exists := false
//遍歷最終結果切片,判斷當前標籤是否已經在最終結果表中已經存在,
//如果存在,將exists賦值位true,並退出迴圈
for _, vv := range addtags {
if vv == tag {
exists = true
break
}
}
//根據exists判斷是否需要將當前標籤加入最終結果切片中
if !exists {
addtags = append(addtags, tag)
}
}
}
}
//更具最終結果切片中的標籤id在標籤表中更新count欄位,或者插入標籤
//在標籤文章表中插入對應記錄
if len(addtags) > 0 {
//遍歷最終結果切片
for _, v := range addtags {
//根據標籤名稱建立標籤
tag := models.Tag{Name:v}
//根據標籤名稱在標籤表中查詢,如果不存在則插入
if err := tag.Read("Name"); err == orm.ErrNoRows {
tag.Count = 1
tag.Insert()
}else {//如果存在更新count欄位
tag.Count++
tag.Update("Count")
}
//建立標籤文章結構體
tp := &models.TagPost{Tagid:tag.Id, Postid:post.Id, Poststatus:post.Status, Posttime:this.getTime()}
//插入
tp.Insert()
}
post.Tags = "," + strings.Join(addtags, ",") + ","
}
post.Updated = this.getTime()
// title color istop tags posttime status content
post.Update("title", "color", "istop", "tags", "posttime", "status", "content", "updated")
this.Redirect("/admin/article/list", 302)
}
##刪除文章
效果圖如下:
使用者在點選刪除按鈕的時候會給與相應的刪除提示,該操作需要謹慎操作,因為資料一旦刪除無法恢復。在使用者確定刪除之後,將對應的id傳遞到後臺,然後在資料庫中根據該id將對應的記錄從資料庫中刪除,刪除成功重定向到文章列表頁面,否則給與對應的錯誤提示。
func (this *ArticleController) Delete() {
id, _ := this.GetInt("id")
post := &models.Post{Id:id}
if post.Read() == nil {
post.Delete()
}
this.Redirect("/admin/article/list", 302)
}
#標籤管理
效果圖如下:
標籤管理模組主要實現了標籤的合併和刪除。
##標籤合併
主要思路:
1.獲取使用者輸入的目標標籤,去除兩邊的空格,根據該標籤名稱去標籤表中查詢對應的記錄,如果沒有對應的記錄需要插入新的記錄
2.根據標籤id在標籤文章表中查詢對應的記錄,將對應的記錄的標籤id更新位目標標籤的id
3.在文章表中將原標籤替換為目標標籤的名稱
4.更新目標標籤的count欄位
func (this *TagController) batch() {
//獲取使用者選擇的id
ids := this.GetStrings("ids[]")
//獲取使用者的操作(刪除還是合併)
op := this.GetString("op")
//建立切片,用於儲存使用者選擇的切片
idarr := make([]int, 0)
//遍歷ids
for _, v := range ids {
//將標籤id轉換為整數,並且判斷id是否大於0,應為不存在小於1的id
if id, _ := strconv.Atoi(v); id > 0 {
//追加id
idarr = append(idarr, id)
}
}
//判斷操作
switch op {
//合併
case "merge":
//獲取目標籤的名稱,並去除兩邊的空格
toname := strings.TrimSpace(this.GetString("toname"))
//判斷目標標籤是否為空且使用者選擇的標籤數量是否大於0
if toname != "" && len(idarr) > 0 {
//建立標籤結構體
tag := new(models.Tag)
//設定標籤的名稱
tag.Name = toname
//根據標籤的名稱查詢標籤
if tag.Read("name") != nil {
//如果標籤表中不存在該標籤,設定count欄位為0
tag.Count = 0
//插入標籤
tag.Insert()
}
//遍歷使用者選擇的標籤
for _, id := range idarr {
//建立標籤結構體,並初始化id
obj := models.Tag{Id:id}
//通過id查詢標籤
if obj.Read() == nil {
//合併標籤
obj.MergeTo(tag)
//刪除原始標籤
obj.Delete()
}
}
//更新標籤表
tag.UpCount()
}
//刪除
case "delete":
//遍歷使用者選擇的標籤
for _, id := range idarr {
//建立標籤結構體,並初始化id
obj := models.Tag{Id:id}
//根據id查詢標籤
if obj.Read() == nil {
//刪除標籤
obj.Delete()
}
}
}
//重定向
this.Redirect("/admin/tag", 302)
}
##標籤刪除
主要思路:
需要根據刪除的標籤的id在標籤文章表中查詢相關記錄,從這些記錄中獲取對應的文章的id,然後根據文章id在文章表中找到對應的記錄,將標籤名替換為逗號,最後刪除標籤文章表中相關的記錄,相關程式碼同上。
學院Go語言視訊主頁
https://edu.csdn.net/lecturer/1928
清華團隊帶你實戰區塊鏈開發
掃碼獲取海量視訊及原始碼 QQ群:721929980