Files
cneicy ceddfd3d6b feat: sync deployed v1.0.0-rc.38-custom.42
Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
2026-09-26 04:49:11 +08:00

70 lines
2.5 KiB
Go

package controller
import (
"encoding/json"
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/model"
"github.com/QuantumNous/new-api/relaykit/dto"
"github.com/gin-gonic/gin"
)
func relayAttemptGuardResult(a model.RelayAttempt) string {
if a.GuardResult == "model_mismatch" {
return "mismatch_rejected"
}
if a.GuardResult == "unchecked" && a.ReturnedModel != "" && a.ReturnedModel == a.RequestedModel {
return "accepted"
}
if a.GuardResult == "accepted" && a.Number > 1 {
return "switched_success"
}
return a.GuardResult
}
// Attempt history is owner-scoped; channel identifiers are administrator-only.
func GetRelayAttempts(c *gin.Context) {
requestID := c.Param("request_id")
if requestID == "" || len(requestID) > 64 {
c.AbortWithStatus(400)
return
}
query := model.DB.Where("request_id = ?", requestID)
admin := c.GetInt("role") >= common.RoleAdminUser
if !admin {
query = query.Where("user_id = ?", c.GetInt("id"))
}
var attempts []model.RelayAttempt
if err := query.Order("number asc, id asc").Limit(100).Find(&attempts).Error; err != nil {
common.ApiError(c, err)
return
}
rows := make([]gin.H, 0, len(attempts))
total := 0
pending := false
for _, a := range attempts {
var usage dto.Usage
_ = common.UnmarshalJsonStr(a.UsageJSON, &usage)
row := gin.H{"number": a.Number, "group": a.GroupName, "requested_model": a.RequestedModel, "returned_model": a.ReturnedModel, "guard_result": relayAttemptGuardResult(a), "usage_source": a.UsageSource, "state": a.State, "quota": a.Quota, "billing_source": a.Funding, "usage": usage}
row["charged"] = a.State == "settled" && a.Quota > 0
row["charge_explanation"] = "Each consumed attempt is charged independently, including rejected results."
var log model.Log
var other map[string]json.RawMessage
price := map[string]json.RawMessage{}
if common.UnmarshalJsonStr(a.LogJSON, &log) == nil && common.UnmarshalJsonStr(log.Other, &other) == nil {
for _, key := range []string{"group_ratio", "model_ratio", "completion_ratio", "cache_ratio", "model_price", "billing_mode", "expr_b64", "matched_tier", "billing_tokens", "billing_unit", "fixed_price"} {
if value, ok := other[key]; ok {
price[key] = value
}
}
}
row["price"] = price
if admin {
row["channel_id"] = a.ChannelID
}
rows = append(rows, row)
total += a.Quota
pending = pending || a.State != "settled"
}
common.ApiSuccess(c, gin.H{"attempts": rows, "total_quota": total, "pending": pending})
}