my-uniapp-tools 1.0.0 → 1.0.2
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 +52 -63
- package/examples/payment-example.js +179 -0
- package/package.json +1 -1
- package/src/clipboard/index.ts +4 -2
- package/src/index.js +6 -0
- package/src/system/index.ts +41 -10
- package/src/utils/index.ts +1 -0
- package/src/utils/payment/index.ts +153 -0
- package/RECORD.md +0 -34
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# My UniApp Tools
|
|
2
2
|
|
|
3
3
|
一个专为 UniApp 开发设计的实用工具函数库,提供常用的功能模块,帮助开发者快速构建跨平台应用。
|
|
4
4
|
|
|
@@ -6,20 +6,20 @@
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
# 使用 npm
|
|
9
|
-
npm install
|
|
9
|
+
npm install my-uniapp-tools
|
|
10
10
|
|
|
11
11
|
# 使用 yarn
|
|
12
|
-
yarn add
|
|
12
|
+
yarn add my-uniapp-tools
|
|
13
13
|
|
|
14
14
|
# 使用 pnpm
|
|
15
|
-
pnpm add
|
|
15
|
+
pnpm add my-uniapp-tools
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## 🚀 快速开始
|
|
19
19
|
|
|
20
20
|
```javascript
|
|
21
21
|
// 导入所有工具函数
|
|
22
|
-
import * from '
|
|
22
|
+
import * as Tools from 'my-uniapp-tools'
|
|
23
23
|
|
|
24
24
|
// 或者按需导入
|
|
25
25
|
import {
|
|
@@ -28,13 +28,15 @@ import {
|
|
|
28
28
|
copyText,
|
|
29
29
|
setStorageSync,
|
|
30
30
|
getStorageSync,
|
|
31
|
+
clearStorageSync,
|
|
32
|
+
useWindowInfo,
|
|
31
33
|
getPlatform,
|
|
32
34
|
getCurrentEnv,
|
|
33
35
|
onCheckForUpdate,
|
|
34
36
|
getStatusBarHeight,
|
|
35
37
|
getNavHeight,
|
|
36
|
-
|
|
37
|
-
} from '
|
|
38
|
+
getTopNavBarHeight
|
|
39
|
+
} from 'my-uniapp-tools'
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
## 📚 API 文档
|
|
@@ -65,6 +67,8 @@ useToast(
|
|
|
65
67
|
)
|
|
66
68
|
```
|
|
67
69
|
|
|
70
|
+
### 🧭 导航工具 (Navigation)
|
|
71
|
+
|
|
68
72
|
#### `useBack(params)`
|
|
69
73
|
|
|
70
74
|
返回上一页并支持传递参数给上一页的 init 方法
|
|
@@ -83,6 +87,8 @@ useBack({ refresh: true, data: 'some data' })
|
|
|
83
87
|
|
|
84
88
|
**注意:** 上一页需要暴露 `init` 方法来接收参数
|
|
85
89
|
|
|
90
|
+
### 📋 剪贴板工具 (Clipboard)
|
|
91
|
+
|
|
86
92
|
#### `copyText(text)`
|
|
87
93
|
|
|
88
94
|
跨平台文本复制功能,支持 H5、App、小程序。H5 平台优先使用现代的 Clipboard API,失败时回退到传统方法。
|
|
@@ -95,12 +101,14 @@ useBack({ refresh: true, data: 'some data' })
|
|
|
95
101
|
copyText('要复制的文本内容')
|
|
96
102
|
```
|
|
97
103
|
|
|
104
|
+
### 🖥️ 系统信息工具 (System)
|
|
105
|
+
|
|
98
106
|
#### `useWindowInfo()`
|
|
99
107
|
|
|
100
108
|
获取当前窗口的尺寸、像素比等信息
|
|
101
109
|
|
|
102
110
|
**返回值:**
|
|
103
|
-
-
|
|
111
|
+
- 窗口信息对象,包含窗口尺寸、像素比等信息
|
|
104
112
|
|
|
105
113
|
**示例:**
|
|
106
114
|
```javascript
|
|
@@ -240,7 +248,7 @@ const customNavStyle = {
|
|
|
240
248
|
}
|
|
241
249
|
```
|
|
242
250
|
|
|
243
|
-
#### `
|
|
251
|
+
#### `getTopNavBarHeight()`
|
|
244
252
|
|
|
245
253
|
一次性获取应用所需的状态栏和导航栏高度配置信息
|
|
246
254
|
|
|
@@ -251,14 +259,14 @@ const customNavStyle = {
|
|
|
251
259
|
|
|
252
260
|
**示例:**
|
|
253
261
|
```javascript
|
|
254
|
-
const
|
|
255
|
-
console.log(
|
|
256
|
-
console.log(
|
|
262
|
+
const topNavConfig = getTopNavBarHeight()
|
|
263
|
+
console.log(topNavConfig.statusBarHeight) // 状态栏高度
|
|
264
|
+
console.log(topNavConfig.navHeight) // 导航栏总高度
|
|
257
265
|
|
|
258
266
|
// 用于全局配置
|
|
259
267
|
const globalConfig = {
|
|
260
|
-
...
|
|
261
|
-
contentHeight: windowHeight -
|
|
268
|
+
...topNavConfig,
|
|
269
|
+
contentHeight: windowHeight - topNavConfig.navHeight
|
|
262
270
|
}
|
|
263
271
|
```
|
|
264
272
|
|
|
@@ -351,6 +359,11 @@ npm install
|
|
|
351
359
|
yarn dev
|
|
352
360
|
# 或
|
|
353
361
|
npm run dev
|
|
362
|
+
|
|
363
|
+
# 运行测试
|
|
364
|
+
yarn test
|
|
365
|
+
# 或
|
|
366
|
+
npm test
|
|
354
367
|
```
|
|
355
368
|
|
|
356
369
|
## 🏗️ 技术栈
|
|
@@ -362,7 +375,9 @@ npm run dev
|
|
|
362
375
|
## 📁 项目结构
|
|
363
376
|
|
|
364
377
|
```
|
|
365
|
-
|
|
378
|
+
my-uniapp-tools/
|
|
379
|
+
├── .augment/ # 增强配置目录
|
|
380
|
+
│ └── rules/
|
|
366
381
|
├── src/
|
|
367
382
|
│ ├── ui/ # UI交互工具函数
|
|
368
383
|
│ │ └── index.ts
|
|
@@ -375,14 +390,17 @@ huang-uniapp-toolkit/
|
|
|
375
390
|
│ ├── localStorage/ # 本地存储工具
|
|
376
391
|
│ │ └── index.ts
|
|
377
392
|
│ └── index.js # 主入口文件
|
|
393
|
+
├── .gitignore # Git 忽略配置
|
|
378
394
|
├── package.json # 项目配置
|
|
379
395
|
├── tsconfig.json # TypeScript 配置
|
|
380
|
-
|
|
396
|
+
├── yarn.lock # Yarn 依赖锁定文件
|
|
397
|
+
├── README.md # 项目说明
|
|
398
|
+
└── RECORD.md # 项目记录
|
|
381
399
|
```
|
|
382
400
|
|
|
383
401
|
## 🔄 版本信息
|
|
384
402
|
|
|
385
|
-
当前版本:v1.0.
|
|
403
|
+
当前版本:v1.0.0
|
|
386
404
|
|
|
387
405
|
## 📄 许可证
|
|
388
406
|
|
|
@@ -402,55 +420,26 @@ ISC
|
|
|
402
420
|
|
|
403
421
|
## 📝 更新日志
|
|
404
422
|
|
|
405
|
-
### v1.0.
|
|
406
|
-
-
|
|
407
|
-
-
|
|
408
|
-
-
|
|
409
|
-
- ⚙️ 新增 `getAppConfig()` 函数,一次性获取状态栏和导航栏配置信息
|
|
410
|
-
- 🛡️ 添加完善的错误处理机制,确保在获取失败时返回默认值
|
|
411
|
-
- 📚 更新API文档,添加详细的使用说明和界面适配示例
|
|
412
|
-
- 💡 遵循单一职责原则,每个函数专注于特定的高度获取功能
|
|
413
|
-
- 🎯 主要用于小程序平台的界面适配和自定义导航栏开发
|
|
414
|
-
|
|
415
|
-
### v1.0.5
|
|
416
|
-
- ✨ **新增功能**:完善 `onCheckForUpdate()` 函数
|
|
417
|
-
- 📱 实现小程序版本更新检查功能,支持自动检查、下载和提示更新
|
|
418
|
-
- 🔄 支持静默下载新版本,用户可选择立即重启或稍后更新
|
|
419
|
-
- 🛡️ 添加完善的错误处理机制,包括下载失败和异常情况处理
|
|
420
|
-
- 📚 更新API文档,添加详细的平台支持说明和使用示例
|
|
421
|
-
- 💡 遵循单一职责原则,提供用户友好的更新体验
|
|
422
|
-
- 🎯 支持微信、支付宝、百度、抖音、QQ、快手、京东等主流小程序平台
|
|
423
|
-
|
|
424
|
-
### v1.0.4
|
|
425
|
-
- ✨ **新增功能**:完善 `getCurrentEnv()` 函数
|
|
426
|
-
- 📱 新增小程序账户信息获取功能,支持获取appId、版本号、环境版本等信息
|
|
427
|
-
- 🛡️ 添加错误处理机制,确保函数调用的稳定性
|
|
428
|
-
- 📚 更新API文档,添加详细的使用说明和示例
|
|
429
|
-
- 💡 遵循单一职责原则,提供清晰的返回值结构
|
|
430
|
-
|
|
431
|
-
### v1.0.3
|
|
432
|
-
- 🏗️ **重大重构**:按功能类型重新组织代码结构
|
|
433
|
-
- 📁 将原 `common` 模块拆分为 5 个专门模块:
|
|
423
|
+
### v1.0.0
|
|
424
|
+
- 🎯 **初始版本发布**
|
|
425
|
+
- 🏗️ **模块化架构**:按功能类型组织代码结构
|
|
426
|
+
- 📁 **五大核心模块**:
|
|
434
427
|
- `ui` - UI交互工具(useToast)
|
|
435
428
|
- `navigation` - 导航工具(useBack)
|
|
436
429
|
- `clipboard` - 剪贴板工具(copyText)
|
|
437
|
-
- `system` - 系统信息工具(useWindowInfo, getPlatform, getCurrentEnv)
|
|
438
|
-
- `localStorage` -
|
|
439
|
-
-
|
|
440
|
-
-
|
|
441
|
-
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
-
|
|
445
|
-
-
|
|
446
|
-
- 🛡️
|
|
447
|
-
-
|
|
448
|
-
-
|
|
449
|
-
|
|
450
|
-
### v1.0.1
|
|
451
|
-
- 🎯 初始版本发布
|
|
452
|
-
- 📦 基础工具函数实现
|
|
453
|
-
- 💾 本地存储工具实现
|
|
430
|
+
- `system` - 系统信息工具(useWindowInfo, getPlatform, getCurrentEnv, onCheckForUpdate, getStatusBarHeight, getNavHeight, getTopNavBarHeight)
|
|
431
|
+
- `localStorage` - 本地存储工具(setStorageSync, getStorageSync, clearStorageSync)
|
|
432
|
+
- ✨ **核心功能**:
|
|
433
|
+
- 📱 跨平台消息提示和导航返回
|
|
434
|
+
- 📋 跨平台剪贴板操作
|
|
435
|
+
- 🖥️ 系统信息获取和平台检测
|
|
436
|
+
- 🔄 小程序版本更新检查
|
|
437
|
+
- 📏 状态栏和导航栏高度适配
|
|
438
|
+
- 💾 本地存储数据管理
|
|
439
|
+
- 🛡️ **完善的错误处理机制**,确保函数调用的稳定性
|
|
440
|
+
- 💡 **遵循单一职责原则**,每个函数专注于特定功能
|
|
441
|
+
- 📚 **详细的API文档**,包含使用说明和示例代码
|
|
442
|
+
- 🎯 **支持主流平台**:微信、支付宝、百度、抖音、QQ、快手、京东等小程序平台以及H5、App
|
|
454
443
|
|
|
455
444
|
---
|
|
456
445
|
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 支付功能使用示例
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { usePayment } from '../src/utils/index.ts';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 微信支付示例 (App端)
|
|
9
|
+
*/
|
|
10
|
+
export const wechatPayExample = async () => {
|
|
11
|
+
try {
|
|
12
|
+
const result = await usePayment('wxpay', {
|
|
13
|
+
// App端微信支付必需参数
|
|
14
|
+
appid: 'your_app_id',
|
|
15
|
+
partnerid: 'your_partner_id',
|
|
16
|
+
prepayid: 'your_prepay_id',
|
|
17
|
+
package: 'Sign=WXPay',
|
|
18
|
+
noncestr: 'random_string_' + Date.now(),
|
|
19
|
+
timestamp: Math.floor(Date.now() / 1000).toString(),
|
|
20
|
+
sign: 'your_calculated_sign'
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (result.success) {
|
|
24
|
+
console.log('微信支付成功!');
|
|
25
|
+
console.log('订单号:', result.orderInfo.orderId);
|
|
26
|
+
console.log('支付时间:', new Date(result.timestamp));
|
|
27
|
+
|
|
28
|
+
// 支付成功后的业务逻辑
|
|
29
|
+
handlePaymentSuccess(result);
|
|
30
|
+
} else {
|
|
31
|
+
console.error('微信支付失败:', result.error);
|
|
32
|
+
|
|
33
|
+
// 支付失败后的业务逻辑
|
|
34
|
+
handlePaymentFail(result);
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('支付过程中发生错误:', error);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 支付宝支付示例 (小程序 - String类型)
|
|
43
|
+
*/
|
|
44
|
+
export const alipayMiniProgramExample = async () => {
|
|
45
|
+
try {
|
|
46
|
+
// 支付宝小程序支付,orderInfo 为 String 类型的交易号
|
|
47
|
+
const result = await usePayment('alipay', 'your_trade_no_from_server');
|
|
48
|
+
|
|
49
|
+
if (result.success) {
|
|
50
|
+
console.log('支付宝小程序支付成功!');
|
|
51
|
+
handlePaymentSuccess(result);
|
|
52
|
+
} else {
|
|
53
|
+
console.error('支付宝小程序支付失败:', result.error);
|
|
54
|
+
handlePaymentFail(result);
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error('支付过程中发生错误:', error);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 支付宝支付示例 (App端 - String类型)
|
|
63
|
+
*/
|
|
64
|
+
export const alipayAppExample = async () => {
|
|
65
|
+
try {
|
|
66
|
+
// App端支付宝支付,orderInfo 为 String 类型的订单字符串
|
|
67
|
+
const result = await usePayment('alipay', 'your_complete_order_string_from_server');
|
|
68
|
+
|
|
69
|
+
if (result.success) {
|
|
70
|
+
console.log('支付宝App支付成功!');
|
|
71
|
+
handlePaymentSuccess(result);
|
|
72
|
+
} else {
|
|
73
|
+
console.error('支付宝App支付失败:', result.error);
|
|
74
|
+
handlePaymentFail(result);
|
|
75
|
+
}
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error('支付过程中发生错误:', error);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 支付成功处理函数
|
|
85
|
+
*/
|
|
86
|
+
const handlePaymentSuccess = (result) => {
|
|
87
|
+
console.log('处理支付成功逻辑...');
|
|
88
|
+
|
|
89
|
+
// 1. 更新本地状态
|
|
90
|
+
// 2. 发送支付成功通知到服务器
|
|
91
|
+
// 3. 更新用户界面
|
|
92
|
+
// 4. 跳转到成功页面
|
|
93
|
+
|
|
94
|
+
// 示例:显示成功提示
|
|
95
|
+
uni.showToast({
|
|
96
|
+
title: '支付成功',
|
|
97
|
+
icon: 'success',
|
|
98
|
+
duration: 2000
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// 示例:跳转到成功页面
|
|
102
|
+
setTimeout(() => {
|
|
103
|
+
uni.navigateTo({
|
|
104
|
+
url: '/pages/payment/success?orderId=' + result.orderInfo.orderId
|
|
105
|
+
});
|
|
106
|
+
}, 2000);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 支付失败处理函数
|
|
111
|
+
*/
|
|
112
|
+
const handlePaymentFail = (result) => {
|
|
113
|
+
console.log('处理支付失败逻辑...');
|
|
114
|
+
|
|
115
|
+
// 1. 记录失败日志
|
|
116
|
+
// 2. 显示错误提示
|
|
117
|
+
// 3. 提供重试选项
|
|
118
|
+
|
|
119
|
+
let errorMessage = '支付失败,请重试';
|
|
120
|
+
|
|
121
|
+
// 根据错误类型显示不同提示
|
|
122
|
+
if (result.error && result.error.errMsg) {
|
|
123
|
+
if (result.error.errMsg.includes('cancel')) {
|
|
124
|
+
errorMessage = '支付已取消';
|
|
125
|
+
} else if (result.error.errMsg.includes('fail')) {
|
|
126
|
+
errorMessage = '支付失败,请检查网络或稍后重试';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
uni.showModal({
|
|
131
|
+
title: '支付提示',
|
|
132
|
+
content: errorMessage,
|
|
133
|
+
showCancel: true,
|
|
134
|
+
cancelText: '取消',
|
|
135
|
+
confirmText: '重试',
|
|
136
|
+
success: (res) => {
|
|
137
|
+
if (res.confirm) {
|
|
138
|
+
// 用户选择重试,重新发起支付
|
|
139
|
+
console.log('用户选择重试支付');
|
|
140
|
+
// 这里可以重新调用对应的支付函数
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* 批量支付示例(多个商品)
|
|
148
|
+
*/
|
|
149
|
+
export const batchPaymentExample = async () => {
|
|
150
|
+
const orders = [
|
|
151
|
+
{ orderId: 'order_001', amount: 1000, description: '商品1' },
|
|
152
|
+
{ orderId: 'order_002', amount: 2000, description: '商品2' },
|
|
153
|
+
{ orderId: 'order_003', amount: 3000, description: '商品3' }
|
|
154
|
+
];
|
|
155
|
+
|
|
156
|
+
// 计算总金额
|
|
157
|
+
const totalAmount = orders.reduce((sum, order) => sum + order.amount, 0);
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
const result = await usePayment('wxpay', {
|
|
161
|
+
orderId: 'batch_order_' + Date.now(),
|
|
162
|
+
amount: totalAmount,
|
|
163
|
+
description: `批量购买${orders.length}个商品`,
|
|
164
|
+
orderList: orders // 附加订单列表信息
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (result.success) {
|
|
168
|
+
console.log('批量支付成功!');
|
|
169
|
+
console.log('总金额:', totalAmount / 100, '元');
|
|
170
|
+
console.log('商品数量:', orders.length);
|
|
171
|
+
handlePaymentSuccess(result);
|
|
172
|
+
} else {
|
|
173
|
+
console.error('批量支付失败:', result.error);
|
|
174
|
+
handlePaymentFail(result);
|
|
175
|
+
}
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.error('批量支付过程中发生错误:', error);
|
|
178
|
+
}
|
|
179
|
+
};
|
package/package.json
CHANGED
package/src/clipboard/index.ts
CHANGED
|
@@ -10,7 +10,8 @@ import { useToast } from '../ui';
|
|
|
10
10
|
* @description 支持 H5、App、小程序。H5 平台优先使用现代的 Clipboard API,失败时回退到传统方法
|
|
11
11
|
*/
|
|
12
12
|
export function copyText(text: string) {
|
|
13
|
-
// #ifndef H5
|
|
13
|
+
// #ifndef H5
|
|
14
|
+
// 条件编译:非 H5 平台(如 App、小程序)执行此代码块
|
|
14
15
|
uni.setClipboardData({
|
|
15
16
|
data: text, // 要复制的文本内容
|
|
16
17
|
success: function () {
|
|
@@ -21,7 +22,8 @@ export function copyText(text: string) {
|
|
|
21
22
|
},
|
|
22
23
|
});
|
|
23
24
|
// #endif
|
|
24
|
-
// #ifdef H5
|
|
25
|
+
// #ifdef H5
|
|
26
|
+
// 条件编译:仅 H5 平台执行此代码块
|
|
25
27
|
// 优先使用现代的 Clipboard API
|
|
26
28
|
if (navigator.clipboard && window.isSecureContext) {
|
|
27
29
|
navigator.clipboard.writeText(text).then(() => {
|
package/src/index.js
CHANGED
package/src/system/index.ts
CHANGED
|
@@ -141,24 +141,55 @@ export const getStatusBarHeight = () => {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
/**
|
|
145
|
+
* 获取菜单按钮边界信息
|
|
146
|
+
* @returns 菜单按钮边界信息对象或null
|
|
147
|
+
* @description 获取小程序右上角菜单按钮的边界信息,仅在小程序平台有效
|
|
148
|
+
*/
|
|
149
|
+
export const getMenuButtonBoundingClientRect = () => {
|
|
150
|
+
try {
|
|
151
|
+
const platform = getPlatform();
|
|
152
|
+
|
|
153
|
+
// 只有在小程序平台才执行getMenuButtonBoundingClientRect
|
|
154
|
+
if (platform === 'weixin' || platform === 'alipay') {
|
|
155
|
+
return uni.getMenuButtonBoundingClientRect();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 非小程序平台返回null
|
|
159
|
+
return null;
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.error('获取菜单按钮边界信息失败:', error);
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
144
166
|
/**
|
|
145
167
|
* 获取导航栏高度
|
|
146
168
|
* @returns 导航栏高度(单位:px)
|
|
147
|
-
* @description
|
|
169
|
+
* @description 获取导航栏的总高度,根据不同平台采用不同的计算方式
|
|
148
170
|
*/
|
|
149
171
|
export const getNavHeight = () => {
|
|
150
172
|
try {
|
|
151
173
|
// 获取状态栏高度
|
|
152
174
|
const statusBarHeight = getStatusBarHeight();
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
175
|
+
const platform = getPlatform();
|
|
176
|
+
|
|
177
|
+
// 小程序平台:状态栏高度 + 菜单按钮高度
|
|
178
|
+
if (platform === 'weixin' || platform === 'alipay') {
|
|
179
|
+
const menuButtonInfo = getMenuButtonBoundingClientRect();
|
|
180
|
+
if (menuButtonInfo) {
|
|
181
|
+
const navHeight = menuButtonInfo.height + statusBarHeight;
|
|
182
|
+
console.log("🚀 ~ 小程序导航栏高度:", navHeight);
|
|
183
|
+
return navHeight;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// App和H5平台:使用默认导航栏高度
|
|
188
|
+
const defaultNavHeight = 44; // 默认导航栏高度
|
|
189
|
+
const totalHeight = statusBarHeight + defaultNavHeight;
|
|
190
|
+
console.log(`🚀 ~ ${platform}平台导航栏高度:`, totalHeight);
|
|
191
|
+
|
|
192
|
+
return totalHeight;
|
|
162
193
|
} catch (error) {
|
|
163
194
|
console.error('获取导航栏高度失败:', error);
|
|
164
195
|
// 返回默认高度(状态栏高度 + 44px 默认导航栏高度)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './payment/index'
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 支付相关工具函数
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 支付提供商类型
|
|
7
|
+
*/
|
|
8
|
+
export type PaymentProvider = 'wxpay' | 'alipay';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 支付订单信息类型
|
|
12
|
+
* @description 根据不同支付方式,orderInfo 的类型和结构会有所不同:
|
|
13
|
+
* - 支付宝小程序:String 类型,表示支付宝交易号(tradeNO)
|
|
14
|
+
* - App端支付宝:String 类型,完整的订单字符串
|
|
15
|
+
* - App端微信:Object 类型,包含微信支付必需参数
|
|
16
|
+
*/
|
|
17
|
+
export type PaymentOrderInfo = string | {
|
|
18
|
+
/** 微信支付参数 (App端) */
|
|
19
|
+
appid?: string;
|
|
20
|
+
partnerid?: string;
|
|
21
|
+
prepayid?: string;
|
|
22
|
+
package?: string;
|
|
23
|
+
noncestr?: string;
|
|
24
|
+
timestamp?: string;
|
|
25
|
+
sign?: string;
|
|
26
|
+
|
|
27
|
+
/** 其他通用参数 */
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 支付结果接口
|
|
33
|
+
*/
|
|
34
|
+
export interface PaymentResult {
|
|
35
|
+
/** 支付是否成功 */
|
|
36
|
+
success: boolean;
|
|
37
|
+
/** 支付提供商 */
|
|
38
|
+
provider: PaymentProvider;
|
|
39
|
+
/** 订单信息 */
|
|
40
|
+
orderInfo: PaymentOrderInfo;
|
|
41
|
+
/** 支付时间戳 */
|
|
42
|
+
timestamp: number;
|
|
43
|
+
/** 错误信息(支付失败时) */
|
|
44
|
+
error?: any;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 统一支付接口
|
|
49
|
+
* @param provider 支付提供商,默认为 'wxpay'
|
|
50
|
+
* @param orderInfo 订单信息对象
|
|
51
|
+
* @returns Promise<PaymentResult> 支付结果
|
|
52
|
+
* @description 封装 uni.requestPayment,提供统一的支付接口,支持多种支付方式
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* // 微信支付 (App端)
|
|
56
|
+
* const wxResult = await usePayment('wxpay', {
|
|
57
|
+
* appid: 'your_app_id',
|
|
58
|
+
* partnerid: 'your_partner_id',
|
|
59
|
+
* prepayid: 'your_prepay_id',
|
|
60
|
+
* package: 'Sign=WXPay',
|
|
61
|
+
* noncestr: 'random_string',
|
|
62
|
+
* timestamp: '1234567890',
|
|
63
|
+
* sign: 'your_sign'
|
|
64
|
+
* });
|
|
65
|
+
*
|
|
66
|
+
* // 支付宝支付 (小程序 - String类型)
|
|
67
|
+
* const alipayResult = await usePayment('alipay', 'your_trade_no_string');
|
|
68
|
+
*
|
|
69
|
+
* // 支付宝支付 (App端 - String类型)
|
|
70
|
+
* const alipayAppResult = await usePayment('alipay', 'your_order_string');
|
|
71
|
+
*
|
|
72
|
+
* // 检查支付结果
|
|
73
|
+
* if (wxResult.success) {
|
|
74
|
+
* console.log('支付成功');
|
|
75
|
+
* } else {
|
|
76
|
+
* console.error('支付失败:', wxResult.error);
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export const usePayment = (
|
|
81
|
+
provider: PaymentProvider = 'wxpay',
|
|
82
|
+
orderInfo: PaymentOrderInfo = {}
|
|
83
|
+
): Promise<PaymentResult> => {
|
|
84
|
+
return new Promise<PaymentResult>((resolve, reject) => {
|
|
85
|
+
// 参数验证
|
|
86
|
+
if (!provider) {
|
|
87
|
+
const error = new Error('支付提供商不能为空');
|
|
88
|
+
reject(error);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 根据不同平台验证 orderInfo 类型
|
|
93
|
+
if (orderInfo === null || orderInfo === undefined) {
|
|
94
|
+
const error = new Error('订单信息不能为空');
|
|
95
|
+
reject(error);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 支付宝小程序和App端支付宝需要 String 类型
|
|
100
|
+
if ((provider === 'alipay') && typeof orderInfo !== 'string' && typeof orderInfo !== 'object') {
|
|
101
|
+
const error = new Error('支付宝支付的订单信息格式不正确');
|
|
102
|
+
reject(error);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 其他平台需要 Object 类型
|
|
107
|
+
if (provider !== 'alipay' && typeof orderInfo !== 'object') {
|
|
108
|
+
const error = new Error('订单信息必须是一个对象');
|
|
109
|
+
reject(error);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// 记录支付开始时间
|
|
114
|
+
const timestamp = Date.now();
|
|
115
|
+
|
|
116
|
+
// 调用 uni.requestPayment 进行支付
|
|
117
|
+
uni.requestPayment({
|
|
118
|
+
provider,
|
|
119
|
+
orderInfo,
|
|
120
|
+
success: () => {
|
|
121
|
+
// 支付成功,返回成功结果
|
|
122
|
+
const result: PaymentResult = {
|
|
123
|
+
success: true,
|
|
124
|
+
provider,
|
|
125
|
+
orderInfo,
|
|
126
|
+
timestamp,
|
|
127
|
+
};
|
|
128
|
+
resolve(result);
|
|
129
|
+
},
|
|
130
|
+
fail: (err) => {
|
|
131
|
+
// 支付失败,返回失败结果
|
|
132
|
+
const result: PaymentResult = {
|
|
133
|
+
success: false,
|
|
134
|
+
provider,
|
|
135
|
+
orderInfo,
|
|
136
|
+
timestamp,
|
|
137
|
+
error: err,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// 根据错误类型进行不同处理
|
|
141
|
+
if (err.errMsg && err.errMsg.includes('cancel')) {
|
|
142
|
+
console.log('用户取消支付');
|
|
143
|
+
} else {
|
|
144
|
+
console.error('支付失败:', err);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 这里选择 resolve 而不是 reject,让调用者通过 result.success 判断支付结果
|
|
148
|
+
// 这样可以避免未捕获的 Promise 异常
|
|
149
|
+
resolve(result);
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
};
|
package/RECORD.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# 项目记录 (RECORD.md)
|
|
2
|
-
|
|
3
|
-
## 项目简介
|
|
4
|
-
|
|
5
|
-
本项目名为 `my-uniapp-tool`,是一个基于 Node.js 的工具库,旨在为 UniApp 开发提供便利。根据 `package.json`,当前版本为 `1.0.2`,使用 ES Module 规范。
|
|
6
|
-
|
|
7
|
-
## 核心框架/技术
|
|
8
|
-
|
|
9
|
-
- **主要语言**: TypeScript (从 `tsconfig.json` 和 `.ts` 文件扩展名推断)
|
|
10
|
-
- **运行环境**: Node.js (从 `package.json` 的 `scripts` 和 `main` 指向 `.js` 文件推断)
|
|
11
|
-
- **核心依赖**:
|
|
12
|
-
- `@dcloudio/types`: 提供 DCloud UniApp 相关的类型定义,表明项目与 UniApp 生态紧密相关。
|
|
13
|
-
|
|
14
|
-
## 目录结构
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
.
|
|
18
|
-
├── .gitignore # Git 忽略配置文件
|
|
19
|
-
├── package.json # 项目元数据和依赖管理
|
|
20
|
-
├── tsconfig.json # TypeScript 编译配置文件
|
|
21
|
-
├── yarn.lock # Yarn 依赖版本锁定文件
|
|
22
|
-
├── src/ # 源代码目录
|
|
23
|
-
│ ├── index.js # 项目入口文件 (可能是编译后的 JS)
|
|
24
|
-
│ ├── common/ # 通用工具或模块目录
|
|
25
|
-
│ │ └── index.ts # 通用模块入口文件
|
|
26
|
-
│ └── localStorage/ # 本地存储相关模块目录
|
|
27
|
-
│ └── index.ts # 本地存储模块入口文件
|
|
28
|
-
└── RECORD.md # 本项目记录文件 (即本文档)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
- **根目录**: 包含项目的基本配置文件和元数据。
|
|
32
|
-
- **`src` 目录**: 存放项目的主要源代码。
|
|
33
|
-
- `common`: 包含项目中可复用的通用函数、常量或类型定义。
|
|
34
|
-
- `localStorage`: 封装了与浏览器或小程序本地存储相关的操作。
|