mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-09-29 22:56:39 +08:00
123 lines
2.6 KiB
Go
123 lines
2.6 KiB
Go
package model
|
|
|
|
import (
|
|
"fmt"
|
|
"one-api/common"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type modelable interface {
|
|
any
|
|
}
|
|
|
|
type GenericParams struct {
|
|
PaginationParams
|
|
Keyword string `form:"keyword"`
|
|
}
|
|
|
|
type PaginationParams struct {
|
|
Page int `form:"page"`
|
|
Size int `form:"size"`
|
|
Order string `form:"order"`
|
|
}
|
|
|
|
type DataResult[T modelable] struct {
|
|
Data *[]*T `json:"data"`
|
|
Page int `json:"page"`
|
|
Size int `json:"size"`
|
|
TotalCount int64 `json:"total_count"`
|
|
}
|
|
|
|
func PaginateAndOrder[T modelable](db *gorm.DB, params *PaginationParams, result *[]*T, allowedOrderFields map[string]bool) (*DataResult[T], error) {
|
|
// 获取总数
|
|
var totalCount int64
|
|
err := db.Model(result).Count(&totalCount).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 分页
|
|
if params.Page < 1 {
|
|
params.Page = 1
|
|
}
|
|
if params.Size < 1 {
|
|
params.Size = common.ItemsPerPage
|
|
}
|
|
|
|
if params.Size > common.MaxRecentItems {
|
|
return nil, fmt.Errorf("size 参数不能超过 %d", common.MaxRecentItems)
|
|
}
|
|
|
|
offset := (params.Page - 1) * params.Size
|
|
db = db.Offset(offset).Limit(params.Size)
|
|
|
|
// 排序
|
|
if params.Order != "" {
|
|
orderFields := strings.Split(params.Order, ",")
|
|
for _, field := range orderFields {
|
|
field = strings.TrimSpace(field)
|
|
desc := strings.HasPrefix(field, "-")
|
|
if desc {
|
|
field = field[1:]
|
|
}
|
|
if !allowedOrderFields[field] {
|
|
return nil, fmt.Errorf("不允许对字段 '%s' 进行排序", field)
|
|
}
|
|
if desc {
|
|
field = field + " DESC"
|
|
}
|
|
db = db.Order(field)
|
|
}
|
|
} else {
|
|
// 默认排序
|
|
db = db.Order("id DESC")
|
|
}
|
|
|
|
// 查询
|
|
err = db.Find(result).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 返回结果
|
|
return &DataResult[T]{
|
|
Data: result,
|
|
Page: params.Page,
|
|
Size: params.Size,
|
|
TotalCount: totalCount,
|
|
}, nil
|
|
}
|
|
|
|
func getDateFormat(groupType string) string {
|
|
var dateFormat string
|
|
if groupType == "day" {
|
|
dateFormat = "%Y-%m-%d"
|
|
if common.UsingPostgreSQL {
|
|
dateFormat = "YYYY-MM-DD"
|
|
}
|
|
} else {
|
|
dateFormat = "%Y-%m"
|
|
if common.UsingPostgreSQL {
|
|
dateFormat = "YYYY-MM"
|
|
}
|
|
}
|
|
return dateFormat
|
|
}
|
|
|
|
func getTimestampGroupsSelect(fieldName, groupType, alias string) string {
|
|
dateFormat := getDateFormat(groupType)
|
|
var groupSelect string
|
|
|
|
if common.UsingPostgreSQL {
|
|
groupSelect = fmt.Sprintf(`TO_CHAR(date_trunc('%s', to_timestamp(%s)), '%s') as %s`, groupType, fieldName, dateFormat, alias)
|
|
} else if common.UsingSQLite {
|
|
groupSelect = fmt.Sprintf(`strftime('%s', datetime(%s, 'unixepoch')) as %s`, dateFormat, fieldName, alias)
|
|
} else {
|
|
groupSelect = fmt.Sprintf(`DATE_FORMAT(FROM_UNIXTIME(%s), '%s') as %s`, fieldName, dateFormat, alias)
|
|
}
|
|
|
|
return groupSelect
|
|
}
|