best-unit 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "best-unit",
3
3
  "private": false,
4
- "version": "1.3.1",
4
+ "version": "1.4.1",
5
5
  "type": "module",
6
6
  "main": "dist/best-unit.cjs",
7
7
  "module": "dist/best-unit.js",
package/src/api/index.ts CHANGED
@@ -26,6 +26,7 @@ export function getBalance() {
26
26
  creditUsed: data.credit_used,
27
27
  isCredit: data.credit_config ? true : false,
28
28
  availableAmount: data.available_amount,
29
+ currBalance: data.curr_balance,
29
30
  pendingAmount: data.pending_amount,
30
31
  status: data.status,
31
32
  createdAt: data.created_at,
@@ -128,7 +129,11 @@ export const calcPaymentAmount = async (data: CalcPaymentAmountParams) => {
128
129
  })
129
130
  .then((res) => {
130
131
  const data = res.data;
131
- return data.payment_amount;
132
+ return {
133
+ paymentAmount: data.payment_amount,
134
+ fee: data.fee,
135
+ currency: data.currency,
136
+ }
132
137
  });
133
138
  };
134
139
 
@@ -50,6 +50,7 @@ export const OnlineRechargeForm: FunctionalComponent<
50
50
  const channelDict =
51
51
  allDicts?.channel?.filter((item: any) => item.payment_support) || [];
52
52
  const [actualAmount, setActualAmount] = useState<string>("");
53
+ const [fee, setFee] = useState<string>("");
53
54
  const [showFeeTip, setShowFeeTip] = useState(false);
54
55
  const theme = getOnlineRechargeFormTheme();
55
56
 
@@ -61,8 +62,9 @@ export const OnlineRechargeForm: FunctionalComponent<
61
62
  amount: formState.amount,
62
63
  currency: formState.currency,
63
64
  })
64
- .then((paymentAmount) => {
65
- setActualAmount(paymentAmount);
65
+ .then((data) => {
66
+ setActualAmount(data.paymentAmount);
67
+ setFee(data.fee);
66
68
  setShowFeeTip(true);
67
69
  })
68
70
  .catch((error) => {
@@ -181,6 +183,19 @@ export const OnlineRechargeForm: FunctionalComponent<
181
183
  {t("需要收取手续费,实际支付金额约为:")}${actualAmount}
182
184
  </div>
183
185
  )}
186
+ {showFeeTip && actualAmount && (
187
+ <div style={theme.feeDetailBox}>
188
+ <div style={theme.feeDetailTitle}>
189
+ {t("手续费约为:")}
190
+ <span style={theme.feeAmount}>${fee}</span>
191
+ </div>
192
+ <div style={theme.feeDetailDesc}>
193
+ {t(
194
+ "额外费用说明:您的地区、币种、支付卡类型等因素可能会导致手续费的变动,最终手续费以官方为准。"
195
+ )}
196
+ </div>
197
+ </div>
198
+ )}
184
199
  {formState.error && (
185
200
  <div style={{ color: "#ff4d4f", marginBottom: 12 }}>
186
201
  {formState.error}
@@ -66,6 +66,29 @@ function createOnlineRechargeFormThemes() {
66
66
  fontSize: size === Size.SMALL ? 12 : 14,
67
67
  color: "#52c41a",
68
68
  },
69
+ feeDetailBox: {
70
+ marginTop: size === Size.SMALL ? 8 : 10,
71
+ marginBottom: size === Size.SMALL ? 16 : 20,
72
+ padding: size === Size.SMALL ? "8px 10px" : "12px 16px",
73
+ background: "#fff",
74
+ border: "1px solid #E5E6EB",
75
+ borderRadius: 6,
76
+ },
77
+ feeDetailTitle: {
78
+ fontSize: size === Size.SMALL ? 12 : 14,
79
+ color: "#222",
80
+ fontWeight: 600,
81
+ marginBottom: size === Size.SMALL ? 6 : 8,
82
+ },
83
+ feeAmount: {
84
+ color: "#F53F3F",
85
+ marginLeft: 4,
86
+ },
87
+ feeDetailDesc: {
88
+ fontSize: size === Size.SMALL ? 12 : 13,
89
+ color: "#6b7280",
90
+ lineHeight: 1.5,
91
+ },
69
92
  },
70
93
  dark: {
71
94
  label: {
@@ -127,6 +150,29 @@ function createOnlineRechargeFormThemes() {
127
150
  fontSize: size === Size.SMALL ? 12 : 14,
128
151
  color: "#52c41a",
129
152
  },
153
+ feeDetailBox: {
154
+ marginTop: size === Size.SMALL ? 8 : 10,
155
+ marginBottom: size === Size.SMALL ? 16 : 20,
156
+ padding: size === Size.SMALL ? "8px 10px" : "12px 16px",
157
+ background: "#23262F",
158
+ border: "1px solid #374151",
159
+ borderRadius: 6,
160
+ },
161
+ feeDetailTitle: {
162
+ fontSize: size === Size.SMALL ? 12 : 14,
163
+ color: "#fff",
164
+ fontWeight: 600,
165
+ marginBottom: size === Size.SMALL ? 6 : 8,
166
+ },
167
+ feeAmount: {
168
+ color: "#FF6B6B",
169
+ marginLeft: 4,
170
+ },
171
+ feeDetailDesc: {
172
+ fontSize: size === Size.SMALL ? 12 : 13,
173
+ color: "#B5B8BE",
174
+ lineHeight: 1.5,
175
+ },
130
176
  },
131
177
  };
132
178
  }
@@ -130,7 +130,7 @@ export function Recharge({ visible, onClose, onSubmit }: ModalFormProps) {
130
130
  </button>
131
131
  </div>
132
132
  {/* tab 内容区域 */}
133
- {activeTab === "online" ? (
133
+ <div style={{ display: activeTab === "online" ? "block" : "none" }}>
134
134
  <form onSubmit={handleSubmit}>
135
135
  <OnlineRechargeForm
136
136
  formState={formState}
@@ -139,14 +139,15 @@ export function Recharge({ visible, onClose, onSubmit }: ModalFormProps) {
139
139
  loading={formState.loading}
140
140
  />
141
141
  </form>
142
- ) : (
142
+ </div>
143
+ <div style={{ display: activeTab === "offline" ? "block" : "none" }}>
143
144
  <OfflineTransferForm
144
145
  formState={offlineFormState}
145
146
  setFormState={setOfflineFormState}
146
147
  onClose={onClose}
147
148
  loading={offlineFormState.loading}
148
149
  />
149
- )}
150
+ </div>
150
151
  </Modal>
151
152
  );
152
153
  }
@@ -23,12 +23,12 @@ interface DetailItem {
23
23
 
24
24
  function StatisticalBalance(props: { popoverPosition?: PopoverPosition }) {
25
25
  const [balanceData, setBalanceData] = useState<{
26
- available: number;
26
+ currBalance: number;
27
27
  currency: string;
28
28
  symbol: string;
29
29
  details: DetailItem[];
30
30
  }>({
31
- available: 0,
31
+ currBalance: 0,
32
32
  currency: "USD",
33
33
  symbol: "$",
34
34
  details: [],
@@ -74,10 +74,16 @@ function StatisticalBalance(props: { popoverPosition?: PopoverPosition }) {
74
74
  color: "#1890ff",
75
75
  dot: "#15b36b",
76
76
  },
77
+ {
78
+ label: "",
79
+ value: balance.currBalance,
80
+ color: "#1890ff",
81
+ dot: "#15b36b",
82
+ },
77
83
  ];
78
84
 
79
85
  const newBalanceData = {
80
- available: balance.availableAmount,
86
+ currBalance: balance.currBalance,
81
87
  currency: "USD",
82
88
  symbol: "$",
83
89
  details,
@@ -149,6 +155,12 @@ function StatisticalBalance(props: { popoverPosition?: PopoverPosition }) {
149
155
  : []),
150
156
  {
151
157
  label: t("可用余额"),
158
+ value: balanceData.details[balanceData.details.length - 2]?.value || 0,
159
+ color: "#1890ff",
160
+ dot: "#15b36b",
161
+ },
162
+ {
163
+ label: t("当前余额"),
152
164
  value: balanceData.details[balanceData.details.length - 1]?.value || 0,
153
165
  color: "#1890ff",
154
166
  dot: "#15b36b",
@@ -178,7 +190,7 @@ function StatisticalBalance(props: { popoverPosition?: PopoverPosition }) {
178
190
  >
179
191
  <div style={theme.main}>
180
192
  {balanceData.symbol}
181
- {formatNumber(balanceData.available)}
193
+ {formatNumber(balanceData.currBalance)}
182
194
  <span style={theme.currency}>{balanceData.currency}</span>
183
195
  </div>
184
196
  </HoverPopover>
@@ -1,402 +0,0 @@
1
- # BestUnit 组件库使用文档
2
-
3
- ## 概述
4
-
5
- BestUnit 是一个功能完整的组件库,提供了余额管理、充值功能和刷新按钮等核心功能。本文档详细说明了所有导出的函数、组件及其使用方法。
6
-
7
- ## 快速开始
8
-
9
- ### 1. 安装和引入
10
-
11
- ```javascript
12
- import {
13
- initFundUnit,
14
- getBalanceData,
15
- refreshBalance,
16
- npmTest,
17
- printCurrentTime,
18
- viteProxy,
19
- } from "best-unit";
20
-
21
- // 引入组件
22
- import "best-unit";
23
- ```
24
-
25
- ### 2. 初始化
26
-
27
- ```javascript
28
- // 初始化组件库
29
- initFundUnit({
30
- token: "your-jwt-token",
31
- user_id: "user-uuid",
32
- env: "dev",
33
- });
34
- ```
35
-
36
- ## 核心函数
37
-
38
- ### initFundUnit(params: InitParams)
39
-
40
- 初始化组件库的核心函数,必须在其他功能使用前调用。
41
-
42
- #### 参数说明
43
-
44
- | 参数名 | 类型 | 必填 | 默认值 | 说明 |
45
- | ----------------- | -------- | ---- | ------------- | ------------ |
46
- | `token` | `string` | ✅ | - | JWT 认证令牌 |
47
- | `user_id` | `string` | ✅ | - | 用户唯一标识 |
48
- | `env` | `Env` | ✅ | - | 环境配置 |
49
- | `merchant_id` | `string` | ❌ | - | 商户 ID |
50
- | `biz_type` | `string` | ❌ | - | 业务类型 |
51
- | `fund_balance_id` | `string` | ❌ | - | 余额账户 ID |
52
- | `theme` | `Theme` | ❌ | `Theme.WHITE` | 主题设置 |
53
- | `locale` | `Locale` | ❌ | `Locale.ZH` | 语言设置 |
54
-
55
- #### 使用示例
56
-
57
- ```javascript
58
- import { initFundUnit } from "best-unit";
59
- import { Theme, Locale, Env } from "best-unit";
60
-
61
- // 基本初始化
62
- initFundUnit({
63
- token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
64
- user_id: "19b8a77c-d3fc-45da-9520-4a07463123df",
65
- env: Env.DEV,
66
- });
67
-
68
- // 完整初始化
69
- initFundUnit({
70
- token: "your-jwt-token",
71
- user_id: "user-uuid",
72
- merchant_id: "merchant-123",
73
- biz_type: "payment",
74
- fund_balance_id: "FB1FNZ5Q55M7QP2C",
75
- theme: Theme.DARK,
76
- locale: Locale.EN,
77
- env: Env.PROD,
78
- });
79
- ```
80
-
81
- ### getBalanceData()
82
-
83
- 获取当前余额数据。如果缓存中没有有效数据,会自动调用接口获取最新值。
84
-
85
- #### 返回值
86
-
87
- ```typescript
88
- interface BalanceData {
89
- fundBalanceId: string; // 余额账户ID
90
- merchantId: number; // 商户ID
91
- bizType: string; // 业务类型
92
- currency: string; // 币种
93
- totalAmount: string; // 真实金额
94
- availableAmount: string; // 可用余额
95
- frozenAmount: string; // 冻结金额
96
- pendingAmount: string; // 待处理金额
97
- status: string; // 状态
98
- createdAt: string; // 创建时间
99
- }
100
- ```
101
-
102
- #### 使用示例
103
-
104
- ```javascript
105
- import { getBalanceData } from "best-unit";
106
-
107
- // 异步获取余额数据
108
- const balanceData = await getBalanceData();
109
- console.log("当前余额:", balanceData);
110
-
111
- // 使用 async/await
112
- async function getBalance() {
113
- try {
114
- const data = await getBalanceData();
115
- console.log("余额数据:", data);
116
- } catch (error) {
117
- console.error("获取余额失败:", error);
118
- }
119
- }
120
-
121
- // 使用 Promise
122
- getBalanceData()
123
- .then((data) => {
124
- console.log("余额数据:", data);
125
- })
126
- .catch((error) => {
127
- console.error("获取余额失败:", error);
128
- });
129
- ```
130
-
131
- ### refreshBalance()
132
-
133
- 触发余额刷新事件,所有余额相关组件会自动更新。
134
-
135
- #### 使用示例
136
-
137
- ```javascript
138
- import { refreshBalance } from "best-unit";
139
-
140
- // 手动刷新余额
141
- refreshBalance();
142
- ```
143
-
144
- ## 工具函数
145
-
146
- ### npmTest()
147
-
148
- 测试函数,用于验证包是否正确安装。
149
-
150
- ```javascript
151
- import { npmTest } from "best-unit";
152
-
153
- npmTest(); // 输出: "npm package test!!!"
154
- ```
155
-
156
- ### printCurrentTime()
157
-
158
- 打印当前时间。
159
-
160
- ```javascript
161
- import { printCurrentTime } from "best-unit";
162
-
163
- printCurrentTime(); // 输出: "Current time: 2024-01-01T00:00:00.000Z"
164
- ```
165
-
166
- ### viteProxy
167
-
168
- Vite 代理配置,用于开发环境。
169
-
170
- ```javascript
171
- import { viteProxy } from "best-unit";
172
-
173
- // 在 vite.config.js 中使用
174
- export default {
175
- server: {
176
- proxy: viteProxy,
177
- },
178
- };
179
- ```
180
-
181
- ## 组件使用
182
-
183
- ### 1. best-statistical-balance (余额统计组件)
184
-
185
- 显示用户余额信息的组件,支持悬停查看详情。
186
-
187
- #### 基本用法
188
-
189
- ```html
190
- <!-- 基本使用 -->
191
- <best-statistical-balance></best-statistical-balance>
192
-
193
- <!-- 自定义弹窗位置 -->
194
- <best-statistical-balance popover-position="top"></best-statistical-balance>
195
- ```
196
-
197
- #### 属性说明
198
-
199
- | 属性名 | 类型 | 必填 | 默认值 | 说明 |
200
- | ------------------ | -------- | ---- | ---------- | -------------------------------------------------- |
201
- | `popover-position` | `string` | ❌ | `"bottom"` | 弹窗位置:`"top"`, `"bottom"`, `"left"`, `"right"` |
202
-
203
- #### 功能特性
204
-
205
- - 自动获取并显示余额数据
206
- - 悬停显示详细余额信息
207
- - 响应式设计,支持主题切换
208
- - 自动监听刷新事件
209
-
210
- ### 2. best-refresh-button (刷新按钮组件)
211
-
212
- 可自定义的刷新按钮,支持动画效果。
213
-
214
- #### 基本用法
215
-
216
- ```html
217
- <!-- 显示默认文案 -->
218
- <best-refresh-button>刷新</best-refresh-button>
219
-
220
- <!-- 只显示图标 -->
221
- <best-refresh-button></best-refresh-button>
222
-
223
- <!-- 自定义文案 -->
224
- <best-refresh-button>重新加载</best-refresh-button>
225
- ```
226
-
227
- #### 属性说明
228
-
229
- | 属性名 | 类型 | 必填 | 默认值 | 说明 |
230
- | ------- | -------- | ---- | ---------- | ------------------------------------------ |
231
- | `color` | `string` | ❌ | - | 按钮颜色 |
232
- | `size` | `string` | ❌ | `"medium"` | 按钮尺寸:`"small"`, `"medium"`, `"large"` |
233
-
234
- #### 功能特性
235
-
236
- - 点击时图标旋转动画
237
- - 自动触发余额刷新
238
- - 支持自定义文案和颜色
239
- - 响应式设计
240
-
241
- ### 3. best-recharge (充值组件)
242
-
243
- 提供充值功能的组件。
244
-
245
- #### 基本用法
246
-
247
- ```html
248
- <!-- 基本使用 -->
249
- <best-recharge></best-recharge>
250
-
251
- <!-- 自定义主题 -->
252
- <best-recharge theme="dark"></best-recharge>
253
- ```
254
-
255
- #### 属性说明
256
-
257
- | 属性名 | 类型 | 必填 | 默认值 | 说明 |
258
- | ------- | -------- | ---- | --------- | ------------------------- |
259
- | `theme` | `string` | ❌ | `"white"` | 主题:`"white"`, `"dark"` |
260
-
261
- #### 功能特性
262
-
263
- - 在线充值功能
264
- - 支持多种支付方式
265
- - 自动跳转支付页面
266
- - 响应式设计
267
-
268
- ## 类型定义
269
-
270
- ### Env (环境枚举)
271
-
272
- ```typescript
273
- enum Env {
274
- DEV = "dev",
275
- DEVELOPMENT = "development",
276
- TEST = "test",
277
- PROD = "prod",
278
- PRODUCTION = "production",
279
- }
280
- ```
281
-
282
- ### Theme (主题枚举)
283
-
284
- ```typescript
285
- enum Theme {
286
- WHITE = "white",
287
- DARK = "dark",
288
- }
289
- ```
290
-
291
- ### Locale (语言枚举)
292
-
293
- ```typescript
294
- enum Locale {
295
- ZH = "zh",
296
- EN = "en",
297
- }
298
- ```
299
-
300
- ## 完整示例
301
-
302
- ### HTML 页面集成
303
-
304
- ```html
305
- <!DOCTYPE html>
306
- <html lang="zh-CN">
307
- <head>
308
- <meta charset="UTF-8" />
309
- <title>BestUnit 示例</title>
310
- </head>
311
- <body>
312
- <!-- 余额显示 -->
313
- <best-statistical-balance></best-statistical-balance>
314
-
315
- <!-- 刷新按钮 -->
316
- <best-refresh-button>刷新余额</best-refresh-button>
317
-
318
- <!-- 充值按钮 -->
319
- <best-recharge></best-recharge>
320
-
321
- <script type="module">
322
- import { initFundUnit } from "best-unit";
323
- import { Env, Theme, Locale } from "best-unit";
324
-
325
- // 初始化
326
- initFundUnit({
327
- token: "your-jwt-token",
328
- user_id: "user-uuid",
329
- theme: Theme.WHITE,
330
- locale: Locale.ZH,
331
- env: Env.DEV,
332
- });
333
- </script>
334
- </body>
335
- </html>
336
- ```
337
-
338
- ### React/Vue 集成
339
-
340
- ```javascript
341
- // React 示例
342
- import React, { useEffect } from "react";
343
- import { initFundUnit } from "best-unit";
344
-
345
- function App() {
346
- useEffect(() => {
347
- initFundUnit({
348
- token: "your-jwt-token",
349
- user_id: "user-uuid",
350
- env: "dev",
351
- });
352
- }, []);
353
-
354
- return (
355
- <div>
356
- <best-statistical-balance></best-statistical-balance>
357
- <best-refresh-button>刷新</best-refresh-button>
358
- <best-recharge></best-recharge>
359
- </div>
360
- );
361
- }
362
- ```
363
-
364
- ## 注意事项
365
-
366
- 1. **初始化顺序**:必须先调用 `initFundUnit()` 再使用其他功能
367
- 2. **Token 安全**:确保 JWT token 的安全性,不要在客户端存储敏感信息
368
- 3. **环境配置**:根据实际环境选择合适的 `env` 参数
369
- 4. **组件依赖**:所有组件都依赖于初始化配置,确保配置正确
370
- 5. **浏览器兼容性**:需要支持 Custom Elements 和 Shadow DOM 的现代浏览器
371
-
372
- ## 错误处理
373
-
374
- ```javascript
375
- try {
376
- initFundUnit({
377
- token: "invalid-token",
378
- user_id: "user-uuid",
379
- env: "dev",
380
- });
381
- } catch (error) {
382
- console.error("初始化失败:", error);
383
- }
384
-
385
- // 检查余额数据(异步)
386
- async function checkBalanceData() {
387
- try {
388
- const balanceData = await getBalanceData();
389
- if (!balanceData.fundBalanceId) {
390
- console.warn("余额数据未初始化");
391
- }
392
- } catch (error) {
393
- console.error("获取余额数据失败:", error);
394
- }
395
- }
396
- ```
397
-
398
- ## 更新日志
399
-
400
- - **v1.0.0**: 初始版本,包含基础功能
401
- - **v1.1.0**: 添加动画效果和主题支持
402
- - **v1.2.0**: 优化缓存机制和错误处理