pager.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. package utils
  2. import (
  3. // "fmt"
  4. html "html/template"
  5. con "strconv"
  6. "strings"
  7. "fmt"
  8. "github.com/astaxie/beego/orm"
  9. "math"
  10. )
  11. type PageOptions struct {
  12. TableName string //表名 -----------------[必填]
  13. Conditions string //条件
  14. CurrentPage int //当前页 ,默认1 每次分页,必须在前台设置新的页数,不设置始终默认1.在控制器中使用方式:cp, _ := this.GetInt("pno") po.CurrentPage = int(cp)
  15. PageSize int //页面大小,默认20
  16. LinkItemCount int //生成A标签的个数 默认10个
  17. Href string //A标签的链接地址 ---------[不需要设置]
  18. ParamName string //参数名称 默认是pno
  19. FirstPageText string //首页文字 默认"首页"
  20. LastPageText string //尾页文字 默认"尾页"
  21. PrePageText string //上一页文字 默认"上一页"
  22. NextPageText string //下一页文字 默认"下一页"
  23. EnableFirstLastLink bool //是否启用首尾连接 默认false 建议开启
  24. EnablePreNexLink bool //是否启用上一页,下一页连接 默认false 建议开启
  25. TotalPages int
  26. }
  27. /**
  28. * 分页函数,适用任何表
  29. * 返回 总记录条数,总页数,以及当前请求的数据RawSeter,调用中需要"rs.QueryRows(&tblog)"就行了 --tblog是一个Tb_log对象
  30. * 参数:表名,当前页数,页面大小,条件(查询条件,格式为 " and name='zhifeiya' and age=12 ")
  31. */
  32. func GetPagesInfo(tableName string, currentpage int, pagesize int, conditions string) (int, int, orm.RawSeter) {
  33. if currentpage <= 1 {
  34. currentpage = 1
  35. }
  36. if pagesize == 0 {
  37. pagesize = 20
  38. }
  39. var rs orm.RawSeter
  40. o := orm.NewOrm()
  41. var totalItem, totalpages int = 0, 0 //总条数,总页数
  42. o.Raw("SELECT count(*) FROM " + tableName + " where 1 > 0 " + conditions).QueryRow(&totalItem) //获取总条数
  43. if totalItem <= pagesize {
  44. totalpages = 1
  45. } else if totalItem > pagesize {
  46. temp := totalItem / pagesize
  47. if (totalItem % pagesize) != 0 {
  48. temp = temp + 1
  49. }
  50. totalpages = temp
  51. }
  52. rs = o.Raw("select * from " + tableName + " where 1 > 0 " + conditions + " LIMIT " + con.Itoa((currentpage-1)*pagesize) + "," + con.Itoa(pagesize))
  53. return totalItem, totalpages, rs
  54. }
  55. /**
  56. * 返回总记录条数,总页数,当前页面数据,分页html
  57. * 根据分页选项,生成分页连接 下面是一个实例:
  58. func (this *MainController) Test() {
  59. var po util.PageOptions
  60. po.EnablePreNexLink = true
  61. po.EnableFirstLastLink = true
  62. po.LinkItemCount = 7
  63. po.TableName = "help_topic"
  64. cp, _ := this.GetInt("pno")
  65. po.CurrentPage = int(cp)
  66. _,_,_ pager := util.GetPagerLinks(&po, this.Ctx)
  67. this.Data["Email"] = html.HTML(pager)
  68. this.TplName = "test.html"
  69. }
  70. */
  71. func GetPagerLinks(po *PageOptions, requestURI string) (int, int, orm.RawSeter, html.HTML) {
  72. str := ""
  73. totalItem, totalpages, rs := GetPagesInfo(po.TableName, po.CurrentPage, po.PageSize, po.Conditions)
  74. po = setDefault(po, totalpages)
  75. DealUri(po, requestURI)
  76. if totalpages <= po.LinkItemCount {
  77. str = fun1(po, totalpages) //显示完全 12345678910
  78. } else if totalpages > po.LinkItemCount {
  79. if po.CurrentPage < po.LinkItemCount {
  80. str = fun2(po, totalpages) //123456789...200
  81. } else {
  82. if po.CurrentPage+po.LinkItemCount < totalpages {
  83. str = fun3(po, totalpages)
  84. } else {
  85. str = fun4(po, totalpages)
  86. }
  87. }
  88. }
  89. return totalItem, totalpages, rs, html.HTML(str)
  90. }
  91. func GetPagerHtml(requestURI string, pageIndex, pageSize, totalCount int) html.HTML {
  92. po := &PageOptions{
  93. CurrentPage: pageIndex,
  94. PageSize: pageSize,
  95. EnableFirstLastLink: true,
  96. ParamName: "page",
  97. TotalPages: int(math.Ceil(float64(totalCount) / float64(pageSize))),
  98. LinkItemCount: pageSize,
  99. }
  100. totalPages := int(math.Ceil(float64(totalCount) / float64(pageSize)))
  101. setDefault(po, totalPages)
  102. DealUri(po, requestURI)
  103. str := ""
  104. if totalPages <= po.LinkItemCount {
  105. str = fun1(po, totalPages) //显示完全 12345678910
  106. } else if totalPages > po.LinkItemCount {
  107. if po.CurrentPage < po.LinkItemCount {
  108. str = fun2(po, totalPages) //123456789...200
  109. } else {
  110. if po.CurrentPage+po.LinkItemCount < totalPages {
  111. str = fun3(po, totalPages)
  112. } else {
  113. str = fun4(po, totalPages)
  114. }
  115. }
  116. }
  117. str = strings.Replace(str, "?&", "?", -1)
  118. //str = strings.Replace(str,"&&","&",-1)
  119. return html.HTML(str)
  120. }
  121. /**
  122. * 处理url,目的是保存参数
  123. */
  124. func DealUri(po *PageOptions, requestURI string) {
  125. var rs string
  126. if strings.Contains(requestURI, "?") {
  127. arr := strings.Split(requestURI, "?")
  128. rs = ""
  129. arr2 := strings.Split(arr[1], "&")
  130. for _, v := range arr2 {
  131. if !strings.Contains(v, po.ParamName) {
  132. if strings.HasSuffix(rs, "&") {
  133. rs += v
  134. } else {
  135. rs += v + "&"
  136. }
  137. //rs += "&" + v
  138. }
  139. }
  140. if strings.HasPrefix(rs, "&") {
  141. rs = string(rs[1:])
  142. }
  143. if strings.HasSuffix(rs, "&") {
  144. rs = string(rs[0 : strings.Count(rs, "")-1])
  145. }
  146. rs = arr[0] + "?" + rs
  147. fmt.Println(rs)
  148. } else {
  149. //rs = requestURI + "?" //+ po.ParamName + "time=" + con.Itoa(time.Now().Second())
  150. rs = requestURI + "?"
  151. }
  152. po.Href = rs
  153. }
  154. /**
  155. * 1...197 198 199 200
  156. */
  157. func fun4(po *PageOptions, totalPages int) string {
  158. rs := ""
  159. rs += getHeader(po, totalPages)
  160. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>"
  161. rs += "<li><a href=\"#\" class=\"@3\">...</a></li>"
  162. for i := totalPages - po.LinkItemCount-1; i <= totalPages; i++ {
  163. if po.CurrentPage != i {
  164. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
  165. } else {
  166. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  167. }
  168. }
  169. rs += getFooter(po, totalPages)
  170. return rs
  171. }
  172. /**
  173. * 1...6 7 8 9 10 11 12 13 14 15... 200
  174. */
  175. func fun3(po *PageOptions, totalpages int) string {
  176. var rs string = ""
  177. rs += getHeader(po, totalpages)
  178. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>"
  179. rs += "<li><a href=\"#\" class=\"@1\">...</a></li>"
  180. for i := po.CurrentPage - po.LinkItemCount/2 + 1; i <= po.CurrentPage+po.LinkItemCount/2-1; i++ {
  181. if po.CurrentPage != i {
  182. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
  183. } else {
  184. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  185. }
  186. }
  187. rs += "<li><a href=\"#\" class=\"@2\">...</a></li>"
  188. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "'>" + con.Itoa(totalpages) + "</a></li>"
  189. rs += getFooter(po, totalpages)
  190. return rs
  191. }
  192. /**
  193. * totalpages > po.LinkItemCount po.CurrentPage < po.LinkItemCount
  194. * 123456789...200
  195. */
  196. func fun2(po *PageOptions, totalpages int) string {
  197. rs := ""
  198. rs += getHeader(po, totalpages)
  199. for i := 1; i <= po.LinkItemCount+2; i++ {
  200. if i == po.LinkItemCount+2 {
  201. rs += "<li class=\"@4\"><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "\">...</a></li>"
  202. } else if i == po.LinkItemCount+1 {
  203. rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + con.Itoa(totalpages) + "</a></li>"
  204. } else {
  205. if po.CurrentPage != i {
  206. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
  207. } else {
  208. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  209. }
  210. }
  211. }
  212. rs += getFooter(po, totalpages)
  213. return rs
  214. }
  215. /**
  216. * totalpages <= po.LinkItemCount
  217. * 显示完全 12345678910
  218. */
  219. func fun1(po *PageOptions, totalpages int) string {
  220. var rs string = ""
  221. rs += getHeader(po, totalpages)
  222. for i := 1; i <= totalpages; i++ {
  223. if po.CurrentPage != i {
  224. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
  225. } else {
  226. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  227. }
  228. }
  229. rs += getFooter(po, totalpages)
  230. return rs
  231. }
  232. /**
  233. * 头部
  234. */
  235. func getHeader(po *PageOptions, totalpages int) string {
  236. var rs string = "<ul class=\"pagination\">"
  237. if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
  238. if po.CurrentPage == 1 {
  239. rs += "<li" + judgeDisable(po, totalpages, 0) + " class=\"disabled\"><a href=\"###\">" + po.FirstPageText + "</a></li>"
  240. } else {
  241. rs += "<li" + judgeDisable(po, totalpages, 0) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + po.FirstPageText + "</a></li>"
  242. }
  243. }
  244. if po.EnablePreNexLink { // disabled=\"disabled\"
  245. var a int = po.CurrentPage - 1
  246. if po.CurrentPage == 1 {
  247. a = 1
  248. }
  249. rs += "<li" + judgeDisable(po, totalpages, 0) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(a) + "'>" + po.PrePageText + "</a></li>"
  250. }
  251. return rs
  252. }
  253. /**
  254. * 尾部
  255. */
  256. func getFooter(po *PageOptions, totalpages int) string {
  257. var rs string = ""
  258. if po.EnablePreNexLink {
  259. var a int = po.CurrentPage + 1
  260. rs += "<li " + judgeDisable(po, totalpages, 1) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(a) + "'>" + po.NextPageText + "</a></li>"
  261. }
  262. if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
  263. if po.CurrentPage == totalpages {
  264. rs += "<li " + judgeDisable(po, totalpages, 1) + " class=\"disabled\"><a href=\"###\">" + po.LastPageText + "</a></li>"
  265. } else {
  266. rs += "<li " + judgeDisable(po, totalpages, 1) + " ><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + po.LastPageText + "</a></li>"
  267. }
  268. }
  269. rs += "</ul>"
  270. return rs
  271. }
  272. /**
  273. * 设置默认值
  274. */
  275. func setDefault(po *PageOptions, totalpages int) *PageOptions {
  276. if len(po.FirstPageText) <= 0 {
  277. po.FirstPageText = "&laquo;"
  278. }
  279. if len(po.LastPageText) <= 0 {
  280. po.LastPageText = "&raquo;"
  281. }
  282. if len(po.PrePageText) <= 0 {
  283. po.PrePageText = "&lsaquo;"
  284. }
  285. if len(po.NextPageText) <= 0 {
  286. po.NextPageText = "&rsaquo;"
  287. }
  288. if po.CurrentPage >= totalpages {
  289. po.CurrentPage = totalpages
  290. }
  291. if po.CurrentPage <= 1 {
  292. po.CurrentPage = 1
  293. }
  294. if po.LinkItemCount == 0 {
  295. po.LinkItemCount = 10
  296. }
  297. if po.PageSize == 0 {
  298. po.PageSize = 20
  299. }
  300. if len(po.ParamName) <= 0 {
  301. po.ParamName = "pno"
  302. }
  303. return po
  304. }
  305. /**
  306. *判断首页尾页 上一页下一页是否能用
  307. */
  308. func judgeDisable(po *PageOptions, totalpages int, h_f int) string {
  309. var rs string = ""
  310. //判断头部
  311. if h_f == 0 {
  312. if po.CurrentPage == 1 {
  313. rs = " "
  314. }
  315. } else {
  316. if po.CurrentPage == totalpages {
  317. rs = " "
  318. }
  319. }
  320. return rs
  321. }