feat: support paging / sorting (#64)

*  feat: support paging / sorting

* 🔥 del: delete unused files
This commit is contained in:
Buer
2024-02-08 03:41:51 +08:00
committed by GitHub
parent 3789c30154
commit 57cd68e7e3
28 changed files with 796 additions and 691 deletions

View File

@@ -29,23 +29,35 @@ type Channel struct {
TestModel string `json:"test_model" gorm:"type:varchar(50);default:''"`
}
func GetAllChannels(startIdx int, num int, selectAll bool) ([]*Channel, error) {
var channels []*Channel
var err error
if selectAll {
err = DB.Order("id desc").Find(&channels).Error
} else {
err = DB.Order("id desc").Limit(num).Offset(startIdx).Omit("key").Find(&channels).Error
}
return channels, err
var allowedChannelOrderFields = map[string]bool{
"id": true,
"name": true,
"group": true,
"type": true,
"status": true,
"response_time": true,
"balance": true,
"priority": true,
}
func SearchChannels(keyword string) (channels []*Channel, err error) {
keyCol := "`key`"
if common.UsingPostgreSQL {
keyCol = `"key"`
func GetChannelsList(params *GenericParams) (*DataResult, error) {
var channels []*Channel
db := DB.Omit("key")
if params.Keyword != "" {
keyCol := "`key`"
if common.UsingPostgreSQL {
keyCol = `"key"`
}
db = db.Where("id = ? or name LIKE ? or "+keyCol+" = ?", common.String2Int(params.Keyword), params.Keyword+"%", params.Keyword)
}
err = DB.Omit("key").Where("id = ? or name LIKE ? or "+keyCol+" = ?", common.String2Int(keyword), keyword+"%", keyword).Find(&channels).Error
return PaginateAndOrder(db, &params.PaginationParams, &channels, allowedChannelOrderFields)
}
func GetAllChannels() ([]*Channel, error) {
var channels []*Channel
err := DB.Order("id desc").Find(&channels).Error
return channels, err
}

View File

@@ -3,8 +3,91 @@ package model
import (
"fmt"
"one-api/common"
"strings"
"gorm.io/gorm"
)
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 struct {
Data interface{} `json:"data"`
Page int `json:"page"`
Size int `json:"size"`
TotalCount int64 `json:"total_count"`
}
func PaginateAndOrder(db *gorm.DB, params *PaginationParams, result interface{}, allowedOrderFields map[string]bool) (*DataResult, error) {
// 获取总数
var totalCount int64
err := db.Model(result).Count(&totalCount).Error
if err != nil {
return nil, err
}
fmt.Println("totalCount", totalCount)
// 分页
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{
Data: result,
Page: params.Page,
Size: params.Size,
TotalCount: totalCount,
}, nil
}
func getDateFormat(groupType string) string {
var dateFormat string
if groupType == "day" {

View File

@@ -74,56 +74,79 @@ func RecordConsumeLog(ctx context.Context, userId int, channelId int, promptToke
}
}
func GetAllLogs(logType int, startTimestamp int64, endTimestamp int64, modelName string, username string, tokenName string, startIdx int, num int, channel int) (logs []*Log, err error) {
var tx *gorm.DB
if logType == LogTypeUnknown {
tx = DB
} else {
tx = DB.Where("type = ?", logType)
}
if modelName != "" {
tx = tx.Where("model_name = ?", modelName)
}
if username != "" {
tx = tx.Where("username = ?", username)
}
if tokenName != "" {
tx = tx.Where("token_name = ?", tokenName)
}
if startTimestamp != 0 {
tx = tx.Where("created_at >= ?", startTimestamp)
}
if endTimestamp != 0 {
tx = tx.Where("created_at <= ?", endTimestamp)
}
if channel != 0 {
tx = tx.Where("channel_id = ?", channel)
}
err = tx.Order("id desc").Limit(num).Offset(startIdx).Find(&logs).Error
return logs, err
type LogsListParams struct {
PaginationParams
LogType int `form:"log_type"`
StartTimestamp int64 `form:"start_timestamp"`
EndTimestamp int64 `form:"end_timestamp"`
ModelName string `form:"model_name"`
Username string `form:"username"`
TokenName string `form:"token_name"`
Channel int `form:"channel"`
}
func GetUserLogs(userId int, logType int, startTimestamp int64, endTimestamp int64, modelName string, tokenName string, startIdx int, num int) (logs []*Log, err error) {
var allowedLogsOrderFields = map[string]bool{
"created_at": true,
"channel_id": true,
"user_id": true,
"token_name": true,
"model_name": true,
"type": true,
}
func GetLogsList(params *LogsListParams) (*DataResult, error) {
var tx *gorm.DB
if logType == LogTypeUnknown {
tx = DB.Where("user_id = ?", userId)
var logs []*Log
if params.LogType == LogTypeUnknown {
tx = DB
} else {
tx = DB.Where("user_id = ? and type = ?", userId, logType)
tx = DB.Where("type = ?", params.LogType)
}
if modelName != "" {
tx = tx.Where("model_name = ?", modelName)
if params.ModelName != "" {
tx = tx.Where("model_name = ?", params.ModelName)
}
if tokenName != "" {
tx = tx.Where("token_name = ?", tokenName)
if params.Username != "" {
tx = tx.Where("username = ?", params.Username)
}
if startTimestamp != 0 {
tx = tx.Where("created_at >= ?", startTimestamp)
if params.TokenName != "" {
tx = tx.Where("token_name = ?", params.TokenName)
}
if endTimestamp != 0 {
tx = tx.Where("created_at <= ?", endTimestamp)
if params.StartTimestamp != 0 {
tx = tx.Where("created_at >= ?", params.StartTimestamp)
}
err = tx.Order("id desc").Limit(num).Offset(startIdx).Omit("id").Find(&logs).Error
return logs, err
if params.EndTimestamp != 0 {
tx = tx.Where("created_at <= ?", params.EndTimestamp)
}
if params.Channel != 0 {
tx = tx.Where("channel_id = ?", params.Channel)
}
return PaginateAndOrder(tx, &params.PaginationParams, &logs, allowedLogsOrderFields)
}
func GetUserLogsList(userId int, params *LogsListParams) (*DataResult, error) {
var logs []*Log
tx := DB.Where("user_id = ?", userId).Omit("id")
if params.LogType != LogTypeUnknown {
tx = DB.Where("type = ?", params.LogType)
}
if params.ModelName != "" {
tx = tx.Where("model_name = ?", params.ModelName)
}
if params.TokenName != "" {
tx = tx.Where("token_name = ?", params.TokenName)
}
if params.StartTimestamp != 0 {
tx = tx.Where("created_at >= ?", params.StartTimestamp)
}
if params.EndTimestamp != 0 {
tx = tx.Where("created_at <= ?", params.EndTimestamp)
}
return PaginateAndOrder(tx, &params.PaginationParams, &logs, allowedLogsOrderFields)
}
func SearchAllLogs(keyword string) (logs []*Log, err error) {

View File

@@ -20,16 +20,23 @@ type Redemption struct {
Count int `json:"count" gorm:"-:all"` // only for api request
}
func GetAllRedemptions(startIdx int, num int) ([]*Redemption, error) {
var redemptions []*Redemption
var err error
err = DB.Order("id desc").Limit(num).Offset(startIdx).Find(&redemptions).Error
return redemptions, err
var allowedRedemptionslOrderFields = map[string]bool{
"id": true,
"name": true,
"status": true,
"quota": true,
"created_time": true,
"redeemed_time": true,
}
func SearchRedemptions(keyword string) (redemptions []*Redemption, err error) {
err = DB.Where("id = ? or name LIKE ?", common.String2Int(keyword), keyword+"%").Find(&redemptions).Error
return redemptions, err
func GetRedemptionsList(params *GenericParams) (*DataResult, error) {
var redemptions []*Redemption
db := DB
if params.Keyword != "" {
db = db.Where("id = ? or name LIKE ?", common.String2Int(params.Keyword), params.Keyword+"%")
}
return PaginateAndOrder(db, &params.PaginationParams, &redemptions, allowedRedemptionslOrderFields)
}
func GetRedemptionById(id int) (*Redemption, error) {

View File

@@ -22,16 +22,25 @@ type Token struct {
UsedQuota int `json:"used_quota" gorm:"default:0"` // used quota
}
func GetAllUserTokens(userId int, startIdx int, num int) ([]*Token, error) {
var tokens []*Token
var err error
err = DB.Where("user_id = ?", userId).Order("id desc").Limit(num).Offset(startIdx).Find(&tokens).Error
return tokens, err
var allowedTokenOrderFields = map[string]bool{
"id": true,
"name": true,
"status": true,
"expired_time": true,
"created_time": true,
"remain_quota": true,
"used_quota": true,
}
func SearchUserTokens(userId int, keyword string) (tokens []*Token, err error) {
err = DB.Where("user_id = ?", userId).Where("name LIKE ?", keyword+"%").Find(&tokens).Error
return tokens, err
func GetUserTokensList(userId int, params *GenericParams) (*DataResult, error) {
var tokens []*Token
db := DB.Where("user_id = ?", userId)
if params.Keyword != "" {
db = db.Where("name LIKE ?", params.Keyword+"%")
}
return PaginateAndOrder(db, &params.PaginationParams, &tokens, allowedTokenOrderFields)
}
func ValidateUserToken(key string) (token *Token, err error) {

View File

@@ -38,15 +38,22 @@ func GetMaxUserId() int {
return user.Id
}
func GetAllUsers(startIdx int, num int) (users []*User, err error) {
err = DB.Order("id desc").Limit(num).Offset(startIdx).Omit("password").Find(&users).Error
return users, err
var allowedUserOrderFields = map[string]bool{
"id": true,
"username": true,
"role": true,
"status": true,
"created_time": true,
}
func SearchUsers(keyword string) (users []*User, err error) {
err = DB.Omit("password").Where("id = ? or username LIKE ? or email LIKE ? or display_name LIKE ?", common.String2Int(keyword), keyword+"%", keyword+"%", keyword+"%").Find(&users).Error
func GetUsersList(params *GenericParams) (*DataResult, error) {
var users []*User
db := DB.Omit("password")
if params.Keyword != "" {
db = db.Where("id = ? or username LIKE ? or email LIKE ? or display_name LIKE ?", common.String2Int(params.Keyword), params.Keyword+"%", params.Keyword+"%", params.Keyword+"%")
}
return users, err
return PaginateAndOrder(db, &params.PaginationParams, &users, allowedUserOrderFields)
}
func GetUserById(id int, selectAll bool) (*User, error) {