import ReturnArrowSvg from '@/assets/icons/svg/returnArrow.svg'; import StarSvg from '@/assets/icons/svg/whiteStart.svg'; import CheckSvg from '@/assets/icons/svg/yes.svg'; import PrivacyModal from '@/components/owner/qualification/privacy'; import Normal from '@/components/owner/rights/normal'; import Premium, { PayItem } from '@/components/owner/rights/premium'; import ProRights from '@/components/owner/rights/proRights'; import { createOrder, createPayment, getPAy, isOrderExpired, payFailure, payProcessing, paySuccess } from '@/components/owner/rights/utils'; import { ThemedText } from '@/components/ThemedText'; import { CreateOrder } from '@/types/personal-info'; import { useLocalSearchParams, useRouter } from "expo-router"; import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { ActivityIndicator, Image, Platform, ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; // 根据平台动态导入 expo-iap let useIAP: any, requestPurchase: any, getPurchaseHistories: any; if (Platform.OS !== 'web') { const iap = require('expo-iap'); useIAP = iap.useIAP; requestPurchase = iap.requestPurchase; getPurchaseHistories = iap.getPurchaseHistories; } else { // 为 Web 端提供 mock 实现 useIAP = () => ({ connected: false }); requestPurchase = async () => { console.log('IAP is not available on web.'); }; getPurchaseHistories = async () => []; } export default function Rights() { const insets = useSafeAreaInsets(); const router = useRouter(); const { t } = useTranslation(); const { connected, requestProducts, ErrorCode } = useIAP(); const { points, pro } = useLocalSearchParams<{ credit: string; points: string; pro: string }>(); // 用户勾选协议 const [agree, setAgree] = useState(false); // 用户选择购买的loading const [confirmLoading, setConfirmLoading] = useState(false); // 选择购买方式 const [payChoice, setPayChoice] = useState<'ApplePay'>('ApplePay'); // 普通用户,会员 const [userType, setUserType] = useState<'normal' | 'premium'>('normal'); // 选择权益方式 const [payType, setPayType] = useState(''); // 用户协议弹窗打开 const [showTerms, setShowTerms] = useState(false); // 调接口获取支付信息 const [premiumPay, setPremiumPay] = useState(); const [loading, setLoading] = useState(false); // 查看历史订单 const fetchPurchaseHistory = async () => { try { const purchaseHistories = await getPurchaseHistories(); console.log('Purchase history fetched:', purchaseHistories); return purchaseHistories } catch (error) { console.error('Failed to fetch purchase history:', error); } }; // 恢复购买 // const restorePurchases = async () => { // try { // const purchases = await getAvailablePurchases(); // console.log('Available purchases:', purchases); // // Process and validate restored purchases // for (const purchase of purchases) { // await validateAndGrantPurchase(purchase); // } // alert(t('personal:rights.restoreSuccess')); // } catch (error) { // console.error('Restore failed:', error); // } // }; // 处理购买 const handlePurchase = async (sku: string, transaction_id: string) => { try { // 支付中 await payProcessing(transaction_id, "") const res = await requestPurchase({ request: { ios: { sku: sku, andDangerouslyFinishTransactionAutomaticallyIOS: false, }, }, }); // 支付成功 await paySuccess(transaction_id, res?.transaction_id || "") } catch (error: any) { console.log('Purchase failed:', error); // 支付失败 payFailure(transaction_id, ErrorCode[error?.code as keyof typeof ErrorCode || "E_UNKNOWN"]) } }; // 获取苹果订单信息 useEffect(() => { if (!connected) return; const initializeStore = async () => { try { await requestProducts({ skus: ["MEMBERSHIP_PRO_QUARTERLY", "MEMBERSHIP_PRO_YEARLY", "MEMBERSHIP_PRO_MONTH"], type: 'subs' }); } catch (error) { console.error('Failed to initialize store:', error); } }; initializeStore(); }, [connected]); // 初始化获取产品项 useEffect(() => { setLoading(true); getPAy().then(({ bestValue, payInfo }) => { setPayType(bestValue?.product_code) setPremiumPay([bestValue, ...payInfo?.filter((item) => item.product_code !== bestValue?.product_code)]); setLoading(false); }).catch(() => { setLoading(false); }) }, []); // 用户确认购买时,进行 创建订单,创建支付 接口调用 const confirmPurchase = async () => { if (!agree) { alert(t('personal:rights.agreementError')); return } setConfirmLoading(true); const history = await fetchPurchaseHistory() const historyIds = history?.filter((item: any) => isOrderExpired(item?.expirationDateIos))?.map((i: any) => { return i?.id }) if (historyIds?.includes(payType)) { setConfirmLoading(false); setTimeout(() => { alert(t('personal:rights.againError')); }, 0); return } try { // 创建订单 createOrder(premiumPay?.filter((item) => item.product_code === payType)?.[0]?.id || 1, 1).then((res: CreateOrder) => { // 创建支付 createPayment(res?.id || "", payChoice).then(async (res) => { // 苹果支付 await handlePurchase(payType, res?.transaction_id || "") setConfirmLoading(false); }).catch((err) => { console.log("createPayment", err); setConfirmLoading(false); }) }).catch((err) => { console.log("createOrder", err); setConfirmLoading(false); }) } catch (error) { console.log("confirmPurchase", error); setConfirmLoading(false); } }; useEffect(() => { if (pro === "Pro") { setUserType('premium') } else { setUserType('normal') } }, [pro]) useEffect(() => { fetchPurchaseHistory() }, []) return ( {/* 整个页面的中间添加一个loading */} {confirmLoading && ( {t('personal:rights.confirmLoading')} )} {/* 导航栏 */} { router.push('/owner'); setConfirmLoading(false) }} style={{ padding: 16 }}> {t('rights.title', { ns: 'personal' })} 123 {/* 会员卡 */} {userType === 'normal' ? ( ) : ( )} {t('rights.purchase', { ns: 'personal' })} {points} {/* 会员信息 */} {/* 切换按钮 */} { setUserType("normal") }} style={[styles.switchButtonItem, { backgroundColor: userType === 'normal' ? "#FFB645" : "#fff", borderColor: userType === 'normal' ? "#FFB645" : "#E2793F" }]} > {t('rights.free', { ns: 'personal' })} { setUserType("premium") }} style={[styles.switchButtonItem, { backgroundColor: userType === 'premium' ? "#E2793F" : "#fff", borderColor: userType === 'premium' ? "#E2793F" : "#E2793F" }]} > {t('rights.premium', { ns: 'personal' })} {/* 普通权益 */} {/* 会员权益 */} {/* 支付方式 */} {/* */} {/* 会员权益信息 */} {/* 付费按钮 */} { setAgree(!agree) }} activeOpacity={0.8}> {agree && } {t('personal:rights.agreement')} { setShowTerms(true); }} activeOpacity={0.8} > {t('personal:rights.membership')} { confirmPurchase() }} activeOpacity={0.8} > {t('rights.subscribe', { ns: 'personal' })} {payType?.split('_')[payType?.split('_')?.length - 1]} {/* 协议弹窗 */} ); } const styles = StyleSheet.create({ agree: { width: 15, height: 15, borderRadius: 15, alignItems: 'center', justifyContent: 'center', borderColor: '#AC7E35', borderWidth: 1, }, loadingContent: { justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', borderRadius: 12, padding: 16, }, loadingContainer: { justifyContent: 'center', alignItems: 'center', position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 9, backgroundColor: 'rgba(255, 255, 255, 0.5)', }, payChoice: { width: 20, height: 20, borderRadius: 15, alignItems: 'center', justifyContent: 'center', }, paymentMethod: { marginHorizontal: 16, marginVertical: 16, borderRadius: 12, backgroundColor: '#fff', shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 5, elevation: 5, }, goPay: { backgroundColor: '#E2793F', borderRadius: 32, paddingVertical: 16, display: "flex", alignItems: "center", width: "100%", }, switchButton: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 16, marginBottom: 16 }, switchButtonItem: { width: "47%", borderRadius: 24, paddingVertical: 8, display: "flex", alignItems: "center", borderWidth: 1 }, info: { marginHorizontal: 16, marginVertical: 16, padding: 16, borderRadius: 32, backgroundColor: '#fff', shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.25, shadowRadius: 5, elevation: 5, }, container: { flex: 1, backgroundColor: 'white', }, header: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginVertical: 16, }, headerTitle: { fontSize: 20, fontWeight: '700', color: '#4C320C', }, card: { marginHorizontal: 16, marginVertical: 16, backgroundColor: '#FFB645', borderRadius: 32, }, cardContent: { position: 'absolute', top: 0, right: 0, bottom: 0, left: 0, padding: 16, justifyContent: 'space-between' }, cardinfo: { alignItems: 'flex-end', }, cardTitle: { fontSize: 12, fontWeight: '700', color: '#E2793F', backgroundColor: '#fff', paddingHorizontal: 16, paddingVertical: 2, borderRadius: 20, textAlign: 'center', marginBottom: 24 }, cardPoints: { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 8 }, cardPointsText: { fontSize: 32, fontWeight: '700', color: '#4C320C', lineHeight: 36 } });