feat: 图片生成计费功能
- 新增 Group 图片价格配置(image_price_1k/2k/4k) - BillingService 新增 CalculateImageCost 方法 - AntigravityGatewayService 支持识别图片生成模型并按次计费 - UsageLog 新增 image_count 和 image_size 字段 - 前端分组管理支持配置图片价格(antigravity 和 gemini 平台) - 图片计费复用通用计费能力(余额检查、扣费、倍率、订阅限额)
This commit is contained in:
@@ -652,6 +652,9 @@ func (s *AntigravityGatewayService) ForwardGemini(ctx context.Context, c *gin.Co
|
||||
return nil, s.writeGoogleError(c, http.StatusBadRequest, "Request body is empty")
|
||||
}
|
||||
|
||||
// 解析请求以获取 image_size(用于图片计费)
|
||||
imageSize := s.extractImageSize(body)
|
||||
|
||||
switch action {
|
||||
case "generateContent", "streamGenerateContent":
|
||||
// ok
|
||||
@@ -832,6 +835,13 @@ handleSuccess:
|
||||
usage = &ClaudeUsage{}
|
||||
}
|
||||
|
||||
// 判断是否为图片生成模型
|
||||
imageCount := 0
|
||||
if isImageGenerationModel(mappedModel) {
|
||||
// 图片模型按次计费,默认 1 张图片
|
||||
imageCount = 1
|
||||
}
|
||||
|
||||
return &ForwardResult{
|
||||
RequestID: requestID,
|
||||
Usage: *usage,
|
||||
@@ -839,6 +849,8 @@ handleSuccess:
|
||||
Stream: stream,
|
||||
Duration: time.Since(startTime),
|
||||
FirstTokenMs: firstTokenMs,
|
||||
ImageCount: imageCount,
|
||||
ImageSize: imageSize,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1161,3 +1173,27 @@ func (s *AntigravityGatewayService) handleClaudeStreamingResponse(c *gin.Context
|
||||
|
||||
return &antigravityStreamResult{usage: convertUsage(agUsage), firstTokenMs: firstTokenMs}, nil
|
||||
}
|
||||
|
||||
// extractImageSize 从 Gemini 请求中提取 image_size 参数
|
||||
func (s *AntigravityGatewayService) extractImageSize(body []byte) string {
|
||||
var req antigravity.GeminiRequest
|
||||
if err := json.Unmarshal(body, &req); err != nil {
|
||||
return "2K" // 默认 2K
|
||||
}
|
||||
|
||||
if req.GenerationConfig != nil && req.GenerationConfig.ImageConfig != nil {
|
||||
size := strings.ToUpper(strings.TrimSpace(req.GenerationConfig.ImageConfig.ImageSize))
|
||||
if size == "1K" || size == "2K" || size == "4K" {
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
return "2K" // 默认 2K
|
||||
}
|
||||
|
||||
// isImageGenerationModel 判断模型是否为图片生成模型
|
||||
func isImageGenerationModel(model string) bool {
|
||||
modelLower := strings.ToLower(model)
|
||||
return strings.Contains(modelLower, "gemini-3-pro-image") ||
|
||||
strings.Contains(modelLower, "gemini-2.5-flash-image")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user