| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- 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
- }
|