diff --git a/packages/shared/src/components/PlatformProfileRechargeModal/index.test.tsx b/packages/shared/src/components/PlatformProfileRechargeModal/index.test.tsx index fbea85958..afb55f7f1 100644 --- a/packages/shared/src/components/PlatformProfileRechargeModal/index.test.tsx +++ b/packages/shared/src/components/PlatformProfileRechargeModal/index.test.tsx @@ -261,6 +261,50 @@ describe('PlatformProfileRechargeModal', () => { expect(onSubmitMembershipCheckout).toHaveBeenCalledWith('max', 'yearly'); }); + test('keeps an active member as member when their current plan is disabled', async () => { + const user = userEvent.setup(); + const onRequestMembershipQuote = vi.fn(); + + render( + , + ); + + // 状态卡仍认得当前档位,而不是退化成「会员」。 + expect(screen.getByText('当前 Plus · 年付')).toBeTruthy(); + // 有效会员看到的是补差升级,而不是可在有效会员上重复开通的「开通会员」。 + await user.click(screen.getByRole('button', { name: 'Max 年付 补差升级' })); + expect(onRequestMembershipQuote).toHaveBeenCalledWith('max'); + + const checkout = screen.getByRole('dialog', { name: '确认套餐变更' }); + // 即使原档位已禁用,升级摘要也要给出「原套餐标准年价」。 + expect(within(checkout).getByText('原套餐标准年价')).toBeTruthy(); + expect(within(checkout).getByText('¥990')).toBeTruthy(); + }); + test('shows a placeholder instead of the list price while the upgrade quote is loading', async () => { const user = userEvent.setup(); diff --git a/packages/shared/src/components/PlatformProfileRechargeModal/index.tsx b/packages/shared/src/components/PlatformProfileRechargeModal/index.tsx index c81eb11f6..e8bd6abea 100644 --- a/packages/shared/src/components/PlatformProfileRechargeModal/index.tsx +++ b/packages/shared/src/components/PlatformProfileRechargeModal/index.tsx @@ -936,7 +936,7 @@ function PlatformPointProductGrid({ function PlatformRechargeCheckoutDialog({ target, membershipPlans, - membership, + currentPlan, membershipQuote, isLoadingMembershipQuote, membershipQuoteError, @@ -949,7 +949,8 @@ function PlatformRechargeCheckoutDialog({ }: { target: PlatformProfileRechargeCheckoutTarget; membershipPlans: ProfileMembershipPlanRecord[]; - membership: ProfileMembership | null; + /** 会员当前档位;来自未过滤目录,档位被后台临时禁用时仍保留「原套餐标准价」。 */ + currentPlan: ProfileMembershipPlanRecord | null; membershipQuote: ProfileMembershipUpgradeQuote | null; isLoadingMembershipQuote: boolean; membershipQuoteError: string | null; @@ -1001,8 +1002,6 @@ function PlatformRechargeCheckoutDialog({ ? (plan?.yearPriceCents ?? 0) : (plan?.monthPriceCents ?? 0); const isUpgrade = target.mode === 'upgrade'; - const currentPlan = - membershipPlans.find((item) => item.plan === membership?.plan) ?? null; const productId = resolveMembershipProductId(target.plan, target.cycleKind); const submitting = submittingProductId === productId; const quoteForTarget = @@ -1317,10 +1316,14 @@ export function PlatformProfileRechargeModal({ () => center?.pointProducts ?? [], [center?.pointProducts], ); + // 当前档位必须从「未过滤目录」里查:会员有效期内若该档被后台临时禁用, + // 过滤后的 membershipPlans 查不到会把有效会员误判成非会员(状态卡丢标题、按钮变「开通会员」)。 const currentPlanRecord = useMemo( () => - membershipPlans.find((plan) => plan.plan === membership?.plan) ?? null, - [membership?.plan, membershipPlans], + (center?.membershipPlans ?? []).find( + (plan) => plan.plan === membership?.plan, + ) ?? null, + [center?.membershipPlans, membership?.plan], ); const [activeTab, setActiveTab] = useState('subscription'); @@ -1546,7 +1549,7 @@ export function PlatformProfileRechargeModal({