mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
fix: 修复订阅支付金额显示错误
This commit is contained in:
@@ -275,7 +275,7 @@ import { platformAccentBarClass, platformBadgeLightClass, platformBadgeClass, pl
|
||||
import SubscriptionPlanCard from '@/components/payment/SubscriptionPlanCard.vue'
|
||||
import PaymentStatusPanel from '@/components/payment/PaymentStatusPanel.vue'
|
||||
import Icon from '@/components/icons/Icon.vue'
|
||||
import { DEFAULT_PAYMENT_CURRENCY, formatPaymentAmount, normalizePaymentCurrency } from '@/components/payment/currency'
|
||||
import { formatPaymentAmount, normalizePaymentCurrency } from '@/components/payment/currency'
|
||||
import type { PaymentMethodOption } from '@/components/payment/PaymentMethodSelector.vue'
|
||||
import { buildPaymentErrorToastMessage, describePaymentScenarioError } from './paymentUx'
|
||||
import { hasWechatResumeQuery, parseWechatResumeRoute, stripWechatResumeQuery } from './paymentWechatResume'
|
||||
@@ -540,10 +540,6 @@ const localeCode = computed(() => {
|
||||
return undefined
|
||||
})
|
||||
|
||||
interface PaymentAmountFormatOptions {
|
||||
subscription?: boolean
|
||||
}
|
||||
|
||||
function currencyFractionDigits(currency: string): number {
|
||||
try {
|
||||
return new Intl.NumberFormat(undefined, {
|
||||
@@ -567,22 +563,12 @@ function ceilPaymentAmount(value: number, currency: string): number {
|
||||
return Math.ceil(value * factor) / factor
|
||||
}
|
||||
|
||||
function subscriptionPaymentAmountForCurrency(value: number, currency: string): number {
|
||||
if (currency !== DEFAULT_PAYMENT_CURRENCY) return value
|
||||
return roundPaymentAmount(value / balanceRechargeMultiplier.value, currency)
|
||||
}
|
||||
|
||||
function subscriptionPaymentAmount(value: number): number {
|
||||
return subscriptionPaymentAmountForCurrency(value, selectedCurrency.value)
|
||||
}
|
||||
|
||||
function formatSelectedPaymentAmount(value: number, options: PaymentAmountFormatOptions = {}): string {
|
||||
const amount = options.subscription ? subscriptionPaymentAmount(value) : value
|
||||
return formatPaymentAmount(amount, selectedCurrency.value, localeCode.value)
|
||||
function formatSelectedPaymentAmount(value: number): string {
|
||||
return formatPaymentAmount(value, selectedCurrency.value, localeCode.value)
|
||||
}
|
||||
|
||||
function formatSelectedSubscriptionPaymentAmount(value: number): string {
|
||||
return formatSelectedPaymentAmount(value, { subscription: true })
|
||||
return formatSelectedPaymentAmount(roundPaymentAmount(value, selectedCurrency.value))
|
||||
}
|
||||
|
||||
const methodOptions = computed<PaymentMethodOption[]>(() =>
|
||||
@@ -631,7 +617,7 @@ const canSubmit = computed(() =>
|
||||
|
||||
const subPaymentAmount = computed(() => {
|
||||
const price = selectedPlan.value?.price ?? 0
|
||||
return subscriptionPaymentAmount(price)
|
||||
return roundPaymentAmount(price, selectedCurrency.value)
|
||||
})
|
||||
|
||||
const subFeeAmount = computed(() => {
|
||||
@@ -645,7 +631,7 @@ const subTotalAmount = computed(() => {
|
||||
})
|
||||
|
||||
function subscriptionTotalAmountForCurrency(value: number, currency: string): number {
|
||||
const paymentAmount = subscriptionPaymentAmountForCurrency(value, currency)
|
||||
const paymentAmount = roundPaymentAmount(value, currency)
|
||||
if (feeRate.value <= 0 || paymentAmount <= 0) return paymentAmount
|
||||
const fee = ceilPaymentAmount((paymentAmount * feeRate.value) / 100, currency)
|
||||
return roundPaymentAmount(paymentAmount + fee, currency)
|
||||
|
||||
@@ -236,28 +236,29 @@ async function mountSubscriptionConfirm(options: Parameters<typeof checkoutInfoW
|
||||
}
|
||||
|
||||
describe('PaymentView subscription confirmation amounts', () => {
|
||||
it('shows converted CNY pay amount for plan price, original price, and create button', async () => {
|
||||
it('keeps subscription plan price independent from balance recharge multiplier', async () => {
|
||||
const wrapper = await mountSubscriptionConfirm({
|
||||
checkout: {
|
||||
balance_recharge_multiplier: 0.14,
|
||||
balance_recharge_multiplier: 4,
|
||||
},
|
||||
method: {
|
||||
currency: 'CNY',
|
||||
},
|
||||
plan: {
|
||||
price: 7.99,
|
||||
original_price: 9.99,
|
||||
price: 200,
|
||||
original_price: 300,
|
||||
},
|
||||
})
|
||||
|
||||
const text = wrapper.text()
|
||||
const convertedPrice = formatPaymentAmount(57.07, 'CNY')
|
||||
const convertedOriginalPrice = formatPaymentAmount(71.36, 'CNY')
|
||||
const planPrice = formatPaymentAmount(200, 'CNY')
|
||||
const originalPrice = formatPaymentAmount(300, 'CNY')
|
||||
const convertedByRechargeMultiplier = formatPaymentAmount(50, 'CNY')
|
||||
|
||||
expect(text).toContain(convertedPrice)
|
||||
expect(text).toContain(convertedOriginalPrice)
|
||||
expect(text).not.toContain(formatPaymentAmount(7.99, 'CNY'))
|
||||
expect(wrapper.findAll('button').some(button => button.text().includes(convertedPrice))).toBe(true)
|
||||
expect(text).toContain(planPrice)
|
||||
expect(text).toContain(originalPrice)
|
||||
expect(text).not.toContain(convertedByRechargeMultiplier)
|
||||
expect(wrapper.findAll('button').some(button => button.text().includes(planPrice))).toBe(true)
|
||||
})
|
||||
|
||||
it('keeps plan price when multiplier is not configured or payment currency is not CNY', async () => {
|
||||
@@ -293,10 +294,10 @@ describe('PaymentView subscription confirmation amounts', () => {
|
||||
expect(usdWrapper.text()).toContain(formatPaymentAmount(9.99, 'USD'))
|
||||
})
|
||||
|
||||
it('adds fee rate after CNY multiplier conversion to match backend pay_amount', async () => {
|
||||
it('adds fee rate to the direct subscription plan price to match backend pay_amount', async () => {
|
||||
const wrapper = await mountSubscriptionConfirm({
|
||||
checkout: {
|
||||
balance_recharge_multiplier: 0.14,
|
||||
balance_recharge_multiplier: 4,
|
||||
recharge_fee_rate: 2.5,
|
||||
},
|
||||
method: {
|
||||
@@ -308,11 +309,11 @@ describe('PaymentView subscription confirmation amounts', () => {
|
||||
})
|
||||
|
||||
const text = wrapper.text()
|
||||
const convertedPrice = formatPaymentAmount(57.07, 'CNY')
|
||||
const fee = formatPaymentAmount(1.43, 'CNY')
|
||||
const total = formatPaymentAmount(58.5, 'CNY')
|
||||
const price = formatPaymentAmount(7.99, 'CNY')
|
||||
const fee = formatPaymentAmount(0.20, 'CNY')
|
||||
const total = formatPaymentAmount(8.19, 'CNY')
|
||||
|
||||
expect(text).toContain(convertedPrice)
|
||||
expect(text).toContain(price)
|
||||
expect(text).toContain(fee)
|
||||
expect(text).toContain(total)
|
||||
expect(wrapper.findAll('button').some(button => button.text().includes(total))).toBe(true)
|
||||
|
||||
Reference in New Issue
Block a user