feat(toast): 实现原生Toast系统并优化会员购买错误处理

- 新增iOS原生Toast模块(NativeToastManager),提供毛玻璃风格的Toast展示
- 重构ToastContext为原生模块调用,添加错误边界和回退机制
- 优化会员购买流程的错误处理,使用RevenueCat标准错误码
- 调整购买按钮高度和恢复购买按钮字体大小,改善UI体验
- 移除不必要的延迟和注释代码,提升代码质量
This commit is contained in:
richarjiang
2025-10-28 11:04:34 +08:00
parent db8b50f6d7
commit 71a8bb9740
6 changed files with 707 additions and 140 deletions

View File

@@ -1,8 +1,6 @@
/* eslint-disable react-hooks/exhaustive-deps */
import CustomCheckBox from '@/components/ui/CheckBox';
import { USER_AGREEMENT_URL } from '@/constants/Agree';
// import { useAuth } from '@/contexts/AuthContext';
// import { UserApi } from '@/services';
import { log, logger } from '@/utils/logger';
import {
captureMessage,
@@ -275,9 +273,6 @@ export function MembershipModal({ visible, onClose, onPurchaseSuccess }: Members
capturePurchaseEvent('init', '开始获取会员产品套餐');
try {
// 添加延迟,确保 RevenueCat SDK 完全初始化
await new Promise(resolve => setTimeout(resolve, 500));
const offerings = await Purchases.getOfferings();
log.info('获取产品套餐', { offerings });
@@ -639,27 +634,27 @@ export function MembershipModal({ visible, onClose, onPurchaseSuccess }: Members
});
// 处理不同类型的购买错误
if (error.code === 1 || error.code === 'USER_CANCELLED') {
if (error.userCancelled || error.code === Purchases.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
// 用户取消购买
GlobalToast.show({
message: '购买已取消',
});
} else if (error.code === 'ITEM_ALREADY_OWNED' || error.code === 'PRODUCT_ALREADY_PURCHASED') {
} else if (error.code === Purchases.PURCHASES_ERROR_CODE.PRODUCT_ALREADY_PURCHASED_ERROR) {
// 商品已拥有
GlobalToast.show({
message: '您已拥有此商品',
});
} else if (error.code === 'NETWORK_ERROR') {
} else if (error.code === Purchases.PURCHASES_ERROR_CODE.NETWORK_ERROR) {
// 网络错误
GlobalToast.show({
message: '网络连接失败',
});
} else if (error.code === 'PAYMENT_PENDING') {
} else if (error.code === Purchases.PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR) {
// 支付待处理
GlobalToast.show({
message: '支付正在处理中',
});
} else if (error.code === 'INVALID_CREDENTIALS') {
} else if (error.code === Purchases.PURCHASES_ERROR_CODE.INVALID_CREDENTIALS_ERROR) {
// 凭据无效
GlobalToast.show({
message: '账户验证失败',
@@ -813,15 +808,15 @@ export function MembershipModal({ visible, onClose, onPurchaseSuccess }: Members
capturePurchaseEvent('error', `恢复购买失败: ${errorData.message}`, errorData);
// 处理特定的恢复购买错误
if (error.code === 'RESTORE_CANCELLED' || error.code === 'USER_CANCELLED') {
if (error.userCancelled || error.code === Purchases.PURCHASES_ERROR_CODE.PURCHASE_CANCELLED_ERROR) {
GlobalToast.show({
message: '恢复购买已取消',
});
} else if (error.code === 'NETWORK_ERROR') {
} else if (error.code === Purchases.PURCHASES_ERROR_CODE.NETWORK_ERROR) {
GlobalToast.show({
message: '网络错误',
});
} else if (error.code === 'INVALID_CREDENTIALS') {
} else if (error.code === Purchases.PURCHASES_ERROR_CODE.INVALID_CREDENTIALS_ERROR) {
GlobalToast.show({
message: '账户验证失败',
});
@@ -1400,7 +1395,7 @@ const styles = StyleSheet.create({
},
purchaseButton: {
borderRadius: 28,
height: 52,
height: 64,
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
@@ -1465,7 +1460,7 @@ const styles = StyleSheet.create({
},
restoreButtonText: {
color: '#6F6F7A',
fontSize: 14,
fontSize: 12,
fontWeight: '500',
},
disabledRestoreButton: {