# PricingTable

`PricingTable` 组件是一个灵活的 UI 元素，旨在以结构化的响应式表格显示订阅计划和定价选项。它允许用户在计费周期（例如，月度、年度）之间切换，选择他们偏好的货币，并选择一个计划以继续。

该组件非常适合用于构建需要对定价计划的呈现进行精细控制的自定义结账流程。如果需要一个能处理整个结账流程的更集成的解决方案，请考虑使用更高级别的 [`CheckoutTable`](./components-checkout-checkout-table.md) 组件。

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `table` | `TPricingTableExpanded` | - | **必需**。一个包含定价表数据的对象，包括项目（计划）列表、货币信息和其他详细信息。 |
| `onSelect` | `(priceId: string, currencyId: string) => void` | - | **必需**。当用户点击计划的操作按钮时触发的回调函数。它接收所选的 `priceId` 和 `currencyId`。 |
| `alignItems` | `'center' \| 'left'` | `'center'` | 控制表格头部内容（计费周期和货币选择器）的水平对齐方式。 |
| `mode` | `'checkout' \| 'select'` | `'checkout'` | 决定操作按钮的行为和文本。`'checkout'` 模式用于发起支付，而 `'select'` 模式用于在更大的表单中选择一个计划。 |
| `interval` | `string` | `''` | 设置初始选定的计费周期。格式通常是 `interval-interval_count`（例如，`month-1`，`year-1`）。 |
| `hideCurrency` | `boolean` | `false` | 如果为 `true`，即使有多种货币可用，货币选择器下拉列表也将被隐藏。 |

## 用法示例

要使用 `PricingTable`，您必须将其包裹在 `PaymentProvider` 中。该组件需要一个包含您的产品数据的 `table` 对象和一个用于管理用户选择的 `onSelect` 处理程序。

```tsx Integration Example icon=lucide:code
import { PaymentProvider } from '@blocklet/payment-react';
import { PricingTable } from '@blocklet/payment-react/components/ui';
import type { TPricingTableExpanded } from '@blocklet/payment-types';

// 在实际应用中，您将从支付服务中获取此数据。
const pricingTableData: TPricingTableExpanded = {
  id: 'pt_123',
  livemode: false,
  currency: { id: 'usd', symbol: '$' },
  items: [
    {
      price_id: 'price_basic_monthly',
      product: {
        name: '基础计划',
        description: '适用于个人和小型团队。',
        unit_label: '用户',
        features: [{ name: '5 个项目' }, { name: '10GB 存储空间' }, { name: '基础支持' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '1000', // 单位为美分
        recurring: { interval: 'month', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '1000' }],
      },
      is_highlight: false,
    },
    {
      price_id: 'price_pro_monthly',
      product: {
        name: '专业版计划',
        description: '适用于成长中的企业。',
        unit_label: '用户',
        features: [{ name: '无限项目' }, { name: '100GB 存储空间' }, { name: '优先支持' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '2500',
        recurring: { interval: 'month', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '2500' }],
      },
      is_highlight: true,
      highlight_text: '热门',
    },
    {
      price_id: 'price_basic_yearly',
      product: {
        name: '基础计划',
        description: '适用于个人和小型团队。',
        unit_label: '用户',
        features: [{ name: '5 个项目' }, { name: '10GB 存储空间' }, { name: '基础支持' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '10000',
        recurring: { interval: 'year', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '10000' }],
      },
      is_highlight: false,
    },
    {
      price_id: 'price_pro_yearly',
      product: {
        name: '专业版计划',
        description: '适用于成长中的企业。',
        unit_label: '用户',
        features: [{ name: '无限项目' }, { name: '100GB 存储空间' }, { name: '优先支持' }],
      },
      price: {
        currency: 'usd',
        unit_amount: '25000',
        recurring: { interval: 'year', interval_count: 1, usage_type: 'licensed' },
        currency_options: [{ currency_id: 'usd', unit_amount: '25000' }],
      },
      is_highlight: true,
      highlight_text: '热门',
    },
  ],
};

function MyPricingPage() {
  const { session, connect } = useSessionContext();

  const handlePlanSelect = async (priceId: string, currencyId: string) => {
    console.log(`已选择计划：${priceId}，货币：${currencyId}`);
    // 在这里，您通常会导航到结账页面或打开一个支付模态框。
    // 例如：`router.push(\"/checkout?price_id=${priceId}&currency_id=${currencyId}\")`
    alert(`已选择价格 ID：${priceId}`);
  };

  return (
    <PaymentProvider session={session} connect={connect}>
      <div style={{ maxWidth: 800, margin: 'auto' }}>
        <PricingTable table={pricingTableData} onSelect={handlePlanSelect} />
      </div>
    </PaymentProvider>
  );
}

export default MyPricingPage;
```

## 使用场景

### 模式：`checkout` vs. `select`

`mode` prop 会更改号召性用语按钮以适应不同的用例。

-   **`mode='checkout'` (默认):** 按钮文本将具有上下文感知能力，显示“订阅”或“开始试用”等标签。此模式旨在当用户的点击应立即启动支付或结账流程时使用。

-   **`mode='select'`:** 按钮文本将显示“选择”或“已选择”。当定价表是更大表单或多步骤流程的一部分时，这非常有用。`onSelect` 回调可用于更新应用程序状态中的所选计划，并且 UI 将在视觉上指示当前选择的计划。

### 处理 `onSelect`

`onSelect` 回调是处理用户交互的核心机制。它是一个接收所选计划的 `priceId` 和 `currencyId` 的异步函数。您的应用程序逻辑应放在此处。常见操作包括：

-   在应用程序的状态中存储所选的计划。
-   将用户重定向到专用的结账页面，并将 `priceId` 作为 URL 参数传递。
-   使用 `priceId` 与支付服务后端创建一个结账会话，然后打开一个支付表单。