mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-09-07 01:56:53 +00:00
feat(default): reorganize system settings pricing UI
Refine the default system settings structure and model pricing editor so pricing configuration is easier to scan and edit.
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import { SettingsPage } from '../components/settings-page'
|
||||
import type { BillingSettings } from '../types'
|
||||
import {
|
||||
BILLING_DEFAULT_SECTION,
|
||||
getBillingSectionContent,
|
||||
} from './section-registry.tsx'
|
||||
|
||||
const defaultBillingSettings: BillingSettings = {
|
||||
QuotaForNewUser: 0,
|
||||
PreConsumedQuota: 0,
|
||||
QuotaForInviter: 0,
|
||||
QuotaForInvitee: 0,
|
||||
TopUpLink: '',
|
||||
'general_setting.docs_link': '',
|
||||
'quota_setting.enable_free_model_pre_consume': true,
|
||||
QuotaPerUnit: 500000,
|
||||
USDExchangeRate: 7,
|
||||
'general_setting.quota_display_type': 'USD',
|
||||
'general_setting.custom_currency_symbol': '¤',
|
||||
'general_setting.custom_currency_exchange_rate': 1,
|
||||
DisplayInCurrencyEnabled: true,
|
||||
DisplayTokenStatEnabled: true,
|
||||
ModelPrice: '',
|
||||
ModelRatio: '',
|
||||
CacheRatio: '',
|
||||
CreateCacheRatio: '',
|
||||
CompletionRatio: '',
|
||||
ImageRatio: '',
|
||||
AudioRatio: '',
|
||||
AudioCompletionRatio: '',
|
||||
ExposeRatioEnabled: false,
|
||||
'billing_setting.billing_mode': '{}',
|
||||
'billing_setting.billing_expr': '{}',
|
||||
'tool_price_setting.prices': '{}',
|
||||
TopupGroupRatio: '',
|
||||
GroupRatio: '',
|
||||
UserUsableGroups: '',
|
||||
GroupGroupRatio: '',
|
||||
AutoGroups: '',
|
||||
DefaultUseAutoGroup: false,
|
||||
'group_ratio_setting.group_special_usable_group': '{}',
|
||||
PayAddress: '',
|
||||
EpayId: '',
|
||||
EpayKey: '',
|
||||
Price: 7.3,
|
||||
MinTopUp: 1,
|
||||
CustomCallbackAddress: '',
|
||||
PayMethods: '',
|
||||
'payment_setting.amount_options': '',
|
||||
'payment_setting.amount_discount': '',
|
||||
StripeApiSecret: '',
|
||||
StripeWebhookSecret: '',
|
||||
StripePriceId: '',
|
||||
StripeUnitPrice: 8.0,
|
||||
StripeMinTopUp: 1,
|
||||
StripePromotionCodesEnabled: false,
|
||||
CreemApiKey: '',
|
||||
CreemWebhookSecret: '',
|
||||
CreemTestMode: false,
|
||||
CreemProducts: '[]',
|
||||
WaffoEnabled: false,
|
||||
WaffoApiKey: '',
|
||||
WaffoPrivateKey: '',
|
||||
WaffoPublicCert: '',
|
||||
WaffoSandboxPublicCert: '',
|
||||
WaffoSandboxApiKey: '',
|
||||
WaffoSandboxPrivateKey: '',
|
||||
WaffoSandbox: false,
|
||||
WaffoMerchantId: '',
|
||||
WaffoCurrency: 'USD',
|
||||
WaffoUnitPrice: 1,
|
||||
WaffoMinTopUp: 1,
|
||||
WaffoNotifyUrl: '',
|
||||
WaffoReturnUrl: '',
|
||||
WaffoPayMethods: '[]',
|
||||
WaffoPancakeEnabled: false,
|
||||
WaffoPancakeSandbox: false,
|
||||
WaffoPancakeMerchantID: '',
|
||||
WaffoPancakePrivateKey: '',
|
||||
WaffoPancakeWebhookPublicKey: '',
|
||||
WaffoPancakeWebhookTestKey: '',
|
||||
WaffoPancakeStoreID: '',
|
||||
WaffoPancakeProductID: '',
|
||||
WaffoPancakeReturnURL: '',
|
||||
WaffoPancakeCurrency: 'USD',
|
||||
WaffoPancakeUnitPrice: 1,
|
||||
WaffoPancakeMinTopUp: 1,
|
||||
'checkin_setting.enabled': false,
|
||||
'checkin_setting.min_quota': 1000,
|
||||
'checkin_setting.max_quota': 10000,
|
||||
}
|
||||
|
||||
export function BillingSettings() {
|
||||
return (
|
||||
<SettingsPage
|
||||
routePath='/_authenticated/system-settings/billing/$section'
|
||||
defaultSettings={defaultBillingSettings}
|
||||
defaultSection={BILLING_DEFAULT_SECTION}
|
||||
getSectionContent={getBillingSectionContent}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
import { parseCurrencyDisplayType } from '@/lib/currency'
|
||||
import type { BillingSettings } from '../types'
|
||||
import { createSectionRegistry } from '../utils/section-registry'
|
||||
import { CheckinSettingsSection } from '../general/checkin-settings-section'
|
||||
import { PricingSection } from '../general/pricing-section'
|
||||
import { QuotaSettingsSection } from '../general/quota-settings-section'
|
||||
import { PaymentSettingsSection } from '../integrations/payment-settings-section'
|
||||
import { RatioSettingsCard } from '../models/ratio-settings-card'
|
||||
|
||||
const getModelDefaults = (settings: BillingSettings) => ({
|
||||
ModelPrice: settings.ModelPrice,
|
||||
ModelRatio: settings.ModelRatio,
|
||||
CacheRatio: settings.CacheRatio,
|
||||
CreateCacheRatio: settings.CreateCacheRatio,
|
||||
CompletionRatio: settings.CompletionRatio,
|
||||
ImageRatio: settings.ImageRatio,
|
||||
AudioRatio: settings.AudioRatio,
|
||||
AudioCompletionRatio: settings.AudioCompletionRatio,
|
||||
ExposeRatioEnabled: settings.ExposeRatioEnabled,
|
||||
BillingMode: settings['billing_setting.billing_mode'],
|
||||
BillingExpr: settings['billing_setting.billing_expr'],
|
||||
})
|
||||
|
||||
const getGroupDefaults = (settings: BillingSettings) => ({
|
||||
TopupGroupRatio: settings.TopupGroupRatio,
|
||||
GroupRatio: settings.GroupRatio,
|
||||
UserUsableGroups: settings.UserUsableGroups,
|
||||
GroupGroupRatio: settings.GroupGroupRatio,
|
||||
AutoGroups: settings.AutoGroups,
|
||||
DefaultUseAutoGroup: settings.DefaultUseAutoGroup,
|
||||
GroupSpecialUsableGroup:
|
||||
settings['group_ratio_setting.group_special_usable_group'],
|
||||
})
|
||||
|
||||
const BILLING_SECTIONS = [
|
||||
{
|
||||
id: 'quota',
|
||||
titleKey: 'Quota Settings',
|
||||
descriptionKey: 'Configure user quota allocation and rewards',
|
||||
build: (settings: BillingSettings) => (
|
||||
<QuotaSettingsSection
|
||||
defaultValues={{
|
||||
QuotaForNewUser: settings.QuotaForNewUser,
|
||||
PreConsumedQuota: settings.PreConsumedQuota,
|
||||
QuotaForInviter: settings.QuotaForInviter,
|
||||
QuotaForInvitee: settings.QuotaForInvitee,
|
||||
TopUpLink: settings.TopUpLink,
|
||||
'general_setting.docs_link': settings['general_setting.docs_link'],
|
||||
'quota_setting.enable_free_model_pre_consume':
|
||||
settings['quota_setting.enable_free_model_pre_consume'],
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'currency',
|
||||
titleKey: 'Currency & Display',
|
||||
descriptionKey: 'Configure currency conversion and quota display options',
|
||||
build: (settings: BillingSettings) => (
|
||||
<PricingSection
|
||||
defaultValues={{
|
||||
QuotaPerUnit: settings.QuotaPerUnit,
|
||||
USDExchangeRate: settings.USDExchangeRate,
|
||||
DisplayInCurrencyEnabled: settings.DisplayInCurrencyEnabled,
|
||||
DisplayTokenStatEnabled: settings.DisplayTokenStatEnabled,
|
||||
general_setting: {
|
||||
quota_display_type: parseCurrencyDisplayType(
|
||||
settings['general_setting.quota_display_type']
|
||||
),
|
||||
custom_currency_symbol:
|
||||
settings['general_setting.custom_currency_symbol'] ?? '¤',
|
||||
custom_currency_exchange_rate:
|
||||
settings['general_setting.custom_currency_exchange_rate'] ?? 1,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'model-pricing',
|
||||
titleKey: 'Model Pricing',
|
||||
descriptionKey: 'Configure model pricing ratios and tool prices',
|
||||
build: (settings: BillingSettings) => (
|
||||
<RatioSettingsCard
|
||||
titleKey='Model Pricing'
|
||||
descriptionKey='Configure model pricing ratios and tool prices'
|
||||
modelDefaults={getModelDefaults(settings)}
|
||||
groupDefaults={getGroupDefaults(settings)}
|
||||
toolPricesDefault={settings['tool_price_setting.prices']}
|
||||
visibleTabs={['models', 'tool-prices', 'upstream-sync']}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'group-pricing',
|
||||
titleKey: 'Group Pricing',
|
||||
descriptionKey: 'Configure group ratios and group-specific pricing rules',
|
||||
build: (settings: BillingSettings) => (
|
||||
<RatioSettingsCard
|
||||
titleKey='Group Pricing'
|
||||
descriptionKey='Configure group ratios and group-specific pricing rules'
|
||||
modelDefaults={getModelDefaults(settings)}
|
||||
groupDefaults={getGroupDefaults(settings)}
|
||||
toolPricesDefault={settings['tool_price_setting.prices']}
|
||||
visibleTabs={['groups']}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'payment',
|
||||
titleKey: 'Payment Gateway',
|
||||
descriptionKey: 'Configure payment gateway integrations',
|
||||
build: (settings: BillingSettings) => (
|
||||
<PaymentSettingsSection
|
||||
defaultValues={{
|
||||
PayAddress: settings.PayAddress,
|
||||
EpayId: settings.EpayId,
|
||||
EpayKey: settings.EpayKey,
|
||||
Price: settings.Price,
|
||||
MinTopUp: settings.MinTopUp,
|
||||
CustomCallbackAddress: settings.CustomCallbackAddress,
|
||||
PayMethods: settings.PayMethods,
|
||||
AmountOptions: settings['payment_setting.amount_options'],
|
||||
AmountDiscount: settings['payment_setting.amount_discount'],
|
||||
StripeApiSecret: settings.StripeApiSecret,
|
||||
StripeWebhookSecret: settings.StripeWebhookSecret,
|
||||
StripePriceId: settings.StripePriceId,
|
||||
StripeUnitPrice: settings.StripeUnitPrice,
|
||||
StripeMinTopUp: settings.StripeMinTopUp,
|
||||
StripePromotionCodesEnabled: settings.StripePromotionCodesEnabled,
|
||||
CreemApiKey: settings.CreemApiKey,
|
||||
CreemWebhookSecret: settings.CreemWebhookSecret,
|
||||
CreemTestMode: settings.CreemTestMode,
|
||||
CreemProducts: settings.CreemProducts,
|
||||
}}
|
||||
waffoDefaultValues={{
|
||||
WaffoEnabled: settings.WaffoEnabled ?? false,
|
||||
WaffoApiKey: settings.WaffoApiKey ?? '',
|
||||
WaffoPrivateKey: settings.WaffoPrivateKey ?? '',
|
||||
WaffoPublicCert: settings.WaffoPublicCert ?? '',
|
||||
WaffoSandboxPublicCert: settings.WaffoSandboxPublicCert ?? '',
|
||||
WaffoSandboxApiKey: settings.WaffoSandboxApiKey ?? '',
|
||||
WaffoSandboxPrivateKey: settings.WaffoSandboxPrivateKey ?? '',
|
||||
WaffoSandbox: settings.WaffoSandbox ?? false,
|
||||
WaffoMerchantId: settings.WaffoMerchantId ?? '',
|
||||
WaffoCurrency: settings.WaffoCurrency ?? 'USD',
|
||||
WaffoUnitPrice: settings.WaffoUnitPrice ?? 1,
|
||||
WaffoMinTopUp: settings.WaffoMinTopUp ?? 1,
|
||||
WaffoNotifyUrl: settings.WaffoNotifyUrl ?? '',
|
||||
WaffoReturnUrl: settings.WaffoReturnUrl ?? '',
|
||||
WaffoPayMethods: settings.WaffoPayMethods ?? '[]',
|
||||
}}
|
||||
waffoPancakeDefaultValues={{
|
||||
WaffoPancakeEnabled: settings.WaffoPancakeEnabled ?? false,
|
||||
WaffoPancakeSandbox: settings.WaffoPancakeSandbox ?? false,
|
||||
WaffoPancakeMerchantID: settings.WaffoPancakeMerchantID ?? '',
|
||||
WaffoPancakePrivateKey: settings.WaffoPancakePrivateKey ?? '',
|
||||
WaffoPancakeWebhookPublicKey:
|
||||
settings.WaffoPancakeWebhookPublicKey ?? '',
|
||||
WaffoPancakeWebhookTestKey:
|
||||
settings.WaffoPancakeWebhookTestKey ?? '',
|
||||
WaffoPancakeStoreID: settings.WaffoPancakeStoreID ?? '',
|
||||
WaffoPancakeProductID: settings.WaffoPancakeProductID ?? '',
|
||||
WaffoPancakeReturnURL: settings.WaffoPancakeReturnURL ?? '',
|
||||
WaffoPancakeCurrency: settings.WaffoPancakeCurrency ?? 'USD',
|
||||
WaffoPancakeUnitPrice: settings.WaffoPancakeUnitPrice ?? 1,
|
||||
WaffoPancakeMinTopUp: settings.WaffoPancakeMinTopUp ?? 1,
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'checkin',
|
||||
titleKey: 'Check-in Rewards',
|
||||
descriptionKey: 'Configure daily check-in rewards for users',
|
||||
build: (settings: BillingSettings) => (
|
||||
<CheckinSettingsSection
|
||||
defaultValues={{
|
||||
enabled: settings['checkin_setting.enabled'],
|
||||
minQuota: settings['checkin_setting.min_quota'],
|
||||
maxQuota: settings['checkin_setting.max_quota'],
|
||||
}}
|
||||
/>
|
||||
),
|
||||
},
|
||||
] as const
|
||||
|
||||
export type BillingSectionId = (typeof BILLING_SECTIONS)[number]['id']
|
||||
|
||||
const billingRegistry = createSectionRegistry<BillingSectionId, BillingSettings>(
|
||||
{
|
||||
sections: BILLING_SECTIONS,
|
||||
defaultSection: 'quota',
|
||||
basePath: '/system-settings/billing',
|
||||
urlStyle: 'path',
|
||||
}
|
||||
)
|
||||
|
||||
export const BILLING_SECTION_IDS = billingRegistry.sectionIds
|
||||
export const BILLING_DEFAULT_SECTION = billingRegistry.defaultSection
|
||||
export const getBillingSectionNavItems = billingRegistry.getSectionNavItems
|
||||
export const getBillingSectionContent = billingRegistry.getSectionContent
|
||||
Reference in New Issue
Block a user