| package model |
|
|
| import ( |
| "fmt" |
| "sync" |
| "time" |
|
|
| "github.com/QuantumNous/new-api/common" |
| "gorm.io/gorm" |
| ) |
|
|
| |
| type QuotaData struct { |
| Id int `json:"id"` |
| UserID int `json:"user_id" gorm:"index"` |
| Username string `json:"username" gorm:"index:idx_qdt_model_user_name,priority:2;size:64;default:''"` |
| ModelName string `json:"model_name" gorm:"index:idx_qdt_model_user_name,priority:1;size:64;default:''"` |
| CreatedAt int64 `json:"created_at" gorm:"bigint;index:idx_qdt_created_at,priority:2"` |
| TokenUsed int `json:"token_used" gorm:"default:0"` |
| Count int `json:"count" gorm:"default:0"` |
| Quota int `json:"quota" gorm:"default:0"` |
| } |
|
|
| func UpdateQuotaData() { |
| for { |
| if common.DataExportEnabled { |
| common.SysLog("正在更新数据看板数据...") |
| SaveQuotaDataCache() |
| } |
| time.Sleep(time.Duration(common.DataExportInterval) * time.Minute) |
| } |
| } |
|
|
| var CacheQuotaData = make(map[string]*QuotaData) |
| var CacheQuotaDataLock = sync.Mutex{} |
|
|
| func logQuotaDataCache(userId int, username string, modelName string, quota int, createdAt int64, tokenUsed int) { |
| key := fmt.Sprintf("%d-%s-%s-%d", userId, username, modelName, createdAt) |
| quotaData, ok := CacheQuotaData[key] |
| if ok { |
| quotaData.Count += 1 |
| quotaData.Quota += quota |
| quotaData.TokenUsed += tokenUsed |
| } else { |
| quotaData = &QuotaData{ |
| UserID: userId, |
| Username: username, |
| ModelName: modelName, |
| CreatedAt: createdAt, |
| Count: 1, |
| Quota: quota, |
| TokenUsed: tokenUsed, |
| } |
| } |
| CacheQuotaData[key] = quotaData |
| } |
|
|
| func LogQuotaData(userId int, username string, modelName string, quota int, createdAt int64, tokenUsed int) { |
| |
| createdAt = createdAt - (createdAt % 3600) |
|
|
| CacheQuotaDataLock.Lock() |
| defer CacheQuotaDataLock.Unlock() |
| logQuotaDataCache(userId, username, modelName, quota, createdAt, tokenUsed) |
| } |
|
|
| func SaveQuotaDataCache() { |
| CacheQuotaDataLock.Lock() |
| defer CacheQuotaDataLock.Unlock() |
| size := len(CacheQuotaData) |
| |
| |
| |
| |
| for _, quotaData := range CacheQuotaData { |
| quotaDataDB := &QuotaData{} |
| DB.Table("quota_data").Where("user_id = ? and username = ? and model_name = ? and created_at = ?", |
| quotaData.UserID, quotaData.Username, quotaData.ModelName, quotaData.CreatedAt).First(quotaDataDB) |
| if quotaDataDB.Id > 0 { |
| |
| |
| |
| increaseQuotaData(quotaData.UserID, quotaData.Username, quotaData.ModelName, quotaData.Count, quotaData.Quota, quotaData.CreatedAt, quotaData.TokenUsed) |
| } else { |
| DB.Table("quota_data").Create(quotaData) |
| } |
| } |
| CacheQuotaData = make(map[string]*QuotaData) |
| common.SysLog(fmt.Sprintf("保存数据看板数据成功,共保存%d条数据", size)) |
| } |
|
|
| func increaseQuotaData(userId int, username string, modelName string, count int, quota int, createdAt int64, tokenUsed int) { |
| err := DB.Table("quota_data").Where("user_id = ? and username = ? and model_name = ? and created_at = ?", |
| userId, username, modelName, createdAt).Updates(map[string]interface{}{ |
| "count": gorm.Expr("count + ?", count), |
| "quota": gorm.Expr("quota + ?", quota), |
| "token_used": gorm.Expr("token_used + ?", tokenUsed), |
| }).Error |
| if err != nil { |
| common.SysLog(fmt.Sprintf("increaseQuotaData error: %s", err)) |
| } |
| } |
|
|
| func GetQuotaDataByUsername(username string, startTime int64, endTime int64) (quotaData []*QuotaData, err error) { |
| var quotaDatas []*QuotaData |
| |
| err = DB.Table("quota_data").Where("username = ? and created_at >= ? and created_at <= ?", username, startTime, endTime).Find("aDatas).Error |
| return quotaDatas, err |
| } |
|
|
| func GetQuotaDataByUserId(userId int, startTime int64, endTime int64) (quotaData []*QuotaData, err error) { |
| var quotaDatas []*QuotaData |
| |
| err = DB.Table("quota_data").Where("user_id = ? and created_at >= ? and created_at <= ?", userId, startTime, endTime).Find("aDatas).Error |
| return quotaDatas, err |
| } |
|
|
| func GetAllQuotaDates(startTime int64, endTime int64, username string) (quotaData []*QuotaData, err error) { |
| if username != "" { |
| return GetQuotaDataByUsername(username, startTime, endTime) |
| } |
| var quotaDatas []*QuotaData |
| |
| |
| |
| err = DB.Table("quota_data").Select("model_name, sum(count) as count, sum(quota) as quota, sum(token_used) as token_used, created_at").Where("created_at >= ? and created_at <= ?", startTime, endTime).Group("model_name, created_at").Find("aDatas).Error |
| return quotaDatas, err |
| } |
|
|