fix(userapi): период тарифа Macloud и отображение ставки на списке VPS
Docker / build (push) Failing after 1m45s
Docker / build (push) Failing after 1m45s
Месячные планы Macloud определяются через inferPlanPeriod; в UI показывается суточная или месячная ставка по tariffType, а не месячный эквивалент. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -120,6 +120,38 @@ export function tariffTypeLabel(type: string): string {
|
||||
return TARIFF_TYPE_LABELS[type] ?? type
|
||||
}
|
||||
|
||||
function tariffRateNumber(value: number | string | null | undefined): number | null {
|
||||
if (value === '' || value == null) return null
|
||||
const n = Number(value)
|
||||
return Number.isFinite(n) ? n : null
|
||||
}
|
||||
|
||||
/** Сумма тарифа в валюте провайдера: суточная или месячная — по tariffType. */
|
||||
export function vpsTariffRateAmount(vps: {
|
||||
tariffType?: string | null
|
||||
dailyRate?: number | string | null
|
||||
monthlyRate?: number | string | null
|
||||
}): number {
|
||||
const daily = tariffRateNumber(vps.dailyRate)
|
||||
const monthly = tariffRateNumber(vps.monthlyRate)
|
||||
if (vps.tariffType === 'daily') {
|
||||
return daily ?? 0
|
||||
}
|
||||
return monthly ?? 0
|
||||
}
|
||||
|
||||
/** Месячный burn-rate для сортировки и отчётов. */
|
||||
export function vpsTariffMonthlyBurn(vps: {
|
||||
tariffType?: string | null
|
||||
dailyRate?: number | string | null
|
||||
monthlyRate?: number | string | null
|
||||
}): number {
|
||||
const daily = tariffRateNumber(vps.dailyRate) ?? 0
|
||||
const monthly = tariffRateNumber(vps.monthlyRate) ?? 0
|
||||
if (vps.tariffType === 'daily') return daily * 30
|
||||
return monthly
|
||||
}
|
||||
|
||||
const ENVIRONMENT_LABELS: Record<string, string> = {
|
||||
prod: 'Production', dev: 'Development', staging: 'Staging',
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
tariffTypeLabel,
|
||||
vpsStatusLabel,
|
||||
paymentTypeLabel,
|
||||
vpsTariffRateAmount,
|
||||
} from '@/lib/format'
|
||||
import { providerByIdMap, accountSelectLabel } from '@/lib/billmanager'
|
||||
import { VPS_SYNC_OVERRIDE_FIELDS, parseUserOverrides } from '@/lib/vps-sync-fields'
|
||||
@@ -215,11 +216,7 @@ function VpsDetailPage() {
|
||||
<InfoRow
|
||||
label="Ставка"
|
||||
value={formatCurrency(
|
||||
row.monthlyRate != null
|
||||
? Number(row.monthlyRate)
|
||||
: row.tariffType === 'daily'
|
||||
? Number(row.dailyRate || 0) * 30
|
||||
: Number(row.monthlyRate || 0),
|
||||
vpsTariffRateAmount(row),
|
||||
effectiveVpsTariffCurrency(row, provider),
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,7 @@ import { toast } from 'sonner'
|
||||
import { snapshotQueryOptions, ratesQueryOptions } from '@/queries/snapshot'
|
||||
import { api, ApiError } from '@/lib/api-client'
|
||||
import type { VpsFormValues } from '@/lib/schemas'
|
||||
import { normalizeRatesPayload, effectiveVpsTariffCurrency, formatCurrency, vpsStatusLabel, tariffTypeLabel } from '@/lib/format'
|
||||
import { normalizeRatesPayload, effectiveVpsTariffCurrency, formatCurrency, vpsStatusLabel, tariffTypeLabel, vpsTariffRateAmount, vpsTariffMonthlyBurn } from '@/lib/format'
|
||||
import { PageShell } from '@/components/page-shell'
|
||||
import { PageHeader } from '@/components/page-header'
|
||||
import { Button } from '@cfdm/ui/components/button'
|
||||
@@ -408,21 +408,11 @@ function VpsPage() {
|
||||
key: 'tariff',
|
||||
header: 'Тариф',
|
||||
icon: CreditCardIcon,
|
||||
sortValue: (v) =>
|
||||
v.monthlyRate != null
|
||||
? Number(v.monthlyRate)
|
||||
: v.tariffType === 'daily'
|
||||
? Number(v.dailyRate || 0) * 30
|
||||
: 0,
|
||||
sortValue: (v) => vpsTariffMonthlyBurn(v),
|
||||
cell: (v) => {
|
||||
const provider = providerById.get(v.providerId)
|
||||
const currency = effectiveVpsTariffCurrency(v, provider)
|
||||
const amount =
|
||||
v.monthlyRate != null
|
||||
? Number(v.monthlyRate)
|
||||
: v.tariffType === 'daily'
|
||||
? Number(v.dailyRate || 0) * 30
|
||||
: Number(v.monthlyRate || 0)
|
||||
const amount = vpsTariffRateAmount(v)
|
||||
return dataGridCellStack(formatCurrency(amount, currency), tariffTypeLabel(v.tariffType))
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user