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.
- package/README.md +1 -0
- package/dist/best-unit.cjs +60 -0
- package/dist/best-unit.js +3988 -0
- package/dist/types/global.d.ts +64 -0
- package/dist/types/index.ts +17 -0
- package/dist/types/preact-custom-element.d.ts +1 -0
- package/index.html +2 -2
- package/package.json +14 -7
- package/src/api/axiosInstance.ts +94 -0
- package/src/api/index.ts +118 -15
- package/src/api/proxy.ts +11 -0
- package/src/components/business/recharge-sdk/components/Button.tsx +42 -0
- package/src/components/business/recharge-sdk/components/OfflineTransferForm.tsx +365 -0
- package/src/components/business/recharge-sdk/components/OnlineRechargeForm.tsx +389 -0
- package/src/components/business/recharge-sdk/components/Recharge.tsx +288 -0
- package/src/components/business/recharge-sdk/index.tsx +39 -0
- package/src/components/business/statistical-balance/index.tsx +206 -0
- package/src/components/common/HoverPopover.tsx +215 -0
- package/src/components/common/Message.tsx +324 -0
- package/src/components/common/Select.tsx +278 -0
- package/src/components/common/Upload.tsx +207 -0
- package/src/demo/App.tsx +429 -0
- package/src/demo/index.tsx +4 -0
- package/src/local/en.ts +61 -0
- package/src/local/index.ts +36 -0
- package/src/local/zh.ts +60 -0
- package/src/main.ts +10 -0
- package/src/types/global.d.ts +64 -0
- package/src/types/index.ts +17 -0
- package/src/types/preact-custom-element.d.ts +1 -0
- package/src/utils/business/index.ts +48 -0
- package/src/utils/common/index.ts +8 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.app.json +31 -0
- package/tsconfig.json +15 -0
- package/tsconfig.node.json +24 -0
- package/vite.config.ts +18 -0
- package/example/index.html +0 -24
- package/public/vite.svg +0 -1
- package/src/App.jsx +0 -6
- package/src/api/define-api.ts +0 -49
- package/src/javascript.svg +0 -1
- package/src/main.jsx +0 -4
- package/src/sdk/index.ts +0 -33
- package/src/style.css +0 -96
- package/src/views/AccountModal.jsx +0 -125
- package/src/views/Home.jsx +0 -53
- 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>
|
|
7
|
+
<title>Best Unit</title>
|
|
8
8
|
</head>
|
|
9
9
|
<body>
|
|
10
10
|
<div id="app"></div>
|
|
11
|
-
<script type="module" src="/src/
|
|
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
|
-
"
|
|
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
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
export function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
14
|
-
return
|
|
15
|
-
|
|
16
|
-
|
|
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));
|
package/src/api/proxy.ts
ADDED
|
@@ -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
|
+
}
|