- Updated the `increaseQuotaData` function to include `tokenUsed` parameter for better quota tracking. - Modified the `GetAllQuotaDates` function to sum `token_used` alongside `count` and `quota` for comprehensive data retrieval. - Improved CSS styles for better layout responsiveness, including padding adjustments for navigation elements and description cards.
134 lines
5.0 KiB
Go
134 lines
5.0 KiB
Go
package model
|
||
|
||
import (
|
||
"fmt"
|
||
"gorm.io/gorm"
|
||
"one-api/common"
|
||
"sync"
|
||
"time"
|
||
)
|
||
|
||
// QuotaData 柱状图数据
|
||
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() {
|
||
// recover
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
common.SysLog(fmt.Sprintf("UpdateQuotaData panic: %s", r))
|
||
}
|
||
}()
|
||
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)
|
||
// 如果缓存中有数据,就保存到数据库中
|
||
// 1. 先查询数据库中是否有数据
|
||
// 2. 如果有数据,就更新数据
|
||
// 3. 如果没有数据,就插入数据
|
||
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 {
|
||
//quotaDataDB.Count += quotaData.Count
|
||
//quotaDataDB.Quota += quotaData.Quota
|
||
//DB.Table("quota_data").Save(quotaDataDB)
|
||
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
|
||
// 从quota_data表中查询数据
|
||
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
|
||
// 从quota_data表中查询数据
|
||
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
|
||
// 从quota_data表中查询数据
|
||
// only select model_name, sum(count) as count, sum(quota) as quota, model_name, created_at from quota_data group by model_name, created_at;
|
||
//err = DB.Table("quota_data").Where("created_at >= ? and created_at <= ?", startTime, endTime).Find("aDatas).Error
|
||
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
|
||
}
|