# 工具程式

`@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;
};

// 帶有 payload 的 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` 實例時，您可以提供以下選項：

| Option | Type | Description | Default |
| :--- | :--- | :--- | :--- |
| `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
);
```

## 格式化工具程式

提供數個輔助函式可用於格式化顯示資料。

| Function | Description |
| :--- | :--- |
| `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');
```