選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

112 行
3.5 KiB

  1. package model
  2. import (
  3. "github.com/QuantumNous/new-api/common"
  4. "gorm.io/gorm"
  5. "gorm.io/gorm/clause"
  6. )
  7. // QuotaType 计费类型
  8. const (
  9. QuotaTypeByTokens = 0 // 按量计费
  10. QuotaTypeByCall = 1 // 按次计费
  11. )
  12. // ChannelPricing 渠道定价表
  13. // 支持同一模型在不同渠道设置不同价格
  14. type ChannelPricing struct {
  15. Id int `json:"id" gorm:"primaryKey"`
  16. ModelName string `json:"model_name" gorm:"size:128;not null;uniqueIndex:idx_model_channel,priority:1"`
  17. ChannelId int `json:"channel_id" gorm:"not null;uniqueIndex:idx_model_channel,priority:2;index"`
  18. QuotaType int `json:"quota_type" gorm:"default:0"` // 0=按量, 1=按次
  19. ModelRatio float64 `json:"model_ratio" gorm:"default:0"`
  20. CompletionRatio float64 `json:"completion_ratio" gorm:"default:0"`
  21. ModelPrice float64 `json:"model_price" gorm:"default:0"`
  22. TagIds string `json:"tag_ids" gorm:"type:varchar(255)"` // 逗号分隔的标签ID
  23. CreatedTime int64 `json:"created_time" gorm:"bigint"`
  24. UpdatedTime int64 `json:"updated_time" gorm:"bigint"`
  25. DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
  26. }
  27. func (cp *ChannelPricing) Insert() error {
  28. now := common.GetTimestamp()
  29. cp.CreatedTime = now
  30. cp.UpdatedTime = now
  31. return DB.Create(cp).Error
  32. }
  33. func (cp *ChannelPricing) Update() error {
  34. cp.UpdatedTime = common.GetTimestamp()
  35. return DB.Model(&ChannelPricing{}).Where("id = ?", cp.Id).Updates(map[string]interface{}{
  36. "quota_type": cp.QuotaType,
  37. "model_ratio": cp.ModelRatio,
  38. "completion_ratio": cp.CompletionRatio,
  39. "model_price": cp.ModelPrice,
  40. "tag_ids": cp.TagIds,
  41. "updated_time": cp.UpdatedTime,
  42. }).Error
  43. }
  44. func (cp *ChannelPricing) Delete() error {
  45. return DB.Delete(cp).Error
  46. }
  47. // GetChannelPricing 获取指定模型在指定渠道的定价
  48. func GetChannelPricing(modelName string, channelId int) (*ChannelPricing, error) {
  49. var cp ChannelPricing
  50. err := DB.Where("model_name = ? AND channel_id = ?", modelName, channelId).First(&cp).Error
  51. if err != nil {
  52. return nil, err
  53. }
  54. return &cp, nil
  55. }
  56. // GetChannelPricingByModel 获取指定模型的所有渠道定价
  57. func GetChannelPricingByModel(modelName string) ([]*ChannelPricing, error) {
  58. var list []*ChannelPricing
  59. err := DB.Where("model_name = ?", modelName).Find(&list).Error
  60. return list, err
  61. }
  62. // GetAllChannelPricing 获取所有渠道定价(分页)
  63. func GetAllChannelPricing(offset int, limit int) ([]*ChannelPricing, int64, error) {
  64. var list []*ChannelPricing
  65. var total int64
  66. if err := DB.Model(&ChannelPricing{}).Count(&total).Error; err != nil {
  67. return nil, 0, err
  68. }
  69. err := DB.Order("id DESC").Offset(offset).Limit(limit).Find(&list).Error
  70. return list, total, err
  71. }
  72. // BatchUpsertChannelPricing 批量创建或更新渠道定价
  73. func BatchUpsertChannelPricing(pricings []*ChannelPricing) error {
  74. if len(pricings) == 0 {
  75. return nil
  76. }
  77. now := common.GetTimestamp()
  78. for _, cp := range pricings {
  79. cp.UpdatedTime = now
  80. // 仅在 CreatedTime 为空时设置(新记录)
  81. if cp.CreatedTime == 0 {
  82. cp.CreatedTime = now
  83. }
  84. }
  85. // 使用 GORM 的 OnConflict 实现 upsert
  86. // 唯一索引为 idx_model_channel (model_name, channel_id)
  87. return DB.Clauses(clause.OnConflict{
  88. Columns: []clause.Column{
  89. {Name: "model_name"},
  90. {Name: "channel_id"},
  91. },
  92. DoUpdates: clause.AssignmentColumns([]string{
  93. "quota_type",
  94. "model_ratio",
  95. "completion_ratio",
  96. "model_price",
  97. "tag_ids",
  98. "updated_time",
  99. }),
  100. }).Create(&pricings).Error
  101. }