github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgPage/kmgPage.go (about)

     1  package kmgPage
     2  
     3  import (
     4  	"math"
     5  	"strconv"
     6  
     7  	"github.com/bronze1man/kmg/kmgNet/kmgHttp"
     8  	"github.com/bronze1man/kmg/kmgSql"
     9  	"github.com/bronze1man/kmg/kmgSql/MysqlAst"
    10  )
    11  
    12  type KmgPage struct {
    13  	ItemPerPage int                 // 每页数据量
    14  	ShowPageNum int                 // 显示分页的页面的时候,显示出来的页数 如 10,11,12,13,14,15 就是显示了6个页
    15  	PageKeyName string              // 页面参数的名字
    16  	CurrentPage int                 // 当前页数,默认为1
    17  	TotalItem   int                 // 总数据量
    18  	BaseUrl     string              // 不包含页码参数的url,具体渲染url的时候会把页面参数加上
    19  	Data        []map[string]string // 本次分页查询到的数据
    20  	TotalPage   int                 // 共有多少个页面
    21  	StartIndex  int
    22  	EndIndex    int
    23  }
    24  
    25  func CreateFromSelectCommandAndHttpContext(Select *MysqlAst.SelectCommand, Ctx *kmgHttp.Context) *KmgPage {
    26  	page := &KmgPage{}
    27  	page.BaseUrl = Ctx.GetRequestUrl()
    28  	page.CurrentPage = Ctx.InNum("Page")
    29  	page.PageKeyName = "Page"
    30  	page.init()
    31  	return page.runSelectCommand(Select)
    32  }
    33  
    34  func CreateFromSelectCommandAndHttpContextByItemPerPage(Select *MysqlAst.SelectCommand, Ctx *kmgHttp.Context, num int) *KmgPage {
    35  	page := &KmgPage{}
    36  	page.BaseUrl = Ctx.GetRequestUrl()
    37  	page.CurrentPage = Ctx.InNum("Page")
    38  	page.PageKeyName = "Page"
    39  	page.ItemPerPage = num
    40  	page.init()
    41  	return page.runSelectCommand(Select)
    42  }
    43  
    44  type CreateFromDataRequest struct {
    45  	Data        []map[string]string
    46  	BaseUrl     string
    47  	ItemPerPage int
    48  	CurrentPage int
    49  	StartIndex  int
    50  	EndIndex    int
    51  	PageKeyName string
    52  	DataSize    int
    53  }
    54  
    55  func CreateFromData(req CreateFromDataRequest) *KmgPage {
    56  	page := &KmgPage{}
    57  	page.BaseUrl = req.BaseUrl
    58  	page.ItemPerPage = req.ItemPerPage
    59  	page.CurrentPage = req.CurrentPage
    60  	page.PageKeyName = req.PageKeyName
    61  	page.TotalItem = req.DataSize
    62  	page.TotalPage = int(math.Ceil(float64(page.TotalItem) / float64(page.ItemPerPage)))
    63  	page.StartIndex = (req.CurrentPage - 1) * req.ItemPerPage
    64  	if req.CurrentPage*req.ItemPerPage > req.DataSize {
    65  		page.EndIndex = req.DataSize
    66  	} else {
    67  		page.EndIndex = req.CurrentPage * req.ItemPerPage
    68  	}
    69  	page.init()
    70  	page.StartIndex = (page.CurrentPage - 1) * page.ItemPerPage
    71  	return page
    72  }
    73  
    74  func (page *KmgPage) runSelectCommand(selectCommand *MysqlAst.SelectCommand) *KmgPage {
    75  	if page.BaseUrl == "" {
    76  		panic("runSelectCommand need baseUrl parameter")
    77  	}
    78  	output, parameterList := selectCommand.GetPrepareParameter()
    79  	countData, err := kmgSql.QueryOne("SELECT COUNT(*) AS c FROM ("+output+") as View", parameterList...)
    80  	if err != nil {
    81  		panic(err)
    82  	}
    83  	page.TotalItem, err = strconv.Atoi(countData["c"])
    84  	if err != nil {
    85  		panic(err)
    86  	}
    87  	dataSelect := selectCommand.Copy()
    88  	dataSelect = dataSelect.Limit(strconv.Itoa(page.GetMysqlOffset()) + "," + strconv.Itoa(page.ItemPerPage))
    89  	page.Data = kmgSql.MustRunSelectCommand(dataSelect)
    90  	return page
    91  }
    92  
    93  func (page *KmgPage) init() {
    94  	if page.ItemPerPage == 0 {
    95  		page.ItemPerPage = 30
    96  	}
    97  	if page.ShowPageNum == 0 {
    98  		page.ShowPageNum = 10
    99  	}
   100  	if page.PageKeyName == "" {
   101  		page.PageKeyName = "Page"
   102  	}
   103  	if page.CurrentPage == 0 {
   104  		page.CurrentPage = 1
   105  	}
   106  	if page.CurrentPage < 1 {
   107  		page.CurrentPage = 1
   108  	}
   109  	if page.CurrentPage > page.TotalPage && page.TotalPage > 0 {
   110  		page.CurrentPage = page.TotalPage
   111  	}
   112  }
   113  
   114  func (page *KmgPage) GetTotalPage() int {
   115  	totalPage := int(math.Ceil(float64(page.TotalItem) / float64(page.ItemPerPage)))
   116  	if totalPage <= 0 {
   117  		totalPage = 1
   118  	}
   119  	return totalPage
   120  }
   121  
   122  func (page *KmgPage) HtmlRender() string {
   123  	return tplPager(page)
   124  }
   125  
   126  // 一共有多少项
   127  func (page *KmgPage) GetTotalItem() int {
   128  	return page.TotalItem
   129  }
   130  
   131  // 是否有向前的按钮
   132  func (page *KmgPage) IsBeforePageActive() bool {
   133  	return page.CurrentPage-1 >= 1
   134  }
   135  
   136  // 是否有后向的按钮
   137  func (page *KmgPage) IsAfterPageActive() bool {
   138  	return page.CurrentPage+1 <= page.GetTotalPage()
   139  }
   140  
   141  // MySQL 数据库的偏移量
   142  func (page *KmgPage) GetMysqlOffset() int {
   143  	ret := (page.CurrentPage - 1) * page.ItemPerPage
   144  	return ret
   145  }
   146  
   147  // 前一页的 Url
   148  func (page *KmgPage) GetBeforePageUrl() string {
   149  	pageNumber := page.CurrentPage - 1
   150  	if pageNumber < 1 {
   151  		pageNumber = 1
   152  		return "javascript:"
   153  	}
   154  	return page.GetUrlWithPage(pageNumber)
   155  }
   156  
   157  // 后一页的 Url
   158  func (page *KmgPage) GetAfterPageUrl() string {
   159  	pageNumber := page.CurrentPage + 1
   160  	if pageNumber > page.GetTotalPage() {
   161  		return "javascript:"
   162  	}
   163  	return page.GetUrlWithPage(pageNumber)
   164  }
   165  
   166  // 中间显示的分页的数据
   167  func (page *KmgPage) GetShowPageArray() []UrlParam {
   168  	// 页面比显示数据量还少,快速通道
   169  	if page.GetTotalPage() <= page.ShowPageNum {
   170  		return page.getShowPageArrayFromNum(1, page.GetTotalPage())
   171  	}
   172  	start := page.CurrentPage - page.ShowPageNum/2
   173  	end := page.CurrentPage + page.ShowPageNum/2
   174  	if start < 1 {
   175  		end = page.ShowPageNum
   176  		start = 1
   177  	}
   178  	if end > page.GetTotalPage() {
   179  		start = page.GetTotalPage() - page.ShowPageNum + 1
   180  		end = page.GetTotalPage()
   181  	}
   182  	return page.getShowPageArrayFromNum(start, end)
   183  }
   184  
   185  type UrlParam struct {
   186  	IsCurrent bool
   187  	PageNum   int
   188  	Url       string
   189  }
   190  
   191  func (page *KmgPage) getShowPageArrayFromNum(start int, end int) []UrlParam {
   192  	var output []UrlParam
   193  	var param UrlParam
   194  	for i := start; i <= end; i++ {
   195  		url := page.GetUrlWithPage(i)
   196  		param.IsCurrent = (i == page.CurrentPage)
   197  		param.PageNum = i
   198  		param.Url = url
   199  		output = append(output, param)
   200  	}
   201  	return output
   202  }
   203  
   204  // 获取页面的 Url
   205  func (page *KmgPage) GetUrlWithPage(pageNum int) string {
   206  	return kmgHttp.MustSetParameterToUrl(page.BaseUrl, page.PageKeyName, strconv.Itoa(pageNum))
   207  }