usedata.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package model
  2. import (
  3. "fmt"
  4. "gorm.io/gorm"
  5. "one-api/common"
  6. "one-api/logger"
  7. "sync"
  8. "time"
  9. )
  10. // QuotaData 柱状图数据
  11. type QuotaData struct {
  12. Id int `json:"id"`
  13. UserID int `json:"user_id" gorm:"index"`
  14. Username string `json:"username" gorm:"index:idx_qdt_model_user_name,priority:2;size:64;default:''"`
  15. ModelName string `json:"model_name" gorm:"index:idx_qdt_model_user_name,priority:1;size:64;default:''"`
  16. CreatedAt int64 `json:"created_at" gorm:"bigint;index:idx_qdt_created_at,priority:2"`
  17. TokenUsed int `json:"token_used" gorm:"default:0"`
  18. Count int `json:"count" gorm:"default:0"`
  19. Quota int `json:"quota" gorm:"default:0"`
  20. }
  21. func UpdateQuotaData() {
  22. // recover
  23. defer func() {
  24. if r := recover(); r != nil {
  25. logger.SysLog(fmt.Sprintf("UpdateQuotaData panic: %s", r))
  26. }
  27. }()
  28. for {
  29. if common.DataExportEnabled {
  30. logger.SysLog("正在更新数据看板数据...")
  31. SaveQuotaDataCache()
  32. }
  33. time.Sleep(time.Duration(common.DataExportInterval) * time.Minute)
  34. }
  35. }
  36. var CacheQuotaData = make(map[string]*QuotaData)
  37. var CacheQuotaDataLock = sync.Mutex{}
  38. func logQuotaDataCache(userId int, username string, modelName string, quota int, createdAt int64, tokenUsed int) {
  39. key := fmt.Sprintf("%d-%s-%s-%d", userId, username, modelName, createdAt)
  40. quotaData, ok := CacheQuotaData[key]
  41. if ok {
  42. quotaData.Count += 1
  43. quotaData.Quota += quota
  44. quotaData.TokenUsed += tokenUsed
  45. } else {
  46. quotaData = &QuotaData{
  47. UserID: userId,
  48. Username: username,
  49. ModelName: modelName,
  50. CreatedAt: createdAt,
  51. Count: 1,
  52. Quota: quota,
  53. TokenUsed: tokenUsed,
  54. }
  55. }
  56. CacheQuotaData[key] = quotaData
  57. }
  58. func LogQuotaData(userId int, username string, modelName string, quota int, createdAt int64, tokenUsed int) {
  59. // 只精确到小时
  60. createdAt = createdAt - (createdAt % 3600)
  61. CacheQuotaDataLock.Lock()
  62. defer CacheQuotaDataLock.Unlock()
  63. logQuotaDataCache(userId, username, modelName, quota, createdAt, tokenUsed)
  64. }
  65. func SaveQuotaDataCache() {
  66. CacheQuotaDataLock.Lock()
  67. defer CacheQuotaDataLock.Unlock()
  68. size := len(CacheQuotaData)
  69. // 如果缓存中有数据,就保存到数据库中
  70. // 1. 先查询数据库中是否有数据
  71. // 2. 如果有数据,就更新数据
  72. // 3. 如果没有数据,就插入数据
  73. for _, quotaData := range CacheQuotaData {
  74. quotaDataDB := &QuotaData{}
  75. DB.Table("quota_data").Where("user_id = ? and username = ? and model_name = ? and created_at = ?",
  76. quotaData.UserID, quotaData.Username, quotaData.ModelName, quotaData.CreatedAt).First(quotaDataDB)
  77. if quotaDataDB.Id > 0 {
  78. //quotaDataDB.Count += quotaData.Count
  79. //quotaDataDB.Quota += quotaData.Quota
  80. //DB.Table("quota_data").Save(quotaDataDB)
  81. increaseQuotaData(quotaData.UserID, quotaData.Username, quotaData.ModelName, quotaData.Count, quotaData.Quota, quotaData.CreatedAt, quotaData.TokenUsed)
  82. } else {
  83. DB.Table("quota_data").Create(quotaData)
  84. }
  85. }
  86. CacheQuotaData = make(map[string]*QuotaData)
  87. logger.SysLog(fmt.Sprintf("保存数据看板数据成功,共保存%d条数据", size))
  88. }
  89. func increaseQuotaData(userId int, username string, modelName string, count int, quota int, createdAt int64, tokenUsed int) {
  90. err := DB.Table("quota_data").Where("user_id = ? and username = ? and model_name = ? and created_at = ?",
  91. userId, username, modelName, createdAt).Updates(map[string]interface{}{
  92. "count": gorm.Expr("count + ?", count),
  93. "quota": gorm.Expr("quota + ?", quota),
  94. "token_used": gorm.Expr("token_used + ?", tokenUsed),
  95. }).Error
  96. if err != nil {
  97. logger.SysLog(fmt.Sprintf("increaseQuotaData error: %s", err))
  98. }
  99. }
  100. func GetQuotaDataByUsername(username string, startTime int64, endTime int64) (quotaData []*QuotaData, err error) {
  101. var quotaDatas []*QuotaData
  102. // 从quota_data表中查询数据
  103. err = DB.Table("quota_data").Where("username = ? and created_at >= ? and created_at <= ?", username, startTime, endTime).Find(&quotaDatas).Error
  104. return quotaDatas, err
  105. }
  106. func GetQuotaDataByUserId(userId int, startTime int64, endTime int64) (quotaData []*QuotaData, err error) {
  107. var quotaDatas []*QuotaData
  108. // 从quota_data表中查询数据
  109. err = DB.Table("quota_data").Where("user_id = ? and created_at >= ? and created_at <= ?", userId, startTime, endTime).Find(&quotaDatas).Error
  110. return quotaDatas, err
  111. }
  112. func GetAllQuotaDates(startTime int64, endTime int64, username string) (quotaData []*QuotaData, err error) {
  113. if username != "" {
  114. return GetQuotaDataByUsername(username, startTime, endTime)
  115. }
  116. var quotaDatas []*QuotaData
  117. // 从quota_data表中查询数据
  118. // 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;
  119. //err = DB.Table("quota_data").Where("created_at >= ? and created_at <= ?", startTime, endTime).Find(&quotaDatas).Error
  120. 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(&quotaDatas).Error
  121. return quotaDatas, err
  122. }