Goweb开发之Beego框架实战: 第九节 首页设计及分页实现

在上节课内容中,我们学习实现了写文章的功能。本节课,我们要实现首页功能的开发。首页是用户登录后要展示的页面。最终想实现的功能是:点击首页,就会自动查询数据库,显示文章;如果文章较多,我们可以实现分页。

一、查询文章功能

1.1 Controller

我们首先修改home_controller.go文件,在Get()方法中,先查询所有的文章,并显示到页面上。因为文章可能很多,为了更好的用户体验,我们需要分页查询。默认查询第一页。

func (this *HomeController) Get() {
    page, _ := this.GetInt("page")
    if page <= 0 {
        page = 1
    }
    var artList []models.Article
    artList, _ = models.FindArticleWithPage(page)
    this.Data["PageCode"] = 1
    this.Data["HasFooter"] = true
​
    fmt.Println("IsLogin:", this.IsLogin, this.Loginuser)
    this.Data["Content"] = models.MakeHomeBlocks(artList, this.IsLogin)
​
    this.TplName = "home.html"
}

1.2 Model

我们现在article_model.go文件中,添加文章的查询,而且要分页查询:

​
//-----------查询文章---------
​
//根据页码查询文章
func FindArticleWithPage(page int) ([]Article, error) {
    //从配置文件中获取每页的文章数量
    num, _ := beego.AppConfig.Int("articleListPageNum")
    page--
    fmt.Println("---------->page", page)
    return QueryArticleWithPage(page, num)
}
​
/**
分页查询数据库
limit分页查询语句,
    语法:limit m,n
​
    m代表从多少位开始获取,与id值无关
    n代表获取多少条数据
​
注意limit前面咩有where
 */
func QueryArticleWithPage(page, num int) ([]Article, error) {
    sql := fmt.Sprintf("limit %d,%d", page*num, num)
    return QueryArticlesWithCon(sql)
}
​
func QueryArticlesWithCon(sql string) ([]Article, error) {
    sql = "select id,title,tags,short,content,author,createtime from article " + sql
    rows, err := utils.QueryDB(sql)
    if err != nil {
        return nil, err
    }
    var artList []Article
    for rows.Next() {
        id := 0
        title := ""
        tags := ""
        short := ""
        content := ""
        author := ""
        var createtime int64
        createtime = 0
        rows.Scan(&id, &title, &tags, &short, &content, &author, &createtime)
        art := Article{id, title, tags, short, content, author, createtime}
        artList = append(artList, art)
    }
    return artList, nil
}
​

在models目录下创建一个go文件,用来控制首页显示内容:

type HomeBlockParam struct {
    Id         int
    Title      string
    Tags       [] TagLink
    Short      string
    Content    string
    Author     string
    CreateTime string
    //查看文章的地址
    Link string
​
    //修改文章的地址
    UpdateLink string
    DeleteLink string
​
    //记录是否登录
    IsLogin bool
}
​
type TagLink struct {
    TagName string
    TagUrl  string
}

我们需要将从数据库中查询出来的数据,转为对应的结构体对象,所以先设计结构体,这里我们需要考虑如果用户是登录状态,那么是可以修改或删除某一篇文章。当然,如果没有登录,那么只能查看。所以在设计结构体的时候,我们直接创建了修改和删除的链接字段。

接下来,我们添加一个方法,用于将文章中的内容,显示到页面上:

//----------首页显示内容---------
func MakeHomeBlocks(articles []Article, isLogin bool) template.HTML {
    htmlHome := ""
    for _, art := range articles {
        //将数据库model转换为首页模板所需要的model
        homeParam := HomeBlockParam{}
        homeParam.Id = art.Id
        homeParam.Title = art.Title
        homeParam.Tags = createTagsLinks(art.Tags)
        fmt.Println("tag-->", art.Tags)
        homeParam.Short = art.Short
        homeParam.Content = art.Content
        homeParam.Author = art.Author
        homeParam.CreateTime = utils.SwitchTimeStampToData(art.Createtime)
        homeParam.Link = "/article/" + strconv.Itoa(art.Id)
        homeParam.UpdateLink = "/article/update?id=" + strconv.Itoa(art.Id)
        homeParam.DeleteLink = "/article/delete?id=" + strconv.Itoa(art.Id)
        homeParam.IsLogin = isLogin
​
        //处理变量
        //ParseFile解析该文件,用于插入变量
        t, _ := template.ParseFiles("views/block/home_block.html")
        buffer := bytes.Buffer{}
        //就是将html文件里面的比那两替换为穿进去的数据
        t.Execute(&buffer, homeParam)
        htmlHome += buffer.String()
    }
    fmt.Println("htmlHome-->",htmlHome)
    return template.HTML(htmlHome)
}

额外还需要一个方法:

​
//将tags字符串转化成首页模板所需要的数据结构
func createTagsLinks(tags string) []TagLink {
    var tagLink [] TagLink
    tagsPamar := strings.Split(tags, "&")
    for _, tag := range tagsPamar {
        tagLink = append(tagLink, TagLink{tag, "/?tag=" + tag})
    }
    return tagLink
}

1.3 View

接下来我们设计一下页面,刚刚在model的MakeHomeBlocks()方法中,就是需要使用模板填充格式化html页面内容,所以我们在views/block下再创建一个html页面:home_block.html,内容如下:

<div id="home-block-item">
    <h2><a href="{{.Link}}">{{.Title}}</a></h2>
    <div>
        <span>{{.CreateTime}}</span>
        <span>
        {{range .Tags}}
            <a href="{{.TagUrl}}">&nbsp{{.TagName}}</a>
        {{end}}
        </span>
    </div>
    <p><a href={{.Link}}>{{.Short}}</a></p>
{{if .IsLogin}}
    <div class="home-block-item-udpate">
        <a href='javascript:if(confirm("确定删除吗?")){location="{{.DeleteLink}}"}'>删除</a>
        <a href={{.UpdateLink}}>修改</a>
    </div>
{{end}}
</div>

我们现实了从数据中查询出的文章的数据,如果用户是登录状态,那么我们现实删除和修改,因为用户有这两个权限,否则就不显示。

1.4 运行

我们在数据库中插入10条数据:

接下来我们设置一下配置文件,每页显示6条(也可以8条,10条。。),

修改conf目录下的app.conf文件:

appname = myblog
httpport = 8080
runmode = dev
​
#mysql配置
driverName = mysql
mysqluser = root
mysqlpwd = yu271400
host = 127.0.0.1
port = 3306
dbname = myblog
​
#Session
sessionon = true
sessionprovider = "file"
sessionname = "qianfengjiaoyumyblog"
sessiongcmaxlifetime = 1800
sessionproviderconfig = "./tmp"
sessioncookielifetime = 1800
​
articleListPageNum = 6

然后启动项目,打开浏览器输入网址:http://127.0.0.1:8080/

用户虽然没有登录,但是也是可以查看的,接下来我们点击登录按钮进行登录:

登录后,用户就可以有删除和修改的功能了。

二、分页功能

截止,我们已经已经能够显示出第一页的内容了,接下来我们添加上一页和下一页的功能。

2.1 Model

首先在home_model.go中添加一个分页的结构体对象:

type HomeFooterPageCode struct {
    HasPre bool
    HasNext bool
    ShowPage string
    PreLink string
    NextLink string
}

接下来添加方法:

​
​
//-----------翻页-----------
//page是当前的页数
func ConfigHomeFooterPageCode(page int) HomeFooterPageCode {
    pageCode := HomeFooterPageCode{}
    //查询出总的条数
    num := GetArticleRowsNum()
    //从配置文件中读取每页显示的条数
    pageRow, _ := beego.AppConfig.Int("articleListPageNum")
    //计算出总页数
    allPageNum := (num-1)/pageRow + 1
​
    pageCode.ShowPage = fmt.Sprintf("%d/%d", page, allPageNum)
​
    //当前页数小于等于1,那么上一页的按钮不能点击
    if page <= 1 {
        pageCode.HasPre = false
    } else {
        pageCode.HasPre = true
    }
​
    //当前页数大于等于总页数,那么下一页的按钮不能点击
    if page >= allPageNum {
        pageCode.HasNext = false
    } else {
        pageCode.HasNext = true
    }
​
    pageCode.PreLink = "/?page=" + strconv.Itoa(page-1)
    pageCode.NextLink = "/?page=" + strconv.Itoa(page+1)
    return pageCode
​
}
​

这段代码需要查询出数据库中所有文章的总量,所以我们要先在article_model.go文件中,加入查询总数据量的方法:

//------翻页------

//存储表的行数,只有自己可以更改,当文章新增或者删除时需要更新这个值
var artcileRowsNum = 0

//只有首次获取行数的时候采取统计表里的行数
func GetArticleRowsNum() int {
	if artcileRowsNum == 0 {
		artcileRowsNum = QueryArticleRowNum()
	}
	return artcileRowsNum
}

//查询文章的总条数
func QueryArticleRowNum() int {
	row := utils.QueryRowDB("select count(id) from article")
	num := 0
	row.Scan(&num)
	return num
}

我们还要考虑一个问题,就是当新增或删除文章的时候,数据总量会发生改变,所以还要修改增加文章的方法:

先新增一个方法用于设置总页数:

//设置页数
func SetArticleRowsNum(){
    artcileRowsNum = QueryArticleRowNum()
}

然后修改增加文章的方法:

//---------添加文章-----------
func AddArticle(article Article) (int64, error) {
    i, err := insertArticle(article)
    SetArticleRowsNum()
    return i, err
}

2.2 Controller

修改home_controller.go的Get()方法:

func (this *HomeController) Get() {
    ...
    artList, _ = models.FindArticleWithPage(page)
    this.Data["PageCode"] = models.ConfigHomeFooterPageCode(page)
    this.Data["HasFooter"] = true
    ...
}
​

2.3 View

修改home.html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <link href="../static/css/blogsheet.css" rel="stylesheet">
</head>
<body>
{{template "block/nav.html" .}}
​
​
<div id="main">
{{.Content}}
​
​
​
{{if .HasFooter}}
    <div id="home-footer">
        <a {{if .PageCode.HasPre}}href="{{.PageCode.PreLink}}" {{else}} class="disable" {{end}}>上一页</a>
        <span>{{.PageCode.ShowPage}}页</span>
        <a {{if .PageCode.HasNext}}href="{{.PageCode.NextLink}}" {{else}} class="disable" {{end}}>下一页</a>
    </div>
{{end}}
​
​
</div>
​
</body>
</html>

增添上一页,下一页的链接。

2.4 运行

首先我们再向数据库中插入5条数据:

然后修改配置文件,每页显示5条。

接下来,我们新增加一篇文章,点击写博客:

最后一页显示为我们刚刚增加的一篇文章,截止到现在我们可以很完美的显示页码了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值