# 工具函数

`@blocklet/payment-react` 库导出了一套工具函数和类，旨在简化常见任务，例如发出 API 请求、管理缓存、处理日期、格式化价格和设置国际化。这些工具旨在与库的组件和提供程序无缝协作。

## API 客户端

该库提供了一个预配置的 Axios 实例，用于向你的支付后端发出 API 请求。它会自动处理基本 URL 和其他必要的配置。

```tsx API Client Usage icon=logos:javascript
import { api } from '@blocklet/payment-react';

// 基本的 GET 请求
const getPayments = async () => {
  const response = await api.get('/api/payments');
  return response.data;
};

// 带负载的 POST 请求
const createCheckout = async (amount) => {
  const data = await api.post('/api/checkout', { amount });
  return data;
};

// 带查询参数的 GET 请求
const getPaidInvoices = async () => {
  const results = await api.get('/api/invoices', { 
    params: { status: 'paid' } 
  });
  return results.data;
};

// 带附加配置的 PUT 请求
const updateSubscription = async (data) => {
  const config = { 
    headers: { 'Custom-Header': 'value' }
  };
  const response = await api.put('/api/subscription', data, config);
  return response.data;
};
```

## CachedRequest

为了优化性能并减少冗余的网络请求，你可以使用 `CachedRequest` 类。它提供了一种简单的方法来缓存数据，具有可配置的策略和生存时间（TTL）。

### 配置选项

在创建 `CachedRequest` 实例时，你可以提供以下选项：

| 选项 | 类型 | 描述 | 默认值 |
| :--- | :--- | :--- | :--- |
| `strategy` | `'session' \| 'local' \| 'memory'` | 缓存的存储机制。 | `'session'` |
| `ttl` | `number` | 缓存的生存时间（毫秒）。值为 `0` 表示永不过期。 | `0` |

### 使用示例

以下是如何创建和使用缓存请求来获取产品价格的示例。

```tsx CachedRequest Example icon=logos:javascript
import { CachedRequest, api } from '@blocklet/payment-react';

// 1. 创建一个缓存请求实例
const priceRequest = new CachedRequest(
  'product-prices', 
  () => api.get('/api/prices'),
  {
    strategy: 'session',  // 在 sessionStorage 中缓存数据
    ttl: 5 * 60 * 1000   // 缓存 5 分钟
  }
);

// 2. 在你的组件中使用缓存请求
async function fetchPrices() {
  // 如果缓存可用且未过期，将使用缓存
  const prices = await priceRequest.fetch();
  
  // 绕过缓存并强制获取新数据
  const freshPrices = await priceRequest.fetch(true);
  
  return prices;
}

// 3. 当数据发生变化时清除缓存
async function updatePrices() {
  await api.post('/api/prices', newPriceData);
  priceRequest.clearCache(); // 或者 await priceRequest.fetch(true);
}
```

## 日期处理

该库重新导出了一个预配置的 `dayjs` 实例，其中已包含 `relativeTime`、`utc` 和 `timezone` 等有用的插件。你可以用它来满足任何日期和时间操作的需求。

```tsx Date Handling with dayjs icon=logos:javascript
import { dayjs } from '@blocklet/payment-react';

// 格式化当前日期
const formattedDate = dayjs().format('YYYY-MM-DD HH:mm');

// 解析时间戳
const dateFromTimestamp = dayjs(1672531200000);
const unixTimestamp = dateFromTimestamp.unix();

// 计算相对时间
const fiveMinutesAgo = dayjs().subtract(5, 'minute');
const relativeTime = dayjs().from(fiveMinutesAgo); // "5 分钟前"
```

## 国际化 (i18n)

`@blocklet/payment-react` 内置了对 i18n 的支持。你可以创建自己的翻译器，也可以将你的翻译与库的默认翻译合并。

### 创建翻译器

使用 `createTranslator` 函数来设置你自己的翻译实例。

```tsx Custom Translator Setup icon=logos:javascript
import { createTranslator } from '@blocklet/payment-react';

const myTranslations = {
  en: { 
    checkout: { title: 'Complete Payment' }
  },
  zh: { 
    checkout: { title: '完成支付' }
  }
};

const translator = createTranslator({ fallbackLocale: 'en' }, myTranslations);

translator('checkout.title', 'zh'); // '完成支付'
```

### 与库翻译合并

为了在添加自己的翻译的同时利用库为组件提供的内置翻译，你可以将它们合并在一起。

```tsx Merging Translations icon=logos:javascript
import { translations as paymentTranslations } from '@blocklet/payment-react';
import merge from 'lodash/merge';

// 你的应用程序的翻译
import en from './locales/en';
import zh from './locales/zh';

export const translations = merge(
  {
    en,
    zh,
  },
  paymentTranslations
);
```

## 格式化工具

有几个辅助函数可用于格式化数据显示。

| 函数 | 描述 |
| :--- | :--- |
| `formatPrice` | 将价格对象格式化为人类可读的字符串，并考虑重复周期。 |
| `formatRecurring` | 将重复周期对象格式化为“每月”或“每 3 个月”之类的字符串。 |
| `formatBNStr` | 将 BigNumber 字符串从基本单位格式化为具有指定精度的代币值。 |
| `formatNumber` | 使用千位分隔符和指定精度格式化数字或字符串。 |
| `formatError` | 将各种错误格式（GraphQL、Joi、Axios）解析为可读的字符串。 |

```tsx Formatting Example icon=logos:javascript
import { formatNumber, formatRecurring } from '@blocklet/payment-react';

// 格式化数字
const formatted = formatNumber('1234567.89123', 2); // "1,234,567.89"

// 格式化重复周期
const monthly = formatRecurring({ interval: 'month', interval_count: 1 }); // "每月"
const quarterly = formatRecurring({ interval: 'month', interval_count: 3 }); // "每季度"
```

## 验证工具

该库还包含用于表单验证的辅助函数。

### `validatePostalCode`

检查给定的邮政编码对于特定国家是否有效。

```tsx Postal Code Validation icon=logos:javascript
import { validatePostalCode } from '@blocklet/payment-react';

// 返回 true
const isValidUS = validatePostalCode('90210', 'US');

// 返回 false
const isInvalidUS = validatePostalCode('ABC-123', 'US');

// 对于英国邮政编码，返回 true
const isValidGB = validatePostalCode('SW1A 0AA', 'GB');
```