2018-04-22 10:07:24 +08:00
|
|
|
|
// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
|
|
|
|
//
|
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
|
|
|
|
// You can obtain one at https://gitee.com/johng/gf.
|
|
|
|
|
|
|
|
|
|
// 分页管理.
|
|
|
|
|
package gpage
|
|
|
|
|
|
|
|
|
|
import (
|
2018-04-22 11:26:19 +08:00
|
|
|
|
"fmt"
|
2018-04-22 20:44:32 +08:00
|
|
|
|
"math"
|
2018-04-22 11:26:19 +08:00
|
|
|
|
"strings"
|
2018-04-22 20:44:32 +08:00
|
|
|
|
url2 "net/url"
|
|
|
|
|
"gitee.com/johng/gf/g/util/gconv"
|
2018-07-30 10:28:07 +08:00
|
|
|
|
"gitee.com/johng/gf/g/net/ghttp"
|
|
|
|
|
"gitee.com/johng/gf/g/util/gregex"
|
|
|
|
|
"gitee.com/johng/gf/g/util/gutil"
|
2018-04-22 10:07:24 +08:00
|
|
|
|
)
|
|
|
|
|
|
2018-04-22 20:44:32 +08:00
|
|
|
|
// 分页对象
|
2018-04-22 10:07:24 +08:00
|
|
|
|
type Page struct {
|
2018-07-30 10:28:07 +08:00
|
|
|
|
Url *url2.URL // 当前页面的URL对象
|
|
|
|
|
Router *ghttp.Router // 当前页面的路由对象(与gf框架耦合,在静态分页下有效)
|
|
|
|
|
TotalSize int // 总共数据条数
|
|
|
|
|
TotalPage int // 总页数
|
|
|
|
|
CurrentPage int // 当前页码
|
|
|
|
|
PageName string // 分页参数名称(GET参数)
|
|
|
|
|
NextPageTag string // 下一页标签
|
|
|
|
|
PrevPageTag string // 上一页标签
|
|
|
|
|
FirstPageTag string // 首页标签
|
|
|
|
|
LastPageTag string // 尾页标签
|
|
|
|
|
PrevBar string // 上一分页条
|
|
|
|
|
NextBar string // 下一分页条
|
|
|
|
|
PageBarNum int // 控制分页条的数量
|
|
|
|
|
AjaxActionName string // AJAX方法名,当该属性有值时,表示使用AJAX分页
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-22 20:44:32 +08:00
|
|
|
|
// 创建一个分页对象,输入参数分别为:
|
2018-07-30 10:28:07 +08:00
|
|
|
|
// 总数量、每页数量、当前页码、当前的URL(URI+QUERY)、(可选)路由规则(例如: /user/list/:page、/order/list/*page)
|
|
|
|
|
func New(TotalSize, perPage int, CurrentPage interface{}, url string, router...*ghttp.Router) *Page {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
u, _ := url2.Parse(url)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
page := &Page {
|
2018-04-22 22:17:20 +08:00
|
|
|
|
PageName : "page",
|
|
|
|
|
PrevPageTag : "<",
|
|
|
|
|
NextPageTag : ">",
|
|
|
|
|
FirstPageTag : "|<",
|
|
|
|
|
LastPageTag : ">|",
|
|
|
|
|
PrevBar : "<<",
|
|
|
|
|
NextBar : ">>",
|
|
|
|
|
TotalSize : TotalSize,
|
2018-05-24 17:16:03 +08:00
|
|
|
|
TotalPage : int(math.Ceil(float64(TotalSize)/float64(perPage))),
|
2018-04-23 11:20:48 +08:00
|
|
|
|
CurrentPage : 1,
|
2018-04-22 22:17:20 +08:00
|
|
|
|
PageBarNum : 10,
|
|
|
|
|
Url : u,
|
2018-04-22 20:44:32 +08:00
|
|
|
|
}
|
2018-04-23 11:20:48 +08:00
|
|
|
|
curPage := gconv.Int(CurrentPage)
|
|
|
|
|
if curPage > 0 {
|
|
|
|
|
page.CurrentPage = curPage
|
|
|
|
|
}
|
2018-07-30 10:28:07 +08:00
|
|
|
|
if len(router) > 0 {
|
|
|
|
|
page.Router = router[0]
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
|
|
|
|
return page
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-22 11:26:19 +08:00
|
|
|
|
// 启用AJAX分页
|
2018-04-22 22:17:20 +08:00
|
|
|
|
func (page *Page) EnableAjax(actionName string) {
|
|
|
|
|
page.AjaxActionName = actionName
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-22 11:26:19 +08:00
|
|
|
|
// 获取显示"下一页"的内容.
|
2018-04-22 22:17:20 +08:00
|
|
|
|
func (page *Page) NextPage(styles ... string) string {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
var curStyle, style string
|
|
|
|
|
if len(styles) > 0 {
|
|
|
|
|
curStyle = styles[0]
|
|
|
|
|
}
|
|
|
|
|
if len(styles) > 1 {
|
|
|
|
|
style = styles[0]
|
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
if page.CurrentPage < page.TotalPage {
|
|
|
|
|
return page.GetLink(page.GetUrl(page.CurrentPage + 1), page.NextPageTag, "下一页", style)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
return fmt.Sprintf(`<span class="%s">%s</span>`, curStyle, page.NextPageTag)
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-22 11:26:19 +08:00
|
|
|
|
/// 获取显示“上一页”的内容
|
2018-04-22 22:17:20 +08:00
|
|
|
|
func (page *Page) PrevPage(styles ... string) string {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
var curStyle, style string
|
|
|
|
|
if len(styles) > 0 {
|
|
|
|
|
curStyle = styles[0]
|
|
|
|
|
}
|
|
|
|
|
if len(styles) > 1 {
|
|
|
|
|
style = styles[0]
|
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
if page.CurrentPage > 1 {
|
|
|
|
|
return page.GetLink(page.GetUrl(page.CurrentPage - 1), page.PrevPageTag, "上一页", style)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
return fmt.Sprintf(`<span class="%s">%s</span>`, curStyle, page.PrevPageTag)
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取显示“首页”的代码
|
|
|
|
|
*
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2018-04-22 22:17:20 +08:00
|
|
|
|
func (page *Page) FirstPage(styles ... string) string {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
var curStyle, style string
|
|
|
|
|
if len(styles) > 0 {
|
|
|
|
|
curStyle = styles[0]
|
|
|
|
|
}
|
|
|
|
|
if len(styles) > 1 {
|
|
|
|
|
style = styles[0]
|
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
if page.CurrentPage == 1 {
|
|
|
|
|
return fmt.Sprintf(`<span class="%s">%s</span>`, curStyle, page.FirstPageTag)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
return page.GetLink(page.GetUrl(1), page.FirstPageTag, "第一页", style)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取显示“尾页”的内容
|
2018-04-22 22:17:20 +08:00
|
|
|
|
func (page *Page) LastPage(styles ... string) string {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
var curStyle, style string
|
|
|
|
|
if len(styles) > 0 {
|
|
|
|
|
curStyle = styles[0]
|
|
|
|
|
}
|
|
|
|
|
if len(styles) > 1 {
|
|
|
|
|
style = styles[0]
|
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
if page.CurrentPage == page.TotalPage {
|
|
|
|
|
return fmt.Sprintf(`<span class="%s">%s</span>`, curStyle, page.LastPageTag)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
return page.GetLink(page.GetUrl(page.TotalPage), page.LastPageTag, "最后页", style)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-22 22:17:20 +08:00
|
|
|
|
// 获得分页条列表内容
|
|
|
|
|
func (page *Page) PageBar(styles ... string) string {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
var curStyle, style string
|
|
|
|
|
if len(styles) > 0 {
|
|
|
|
|
curStyle = styles[0]
|
|
|
|
|
}
|
|
|
|
|
if len(styles) > 1 {
|
|
|
|
|
style = styles[0]
|
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
plus := int(math.Ceil(float64(page.PageBarNum / 2)))
|
|
|
|
|
if page.PageBarNum - plus + page.CurrentPage > page.TotalPage {
|
|
|
|
|
plus = page.PageBarNum - page.TotalPage + page.CurrentPage
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
begin := page.CurrentPage - plus + 1
|
2018-04-22 11:26:19 +08:00
|
|
|
|
if begin < 1 {
|
|
|
|
|
begin = 1
|
|
|
|
|
}
|
|
|
|
|
ret := ""
|
2018-04-22 22:17:20 +08:00
|
|
|
|
for i := begin; i < begin + page.PageBarNum; i++ {
|
|
|
|
|
if i <= page.TotalPage {
|
|
|
|
|
if i != page.CurrentPage {
|
|
|
|
|
ret += page.GetLink(page.GetUrl(i), gconv.String(i), style, "")
|
2018-04-22 11:26:19 +08:00
|
|
|
|
} else {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
ret += fmt.Sprintf(`<span class="%s">%d</span>`, curStyle, i)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
// 获取基于select标签的显示跳转按钮的代码
|
|
|
|
|
func (page *Page) SelectBar() string {
|
|
|
|
|
ret := `<select name="gpage_select" onchange="window.location.href=this.value">`
|
|
|
|
|
for i := 1; i <= page.TotalPage; i++ {
|
|
|
|
|
if i == page.CurrentPage {
|
|
|
|
|
ret += fmt.Sprintf(`<option value="%s" selected>%d</option>`, page.GetUrl(i), i)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
} else {
|
2018-04-22 22:17:20 +08:00
|
|
|
|
ret += fmt.Sprintf(`<option value="%s">%d</option>`, page.GetUrl(i), i)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ret += "</select>"
|
|
|
|
|
return ret
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-22 20:44:32 +08:00
|
|
|
|
// 预定义的分页显示风格内容
|
|
|
|
|
func (page *Page) GetContent(mode int) string {
|
2018-04-22 22:17:20 +08:00
|
|
|
|
switch mode {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
case 1:
|
2018-04-22 22:17:20 +08:00
|
|
|
|
page.NextPageTag = "下一页"
|
|
|
|
|
page.PrevPageTag = "上一页"
|
|
|
|
|
return fmt.Sprintf(
|
|
|
|
|
`%s <span class="current">%d</span> %s`,
|
|
|
|
|
page.PrevPage(),
|
|
|
|
|
page.CurrentPage,
|
|
|
|
|
page.NextPage(),
|
|
|
|
|
)
|
2018-04-22 20:44:32 +08:00
|
|
|
|
|
|
|
|
|
case 2:
|
2018-04-22 22:17:20 +08:00
|
|
|
|
page.NextPageTag = "下一页>>"
|
|
|
|
|
page.PrevPageTag = "<<上一页"
|
|
|
|
|
page.FirstPageTag = "首页"
|
|
|
|
|
page.LastPageTag = "尾页"
|
|
|
|
|
return fmt.Sprintf(
|
|
|
|
|
`%s%s<span class="current">[第%d页]</span>%s%s第%s页`,
|
|
|
|
|
page.FirstPage(),
|
|
|
|
|
page.PrevPage(),
|
|
|
|
|
page.CurrentPage,
|
|
|
|
|
page.NextPage(),
|
|
|
|
|
page.LastPage(),
|
|
|
|
|
page.SelectBar(),
|
|
|
|
|
)
|
2018-04-22 20:44:32 +08:00
|
|
|
|
|
|
|
|
|
case 3:
|
2018-04-22 22:17:20 +08:00
|
|
|
|
page.NextPageTag = "下一页"
|
|
|
|
|
page.PrevPageTag = "上一页"
|
|
|
|
|
page.FirstPageTag = "首页"
|
|
|
|
|
page.LastPageTag = "尾页"
|
|
|
|
|
pageStr := page.FirstPage()
|
|
|
|
|
pageStr += page.PrevPage()
|
|
|
|
|
pageStr += page.PageBar("current")
|
|
|
|
|
pageStr += page.NextPage()
|
|
|
|
|
pageStr += page.LastPage()
|
|
|
|
|
pageStr += fmt.Sprintf(
|
|
|
|
|
`<span>当前页%d/%d</span> <span>共%d条</span>`,
|
|
|
|
|
page.CurrentPage,
|
|
|
|
|
page.TotalPage,
|
|
|
|
|
page.TotalSize,
|
|
|
|
|
)
|
2018-04-22 20:44:32 +08:00
|
|
|
|
return pageStr
|
|
|
|
|
|
|
|
|
|
case 4:
|
2018-04-22 22:17:20 +08:00
|
|
|
|
page.NextPageTag = "下一页"
|
|
|
|
|
page.PrevPageTag = "上一页"
|
|
|
|
|
page.FirstPageTag = "首页"
|
|
|
|
|
page.LastPageTag = "尾页"
|
|
|
|
|
pageStr := page.FirstPage()
|
|
|
|
|
pageStr += page.PrevPage()
|
|
|
|
|
pageStr += page.PageBar("current")
|
|
|
|
|
pageStr += page.NextPage()
|
|
|
|
|
pageStr += page.LastPage()
|
2018-04-22 20:44:32 +08:00
|
|
|
|
return pageStr
|
|
|
|
|
}
|
2018-04-22 11:26:19 +08:00
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 为指定的页面返回地址值
|
2018-04-22 22:17:20 +08:00
|
|
|
|
func (page *Page) GetUrl(pageNo int) string {
|
|
|
|
|
url := *page.Url
|
2018-07-30 10:28:07 +08:00
|
|
|
|
if page.Router != nil {
|
|
|
|
|
if page.Router != nil {
|
|
|
|
|
gutil.Dump(page.Router)
|
|
|
|
|
|
|
|
|
|
url.Path, _ = gregex.ReplaceStringFunc(page.Router.RegRule, url.Path, func(s string) string {
|
|
|
|
|
gutil.Dump(s)
|
|
|
|
|
if strings.EqualFold(s, page.PageName) {
|
|
|
|
|
s = gconv.String(pageNo)
|
|
|
|
|
}
|
|
|
|
|
return s
|
|
|
|
|
})
|
2018-04-22 22:17:20 +08:00
|
|
|
|
return url.String()
|
2018-04-22 20:44:32 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
values := page.Url.Query()
|
|
|
|
|
values.Set(page.PageName, gconv.String(pageNo))
|
|
|
|
|
url.RawQuery = values.Encode()
|
2018-04-22 20:44:32 +08:00
|
|
|
|
return url.String()
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取链接地址
|
2018-04-22 22:17:20 +08:00
|
|
|
|
func (page *Page) GetLink(url, text, title, style string) string {
|
2018-04-22 11:26:19 +08:00
|
|
|
|
if len(style) > 0 {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
style = fmt.Sprintf(`class="%s" `, style)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
2018-04-22 22:17:20 +08:00
|
|
|
|
if len(page.AjaxActionName) > 0 {
|
|
|
|
|
return fmt.Sprintf(`<a %shref='#' onclick="%s('%s')">%s</a>`, style, page.AjaxActionName, url, text)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
} else {
|
2018-04-22 20:44:32 +08:00
|
|
|
|
return fmt.Sprintf(`<a %shref="%s" title="%s">%s</a>`, style, url, title, text)
|
2018-04-22 11:26:19 +08:00
|
|
|
|
}
|
2018-04-22 10:07:24 +08:00
|
|
|
|
}
|
|
|
|
|
|