best-unit 1.0.0 → 1.0.3

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.
Files changed (48) hide show
  1. package/README.md +1 -0
  2. package/dist/best-unit.cjs +60 -0
  3. package/dist/best-unit.js +3988 -0
  4. package/dist/types/global.d.ts +64 -0
  5. package/dist/types/index.ts +17 -0
  6. package/dist/types/preact-custom-element.d.ts +1 -0
  7. package/index.html +2 -2
  8. package/package.json +14 -7
  9. package/src/api/axiosInstance.ts +94 -0
  10. package/src/api/index.ts +118 -15
  11. package/src/api/proxy.ts +11 -0
  12. package/src/components/business/recharge-sdk/components/Button.tsx +42 -0
  13. package/src/components/business/recharge-sdk/components/OfflineTransferForm.tsx +365 -0
  14. package/src/components/business/recharge-sdk/components/OnlineRechargeForm.tsx +389 -0
  15. package/src/components/business/recharge-sdk/components/Recharge.tsx +288 -0
  16. package/src/components/business/recharge-sdk/index.tsx +39 -0
  17. package/src/components/business/statistical-balance/index.tsx +206 -0
  18. package/src/components/common/HoverPopover.tsx +215 -0
  19. package/src/components/common/Message.tsx +324 -0
  20. package/src/components/common/Select.tsx +278 -0
  21. package/src/components/common/Upload.tsx +207 -0
  22. package/src/demo/App.tsx +429 -0
  23. package/src/demo/index.tsx +4 -0
  24. package/src/local/en.ts +61 -0
  25. package/src/local/index.ts +36 -0
  26. package/src/local/zh.ts +60 -0
  27. package/src/main.ts +10 -0
  28. package/src/types/global.d.ts +64 -0
  29. package/src/types/index.ts +17 -0
  30. package/src/types/preact-custom-element.d.ts +1 -0
  31. package/src/utils/business/index.ts +48 -0
  32. package/src/utils/common/index.ts +8 -0
  33. package/src/vite-env.d.ts +1 -0
  34. package/tsconfig.app.json +31 -0
  35. package/tsconfig.json +15 -0
  36. package/tsconfig.node.json +24 -0
  37. package/vite.config.ts +18 -0
  38. package/example/index.html +0 -24
  39. package/public/vite.svg +0 -1
  40. package/src/App.jsx +0 -6
  41. package/src/api/define-api.ts +0 -49
  42. package/src/javascript.svg +0 -1
  43. package/src/main.jsx +0 -4
  44. package/src/sdk/index.ts +0 -33
  45. package/src/style.css +0 -96
  46. package/src/views/AccountModal.jsx +0 -125
  47. package/src/views/Home.jsx +0 -53
  48. package/vite.config.js +0 -31
@@ -0,0 +1,64 @@
1
+ export declare function npmTest(): void;
2
+
3
+ export declare function printCurrentTime(): void;
4
+
5
+ export declare function initFundUnit(params: {
6
+ token: string;
7
+ merchant_id?: string;
8
+ biz_type?: string;
9
+ fund_balance_id?: string;
10
+ user_id: string;
11
+ theme?: Theme;
12
+ locale?: Locale;
13
+ env: Env;
14
+ }): {
15
+ token: string;
16
+ merchantId?: string;
17
+ bizType?: string;
18
+ fundBalanceId?: string;
19
+ theme?: Theme;
20
+ locale: Locale;
21
+ env: Env;
22
+ };
23
+
24
+ // Vite 代理配置类型
25
+ export declare const viteProxy: {
26
+ "/api": {
27
+ target: string;
28
+ changeOrigin: boolean;
29
+ rewrite: (path: string) => string;
30
+ secure: boolean;
31
+ };
32
+ };
33
+
34
+ declare global {
35
+ interface Window {
36
+ bestUnit: {
37
+ initFundUnit: (params: {
38
+ token: string;
39
+ merchant_id: string;
40
+ biz_type: string;
41
+ user_id: string;
42
+ fund_balance_id?: string;
43
+ locale?: "zh" | "en";
44
+ theme?: Theme;
45
+ env: Env;
46
+ }) => void;
47
+ };
48
+ }
49
+
50
+ namespace JSX {
51
+ interface IntrinsicElements {
52
+ "best-recharge": {
53
+ theme?: any;
54
+ merchant_id?: string;
55
+ biz_type?: string;
56
+ token?: string;
57
+ [key: string]: any;
58
+ };
59
+ "best-statistical-balance": any;
60
+ }
61
+ }
62
+ }
63
+ export {};
64
+ /// <reference path="./preact-custom-element.d.ts" />
@@ -0,0 +1,17 @@
1
+ export enum Locale {
2
+ ZH = "zh",
3
+ EN = "en",
4
+ }
5
+
6
+ export enum Theme {
7
+ WHITE = "white",
8
+ DARK = "dark",
9
+ }
10
+
11
+ export enum Env {
12
+ DEV = "dev",
13
+ DEVELOPMENT = "development",
14
+ TEST = "test",
15
+ PROD = "prod",
16
+ PRODUCTION = "production",
17
+ }
@@ -0,0 +1 @@
1
+ declare module 'preact-custom-element'
package/index.html CHANGED
@@ -4,10 +4,10 @@
4
4
  <meta charset="UTF-8" />
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Vite App</title>
7
+ <title>Best Unit</title>
8
8
  </head>
9
9
  <body>
10
10
  <div id="app"></div>
11
- <script type="module" src="/src/main.jsx"></script>
11
+ <script type="module" src="/src/demo/index.tsx"></script>
12
12
  </body>
13
13
  </html>
package/package.json CHANGED
@@ -1,18 +1,25 @@
1
1
  {
2
2
  "name": "best-unit",
3
- "version": "1.0.0",
3
+ "private": false,
4
+ "version": "1.0.3",
4
5
  "type": "module",
6
+ "main": "dist/best-unit.cjs",
7
+ "module": "dist/best-unit.js",
8
+ "types": "dist/types/global.d.ts",
5
9
  "scripts": {
6
10
  "dev": "vite",
7
- "build": "vite build",
11
+ "build": "tsc -b && vite build && cp -r src/types dist/types",
12
+ "prepublishOnly": "npm version patch --no-git-tag-version",
8
13
  "preview": "vite preview"
9
14
  },
10
- "devDependencies": {
11
- "vite": "^7.0.4"
12
- },
13
15
  "dependencies": {
14
- "@preact/preset-vite": "^2.10.2",
15
16
  "axios": "^1.10.0",
16
- "preact": "^10.26.9"
17
+ "preact": "^10.26.9",
18
+ "preact-custom-element": "^4.3.0"
19
+ },
20
+ "devDependencies": {
21
+ "@preact/preset-vite": "^2.10.2",
22
+ "typescript": "~5.8.3",
23
+ "vite": "^7.0.4"
17
24
  }
18
25
  }
@@ -0,0 +1,94 @@
1
+ import axios from "axios";
2
+ import type {
3
+ AxiosInstance,
4
+ AxiosResponse,
5
+ InternalAxiosRequestConfig,
6
+ } from "axios";
7
+ import { message } from "../components/common/Message";
8
+ import { Env, Locale } from "../types";
9
+
10
+ export interface CreateAxiosOptions {
11
+ baseURL?: string;
12
+ timeout?: number;
13
+ onError?: (msg: string, error: any) => void;
14
+ }
15
+
16
+ export function createAxiosInstance(options: CreateAxiosOptions = {}) {
17
+ // 根据 fund_unit_params 中的 env 参数选择 API URL
18
+ const fundUnitParams = JSON.parse(
19
+ sessionStorage.getItem("fund_unit_params") || "{}"
20
+ );
21
+ const { env } = fundUnitParams;
22
+
23
+ let apiUrl: string;
24
+ switch (env) {
25
+ case Env.PROD:
26
+ case Env.PRODUCTION:
27
+ apiUrl = "https://fund.bestfulfill.com/api/sdk";
28
+ break;
29
+ case Env.TEST:
30
+ apiUrl = "https://fund.bestfulfill.tech/api/sdk";
31
+ break;
32
+ case Env.DEV:
33
+ case Env.DEVELOPMENT:
34
+ default:
35
+ apiUrl = "/api";
36
+ break;
37
+ }
38
+
39
+ const { baseURL = apiUrl, timeout = 10000, onError } = options;
40
+
41
+ const instance: AxiosInstance = axios.create({ baseURL, timeout });
42
+
43
+ // 请求拦截:加 token、国际化
44
+ instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
45
+ const { token, locale } = fundUnitParams;
46
+ config.headers = {
47
+ ...config.headers,
48
+ Authorization: token,
49
+ "x-locale": locale === Locale.ZH ? "zh-CN" : "en-US",
50
+ } as any;
51
+
52
+ return config;
53
+ });
54
+
55
+ // 响应拦截:code=0判定成功,其他走 onError
56
+ instance.interceptors.response.use(
57
+ (response: AxiosResponse) => {
58
+ if (response.data && response.data.code === 0) {
59
+ return response.data;
60
+ }
61
+ const errorMsg =
62
+ response.data?.msg || response.data?.message || "未知错误";
63
+
64
+ // 显示错误消息
65
+ message.error(errorMsg);
66
+
67
+ if (onError) {
68
+ onError(errorMsg, response);
69
+ }
70
+ return Promise.reject(response.data || { message: "未知错误" });
71
+ },
72
+ (error) => {
73
+ const errorMsg =
74
+ error.response?.data?.msg ||
75
+ error.response?.data?.message ||
76
+ error.message ||
77
+ "网络请求失败";
78
+
79
+ // 显示错误消息
80
+ message.error(errorMsg);
81
+
82
+ if (onError) {
83
+ onError(errorMsg, error);
84
+ }
85
+ return Promise.reject(error);
86
+ }
87
+ );
88
+
89
+ return instance;
90
+ }
91
+
92
+ // 默认实例
93
+ const http = createAxiosInstance();
94
+ export default http;
package/src/api/index.ts CHANGED
@@ -1,19 +1,122 @@
1
- import { request } from './define-api';
2
-
3
- // 示例:获取用户信息
4
- export function getUserInfo(token: string) {
5
- return request('/user/info', 'get', undefined, {
6
- headers: {
7
- authorization: token,
8
- },
9
- });
1
+ import http from "./axiosInstance";
2
+ import type { AxiosProgressEvent } from "axios";
3
+ // 获取余额
4
+ export function getBalance() {
5
+ const fundUnitParams = JSON.parse(
6
+ sessionStorage.getItem("fund_unit_params") || "{}"
7
+ );
8
+ return http
9
+ .get("/balance", {
10
+ params: {
11
+ merchant_id: fundUnitParams.merchantId,
12
+ biz_type: fundUnitParams.bizType,
13
+ fund_balance_id: fundUnitParams.fundBalanceId,
14
+ },
15
+ })
16
+ .then((res) => {
17
+ const data = res.data;
18
+ return {
19
+ totalAmount: data.total_amount || 0,
20
+ availableAmount: data.available_amount || 0,
21
+ frozenAmount: data.frozen_amount || 0,
22
+ };
23
+ });
10
24
  }
11
25
 
12
- // 表单提交接口
13
- export function submitAccountForm(data: { agent: string; requestId: string; remark: string }, token: string) {
14
- return request('/account/submit', 'post', data, {
15
- headers: {
16
- authorization: token,
17
- },
26
+ // 获取所有字典
27
+ export const getAllDicts = async () => {
28
+ return http.get("/all-dicts", {}).then((res) => {
29
+ sessionStorage.setItem("all_dicts", JSON.stringify(res.data));
30
+ return res.data || {};
18
31
  });
32
+ };
33
+
34
+ // 上传文件
35
+ export const uploadFile = async (
36
+ file: any,
37
+ onProgress?: (percent: number) => void
38
+ ) => {
39
+ return http
40
+ .post("/oss/upload", file, {
41
+ headers: {
42
+ "Content-Type": "multipart/form-data",
43
+ },
44
+ onUploadProgress: (progressEvent: AxiosProgressEvent) => {
45
+ if (progressEvent.total) {
46
+ const percent = Math.round(
47
+ (progressEvent.loaded * 100) / progressEvent.total
48
+ );
49
+ onProgress && onProgress(percent);
50
+ }
51
+ },
52
+ })
53
+ .then((res) => {
54
+ return res.data?.url || "";
55
+ });
56
+ };
57
+
58
+ // 创建离线充值
59
+ export const createOfflineRecharge = async (data: any) => {
60
+ const fundUnitParams = JSON.parse(
61
+ sessionStorage.getItem("fund_unit_params") || "{}"
62
+ );
63
+
64
+ const params = {
65
+ merchant_id: Number(fundUnitParams.merchantId),
66
+ biz_type: fundUnitParams.bizType,
67
+ fund_balance_id: fundUnitParams.fundBalanceId,
68
+ source_operator: fundUnitParams.userId
69
+ ? String(fundUnitParams.userId)
70
+ : undefined,
71
+ transfer_no: data.transferNo,
72
+ transfer_channel: data.transferChannel,
73
+ voucher_urls: data.voucherUrls,
74
+ };
75
+ return http.post("/offline/recharge/create", params, {});
76
+ };
77
+
78
+ // 创建在线充值
79
+ export const createOnlineRecharge = async (data: any) => {
80
+ const fundUnitParams = JSON.parse(
81
+ sessionStorage.getItem("fund_unit_params") || "{}"
82
+ );
83
+
84
+ console.log(fundUnitParams, "fundUnitParams");
85
+
86
+ const params = {
87
+ merchant_id: Number(fundUnitParams.merchantId),
88
+ biz_type: fundUnitParams.bizType,
89
+ fund_balance_id: fundUnitParams.fundBalanceId,
90
+ source_operator: fundUnitParams.userId
91
+ ? String(fundUnitParams.userId)
92
+ : undefined,
93
+ amount: data.amount,
94
+ currency: data.currency,
95
+ recharge_channel: data.rechargeChannel,
96
+ return_url: window.location.href,
97
+ };
98
+ return http.post("/online/recharge/create", params, {}).then((res) => {
99
+ return res.data.redirect_url;
100
+ });
101
+ };
102
+
103
+ interface CalcPaymentAmountParams {
104
+ channel: string; // 支付平台,如 "stripe"
105
+ amount: string; // 充值金额,如 "10"
106
+ currency: string; // 币种,如 "USD"
19
107
  }
108
+
109
+ // 计算支付金额
110
+ export const calcPaymentAmount = async (data: CalcPaymentAmountParams) => {
111
+ return http
112
+ .get("/calc-payment-amount", {
113
+ params: data,
114
+ })
115
+ .then((res) => {
116
+ const data = res.data;
117
+ return data.payment_amount;
118
+ });
119
+ };
120
+
121
+ // 示例用法:
122
+ // getBalance({ merchant_id: '1128', biz_type: 'ad', token: 'xxx' }).then(res => console.log(res));
@@ -0,0 +1,11 @@
1
+ // Vite 配置用的代理对象
2
+ const viteProxy = {
3
+ "/api": {
4
+ target: "https://fund.bestfulfill.tech/api/sdk",
5
+ changeOrigin: true,
6
+ rewrite: (path: string) => path.replace(/^\/api/, ""),
7
+ secure: false,
8
+ },
9
+ };
10
+
11
+ export { viteProxy };
@@ -0,0 +1,42 @@
1
+ import type { ComponentChildren } from "preact";
2
+ import { Theme } from "../../../../types";
3
+
4
+ interface ButtonProps {
5
+ onClick?: () => void;
6
+ color?: string;
7
+ children: ComponentChildren;
8
+ }
9
+
10
+ export function ThemedButton({ onClick, color, children }: ButtonProps) {
11
+ // 优先theme,其次whiteTheme,默认白色
12
+ const fundUnitParams = JSON.parse(
13
+ sessionStorage.getItem("fund_unit_params") || "{}"
14
+ );
15
+ const whiteTheme = fundUnitParams.theme === Theme.WHITE;
16
+ const style = whiteTheme
17
+ ? {
18
+ background: color || "#1890ff",
19
+ color: "#fff",
20
+ border: "none",
21
+ borderRadius: 6,
22
+ padding: "8px 16px",
23
+ cursor: "pointer",
24
+ fontSize: 16,
25
+ fontWeight: 600,
26
+ }
27
+ : {
28
+ background: color || "#00E8C6",
29
+ color: "#fff",
30
+ border: "none",
31
+ borderRadius: 6,
32
+ padding: "8px 16px",
33
+ cursor: "pointer",
34
+ fontSize: 16,
35
+ fontWeight: 600,
36
+ };
37
+ return (
38
+ <button style={style} onClick={onClick} type="button">
39
+ {children}
40
+ </button>
41
+ );
42
+ }