Files
gpt-plus-gpt/internal/db/query.go
2026-03-15 20:48:19 +08:00

145 lines
4.0 KiB
Go

package db
import (
"time"
"gorm.io/gorm"
)
type PaginationParams struct {
Page int
Size int
}
func (p *PaginationParams) Normalize() {
if p.Page < 1 {
p.Page = 1
}
if p.Size < 1 || p.Size > 100 {
p.Size = 20
}
}
func (p *PaginationParams) Offset() int {
return (p.Page - 1) * p.Size
}
type PaginatedResult struct {
Items interface{} `json:"items"`
Total int64 `json:"total"`
Page int `json:"page"`
Size int `json:"size"`
}
func Paginate(db *gorm.DB, p PaginationParams, dest interface{}) (*PaginatedResult, error) {
p.Normalize()
var total int64
if err := db.Count(&total).Error; err != nil {
return nil, err
}
if err := db.Offset(p.Offset()).Limit(p.Size).Find(dest).Error; err != nil {
return nil, err
}
return &PaginatedResult{
Items: dest,
Total: total,
Page: p.Page,
Size: p.Size,
}, nil
}
// Dashboard stats
type DashboardStats struct {
TotalAccounts int64 `json:"total_accounts"`
PlusCount int64 `json:"plus_count"`
TeamCount int64 `json:"team_count"`
TodayRegistrations int64 `json:"today_registrations"`
SuccessRate float64 `json:"success_rate"`
ActiveTask *Task `json:"active_task"`
RecentTasks []Task `json:"recent_tasks"`
}
func GetDashboardStats(db *gorm.DB) (*DashboardStats, error) {
stats := &DashboardStats{}
db.Model(&Account{}).Count(&stats.TotalAccounts)
db.Model(&Account{}).Where("plan = ?", "plus").Count(&stats.PlusCount)
db.Model(&Account{}).Where("plan IN ?", []string{"team_owner", "team_member"}).Count(&stats.TeamCount)
today := time.Now().Truncate(24 * time.Hour)
db.Model(&Account{}).Where("created_at >= ?", today).Count(&stats.TodayRegistrations)
var totalLogs, successLogs int64
db.Model(&TaskLog{}).Count(&totalLogs)
db.Model(&TaskLog{}).Where("status = ?", "success").Count(&successLogs)
if totalLogs > 0 {
stats.SuccessRate = float64(successLogs) / float64(totalLogs) * 100
}
var activeTask Task
if err := db.Where("status IN ?", []string{"running", "stopping"}).First(&activeTask).Error; err == nil {
stats.ActiveTask = &activeTask
}
db.Order("created_at DESC").Limit(5).Find(&stats.RecentTasks)
return stats, nil
}
// Card stats
type CardStats struct {
Total int64 `json:"total"`
Available int64 `json:"available"`
Active int64 `json:"active"`
Exhausted int64 `json:"exhausted"`
Rejected int64 `json:"rejected"`
Expired int64 `json:"expired"`
Disabled int64 `json:"disabled"`
}
func GetCardStats(db *gorm.DB) *CardStats {
s := &CardStats{}
db.Model(&Card{}).Count(&s.Total)
db.Model(&Card{}).Where("status = ?", "available").Count(&s.Available)
db.Model(&Card{}).Where("status = ?", "active").Count(&s.Active)
db.Model(&Card{}).Where("status = ?", "exhausted").Count(&s.Exhausted)
db.Model(&Card{}).Where("status = ?", "rejected").Count(&s.Rejected)
db.Model(&Card{}).Where("status = ?", "expired").Count(&s.Expired)
db.Model(&Card{}).Where("status = ?", "disabled").Count(&s.Disabled)
return s
}
type CardCodeStats struct {
Total int64 `json:"total"`
Unused int64 `json:"unused"`
Redeemed int64 `json:"redeemed"`
Failed int64 `json:"failed"`
}
func GetCardCodeStats(db *gorm.DB) *CardCodeStats {
s := &CardCodeStats{}
db.Model(&CardCode{}).Count(&s.Total)
db.Model(&CardCode{}).Where("status = ?", "unused").Count(&s.Unused)
db.Model(&CardCode{}).Where("status = ?", "redeemed").Count(&s.Redeemed)
db.Model(&CardCode{}).Where("status = ?", "failed").Count(&s.Failed)
return s
}
type EmailRecordStats struct {
Total int64 `json:"total"`
Used int64 `json:"used"`
UsedMember int64 `json:"used_member"`
UsedFailed int64 `json:"used_failed"`
}
func GetEmailRecordStats(db *gorm.DB) *EmailRecordStats {
s := &EmailRecordStats{}
db.Model(&EmailRecord{}).Count(&s.Total)
db.Model(&EmailRecord{}).Where("status = ?", "used").Count(&s.Used)
db.Model(&EmailRecord{}).Where("status = ?", "used_member").Count(&s.UsedMember)
db.Model(&EmailRecord{}).Where("status = ?", "used_failed").Count(&s.UsedFailed)
return s
}