pagination.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package pagination
  2. import (
  3. "fmt"
  4. "html/template"
  5. "math"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "strings"
  10. "github.com/beego/beego/v2/server/web"
  11. "github.com/beego/i18n"
  12. )
  13. //Pagination 分页器
  14. type Pagination struct {
  15. Request *http.Request
  16. Total int
  17. Pernum int
  18. BaseUrl string
  19. }
  20. //NewPagination 新建分页器
  21. func NewPagination(req *http.Request, total int, pernum int, baseUrl string) *Pagination {
  22. return &Pagination{
  23. Request: req,
  24. Total: total,
  25. Pernum: pernum,
  26. BaseUrl: baseUrl,
  27. }
  28. }
  29. func (p *Pagination) HtmlPages() template.HTML {
  30. return template.HTML(p.Pages())
  31. }
  32. //Pages 渲染生成html分页标签
  33. func (p *Pagination) Pages() string {
  34. queryParams := p.Request.URL.Query()
  35. //从当前请求中获取page
  36. page := queryParams.Get("page")
  37. if page == "" {
  38. page = "1"
  39. }
  40. //将页码转换成整型,以便计算
  41. pagenum, _ := strconv.Atoi(page)
  42. if pagenum == 0 {
  43. return ""
  44. }
  45. //计算总页数
  46. var totalPageNum = int(math.Ceil(float64(p.Total) / float64(p.Pernum)))
  47. lang := p.getLang()
  48. //首页链接
  49. var firstLink string
  50. //上一页链接
  51. var prevLink string
  52. //下一页链接
  53. var nextLink string
  54. //末页链接
  55. var lastLink string
  56. //中间页码链接
  57. var pageLinks []string
  58. //首页和上一页链接
  59. if pagenum > 1 {
  60. firstLink = fmt.Sprintf(`<li><a href="%s">%s</a></li>`, p.pageURL("1"), i18n.Tr(lang, "page.first"))
  61. prevLink = fmt.Sprintf(`<li><a href="%s">%s</a></li>`, p.pageURL(strconv.Itoa(pagenum-1)), i18n.Tr(lang, "page.prev"))
  62. } else {
  63. firstLink = fmt.Sprintf(`<li class="disabled"><a href="#">%s</a></li>`, i18n.Tr(lang, "page.first"))
  64. prevLink = fmt.Sprintf(`<li class="disabled"><a href="#">%s</a></li>`, i18n.Tr(lang, "page.prev"))
  65. }
  66. //末页和下一页
  67. if pagenum < totalPageNum {
  68. lastLink = fmt.Sprintf(`<li><a href="%s">%s</a></li>`, p.pageURL(strconv.Itoa(totalPageNum)), i18n.Tr(lang, "page.last"))
  69. nextLink = fmt.Sprintf(`<li><a href="%s">%s</a></li>`, p.pageURL(strconv.Itoa(pagenum+1)), i18n.Tr(lang, "page.next"))
  70. } else {
  71. lastLink = fmt.Sprintf(`<li class="disabled"><a href="#">%s</a></li>`, i18n.Tr(lang, "page.last"))
  72. nextLink = fmt.Sprintf(`<li class="disabled"><a href="#">%s</a></li>`, i18n.Tr(lang, "page.next"))
  73. }
  74. //生成中间页码链接
  75. pageLinks = make([]string, 0, 10)
  76. startPos := pagenum - 3
  77. endPos := pagenum + 3
  78. if startPos < 1 {
  79. endPos = endPos + int(math.Abs(float64(startPos))) + 1
  80. startPos = 1
  81. }
  82. if endPos > totalPageNum {
  83. endPos = totalPageNum
  84. }
  85. for i := startPos; i <= endPos; i++ {
  86. var s string
  87. if i == pagenum {
  88. s = fmt.Sprintf(`<li class="active"><a href="%s">%d</a></li>`, p.pageURL(strconv.Itoa(i)), i)
  89. } else {
  90. s = fmt.Sprintf(`<li><a href="%s">%d</a></li>`, p.pageURL(strconv.Itoa(i)), i)
  91. }
  92. pageLinks = append(pageLinks, s)
  93. }
  94. return fmt.Sprintf(`<ul class="pagination">%s%s%s%s%s</ul>`, firstLink, prevLink, strings.Join(pageLinks, ""), nextLink, lastLink)
  95. }
  96. //pageURL 生成分页url
  97. func (p *Pagination) pageURL(page string) string {
  98. //基于当前url新建一个url对象
  99. u, _ := url.Parse(p.BaseUrl + p.Request.URL.String())
  100. q := u.Query()
  101. q.Set("page", page)
  102. u.RawQuery = q.Encode()
  103. return u.String()
  104. }
  105. func (p *Pagination) getLang() string {
  106. lang, _ := web.AppConfig.String("default_lang")
  107. ulang := p.Request.FormValue("lang")
  108. if len(ulang) == 0 {
  109. clang, err := p.Request.Cookie("lang")
  110. if err != nil {
  111. return lang
  112. }
  113. ulang = clang.Value
  114. }
  115. if !i18n.IsExist(ulang) {
  116. return lang
  117. }
  118. return ulang
  119. }
  120. type Page struct {
  121. PageNo int `json:"PageNo"`
  122. PageSize int `json:"PageSize"`
  123. TotalPage int `json:"TotalPage"`
  124. TotalCount int `json:"TotalCount"`
  125. FirstPage bool `json:"FirstPage"`
  126. LastPage bool `json:"LastPage"`
  127. List interface{} `json:"List"`
  128. }
  129. func PageUtil(count int, pageNo int, pageSize int, list interface{}) Page {
  130. tp := count / pageSize
  131. if count%pageSize > 0 {
  132. tp = count/pageSize + 1
  133. }
  134. return Page {
  135. PageNo: pageNo,
  136. PageSize: pageSize,
  137. TotalPage: tp,
  138. TotalCount: count,
  139. FirstPage: pageNo == 1,
  140. LastPage: pageNo == tp,
  141. List: list,
  142. }
  143. }