博客内容管理实现

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

内容简介:版权声明:本文为博主尹成联系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

博客内容管理实现

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

查看所有标签

猜你喜欢:

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

Think Python

Think Python

Allen B. Downey / O'Reilly Media / 2012-8-23 / GBP 29.99

Think Python is an introduction to Python programming for students with no programming experience. It starts with the most basic concepts of programming, and is carefully designed to define all terms ......一起来看看 《Think Python》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具