Skip to content

Instantly share code, notes, and snippets.

@bluven
Created July 20, 2022 00:47
Show Gist options
  • Save bluven/3528f0bf8f68f0e5bc5062961728e653 to your computer and use it in GitHub Desktop.
Save bluven/3528f0bf8f68f0e5bc5062961728e653 to your computer and use it in GitHub Desktop.
package store
import (
"math"
"gorm.io/gorm"
)
// Param 分页参数
type Param struct {
DB *gorm.DB
Page int `form:"page"`
Limit int `form:"limit"`
OrderBy []string
ShowSQL bool
}
// Page 分页返回
type Page struct {
TotalRecord int64 `json:"totalRecord"`
TotalPage int `json:"totalPage"`
Items interface{} `json:"items"`
Offset int `json:"offset"`
Page int `form:"page" json:"page"`
Limit int `form:"limit" json:"limit"`
PrevPage int `json:"prevPage"`
NextPage int `json:"nextPage"`
}
// Paging 分页
func Paging(param Param, result interface{}) (Page, error) {
db := param.DB
if param.ShowSQL {
db = db.Debug()
}
if param.Page < 1 {
param.Page = 1
}
if param.Limit == 0 {
param.Limit = 10
}
var page Page
var offset int
var count int64
var err error
if count, err = countRecords(db, result); err != nil {
return page, err
}
if param.Page == 1 {
offset = 0
} else {
offset = (param.Page - 1) * param.Limit
}
if len(param.OrderBy) > 0 {
for _, o := range param.OrderBy {
db = db.Order(o)
}
}
// 不知道为什么,一旦在countRecords用Model(anyType)执行过后, 再次查询时不会用指定的Select
// 所以这里要判断一下是否有指定的Select,然后重新指定Select
if len(db.Statement.Selects) > 0 {
db = db.Select(db.Statement.Selects)
}
if err := db.Limit(param.Limit).Offset(offset).Find(result).Error; err != nil {
return page, err
}
page.TotalRecord = count
page.Items = result
page.Page = param.Page
page.Offset = offset
page.Limit = param.Limit
page.TotalPage = int(math.Ceil(float64(count) / float64(param.Limit)))
if param.Page > 1 {
page.PrevPage = param.Page - 1
} else {
page.PrevPage = param.Page
}
if param.Page == page.TotalPage {
page.NextPage = param.Page
} else {
page.NextPage = param.Page + 1
}
return page, nil
}
func countRecords(db *gorm.DB, anyType interface{}) (int64, error) {
var count int64
result := db.Model(anyType).Count(&count)
return count, result.Error
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment