部落格內容管理實現

尹成發表於2018-11-14

#文章管理
在文章管理模組主要實現了文章的新增,刪除,編輯等功能。
##釋出文章
效果圖如下:
這裡寫圖片描述
該頁面主要實現了文章的釋出,使用者在填寫相應的資訊之後點選提交按鈕將文章資訊提交到後臺,主要的儲存思路如下:
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
在這裡插入圖片描述

相關文章