|
- package ratio_setting
-
- import (
- "fmt"
- "sort"
- "strings"
-
- "github.com/QuantumNous/new-api/common"
- "github.com/QuantumNous/new-api/types"
- )
-
- const ModelDisplayPricingOptionKey = "ModelDisplayPricing"
-
- var displayPricingMap = types.NewRWMap[string, []types.ModelDisplayPricingItem]()
-
- func GetModelDisplayPricing(model string) []types.ModelDisplayPricingItem {
- items, ok := displayPricingMap.Get(model)
- if !ok {
- return nil
- }
- return types.CloneModelDisplayPricingItems(items)
- }
-
- func GetModelDisplayPricingCopy() map[string][]types.ModelDisplayPricingItem {
- src := displayPricingMap.ReadAll()
- dst := make(map[string][]types.ModelDisplayPricingItem, len(src))
- for model, items := range src {
- dst[model] = types.CloneModelDisplayPricingItems(items)
- }
- return dst
- }
-
- func SetModelDisplayPricing(model string, items []types.ModelDisplayPricingItem) error {
- model = strings.TrimSpace(model)
- if model == "" {
- return fmt.Errorf("model name is required")
- }
- normalized, err := normalizeModelDisplayPricingItems(items)
- if err != nil {
- return err
- }
- displayPricingMap.Set(model, normalized)
- InvalidateExposedDataCache()
- return nil
- }
-
- func DeleteModelDisplayPricing(model string) error {
- all := displayPricingMap.ReadAll()
- delete(all, model)
- displayPricingMap.Clear()
- displayPricingMap.AddAll(all)
- InvalidateExposedDataCache()
- return nil
- }
-
- func ModelDisplayPricing2JSONString() string {
- bytes, err := common.Marshal(GetModelDisplayPricingCopy())
- if err != nil {
- return "{}"
- }
- return string(bytes)
- }
-
- func UpdateModelDisplayPricingByJSONString(jsonStr string) error {
- if strings.TrimSpace(jsonStr) == "" {
- jsonStr = "{}"
- }
- raw := map[string][]types.ModelDisplayPricingItem{}
- if err := common.UnmarshalJsonStr(jsonStr, &raw); err != nil {
- return err
- }
- next := make(map[string][]types.ModelDisplayPricingItem, len(raw))
- for model, items := range raw {
- model = strings.TrimSpace(model)
- if model == "" {
- return fmt.Errorf("model name is required")
- }
- normalized, err := normalizeModelDisplayPricingItems(items)
- if err != nil {
- return fmt.Errorf("model %s: %w", model, err)
- }
- next[model] = normalized
- }
- displayPricingMap.Clear()
- displayPricingMap.AddAll(next)
- InvalidateExposedDataCache()
- return nil
- }
-
- func normalizeModelDisplayPricingItems(items []types.ModelDisplayPricingItem) ([]types.ModelDisplayPricingItem, error) {
- normalized := types.CloneModelDisplayPricingItems(items)
- for i := range normalized {
- item := &normalized[i]
- item.Specification = strings.TrimSpace(item.Specification)
- item.OfficialSupplierTip = strings.TrimSpace(item.OfficialSupplierTip)
- item.Unit = strings.TrimSpace(item.Unit)
- if item.Specification == "" {
- return nil, fmt.Errorf("row %d: specification is required", i)
- }
- if item.Price < 0 {
- return nil, fmt.Errorf("row %d: price must be >= 0", i)
- }
- if item.Unit == "" {
- return nil, fmt.Errorf("row %d: unit is required", i)
- }
- if item.DiscountRate == 0 {
- item.DiscountRate = 1
- }
- if item.DiscountRate <= 0 || item.DiscountRate > 1 {
- return nil, fmt.Errorf("row %d: discount_rate must be > 0 and <= 1", i)
- }
- }
- sort.SliceStable(normalized, func(i, j int) bool {
- if normalized[i].SortOrder != normalized[j].SortOrder {
- return normalized[i].SortOrder < normalized[j].SortOrder
- }
- return normalized[i].Specification < normalized[j].Specification
- })
- return normalized, nil
- }
|