Prmbr/docs/pricing-page-improvements.md
2025-08-05 23:18:40 +08:00

4.5 KiB
Raw Permalink Blame History

定价页面改进说明

概述

定价页面现在实现了智能的套餐过滤和按钮显示逻辑,确保只显示有效的可订阅套餐,并提供清晰的用户体验。

主要改进

1. 智能套餐过滤

定价页面现在只显示以下套餐:

  1. 免费套餐 - 总是显示
  2. 用户当前套餐 - 总是显示(即使没有 stripePriceId
  3. 有效的付费套餐 - 必须有 stripePriceId 才显示

过滤逻辑

const filteredPlans = plans.filter((plan: SubscriptionPlan) => {
  // 免费套餐总是显示
  if (isPlanFree(plan)) return true
  
  // 用户当前套餐总是显示
  if (userData && isCurrentPlan(plan.id)) return true
  
  // 其他套餐必须有 stripePriceId 才能显示(可订阅)
  return plan.stripePriceId && plan.stripePriceId.trim() !== ''
})

2. 智能按钮显示

按钮显示遵循以下逻辑:

免费套餐

  • 当前套餐: 显示 "当前方案" 按钮(禁用)
  • 非当前套餐: 不显示任何按钮

付费套餐

  • 当前套餐: 显示 "当前方案" 按钮(禁用)
  • 可订阅套餐: 显示 "立即订阅" 按钮
  • 无价格ID套餐: 不显示按钮(理论上不会出现,因为已过滤)

按钮逻辑代码

{(() => {
  // 免费套餐逻辑
  if (isFree) {
    if (isCurrent) {
      return <Button variant="outline" disabled>{t('currentPlan')}</Button>
    }
    return null // 免费套餐且非当前套餐,不显示按钮
  }
  
  // 付费套餐逻辑
  if (isCurrent) {
    return <Button variant="outline" disabled>{t('currentPlan')}</Button>
  }
  
  // 可订阅的付费套餐
  if (plan.stripePriceId && plan.stripePriceId.trim() !== '') {
    return (
      <SubscribeButton priceId={plan.stripePriceId} planName={plan.displayName}>
        {t('subscribeNow')}
      </SubscribeButton>
    )
  }
  
  return null
})()}

3. 多语言支持

添加了新的翻译键:

英文 (en.json)

{
  "pricing": {
    "subscribeNow": "Subscribe Now",
    "currentPlan": "Current Plan"
  }
}

中文 (zh.json)

{
  "pricing": {
    "subscribeNow": "立即订阅",
    "currentPlan": "当前方案"
  }
}

用户体验场景

1. 匿名用户

  • 看到:免费套餐(无按钮)+ 有价格ID的付费套餐立即订阅按钮
  • 不看到没有价格ID的付费套餐

2. 免费用户

  • 看到:免费套餐(当前方案按钮)+ 有价格ID的付费套餐立即订阅按钮
  • 不看到没有价格ID的付费套餐

3. Pro 用户

  • 看到:免费套餐(无按钮)+ 当前Pro套餐当前方案按钮+ 其他有价格ID的套餐立即订阅按钮
  • 不看到没有价格ID的付费套餐

技术实现

1. 动态数据获取

useEffect(() => {
  fetchPlans()
}, [userData]) // 依赖 userData确保用户数据加载后再过滤套餐

2. 套餐判定工具

使用统一的工具函数:

  • isPlanFree(plan) - 判断是否为免费套餐
  • isPlanPro(plan) - 判断是否为Pro套餐
  • isCurrentPlan(planId) - 判断是否为用户当前套餐

3. 类型安全

const filteredPlans = (data.plans || []).filter((plan: SubscriptionPlan) => {
  // 过滤逻辑
})

配置要求

1. 套餐配置

确保付费套餐有有效的 stripePriceId

-- 检查套餐配置
SELECT id, name, "displayName", price, "stripePriceId", "isActive" 
FROM subscription_plans 
WHERE "isActive" = true;

-- 设置价格ID
UPDATE subscription_plans 
SET "stripePriceId" = 'price_your_stripe_price_id' 
WHERE name = 'pro';

2. 验证工具

使用测试脚本验证配置:

npx tsx scripts/test-pricing-page-filtering.ts

优势

  1. 用户友好: 只显示用户可以实际订阅的套餐
  2. 防止错误: 避免显示无法订阅的套餐
  3. 清晰导航: 明确的按钮状态和操作
  4. 灵活配置: 支持动态套餐管理
  5. 多语言: 完整的国际化支持

故障排除

问题:套餐不显示

原因: 付费套餐没有设置 stripePriceId 解决: 在数据库中设置正确的 Stripe 价格 ID

问题:按钮不显示

原因: 套餐被过滤掉或逻辑判断问题 解决: 检查套餐配置和用户状态

问题:翻译缺失

原因: 缺少 subscribeNow 翻译键 解决: 在对应语言文件中添加翻译

测试建议

  1. 测试不同用户状态下的页面显示
  2. 验证按钮功能和状态
  3. 检查多语言显示
  4. 确认套餐过滤逻辑
  5. 测试订阅流程