com.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. package services
  2. import (
  3. "app/commons/core"
  4. "fmt"
  5. "github.com/gin-gonic/gin"
  6. "gorm.io/gorm"
  7. "math"
  8. )
  9. // 业务库公共服务
  10. func NewComService() *CommonService {
  11. return &CommonService{}
  12. }
  13. type CommonService struct {
  14. }
  15. func (s *CommonService) DB() *gorm.DB {
  16. return core.MainDb()
  17. }
  18. func (s *CommonService) FromContext(ctx *gin.Context) Context {
  19. return Context{Context: ctx}
  20. }
  21. // 分页器
  22. type Pagination struct {
  23. Current int64 `json:"current" query:"current" form:"current" ` //当前页
  24. Size int64 `json:"size" query:"size" form:"size" ` //每页条数
  25. Total int64 `json:"total" query:"total" form:"total" ` //总条数
  26. Count int64 `json:"count" query:"count" form:"count" ` //总页数
  27. Start int64 `json:"start" query:"start" form:"start" ` //起始条数
  28. }
  29. func NewPagination() *Pagination {
  30. return &Pagination{}
  31. }
  32. func NewPagingWithCurrentSize(current, size int64) *Pagination {
  33. return &Pagination{Current: current, Start: size}
  34. }
  35. func InitPaging(p, s int64) *Pagination {
  36. return &Pagination{Current: p, Size: s}
  37. }
  38. func (p *Pagination) Computer() {
  39. if p.Current < 1 {
  40. p.Current = 1
  41. }
  42. if p.Size < 1 {
  43. p.Size = 10
  44. }
  45. p.Start = p.Size * (p.Current - 1)
  46. count := math.Ceil(float64(p.Total) / float64(p.Size))
  47. p.Count = int64(count)
  48. }
  49. // 获取单条记录
  50. func GetOne[T any](db *gorm.DB, args ...interface{}) (*T, error) {
  51. db = buildEqualDB(db, args...)
  52. r := new(T)
  53. if err := db.First(&r).Error; err != nil {
  54. return r, err
  55. }
  56. return r, nil
  57. }
  58. // 获取最后一条记录
  59. func GetLast[T any](db *gorm.DB, args ...interface{}) (*T, error) {
  60. db = buildEqualDB(db, args...)
  61. r := new(T)
  62. if err := db.Last(&r).Error; err != nil {
  63. return r, err
  64. }
  65. return r, nil
  66. }
  67. // 统计条数
  68. func CountRow[T any](db *gorm.DB, args ...interface{}) int64 {
  69. db = buildEqualDB(db, args...)
  70. r := new(T)
  71. var total int64 = 0
  72. db.Model(&r).Count(&total)
  73. return total
  74. }
  75. // 列表查询
  76. func Find[T any](db *gorm.DB, args ...interface{}) ([]*T, error) {
  77. db = buildEqualDB(db, args...)
  78. res := make([]*T, 0)
  79. var total int64
  80. err := db.Model(&res).Count(&total).Error
  81. if err != nil {
  82. return res, err
  83. }
  84. if total == 0 {
  85. return res, nil
  86. }
  87. if err := db.Find(&res).Error; err != nil {
  88. return res, err
  89. }
  90. return res, nil
  91. }
  92. // 分页查询
  93. // 可带入简单查询条件
  94. func FindWithPageAndQuery[T any](db *gorm.DB, paging *Pagination, args ...interface{}) ([]*T, *Pagination, error) {
  95. if paging == nil {
  96. paging = InitPaging(1, 10)
  97. }
  98. db = buildEqualDB(db, args...)
  99. res := make([]*T, 0)
  100. err := db.Model(&res).Count(&paging.Total).Error
  101. if err != nil {
  102. return res, paging, err
  103. }
  104. paging.Computer()
  105. if paging.Total == 0 {
  106. return res, paging, nil
  107. }
  108. err = db.Model(&res).Limit(int(paging.Size)).Offset(int(paging.Start)).Find(&res).Error
  109. return res, paging, err
  110. }
  111. func FindWithPage[T any](query *gorm.DB, paging *Pagination) ([]*T, error) {
  112. if paging == nil {
  113. paging = InitPaging(1, 10)
  114. }
  115. results := make([]*T, 0)
  116. err := query.Model(&results).Count(&paging.Total).Error
  117. if err != nil {
  118. return nil, err
  119. }
  120. paging.Computer()
  121. if paging.Total == 0 {
  122. return results, nil
  123. }
  124. err = query.Model(&results).Limit(int(paging.Size)).Offset(int(paging.Start)).Find(&results).Error
  125. return results, err
  126. }
  127. // 分页获取所有数据 适用于多条数据
  128. const queryPageSize int64 = 200000 // 批量查询数据最大条数
  129. func FindAllWithBatch[T any](db *gorm.DB) ([]*T, error) {
  130. count := CountRow[T](db)
  131. // 分页循环读取用户数据
  132. paging := &Pagination{
  133. Size: queryPageSize,
  134. Total: count,
  135. }
  136. list := make([]*T, 0, count)
  137. paging.Computer()
  138. if count > 0 {
  139. for i := 0; i < int(paging.Count); i++ {
  140. items, err := findWithPage[T](db, &Pagination{
  141. Size: queryPageSize,
  142. Current: int64(i + 1),
  143. Total: count,
  144. })
  145. if err != nil {
  146. return nil, err
  147. }
  148. list = append(list, items...)
  149. }
  150. }
  151. return list, nil
  152. }
  153. func buildEqualDB(db *gorm.DB, args ...interface{}) *gorm.DB {
  154. tms := len(args) / 2
  155. if tms > 0 {
  156. for i := 0; i < tms; i++ {
  157. db = db.Where(fmt.Sprintf("%s = ?", args[i*2]), args[i*2+1])
  158. }
  159. }
  160. return db
  161. }
  162. func findWithPage[T any](db *gorm.DB, paging *Pagination) ([]*T, error) {
  163. paging.Computer()
  164. res := make([]*T, 0)
  165. err := db.Model(&res).Limit(int(paging.Size)).Offset(int(paging.Start)).Find(&res).Error
  166. return res, err
  167. }