pager.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. package utils
  2. import (
  3. // "fmt"
  4. html "html/template"
  5. con "strconv"
  6. "strings"
  7. "github.com/astaxie/beego/orm"
  8. "fmt"
  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. }
  99. totalPages := int(math.Ceil(float64(totalCount) / float64(pageSize)))
  100. setDefault(po,totalPages)
  101. DealUri(po,requestURI)
  102. str := ""
  103. if totalPages <= po.LinkItemCount {
  104. str = fun1(po, totalPages) //显示完全 12345678910
  105. } else if totalPages > po.LinkItemCount {
  106. if po.CurrentPage < po.LinkItemCount {
  107. str = fun2(po, totalPages) //123456789...200
  108. } else {
  109. if po.CurrentPage + po.LinkItemCount < totalPages {
  110. str = fun3(po, totalPages)
  111. } else {
  112. str = fun4(po, totalPages)
  113. }
  114. }
  115. }
  116. str = strings.Replace(str,"?&","?",-1)
  117. //str = strings.Replace(str,"&&","&",-1)
  118. return html.HTML(str)
  119. }
  120. /**
  121. * 处理url,目的是保存参数
  122. */
  123. func DealUri(po *PageOptions, requestURI string) {
  124. var rs string
  125. if strings.Contains(requestURI, "?") {
  126. arr := strings.Split(requestURI, "?")
  127. rs = ""
  128. arr2 := strings.Split(arr[1], "&")
  129. for _, v := range arr2 {
  130. if !strings.Contains(v, po.ParamName) {
  131. if strings.HasSuffix(rs,"&") {
  132. rs += v
  133. }else{
  134. rs += v + "&"
  135. }
  136. //rs += "&" + v
  137. }
  138. }
  139. if strings.HasPrefix(rs,"&") {
  140. rs = string(rs[1:])
  141. }
  142. if strings.HasSuffix(rs,"&"){
  143. rs = string(rs[0:strings.Count(rs,"")-1])
  144. }
  145. rs = arr[0] + "?" + rs
  146. fmt.Println(rs)
  147. } else {
  148. //rs = requestURI + "?" //+ po.ParamName + "time=" + con.Itoa(time.Now().Second())
  149. rs = requestURI + "?"
  150. }
  151. po.Href = rs
  152. }
  153. /**
  154. * 1...197 198 199 200
  155. */
  156. func fun4(po *PageOptions, totalPages int) string {
  157. rs := ""
  158. rs += getHeader(po, totalPages)
  159. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>"
  160. rs += "<li><a href=''>...</a></li>"
  161. for i := totalPages - po.LinkItemCount; i <= totalPages; i++ {
  162. if po.CurrentPage != i {
  163. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
  164. } else {
  165. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  166. }
  167. }
  168. rs += getFooter(po, totalPages)
  169. return rs
  170. }
  171. /**
  172. * 1...6 7 8 9 10 11 12 13 14 15... 200
  173. */
  174. func fun3(po *PageOptions, totalpages int) string {
  175. var rs string = ""
  176. rs += getHeader(po, totalpages)
  177. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + con.Itoa(1) + "</a></li>"
  178. rs += "<a href=''>...</a>"
  179. for i := po.CurrentPage - po.LinkItemCount/2 + 1; i <= po.CurrentPage+po.LinkItemCount/2-1; i++ {
  180. if po.CurrentPage != i {
  181. rs += "<a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a>"
  182. } else {
  183. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  184. }
  185. }
  186. rs += "<a href=''>...</a>"
  187. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "'>" + con.Itoa(totalpages) + "</a></li>"
  188. rs += getFooter(po, totalpages)
  189. return rs
  190. }
  191. /**
  192. * totalpages > po.LinkItemCount po.CurrentPage < po.LinkItemCount
  193. * 123456789...200
  194. */
  195. func fun2(po *PageOptions, totalpages int) string {
  196. var rs string = ""
  197. rs += getHeader(po, totalpages)
  198. for i := 1; i <= po.LinkItemCount+1; i++ {
  199. if i == po.LinkItemCount {
  200. rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "\">...</a></li>"
  201. } else if i == po.LinkItemCount+1 {
  202. rs += "<li><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + con.Itoa(totalpages) + "</a></li>"
  203. } else {
  204. if po.CurrentPage != i {
  205. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
  206. } else {
  207. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  208. }
  209. }
  210. }
  211. rs += getFooter(po, totalpages)
  212. return rs
  213. }
  214. /**
  215. * totalpages <= po.LinkItemCount
  216. * 显示完全 12345678910
  217. */
  218. func fun1(po *PageOptions, totalpages int) string {
  219. var rs string = ""
  220. rs += getHeader(po, totalpages)
  221. for i := 1; i <= totalpages; i++ {
  222. if po.CurrentPage != i {
  223. rs += "<li><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(i) + "'>" + con.Itoa(i) + "</a></li>"
  224. } else {
  225. rs += "<li class=\"active\"><a href=\"###\">" + con.Itoa(i) + " <span class=\"sr-only\">(current)</span></a></li>"
  226. }
  227. }
  228. rs += getFooter(po, totalpages)
  229. return rs
  230. }
  231. /**
  232. * 头部
  233. */
  234. func getHeader(po *PageOptions, totalpages int) string {
  235. var rs string = "<ul class=\"pagination\">"
  236. if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
  237. if po.CurrentPage == 1 {
  238. rs += "<li" + judgeDisable(po, totalpages, 0) + " class=\"disabled\"><a href=\"###\">" + po.FirstPageText + "</a></li>"
  239. }else{
  240. rs += "<li" + judgeDisable(po, totalpages, 0) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(1) + "'>" + po.FirstPageText + "</a></li>"
  241. }
  242. }
  243. if po.EnablePreNexLink { // disabled=\"disabled\"
  244. var a int = po.CurrentPage - 1
  245. if po.CurrentPage == 1 {
  246. a = 1
  247. }
  248. rs += "<li" + judgeDisable(po, totalpages, 0) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(a) + "'>" + po.PrePageText + "</a></li>"
  249. }
  250. return rs
  251. }
  252. /**
  253. * 尾部
  254. */
  255. func getFooter(po *PageOptions, totalpages int) string {
  256. var rs string = ""
  257. if po.EnablePreNexLink {
  258. var a int = po.CurrentPage + 1
  259. rs += "<li " + judgeDisable(po, totalpages, 1) + " ><a href='" + po.Href + "&" + po.ParamName + "=" + con.Itoa(a) + "'>" + po.NextPageText + "</a></li>"
  260. }
  261. if po.EnableFirstLastLink { //当首页,尾页都设定的时候,就显示
  262. if po.CurrentPage == totalpages {
  263. rs += "<li " + judgeDisable(po, totalpages, 1) + " class=\"disabled\"><a href=\"###\">" + po.LastPageText + "</a></li>"
  264. }else{
  265. rs += "<li " + judgeDisable(po, totalpages, 1) + " ><a href=\"" + po.Href + "&" + po.ParamName + "=" + con.Itoa(totalpages) + "\">" + po.LastPageText + "</a></li>"
  266. }
  267. }
  268. rs += "</ul>"
  269. return rs
  270. }
  271. /**
  272. * 设置默认值
  273. */
  274. func setDefault(po *PageOptions, totalpages int) *PageOptions {
  275. if len(po.FirstPageText) <= 0 {
  276. po.FirstPageText = "&laquo;"
  277. }
  278. if len(po.LastPageText) <= 0 {
  279. po.LastPageText = "&raquo;"
  280. }
  281. if len(po.PrePageText) <= 0 {
  282. po.PrePageText = "&lsaquo;"
  283. }
  284. if len(po.NextPageText) <= 0 {
  285. po.NextPageText = "&rsaquo;"
  286. }
  287. if po.CurrentPage >= totalpages {
  288. po.CurrentPage = totalpages
  289. }
  290. if po.CurrentPage <= 1 {
  291. po.CurrentPage = 1
  292. }
  293. if po.LinkItemCount == 0 {
  294. po.LinkItemCount = 10
  295. }
  296. if po.PageSize == 0 {
  297. po.PageSize = 20
  298. }
  299. if len(po.ParamName) <= 0 {
  300. po.ParamName = "pno"
  301. }
  302. return po
  303. }
  304. /**
  305. *判断首页尾页 上一页下一页是否能用
  306. */
  307. func judgeDisable(po *PageOptions, totalpages int, h_f int) string {
  308. var rs string = ""
  309. //判断头部
  310. if h_f == 0 {
  311. if po.CurrentPage == 1 {
  312. rs = " "
  313. }
  314. } else {
  315. if po.CurrentPage == totalpages {
  316. rs = " "
  317. }
  318. }
  319. return rs
  320. }