Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

121 wiersze
3.3 KiB

  1. package ratio_setting
  2. import (
  3. "fmt"
  4. "sort"
  5. "strings"
  6. "github.com/QuantumNous/new-api/common"
  7. "github.com/QuantumNous/new-api/types"
  8. )
  9. const ModelDisplayPricingOptionKey = "ModelDisplayPricing"
  10. var displayPricingMap = types.NewRWMap[string, []types.ModelDisplayPricingItem]()
  11. func GetModelDisplayPricing(model string) []types.ModelDisplayPricingItem {
  12. items, ok := displayPricingMap.Get(model)
  13. if !ok {
  14. return nil
  15. }
  16. return types.CloneModelDisplayPricingItems(items)
  17. }
  18. func GetModelDisplayPricingCopy() map[string][]types.ModelDisplayPricingItem {
  19. src := displayPricingMap.ReadAll()
  20. dst := make(map[string][]types.ModelDisplayPricingItem, len(src))
  21. for model, items := range src {
  22. dst[model] = types.CloneModelDisplayPricingItems(items)
  23. }
  24. return dst
  25. }
  26. func SetModelDisplayPricing(model string, items []types.ModelDisplayPricingItem) error {
  27. model = strings.TrimSpace(model)
  28. if model == "" {
  29. return fmt.Errorf("model name is required")
  30. }
  31. normalized, err := normalizeModelDisplayPricingItems(items)
  32. if err != nil {
  33. return err
  34. }
  35. displayPricingMap.Set(model, normalized)
  36. InvalidateExposedDataCache()
  37. return nil
  38. }
  39. func DeleteModelDisplayPricing(model string) error {
  40. all := displayPricingMap.ReadAll()
  41. delete(all, model)
  42. displayPricingMap.Clear()
  43. displayPricingMap.AddAll(all)
  44. InvalidateExposedDataCache()
  45. return nil
  46. }
  47. func ModelDisplayPricing2JSONString() string {
  48. bytes, err := common.Marshal(GetModelDisplayPricingCopy())
  49. if err != nil {
  50. return "{}"
  51. }
  52. return string(bytes)
  53. }
  54. func UpdateModelDisplayPricingByJSONString(jsonStr string) error {
  55. if strings.TrimSpace(jsonStr) == "" {
  56. jsonStr = "{}"
  57. }
  58. raw := map[string][]types.ModelDisplayPricingItem{}
  59. if err := common.UnmarshalJsonStr(jsonStr, &raw); err != nil {
  60. return err
  61. }
  62. next := make(map[string][]types.ModelDisplayPricingItem, len(raw))
  63. for model, items := range raw {
  64. model = strings.TrimSpace(model)
  65. if model == "" {
  66. return fmt.Errorf("model name is required")
  67. }
  68. normalized, err := normalizeModelDisplayPricingItems(items)
  69. if err != nil {
  70. return fmt.Errorf("model %s: %w", model, err)
  71. }
  72. next[model] = normalized
  73. }
  74. displayPricingMap.Clear()
  75. displayPricingMap.AddAll(next)
  76. InvalidateExposedDataCache()
  77. return nil
  78. }
  79. func normalizeModelDisplayPricingItems(items []types.ModelDisplayPricingItem) ([]types.ModelDisplayPricingItem, error) {
  80. normalized := types.CloneModelDisplayPricingItems(items)
  81. for i := range normalized {
  82. item := &normalized[i]
  83. item.Specification = strings.TrimSpace(item.Specification)
  84. item.OfficialSupplierTip = strings.TrimSpace(item.OfficialSupplierTip)
  85. item.Unit = strings.TrimSpace(item.Unit)
  86. if item.Specification == "" {
  87. return nil, fmt.Errorf("row %d: specification is required", i)
  88. }
  89. if item.Price < 0 {
  90. return nil, fmt.Errorf("row %d: price must be >= 0", i)
  91. }
  92. if item.Unit == "" {
  93. return nil, fmt.Errorf("row %d: unit is required", i)
  94. }
  95. if item.DiscountRate == 0 {
  96. item.DiscountRate = 1
  97. }
  98. if item.DiscountRate <= 0 || item.DiscountRate > 1 {
  99. return nil, fmt.Errorf("row %d: discount_rate must be > 0 and <= 1", i)
  100. }
  101. }
  102. sort.SliceStable(normalized, func(i, j int) bool {
  103. if normalized[i].SortOrder != normalized[j].SortOrder {
  104. return normalized[i].SortOrder < normalized[j].SortOrder
  105. }
  106. return normalized[i].Specification < normalized[j].Specification
  107. })
  108. return normalized, nil
  109. }