package model import ( "context" "gorm.io/gorm" ) // AIUsageRecordInsert 插入AI使用记录 func AIUsageRecordInsert(ctx context.Context, db *gorm.DB, record *AIUsageRecord) (int64, error) { result := db.WithContext(ctx).Create(record) if result.Error != nil { return 0, result.Error } return record.Id, nil } // AIUsageRecordFindByUser 根据用户ID查询使用记录(分页,按创建时间倒序) func AIUsageRecordFindByUser(ctx context.Context, db *gorm.DB, userId int64, page, pageSize int64) ([]AIUsageRecord, int64, error) { var records []AIUsageRecord var total int64 query := db.WithContext(ctx).Model(&AIUsageRecord{}).Where("user_id = ?", userId) if err := query.Count(&total).Error; err != nil { return nil, 0, err } offset := (page - 1) * pageSize if offset < 0 { offset = 0 } err := query.Order("created_at DESC").Offset(int(offset)).Limit(int(pageSize)).Find(&records).Error if err != nil { return nil, 0, err } return records, total, nil } // AIUsageRecordFindList 查询使用记录(支持过滤,admin/user通用) func AIUsageRecordFindList(ctx context.Context, db *gorm.DB, userId int64, modelId, status string, page, pageSize int64) ([]AIUsageRecord, int64, error) { var records []AIUsageRecord var total int64 query := db.WithContext(ctx).Model(&AIUsageRecord{}) if userId > 0 { query = query.Where("user_id = ?", userId) } if modelId != "" { query = query.Where("model_id = ?", modelId) } if status != "" { query = query.Where("status = ?", status) } if err := query.Count(&total).Error; err != nil { return nil, 0, err } offset := (page - 1) * pageSize if offset < 0 { offset = 0 } err := query.Order("created_at DESC").Offset(int(offset)).Limit(int(pageSize)).Find(&records).Error return records, total, err } // AIUsageRecordModelStats 按模型分组统计(指定天数内) type ModelStatResult struct { ModelId string `json:"modelId"` Calls int64 `json:"calls"` InputTokens int64 `json:"inputTokens"` OutputTokens int64 `json:"outputTokens"` TotalCost float64 `json:"totalCost"` } func AIUsageRecordModelStats(ctx context.Context, db *gorm.DB, days int) ([]ModelStatResult, error) { var results []ModelStatResult err := db.WithContext(ctx).Model(&AIUsageRecord{}). Select("model_id, COUNT(*) as calls, SUM(input_tokens) as input_tokens, SUM(output_tokens) as output_tokens, SUM(cost) as total_cost"). Where("created_at >= DATE_SUB(NOW(), INTERVAL ? DAY)", days). Group("model_id"). Order("total_cost DESC"). Find(&results).Error return results, err } // AIUsageRecordDailyStats 按日统计(指定天数内) type DailyStatResult struct { Date string `json:"date"` Calls int64 `json:"calls"` TotalTokens int64 `json:"totalTokens"` TotalCost float64 `json:"totalCost"` } func AIUsageRecordDailyStats(ctx context.Context, db *gorm.DB, days int) ([]DailyStatResult, error) { var results []DailyStatResult err := db.WithContext(ctx).Model(&AIUsageRecord{}). Select("DATE(created_at) as date, COUNT(*) as calls, SUM(input_tokens + output_tokens) as total_tokens, SUM(cost) as total_cost"). Where("created_at >= DATE_SUB(NOW(), INTERVAL ? DAY)", days). Group("DATE(created_at)"). Order("date ASC"). Find(&results).Error return results, err } // AIUsageRecordTotalStats 总体统计(指定天数内) type TotalStatResult struct { TotalCalls int64 `json:"totalCalls"` TotalTokens int64 `json:"totalTokens"` TotalCost float64 `json:"totalCost"` TotalUsers int64 `json:"totalUsers"` } func AIUsageRecordTotalStats(ctx context.Context, db *gorm.DB, days int) (*TotalStatResult, error) { var result TotalStatResult err := db.WithContext(ctx).Model(&AIUsageRecord{}). Select("COUNT(*) as total_calls, COALESCE(SUM(input_tokens + output_tokens), 0) as total_tokens, COALESCE(SUM(cost), 0) as total_cost, COUNT(DISTINCT user_id) as total_users"). Where("created_at >= DATE_SUB(NOW(), INTERVAL ? DAY)", days). Find(&result).Error return &result, err }