556 lines
20 KiB
Go
556 lines
20 KiB
Go
package controller
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"net/http"
|
||
"strings"
|
||
|
||
"github.com/QuantumNous/new-api/common"
|
||
"github.com/QuantumNous/new-api/model"
|
||
"github.com/QuantumNous/new-api/service"
|
||
"github.com/QuantumNous/new-api/setting/ratio_setting"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// filterChannelPricingMapByVisibleChannels 仅保留可见渠道的渠道倍率配置。
|
||
func filterChannelPricingMapByVisibleChannels(source map[string]map[string]float64, visibleChannelIDs map[int]struct{}) map[string]map[string]float64 {
|
||
filtered := make(map[string]map[string]float64, len(source))
|
||
for channelID, modelRatio := range source {
|
||
id, err := model.ParseSupplierChannelIDFilter(channelID)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
if _, ok := visibleChannelIDs[id]; !ok {
|
||
continue
|
||
}
|
||
filtered[channelID] = modelRatio
|
||
}
|
||
return filtered
|
||
}
|
||
|
||
func filterChannelTierPricingMapByVisibleChannels(source map[string]map[string]ratio_setting.TierSegments, visibleChannelIDs map[int]struct{}) map[string]map[string]ratio_setting.TierSegments {
|
||
filtered := make(map[string]map[string]ratio_setting.TierSegments, len(source))
|
||
for channelID, modelRatio := range source {
|
||
id, err := model.ParseSupplierChannelIDFilter(channelID)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
if _, ok := visibleChannelIDs[id]; !ok {
|
||
continue
|
||
}
|
||
filtered[channelID] = modelRatio
|
||
}
|
||
return filtered
|
||
}
|
||
|
||
// getPricingVisibleChannelsForUser 返回定价/模型广场可见的渠道列表及 channel_* Option 过滤用的 ID 集合。
|
||
// 当前策略:所有角色(包含已审核供应商)均可见全部渠道,与普通用户保持一致。
|
||
func getPricingVisibleChannelsForUser(c *gin.Context) ([]model.ChannelSimplePricingItem, map[int]struct{}, error) {
|
||
channels, err := model.ListChannelsForPricing()
|
||
if err != nil {
|
||
return nil, nil, err
|
||
}
|
||
visibleChannelIDs := make(map[int]struct{}, len(channels))
|
||
for _, item := range channels {
|
||
visibleChannelIDs[item.ChannelID] = struct{}{}
|
||
}
|
||
return channels, visibleChannelIDs, nil
|
||
}
|
||
|
||
// shouldBlurPricing 检查 HeaderNavModules 配置中是否有任一模块开启了 blurPricing。
|
||
func shouldBlurPricing() bool {
|
||
common.OptionMapRWMutex.RLock()
|
||
raw := common.OptionMap["HeaderNavModules"]
|
||
common.OptionMapRWMutex.RUnlock()
|
||
if raw == "" {
|
||
return false
|
||
}
|
||
var modules map[string]any
|
||
if err := common.Unmarshal([]byte(raw), &modules); err != nil {
|
||
return false
|
||
}
|
||
for _, key := range []string{"home", "pricing"} {
|
||
switch v := modules[key].(type) {
|
||
case map[string]any:
|
||
if bp, ok := v["blurPricing"]; ok {
|
||
if b, ok := bp.(bool); ok && b {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// sanitizePricingData 将定价数据中的价格和供应商信息置零/清空。
|
||
func sanitizePricingData(data []model.PricingAPIItem) {
|
||
for i := range data {
|
||
data[i].ModelRatio = 0
|
||
data[i].ModelPrice = 0
|
||
data[i].CompletionRatio = nil
|
||
data[i].CacheRatio = nil
|
||
data[i].CreateCacheRatio = nil
|
||
data[i].ImageRatio = nil
|
||
data[i].AudioRatio = nil
|
||
data[i].AudioCompletionRatio = nil
|
||
data[i].VideoRatio = nil
|
||
data[i].VideoCompletionRatio = nil
|
||
data[i].VideoPrice = nil
|
||
data[i].VideoFlatClipHint = nil
|
||
data[i].ImagePerImageHint = nil
|
||
for j := range data[i].ChannelList {
|
||
data[i].ChannelList[j].ModelPrice = 0
|
||
data[i].ChannelList[j].ModelRatio = 0
|
||
data[i].ChannelList[j].CompletionRatio = 0
|
||
data[i].ChannelList[j].CacheRatio = 0
|
||
data[i].ChannelList[j].CreateCacheRatio = 0
|
||
data[i].ChannelList[j].ModelTierRatio = nil
|
||
data[i].ChannelList[j].CompletionTierRatio = nil
|
||
data[i].ChannelList[j].CacheTierRatio = nil
|
||
data[i].ChannelList[j].CreateCacheTierRatio = nil
|
||
data[i].ChannelList[j].PriceDiscountPercent = 0
|
||
data[i].ChannelList[j].SupplierAlias = ""
|
||
data[i].ChannelList[j].CompanyLogoURL = ""
|
||
data[i].ChannelList[j].SupplierType = ""
|
||
}
|
||
for j := range data[i].SupplierList {
|
||
data[i].SupplierList[j].SupplierAlias = ""
|
||
data[i].SupplierList[j].CompanyLogoURL = ""
|
||
data[i].SupplierList[j].SupplierType = ""
|
||
}
|
||
}
|
||
}
|
||
|
||
func buildPricingAPIData() []model.PricingAPIItem {
|
||
pricing := model.GetPricing()
|
||
filtered := make([]model.Pricing, 0, len(pricing))
|
||
for _, p := range pricing {
|
||
if ratio_setting.ModelHasConfiguredPricing(p.ModelName) {
|
||
filtered = append(filtered, p)
|
||
}
|
||
}
|
||
channels, err := model.ListChannelsForPricing()
|
||
if err != nil {
|
||
channels = nil
|
||
}
|
||
visibleChannelIDs := make(map[int]struct{}, len(channels))
|
||
for _, item := range channels {
|
||
visibleChannelIDs[item.ChannelID] = struct{}{}
|
||
}
|
||
channelPricingMeta, err := model.ListChannelPricingMeta()
|
||
if err != nil {
|
||
channelPricingMeta = nil
|
||
}
|
||
return model.BuildPricingAPIItems(filtered, visibleChannelIDs, channelPricingMeta, true)
|
||
}
|
||
|
||
// CollectPricingShowableModelNames 返回 /pricing 接口前端可展示的模型名集合(与 GetPricing 同源条件)。
|
||
// 判定条件与 /pricing 完全一致:
|
||
// 1. 模型已配置定价(ratio_setting.ModelHasConfiguredPricing)。
|
||
// 2. 至少存在一个 (model, 可见渠道) 满足 model.BuildPricingAPIItems 的单测门禁
|
||
// (ManualDisplayResponseTime>0 或 LastTestSuccess && LastResponseTime>0;该渠道若已有任何成功单测,则本模型也需通过模糊匹配)。
|
||
//
|
||
// 用于操练场等需要"配好定价 + 测试连通性通过"判定与定价页保持一致的位置,避免两端各自实现的判定门槛漂移导致少展示。
|
||
func CollectPricingShowableModelNames() map[string]bool {
|
||
pricing := model.GetPricing()
|
||
filtered := make([]model.Pricing, 0, len(pricing))
|
||
for _, p := range pricing {
|
||
if ratio_setting.ModelHasConfiguredPricing(p.ModelName) {
|
||
filtered = append(filtered, p)
|
||
}
|
||
}
|
||
visibleChannelIDs := make(map[int]struct{})
|
||
if channels, err := model.ListChannelsForPricing(); err == nil {
|
||
for _, item := range channels {
|
||
visibleChannelIDs[item.ChannelID] = struct{}{}
|
||
}
|
||
}
|
||
metas, err := model.ListChannelPricingMeta()
|
||
if err != nil {
|
||
metas = nil
|
||
}
|
||
items := model.BuildPricingAPIItems(filtered, visibleChannelIDs, metas, false)
|
||
out := make(map[string]bool, len(items))
|
||
for i := range items {
|
||
name := strings.TrimSpace(items[i].ModelName)
|
||
if name == "" {
|
||
continue
|
||
}
|
||
out[name] = true
|
||
}
|
||
return out
|
||
}
|
||
|
||
func validateAdminIssuedToken(rawToken string) error {
|
||
tokenKey := strings.TrimSpace(rawToken)
|
||
if strings.HasPrefix(strings.ToLower(tokenKey), "bearer ") {
|
||
tokenKey = strings.TrimSpace(tokenKey[7:])
|
||
}
|
||
tokenKey = strings.TrimPrefix(tokenKey, "sk-")
|
||
token, err := model.ValidateUserToken(tokenKey)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if token == nil || !model.IsAdmin(token.UserId) {
|
||
return errors.New("令牌不是管理员签发")
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func PriceSync(c *gin.Context) {
|
||
var req struct {
|
||
Token string `json:"token"`
|
||
}
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.JSON(http.StatusOK, gin.H{"success": false, "message": "请求参数格式错误"})
|
||
return
|
||
}
|
||
if err := validateAdminIssuedToken(req.Token); err != nil {
|
||
c.JSON(http.StatusOK, gin.H{"success": false, "message": "token 验证失败"})
|
||
return
|
||
}
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"success": true,
|
||
"message": "",
|
||
"data": buildPricingAPIData(),
|
||
})
|
||
}
|
||
|
||
// GetPricing 返回前端定价展示数据。
|
||
func GetPricing(c *gin.Context) {
|
||
pricing := model.GetPricing()
|
||
filtered := make([]model.Pricing, 0, len(pricing))
|
||
for _, p := range pricing {
|
||
if ratio_setting.ModelHasConfiguredPricing(p.ModelName) {
|
||
filtered = append(filtered, p)
|
||
}
|
||
}
|
||
_, visibleChannelIDs, err := getPricingVisibleChannelsForUser(c)
|
||
if err != nil {
|
||
visibleChannelIDs = map[int]struct{}{}
|
||
}
|
||
userId, exists := c.Get("id")
|
||
usableGroup := map[string]string{}
|
||
groupRatio := map[string]float64{}
|
||
groupModelPrice := map[string]map[string]float64{}
|
||
groupModelRatio := map[string]map[string]float64{}
|
||
channelModelPrice := map[string]map[string]float64{}
|
||
channelModelRatio := map[string]map[string]float64{}
|
||
channelCompletionRatio := map[string]map[string]float64{}
|
||
channelCacheRatio := map[string]map[string]float64{}
|
||
channelCreateCacheRatio := map[string]map[string]float64{}
|
||
channelImageRatio := map[string]map[string]float64{}
|
||
channelAudioRatio := map[string]map[string]float64{}
|
||
channelAudioCompletionRatio := map[string]map[string]float64{}
|
||
channelVideoRatio := map[string]map[string]float64{}
|
||
channelVideoCompletionRatio := map[string]map[string]float64{}
|
||
channelVideoPrice := map[string]map[string]float64{}
|
||
channelImagePrice := map[string]map[string]float64{}
|
||
channelModelTierRatio := map[string]map[string]ratio_setting.TierSegments{}
|
||
channelCompletionTierRatio := map[string]map[string]ratio_setting.TierSegments{}
|
||
channelCacheTierRatio := map[string]map[string]ratio_setting.TierSegments{}
|
||
channelCreateCacheTierRatio := map[string]map[string]ratio_setting.TierSegments{}
|
||
supplierModelPrice := map[string]map[string]float64{}
|
||
supplierModelRatio := map[string]map[string]float64{}
|
||
for s, f := range ratio_setting.GetGroupRatioCopy() {
|
||
groupRatio[s] = f
|
||
}
|
||
var group string
|
||
if exists {
|
||
user, err := model.GetUserCache(userId.(int))
|
||
if err == nil {
|
||
group = user.Group
|
||
for g := range groupRatio {
|
||
ratio, ok := ratio_setting.GetGroupGroupRatio(group, g)
|
||
if ok {
|
||
groupRatio[g] = ratio
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
usableGroup = service.GetUserUsableGroups(group)
|
||
// check groupRatio contains usableGroup
|
||
for group := range ratio_setting.GetGroupRatioCopy() {
|
||
if _, ok := usableGroup[group]; !ok {
|
||
delete(groupRatio, group)
|
||
}
|
||
}
|
||
for group, modelPrice := range ratio_setting.GetGroupModelPriceCopy() {
|
||
if _, ok := usableGroup[group]; ok {
|
||
groupModelPrice[group] = modelPrice
|
||
}
|
||
}
|
||
for group, modelRatioByGroup := range ratio_setting.GetGroupModelRatioCopy() {
|
||
if _, ok := usableGroup[group]; ok {
|
||
groupModelRatio[group] = modelRatioByGroup
|
||
}
|
||
}
|
||
for channelID, modelPrice := range ratio_setting.GetChannelModelPriceCopy() {
|
||
channelModelPrice[channelID] = modelPrice
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelModelRatioCopy() {
|
||
channelModelRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelCompletionRatioCopy() {
|
||
channelCompletionRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelCacheRatioCopy() {
|
||
channelCacheRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelCreateCacheRatioCopy() {
|
||
channelCreateCacheRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelImageRatioCopy() {
|
||
channelImageRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelAudioRatioCopy() {
|
||
channelAudioRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelAudioCompletionRatioCopy() {
|
||
channelAudioCompletionRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelVideoRatioCopy() {
|
||
channelVideoRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelRatio := range ratio_setting.GetChannelVideoCompletionRatioCopy() {
|
||
channelVideoCompletionRatio[channelID] = modelRatio
|
||
}
|
||
for channelID, modelPrice := range ratio_setting.GetChannelVideoPriceCopy() {
|
||
channelVideoPrice[channelID] = modelPrice
|
||
}
|
||
for channelID, modelPrice := range ratio_setting.GetChannelImagePriceCopy() {
|
||
channelImagePrice[channelID] = modelPrice
|
||
}
|
||
for channelID, tierRatio := range ratio_setting.GetChannelModelTierRatioCopy() {
|
||
channelModelTierRatio[channelID] = tierRatio
|
||
}
|
||
for channelID, tierRatio := range ratio_setting.GetChannelCompletionTierRatioCopy() {
|
||
channelCompletionTierRatio[channelID] = tierRatio
|
||
}
|
||
for channelID, tierRatio := range ratio_setting.GetChannelCacheTierRatioCopy() {
|
||
channelCacheTierRatio[channelID] = tierRatio
|
||
}
|
||
for channelID, tierRatio := range ratio_setting.GetChannelCreateCacheTierRatioCopy() {
|
||
channelCreateCacheTierRatio[channelID] = tierRatio
|
||
}
|
||
channelModelPrice = filterChannelPricingMapByVisibleChannels(channelModelPrice, visibleChannelIDs)
|
||
channelModelRatio = filterChannelPricingMapByVisibleChannels(channelModelRatio, visibleChannelIDs)
|
||
channelCompletionRatio = filterChannelPricingMapByVisibleChannels(channelCompletionRatio, visibleChannelIDs)
|
||
channelCacheRatio = filterChannelPricingMapByVisibleChannels(channelCacheRatio, visibleChannelIDs)
|
||
channelCreateCacheRatio = filterChannelPricingMapByVisibleChannels(channelCreateCacheRatio, visibleChannelIDs)
|
||
channelImageRatio = filterChannelPricingMapByVisibleChannels(channelImageRatio, visibleChannelIDs)
|
||
channelAudioRatio = filterChannelPricingMapByVisibleChannels(channelAudioRatio, visibleChannelIDs)
|
||
channelAudioCompletionRatio = filterChannelPricingMapByVisibleChannels(channelAudioCompletionRatio, visibleChannelIDs)
|
||
channelVideoRatio = filterChannelPricingMapByVisibleChannels(channelVideoRatio, visibleChannelIDs)
|
||
channelVideoCompletionRatio = filterChannelPricingMapByVisibleChannels(channelVideoCompletionRatio, visibleChannelIDs)
|
||
channelVideoPrice = filterChannelPricingMapByVisibleChannels(channelVideoPrice, visibleChannelIDs)
|
||
channelImagePrice = filterChannelPricingMapByVisibleChannels(channelImagePrice, visibleChannelIDs)
|
||
channelModelTierRatio = filterChannelTierPricingMapByVisibleChannels(channelModelTierRatio, visibleChannelIDs)
|
||
channelCompletionTierRatio = filterChannelTierPricingMapByVisibleChannels(channelCompletionTierRatio, visibleChannelIDs)
|
||
channelCacheTierRatio = filterChannelTierPricingMapByVisibleChannels(channelCacheTierRatio, visibleChannelIDs)
|
||
channelCreateCacheTierRatio = filterChannelTierPricingMapByVisibleChannels(channelCreateCacheTierRatio, visibleChannelIDs)
|
||
for supplierID, modelPrice := range ratio_setting.GetSupplierModelPriceCopy() {
|
||
supplierModelPrice[supplierID] = modelPrice
|
||
}
|
||
for supplierID, modelRatio := range ratio_setting.GetSupplierModelRatioCopy() {
|
||
supplierModelRatio[supplierID] = modelRatio
|
||
}
|
||
|
||
channelPricingMeta, err := model.ListChannelPricingMeta()
|
||
if err != nil {
|
||
channelPricingMeta = nil
|
||
}
|
||
pricingData := model.BuildPricingAPIItems(filtered, visibleChannelIDs, channelPricingMeta, false)
|
||
|
||
if exists && common.IsDistributorProfitShareMode() {
|
||
if uid, ok := userId.(int); ok && uid > 0 {
|
||
model.ApplyInviteeMarkupToPricingAPIForUser(uid, pricingData)
|
||
}
|
||
}
|
||
|
||
// 读取热度统计周期配置
|
||
common.OptionMapRWMutex.RLock()
|
||
heatStatPeriod := common.OptionMap["HeatStatPeriod"]
|
||
common.OptionMapRWMutex.RUnlock()
|
||
if heatStatPeriod == "" {
|
||
heatStatPeriod = model.HeatStatPeriod7d
|
||
}
|
||
|
||
// 查询模型和渠道的请求统计数据
|
||
modelStats, _ := model.GetModelRequestStatsByPeriod(heatStatPeriod)
|
||
|
||
// 将 visibleChannelIDs (map) 转换为 slice
|
||
visibleIDSlice := make([]int, 0, len(visibleChannelIDs))
|
||
for id := range visibleChannelIDs {
|
||
visibleIDSlice = append(visibleIDSlice, id)
|
||
}
|
||
channelStats, _ := model.GetChannelModelRequestStatsByPeriod(visibleIDSlice, heatStatPeriod)
|
||
|
||
// 构建查询映射
|
||
modelStatsMap := make(map[string]model.ModelRequestStats)
|
||
for _, s := range modelStats {
|
||
modelStatsMap[s.ModelName] = s
|
||
}
|
||
|
||
channelStatsMap := make(map[string]model.ChannelModelRequestStats)
|
||
for _, s := range channelStats {
|
||
key := fmt.Sprintf("%d:%s", s.ChannelID, s.ModelName)
|
||
channelStatsMap[key] = s
|
||
}
|
||
|
||
// 预加载所有模型的权重配置
|
||
modelConfigs := make(map[string]model.Model)
|
||
var allModels []model.Model
|
||
model.DB.Find(&allModels)
|
||
for _, m := range allModels {
|
||
modelConfigs[m.ModelName] = m
|
||
}
|
||
|
||
// 预加载所有渠道-模型热力配置
|
||
channelModelHeats, _ := model.GetAllChannelModelHeats()
|
||
channelHeatMap := make(map[string]model.ChannelModelHeat)
|
||
for _, heat := range channelModelHeats {
|
||
key := fmt.Sprintf("%d:%s", heat.ChannelID, heat.ModelName)
|
||
channelHeatMap[key] = heat
|
||
}
|
||
|
||
// 整合统计数据到 pricingData
|
||
for i := range pricingData {
|
||
item := &pricingData[i]
|
||
modelName := item.ModelName
|
||
|
||
// 整合渠道数据
|
||
for j := range item.ChannelList {
|
||
ch := &item.ChannelList[j]
|
||
key := fmt.Sprintf("%d:%s", ch.ChannelID, modelName)
|
||
|
||
var modelWeight float64 = 1
|
||
// 获取渠道-模型热力配置(新表)
|
||
if heat, ok := channelHeatMap[key]; ok {
|
||
ch.SortWeight = heat.ChannelSortWeight
|
||
ch.ManualBaseReqCount = heat.ManualBaseReqCount
|
||
modelWeight = heat.ModelSortWeight
|
||
if modelWeight <= 0 {
|
||
modelWeight = 1
|
||
}
|
||
} else {
|
||
// 默认配置
|
||
ch.SortWeight = 1
|
||
ch.ManualBaseReqCount = 0
|
||
}
|
||
|
||
// 获取渠道-模型自动统计数据
|
||
if cs, ok := channelStatsMap[key]; ok {
|
||
ch.AutoReqCount = cs.RequestCount7d
|
||
} else {
|
||
ch.AutoReqCount = 0
|
||
}
|
||
|
||
// 计算渠道最终调用次数和热度得分
|
||
ch.FinalReqCount = ch.ManualBaseReqCount + ch.AutoReqCount
|
||
// 热度分 = 最终调用次数 × 渠道权重 × 模型权重
|
||
// 防止权重为0导致热度分为0
|
||
if ch.SortWeight <= 0 {
|
||
ch.SortWeight = 1
|
||
}
|
||
ch.ChannelHeatScore = float64(ch.FinalReqCount) * ch.SortWeight * modelWeight
|
||
}
|
||
}
|
||
|
||
blurPricing := false
|
||
if !exists && shouldBlurPricing() {
|
||
blurPricing = true
|
||
sanitizePricingData(pricingData)
|
||
groupRatio = map[string]float64{}
|
||
groupModelPrice = map[string]map[string]float64{}
|
||
groupModelRatio = map[string]map[string]float64{}
|
||
channelModelPrice = map[string]map[string]float64{}
|
||
channelModelRatio = map[string]map[string]float64{}
|
||
channelCompletionRatio = map[string]map[string]float64{}
|
||
channelCacheRatio = map[string]map[string]float64{}
|
||
channelCreateCacheRatio = map[string]map[string]float64{}
|
||
channelImageRatio = map[string]map[string]float64{}
|
||
channelAudioRatio = map[string]map[string]float64{}
|
||
channelAudioCompletionRatio = map[string]map[string]float64{}
|
||
channelVideoRatio = map[string]map[string]float64{}
|
||
channelVideoCompletionRatio = map[string]map[string]float64{}
|
||
channelVideoPrice = map[string]map[string]float64{}
|
||
channelImagePrice = map[string]map[string]float64{}
|
||
channelModelTierRatio = map[string]map[string]ratio_setting.TierSegments{}
|
||
channelCompletionTierRatio = map[string]map[string]ratio_setting.TierSegments{}
|
||
channelCacheTierRatio = map[string]map[string]ratio_setting.TierSegments{}
|
||
channelCreateCacheTierRatio = map[string]map[string]ratio_setting.TierSegments{}
|
||
supplierModelPrice = map[string]map[string]float64{}
|
||
supplierModelRatio = map[string]map[string]float64{}
|
||
}
|
||
|
||
c.JSON(200, gin.H{
|
||
"success": true,
|
||
"data": pricingData,
|
||
"blur_pricing": blurPricing,
|
||
"heat_stat_period": heatStatPeriod,
|
||
"vendors": model.GetVendors(),
|
||
// "channels": channels,
|
||
"group_ratio": groupRatio,
|
||
"group_model_price": groupModelPrice,
|
||
"group_model_ratio": groupModelRatio,
|
||
"channel_model_price": channelModelPrice,
|
||
"channel_model_ratio": channelModelRatio,
|
||
"channel_completion_ratio": channelCompletionRatio,
|
||
"channel_cache_ratio": channelCacheRatio,
|
||
"channel_create_cache_ratio": channelCreateCacheRatio,
|
||
"channel_image_ratio": channelImageRatio,
|
||
"channel_image_price": channelImagePrice,
|
||
"channel_audio_ratio": channelAudioRatio,
|
||
"channel_audio_completion_ratio": channelAudioCompletionRatio,
|
||
"channel_video_ratio": channelVideoRatio,
|
||
"channel_video_completion_ratio": channelVideoCompletionRatio,
|
||
"channel_video_price": channelVideoPrice,
|
||
"channel_model_tier_ratio": channelModelTierRatio,
|
||
"channel_completion_tier_ratio": channelCompletionTierRatio,
|
||
"channel_cache_tier_ratio": channelCacheTierRatio,
|
||
"channel_create_cache_tier_ratio": channelCreateCacheTierRatio,
|
||
"supplier_model_price": supplierModelPrice,
|
||
"supplier_model_ratio": supplierModelRatio,
|
||
"usable_group": usableGroup,
|
||
"supported_endpoint": model.GetSupportedEndpointMap(),
|
||
"auto_groups": service.GetUserAutoGroup(group),
|
||
"pricing_version": "b58e1c9a3f7d4e2a8c0b1d6e9f4a2c7d8e0f1b2a3",
|
||
})
|
||
}
|
||
|
||
func ResetModelRatio(c *gin.Context) {
|
||
defaultStr := ratio_setting.DefaultModelRatio2JSONString()
|
||
err := model.UpdateOption("ModelRatio", defaultStr)
|
||
if err != nil {
|
||
c.JSON(200, gin.H{
|
||
"success": false,
|
||
"message": err.Error(),
|
||
})
|
||
return
|
||
}
|
||
err = ratio_setting.UpdateModelRatioByJSONString(defaultStr)
|
||
if err != nil {
|
||
c.JSON(200, gin.H{
|
||
"success": false,
|
||
"message": err.Error(),
|
||
})
|
||
return
|
||
}
|
||
c.JSON(200, gin.H{
|
||
"success": true,
|
||
"message": "重置模型倍率成功",
|
||
})
|
||
}
|
||
|
||
func GetVendors(c *gin.Context) {
|
||
vendors := model.GetVendors()
|
||
c.JSON(200, gin.H{
|
||
"success": true,
|
||
"data": vendors,
|
||
})
|
||
}
|