|
- package controller
-
- import (
- "fmt"
- "math"
- "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"
- )
-
- // resolveCurrentUser 从 gin.Context 解析当前登录用户信息。
- // 未登录或查询失败时 loggedIn=false,groupRatio=1.0。
- func resolveCurrentUser(c *gin.Context) (loggedIn bool, userId int, userGroup string, groupRatio float64) {
- groupRatio = 1.0
- raw, exists := c.Get("id")
- if !exists {
- return
- }
- userId = raw.(int)
- user, err := model.GetUserCache(userId)
- if err != nil {
- return
- }
- loggedIn = true
- userGroup = user.Group
- groupRatio = service.GetUserGroupRatio(userGroup, userGroup)
- return
- }
-
- func filterPricingByUsableGroups(pricing []model.Pricing, usableGroup map[string]string) []model.Pricing {
- if len(pricing) == 0 {
- return pricing
- }
- if len(usableGroup) == 0 {
- return []model.Pricing{}
- }
-
- filtered := make([]model.Pricing, 0, len(pricing))
- for _, item := range pricing {
- if common.StringsContains(item.EnableGroup, "all") {
- filtered = append(filtered, item)
- continue
- }
- for _, group := range item.EnableGroup {
- if _, ok := usableGroup[group]; ok {
- filtered = append(filtered, item)
- break
- }
- }
- }
- return filtered
- }
-
- func GetPricing(c *gin.Context) {
- pricing := model.GetPricing()
- userId, exists := c.Get("id")
- usableGroup := map[string]string{}
- groupRatio := 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)
- pricing = filterPricingByUsableGroups(pricing, usableGroup)
- // check groupRatio contains usableGroup
- for group := range ratio_setting.GetGroupRatioCopy() {
- if _, ok := usableGroup[group]; !ok {
- delete(groupRatio, group)
- }
- }
-
- c.JSON(200, gin.H{
- "success": true,
- "data": pricing,
- "vendors": model.GetVendors(),
- "group_ratio": groupRatio,
- "usable_group": usableGroup,
- "supported_endpoint": model.GetSupportedEndpointMap(),
- "auto_groups": service.GetUserAutoGroup(group),
- "_": "a42d372ccf0b5dd13ecf71203521f9d2",
- })
- }
-
- // GetUserPricing 获取用户对指定模型的价格信息(原价 vs 用户价)
- func GetUserPricing(c *gin.Context) {
- modelName := c.Param("model")
- // *model 通配符返回值带前导 /,需要去掉
- modelName = strings.TrimPrefix(modelName, "/")
- if modelName == "" {
- common.ApiErrorMsg(c, "模型名不能为空")
- return
- }
-
- pricingData := model.GetPricingByModel(modelName)
- if pricingData == nil {
- common.ApiErrorMsg(c, "未找到该模型的定价信息")
- return
- }
-
- loggedIn, userId, userGroup, groupRatio := resolveCurrentUser(c)
- if !loggedIn {
- respondOriginalPrice(c, pricingData)
- return
- }
-
- bestUserChannelRatio := model.GetBestUserChannelRatio(userId, modelName)
- totalRatio := groupRatio * bestUserChannelRatio
- savingsPercent := int(math.Round((1 - totalRatio) * 100))
-
- result := gin.H{
- "success": true,
- "model_name": pricingData.ModelName,
- "quota_type": pricingData.QuotaType,
- "group": userGroup,
- "group_ratio": groupRatio,
- "user_channel_ratio": bestUserChannelRatio,
- "savings_percent": savingsPercent,
- "logged_in": true,
- }
-
- if pricingData.QuotaType == model.QuotaTypeByTokens {
- originalInput := pricingData.ModelRatio * 2
- originalOutput := pricingData.ModelRatio * pricingData.CompletionRatio * 2
- result["original_input"] = originalInput
- result["original_output"] = originalOutput
- result["user_input"] = originalInput * totalRatio
- result["user_output"] = originalOutput * totalRatio
- } else {
- result["original_price"] = pricingData.ModelPrice
- result["user_price"] = pricingData.ModelPrice * totalRatio
- }
-
- if savingsPercent > 0 {
- result["discount"] = formatDiscount(totalRatio)
- }
-
- c.JSON(200, result)
- }
-
- // respondOriginalPrice 未登录或用户查询失败时,只返回原价
- func respondOriginalPrice(c *gin.Context, pricingData *model.Pricing) {
- result := gin.H{
- "success": true,
- "model_name": pricingData.ModelName,
- "quota_type": pricingData.QuotaType,
- "logged_in": false,
- }
- if pricingData.QuotaType == model.QuotaTypeByTokens {
- result["original_input"] = pricingData.ModelRatio * 2
- result["original_output"] = pricingData.ModelRatio * pricingData.CompletionRatio * 2
- } else {
- result["original_price"] = pricingData.ModelPrice
- }
- c.JSON(200, result)
- }
-
- // formatDiscount 将倍率转换为中文折扣格式
- func formatDiscount(ratio float64) string {
- if ratio <= 0 {
- return "免费"
- }
- discount := int(math.Round(ratio * 10))
- if discount >= 10 {
- return ""
- }
- remainder := int(math.Round(ratio*100)) % 10
- if remainder == 0 {
- return fmt.Sprintf("%d折", discount)
- }
- return fmt.Sprintf("%.1f折", ratio*10)
- }
-
- 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": "重置模型倍率成功",
- })
- }
|