99 lines
4.2 KiB
Go
99 lines
4.2 KiB
Go
package app
|
||
|
||
import "infinite-canvas/backend/internal/model"
|
||
|
||
const maxChannelModelTokenPriceMicrocredits = int64(1_000_000) * CreditScale
|
||
|
||
func validateTokenPrices(capability string, inputPrice, outputPrice, cachedPrice int64) error {
|
||
if inputPrice < 0 || outputPrice < 0 || cachedPrice < 0 {
|
||
return BadAuthRequest("模型积分价格不能小于 0")
|
||
}
|
||
if capability == "video" && (inputPrice != 0 || cachedPrice != 0) {
|
||
return BadAuthRequest("视频 Token 仅按视频用量计费,输入和缓存 Token 价格必须为 0")
|
||
}
|
||
if inputPrice > maxChannelModelTokenPriceMicrocredits || outputPrice > maxChannelModelTokenPriceMicrocredits || cachedPrice > maxChannelModelTokenPriceMicrocredits {
|
||
return BadAuthRequest("Token 每百万用量价格不能超过 1,000,000 积分")
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// ValidateChannelModelPrice 校验渠道模型价格配置的有效性
|
||
// 根据 billingMode 检查必要的价格字段是否已配置
|
||
func ValidateChannelModelPrice(billingMode string, capability string, protocol model.ChannelInterfaceType, unitPrice, inputPrice, outputPrice, cachedPrice int64) bool {
|
||
switch billingMode {
|
||
case "fixed_request":
|
||
// 固定价格模式:0 表示免费,负数无效。
|
||
return unitPrice >= 0
|
||
case "per_second":
|
||
// 按秒计费:0 表示免费,负数无效。
|
||
return unitPrice >= 0
|
||
case "token":
|
||
if validateTokenPrices(capability, inputPrice, outputPrice, cachedPrice) != nil {
|
||
return false
|
||
}
|
||
if capability == "video" {
|
||
return true
|
||
}
|
||
if capability != "" && capability != "text" {
|
||
return false
|
||
}
|
||
// 文本模型:所有 Token 价格为 0 时表示免费。
|
||
return true
|
||
default:
|
||
return false
|
||
}
|
||
}
|
||
|
||
// ValidatePriceTierPrice 校验价格档的价格配置有效性
|
||
func ValidatePriceTierPrice(tier *model.ChannelModelPriceTier, capability string, protocol model.ChannelInterfaceType) bool {
|
||
if tier == nil {
|
||
return false
|
||
}
|
||
return ValidateChannelModelPrice(tier.BillingMode, capability, protocol, tier.UnitPriceMicrocredits, tier.InputTokenPriceMicrocredits, tier.OutputTokenPriceMicrocredits, tier.CachedTokenPriceMicrocredits)
|
||
}
|
||
|
||
// ComputePriceConfigured 根据价格内容计算 PriceConfigured 标志
|
||
// 不再允许手动设置 PriceConfigured,必须由价格字段派生
|
||
func ComputePriceConfigured(billingMode string, capability string, protocol model.ChannelInterfaceType, unitPrice, inputPrice, outputPrice, cachedPrice int64) bool {
|
||
return ValidateChannelModelPrice(billingMode, capability, protocol, unitPrice, inputPrice, outputPrice, cachedPrice)
|
||
}
|
||
|
||
// ComputeTierPriceConfigured 计算价格档的 PriceConfigured 标志
|
||
func ComputeTierPriceConfigured(tier *model.ChannelModelPriceTier, capability string, protocol model.ChannelInterfaceType) bool {
|
||
if tier == nil {
|
||
return false
|
||
}
|
||
return ComputePriceConfigured(tier.BillingMode, capability, protocol, tier.UnitPriceMicrocredits, tier.InputTokenPriceMicrocredits, tier.OutputTokenPriceMicrocredits, tier.CachedTokenPriceMicrocredits)
|
||
}
|
||
|
||
// HasValidPrice 检查渠道模型是否有有效价格
|
||
// 对于有价格档的模型,检查是否至少有一个启用且价格有效的价格档
|
||
func HasValidPrice(channelModel *model.ChannelModel) bool {
|
||
if channelModel == nil {
|
||
return false
|
||
}
|
||
|
||
// 如果有价格档,检查价格档
|
||
if len(channelModel.PriceTiers) > 0 {
|
||
for _, tier := range channelModel.PriceTiers {
|
||
if tier.Enabled && tier.PriceConfigured && ValidatePriceTierPrice(&tier, channelModel.Capability, channelModel.Protocol) {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 否则检查模型级别的价格
|
||
return channelModel.PriceConfigured && ValidateChannelModelPrice(channelModel.BillingMode, channelModel.Capability, channelModel.Protocol, channelModel.UnitPriceMicrocredits, channelModel.InputTokenPriceMicrocredits, channelModel.OutputTokenPriceMicrocredits, channelModel.CachedTokenPriceMicrocredits)
|
||
}
|
||
|
||
// ValidateLogicalModelPrice 校验前台模型的价格配置
|
||
func ValidateLogicalModelPrice(pricePolicy string, billingMode string, unitPrice, inputPrice, outputPrice, cachedPrice int64) bool {
|
||
if pricePolicy == "channel" {
|
||
// 跟随渠道价格,不需要校验前台价格
|
||
return true
|
||
}
|
||
// 统一定价模式,按 billingMode 校验
|
||
return ValidateChannelModelPrice(billingMode, "", "", unitPrice, inputPrice, outputPrice, cachedPrice)
|
||
}
|