内容简介:版权声明:本文为博主尹成联系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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 基于iScroll实现内容滚动效果
- React实现浏览器打印指定内容
- 静态内容实现缓存的七种不同方法
- flex 遍历Object对象内容的实现代码
- jQuery+PHP+ajax实现加载更多内容列表
- MySQL InnoDB 事务实现过程相关内容的概述
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
软件开发者路线图
Dave H. Hoover、Adewale Oshineye / 王江平 / 机械工业出版社 / 2010年9月 / 35.00元
作为一名软件开发者,你在奋力推进自己的职业生涯吗?面对今天日新月异和不断拓展的技术,取得成功需要的不仅仅是技术专长。为了增强专业性,你还需要一些软技能以及高效的学习技能。本书的全部内容都是关于如何修炼这些技能的。两位作者Dave Hoover和Adewale Oshineye给出了数十种行为模式,来帮你提高主要的技能。 本书中的模式凝结了多年的调查研究、无数次的访谈以及来自O’Reilly在......一起来看看 《软件开发者路线图》 这本书的介绍吧!