博客内容管理实现

栏目: 数据库 · 发布时间: 6年前

内容简介:版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究。 https://blog.csdn.net/yincheng01/article/details/84068628

版权声明:本文为博主尹成联系QQ77025077,微信18510341407原创文章,欢迎转载侵权不究。 https://blog.csdn.net/yincheng01/article/details/84068628

#文章管理

在文章管理模块主要实现了文章的添加,删除,编辑等功能。

##发布文章

效果图如下:

博客内容管理实现

该页面主要实现了文章的发布,用户在填写相应的信息之后点击提交按钮将文章信息提交到后台,主要的保存思路如下:

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 := ⊧.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 := ⊧.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 = ⊧.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 := ⊧.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 := ⊧.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

博客内容管理实现

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C语言编程:一本全面的C语言入门教程(第三版)

C语言编程:一本全面的C语言入门教程(第三版)

(美)Stephen Kochan / 张小潘 / 电子社博文视点资讯有限公司 / 2006年 / 59.00元

本书是极负盛名的C语言入门经典教材,其第一版发行至今已有20年的历史。本书内容详实全面,由浅入深,示例丰富,并在每个章节后面附有部分习题,非常适合读者自学使用。除此之外,《C语言编程》一书对于C语言标准的最新进展、C语言常见开发工具以及管理C语言大型项目等重要方面,也进行了深入浅出的说明。一起来看看 《C语言编程:一本全面的C语言入门教程(第三版)》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具