package services import ( "app/commons/core" "fmt" "github.com/gin-gonic/gin" "gorm.io/gorm" "math" ) // 业务库公共服务 func NewComService() *CommonService { return &CommonService{} } type CommonService struct { } func (s *CommonService) DB() *gorm.DB { return core.MainDb() } func (s *CommonService) FromContext(ctx *gin.Context) Context { return Context{Context: ctx} } // 分页器 type Pagination struct { Current int64 `json:"current" query:"current" form:"current" ` //当前页 Size int64 `json:"size" query:"size" form:"size" ` //每页条数 Total int64 `json:"total" query:"total" form:"total" ` //总条数 Count int64 `json:"count" query:"count" form:"count" ` //总页数 Start int64 `json:"start" query:"start" form:"start" ` //起始条数 } func NewPagination() *Pagination { return &Pagination{} } func NewPagingWithCurrentSize(current, size int64) *Pagination { return &Pagination{Current: current, Start: size} } func InitPaging(p, s int64) *Pagination { return &Pagination{Current: p, Size: s} } func (p *Pagination) Computer() { if p.Current < 1 { p.Current = 1 } if p.Size < 1 { p.Size = 10 } p.Start = p.Size * (p.Current - 1) count := math.Ceil(float64(p.Total) / float64(p.Size)) p.Count = int64(count) } // 获取单条记录 func GetOne[T any](db *gorm.DB, args ...interface{}) (*T, error) { db = buildEqualDB(db, args...) r := new(T) if err := db.First(&r).Error; err != nil { return r, err } return r, nil } // 获取最后一条记录 func GetLast[T any](db *gorm.DB, args ...interface{}) (*T, error) { db = buildEqualDB(db, args...) r := new(T) if err := db.Last(&r).Error; err != nil { return r, err } return r, nil } // 统计条数 func CountRow[T any](db *gorm.DB, args ...interface{}) int64 { db = buildEqualDB(db, args...) r := new(T) var total int64 = 0 db.Model(&r).Count(&total) return total } // 列表查询 func Find[T any](db *gorm.DB, args ...interface{}) ([]*T, error) { db = buildEqualDB(db, args...) res := make([]*T, 0) var total int64 err := db.Model(&res).Count(&total).Error if err != nil { return res, err } if total == 0 { return res, nil } if err := db.Find(&res).Error; err != nil { return res, err } return res, nil } // 分页查询 // 可带入简单查询条件 func FindWithPageAndQuery[T any](db *gorm.DB, paging *Pagination, args ...interface{}) ([]*T, *Pagination, error) { if paging == nil { paging = InitPaging(1, 10) } db = buildEqualDB(db, args...) res := make([]*T, 0) err := db.Model(&res).Count(&paging.Total).Error if err != nil { return res, paging, err } paging.Computer() if paging.Total == 0 { return res, paging, nil } err = db.Model(&res).Limit(int(paging.Size)).Offset(int(paging.Start)).Find(&res).Error return res, paging, err } func FindWithPage[T any](query *gorm.DB, paging *Pagination) ([]*T, error) { if paging == nil { paging = InitPaging(1, 10) } results := make([]*T, 0) err := query.Model(&results).Count(&paging.Total).Error if err != nil { return nil, err } paging.Computer() if paging.Total == 0 { return results, nil } err = query.Model(&results).Limit(int(paging.Size)).Offset(int(paging.Start)).Find(&results).Error return results, err } // 分页获取所有数据 适用于多条数据 const queryPageSize int64 = 200000 // 批量查询数据最大条数 func FindAllWithBatch[T any](db *gorm.DB) ([]*T, error) { count := CountRow[T](db) // 分页循环读取用户数据 paging := &Pagination{ Size: queryPageSize, Total: count, } list := make([]*T, 0, count) paging.Computer() if count > 0 { for i := 0; i < int(paging.Count); i++ { items, err := findWithPage[T](db, &Pagination{ Size: queryPageSize, Current: int64(i + 1), Total: count, }) if err != nil { return nil, err } list = append(list, items...) } } return list, nil } func buildEqualDB(db *gorm.DB, args ...interface{}) *gorm.DB { tms := len(args) / 2 if tms > 0 { for i := 0; i < tms; i++ { db = db.Where(fmt.Sprintf("%s = ?", args[i*2]), args[i*2+1]) } } return db } func findWithPage[T any](db *gorm.DB, paging *Pagination) ([]*T, error) { paging.Computer() res := make([]*T, 0) err := db.Model(&res).Limit(int(paging.Size)).Offset(int(paging.Start)).Find(&res).Error return res, err }