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,365 @@
1
+ import type { FunctionalComponent } from "preact";
2
+ import { Upload } from "../../../common/Upload";
3
+ import { createOfflineRecharge } from "../../../../api";
4
+ import { message } from "../../../common/Message";
5
+ import { t } from "../../../../local";
6
+ import { Theme } from "../../../../types";
7
+ import { Select } from "../../../common/Select";
8
+
9
+ interface OfflineTransferFormProps {
10
+ formState: {
11
+ platform: string;
12
+ transactionId: string;
13
+ files: string[]; // 绑定url数组
14
+ platformError?: string;
15
+ transactionIdError?: string;
16
+ filesError?: string;
17
+ loading?: boolean;
18
+ };
19
+ setFormState: (fn: (state: any) => any) => void;
20
+ onClose: () => void;
21
+ loading: boolean;
22
+ }
23
+
24
+ export const OfflineTransferForm: FunctionalComponent<
25
+ OfflineTransferFormProps
26
+ > = ({ formState, setFormState, onClose, loading }) => {
27
+ const allDicts = JSON.parse(sessionStorage.getItem("all_dicts") || "{}");
28
+ console.log(allDicts, "allDicts");
29
+ const channelDict = allDicts?.channel || [];
30
+ const fundUnitParams = JSON.parse(
31
+ sessionStorage.getItem("fund_unit_params") || "{}"
32
+ );
33
+ const whiteTheme = fundUnitParams.theme === Theme.WHITE;
34
+ // 样式对象
35
+ const theme = whiteTheme
36
+ ? {
37
+ label: {
38
+ marginBottom: 8,
39
+ fontSize: 14,
40
+ color: "#222",
41
+ textAlign: "left",
42
+ display: "block",
43
+ },
44
+ input: {
45
+ width: "100%",
46
+ padding: "10px 12px",
47
+ borderRadius: 6,
48
+ boxSizing: "border-box",
49
+ border: "1px solid #E5E6EB",
50
+ background: "#fff",
51
+ color: "#222",
52
+ fontSize: 15,
53
+ outline: "none",
54
+ marginBottom: 0,
55
+ },
56
+ inputError: {
57
+ border: "1px solid #ff4d4f",
58
+ },
59
+ select: {
60
+ width: "100%",
61
+ padding: "10px 12px",
62
+ borderRadius: 6,
63
+ border: "1px solid #E5E6EB",
64
+ background: "#fff",
65
+ color: "#222",
66
+ fontSize: 15,
67
+ outline: "none",
68
+ },
69
+ selectError: {
70
+ border: "1px solid #ff4d4f",
71
+ },
72
+ upload: {
73
+ border: "1px dashed #E5E6EB",
74
+ borderRadius: 8,
75
+ background: "#FCFCFD",
76
+ padding: 24,
77
+ textAlign: "center",
78
+ cursor: "pointer",
79
+ minHeight: 120,
80
+ display: "flex",
81
+ flexDirection: "column",
82
+ alignItems: "center",
83
+ justifyContent: "center",
84
+ color: "#999",
85
+ fontSize: 15,
86
+ },
87
+ uploadError: {
88
+ border: "1px dashed #ff4d4f",
89
+ },
90
+ fileItem: {
91
+ display: "flex",
92
+ alignItems: "center",
93
+ background: "#F7F8FA",
94
+ borderRadius: 8,
95
+ padding: "12px 16px",
96
+ marginBottom: 8,
97
+ fontSize: 15,
98
+ color: "#222",
99
+ justifyContent: "space-between",
100
+ },
101
+ buttonCancel: {
102
+ background: "#fff",
103
+ color: "#222",
104
+ border: "1px solid #E5E6EB",
105
+ borderRadius: 6,
106
+ padding: "8px 24px",
107
+ fontSize: 15,
108
+ cursor: "pointer",
109
+ },
110
+ buttonSubmit: {
111
+ background: "#1890ff",
112
+ color: "#fff",
113
+ border: "none",
114
+ borderRadius: 6,
115
+ padding: "8px 24px",
116
+ fontSize: 15,
117
+ cursor: "pointer",
118
+ fontWeight: 600,
119
+ },
120
+ removeBtn: {
121
+ background: "#FF4D4F",
122
+ color: "#fff",
123
+ border: "none",
124
+ borderRadius: 6,
125
+ padding: "4px 14px",
126
+ fontSize: 15,
127
+ marginLeft: 16,
128
+ cursor: "pointer",
129
+ },
130
+ error: {
131
+ color: "#ff4d4f",
132
+ fontSize: 13,
133
+ marginTop: 4,
134
+ textAlign: "left",
135
+ },
136
+ }
137
+ : {
138
+ label: {
139
+ marginBottom: 8,
140
+ fontSize: 14,
141
+ color: "#fff",
142
+ textAlign: "left",
143
+ display: "block",
144
+ },
145
+ input: {
146
+ width: "100%",
147
+ padding: "10px 12px",
148
+ borderRadius: 6,
149
+ boxSizing: "border-box",
150
+ border: "1px solid #23262F",
151
+ background: "#23262F",
152
+ color: "#fff",
153
+ fontSize: 15,
154
+ outline: "none",
155
+ marginBottom: 0,
156
+ },
157
+ inputError: {
158
+ border: "1px solid #ff4d4f",
159
+ },
160
+ select: {
161
+ width: "100%",
162
+ padding: "10px 12px",
163
+ borderRadius: 6,
164
+ border: "1px solid #23262F",
165
+ background: "#23262F",
166
+ color: "#fff",
167
+ fontSize: 15,
168
+ outline: "none",
169
+ },
170
+ selectError: {
171
+ border: "1px solid #ff4d4f",
172
+ },
173
+ upload: {
174
+ border: "1px dashed #23262F",
175
+ borderRadius: 8,
176
+ background: "#181A20",
177
+ padding: 24,
178
+ textAlign: "center",
179
+ cursor: "pointer",
180
+ minHeight: 120,
181
+ display: "flex",
182
+ flexDirection: "column",
183
+ alignItems: "center",
184
+ justifyContent: "center",
185
+ color: "#999",
186
+ fontSize: 15,
187
+ },
188
+ uploadError: {
189
+ border: "1px dashed #ff4d4f",
190
+ },
191
+ fileItem: {
192
+ display: "flex",
193
+ alignItems: "center",
194
+ background: "#23262F",
195
+ borderRadius: 8,
196
+ padding: "12px 16px",
197
+ marginBottom: 8,
198
+ fontSize: 15,
199
+ color: "#fff",
200
+ justifyContent: "space-between",
201
+ },
202
+ buttonCancel: {
203
+ background: "#23262F",
204
+ color: "#fff",
205
+ border: "none",
206
+ borderRadius: 6,
207
+ padding: "8px 24px",
208
+ fontSize: 15,
209
+ cursor: "pointer",
210
+ },
211
+ buttonSubmit: {
212
+ background: "#00E8C6",
213
+ color: "#fff",
214
+ border: "none",
215
+ borderRadius: 6,
216
+ padding: "8px 24px",
217
+ fontSize: 15,
218
+ cursor: "pointer",
219
+ fontWeight: 600,
220
+ },
221
+ removeBtn: {
222
+ background: "#FF4D4F",
223
+ color: "#fff",
224
+ border: "none",
225
+ borderRadius: 6,
226
+ padding: "4px 14px",
227
+ fontSize: 15,
228
+ marginLeft: 16,
229
+ cursor: "pointer",
230
+ },
231
+ error: {
232
+ color: "#ff4d4f",
233
+ fontSize: 13,
234
+ marginTop: 4,
235
+ textAlign: "left",
236
+ },
237
+ };
238
+
239
+ const handleSubmit = async (e: any) => {
240
+ e.preventDefault();
241
+ let valid = true;
242
+ setFormState((state: any) => ({
243
+ ...state,
244
+ platformError: "",
245
+ transactionIdError: "",
246
+ filesError: "",
247
+ }));
248
+ if (!formState.platform) {
249
+ setFormState((state: any) => ({
250
+ ...state,
251
+ platformError: t("请选择支付平台"),
252
+ }));
253
+ valid = false;
254
+ }
255
+ if (!formState.transactionId.trim()) {
256
+ setFormState((state: any) => ({
257
+ ...state,
258
+ transactionIdError: t("请输入转账交易ID"),
259
+ }));
260
+ valid = false;
261
+ }
262
+ if (!formState.files || formState.files.length === 0) {
263
+ setFormState((state: any) => ({
264
+ ...state,
265
+ filesError: t("请上传转账凭证"),
266
+ }));
267
+ valid = false;
268
+ }
269
+ if (!valid) return;
270
+ await createOfflineRecharge({
271
+ transferChannel: formState.platform,
272
+ transferNo: formState.transactionId,
273
+ voucherUrls: formState.files,
274
+ });
275
+ onClose();
276
+ message.success(t("离线充值创建成功"));
277
+ };
278
+
279
+ return (
280
+ <form onSubmit={handleSubmit}>
281
+ <div style={{ marginBottom: 18 }}>
282
+ <div style={theme.label}>
283
+ <span style={{ color: "#F53F3F" }}>*</span> {t("第三方支付平台")}
284
+ </div>
285
+ <Select
286
+ value={formState.platform}
287
+ onChange={(value) => {
288
+ setFormState((state: any) => ({
289
+ ...state,
290
+ platform: value,
291
+ platformError: value ? "" : state.platformError,
292
+ }));
293
+ }}
294
+ options={[
295
+ ...channelDict?.map((item: any) => ({
296
+ value: item.value,
297
+ label: item.label,
298
+ })),
299
+ ]}
300
+ placeholder={t("请选择支付平台")}
301
+ />
302
+ {formState.platformError && (
303
+ <div style={theme.error}>{formState.platformError}</div>
304
+ )}
305
+ </div>
306
+ <div style={{ marginBottom: 18 }}>
307
+ <div style={theme.label}>
308
+ <span style={{ color: "#F53F3F" }}>*</span> {t("交易ID")}
309
+ </div>
310
+ <input
311
+ type="text"
312
+ placeholder={t("请输入转账交易ID")}
313
+ value={formState.transactionId}
314
+ maxLength={200}
315
+ onInput={(e) => {
316
+ let value = (e.target as HTMLInputElement).value;
317
+ if (value.length > 200) value = value.slice(0, 200);
318
+ setFormState((state: any) => ({
319
+ ...state,
320
+ transactionId: value,
321
+ transactionIdError: value ? "" : state.transactionIdError,
322
+ }));
323
+ }}
324
+ style={{
325
+ ...theme.input,
326
+ ...(formState.transactionIdError ? theme.inputError : {}),
327
+ }}
328
+ />
329
+ {formState.transactionIdError && (
330
+ <div style={theme.error}>{formState.transactionIdError}</div>
331
+ )}
332
+ </div>
333
+ <div style={{ marginBottom: 24 }}>
334
+ <div style={theme.label}>
335
+ <span style={{ color: "#F53F3F" }}>*</span> {t("上传文件")}
336
+ </div>
337
+ <Upload
338
+ value={formState.files}
339
+ onChange={(urls) =>
340
+ setFormState((state: any) => ({
341
+ ...state,
342
+ files: urls,
343
+ filesError: "",
344
+ }))
345
+ }
346
+ maxCount={10}
347
+ accept={".jpg,.jpeg,.png,.pdf"}
348
+ multiple={true}
349
+ />
350
+ {formState.filesError && (
351
+ <div style={theme.error}>{formState.filesError}</div>
352
+ )}
353
+ </div>
354
+ {/* 按钮区 */}
355
+ <div style={{ display: "flex", justifyContent: "flex-end", gap: 12 }}>
356
+ <button type="button" onClick={onClose} style={theme.buttonCancel}>
357
+ {t("取消")}
358
+ </button>
359
+ <button type="submit" disabled={loading} style={theme.buttonSubmit}>
360
+ {t("去支付")}
361
+ </button>
362
+ </div>
363
+ </form>
364
+ );
365
+ };