import { Image } from 'expo-image'; import Alipay from 'expo-native-alipay'; import { useRouter } from 'expo-router'; import React, { useEffect, useState } from 'react'; import { ActivityIndicator, Alert, ImageBackground, Modal, Platform, ScrollView, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Images } from '@/constants/images'; import { Address, getDefaultAddress } from '@/services/address'; import { takeApply, takePreview } from '@/services/award'; interface GroupedGoods { total: number; data: { id: string; cover: string; spuId: string; level: string; name?: string }; } interface CheckoutModalProps { visible: boolean; selectedItems: Array<{ id: string; spu: { id: string; name: string; cover: string }; level: string }>; onClose: () => void; onSuccess: () => void; } export default function CheckoutModal({ visible, selectedItems, onClose, onSuccess }: CheckoutModalProps) { const router = useRouter(); const insets = useSafeAreaInsets(); const [loading, setLoading] = useState(false); const [submitting, setSubmitting] = useState(false); const [address, setAddress] = useState
(null); const [expressAmount, setExpressAmount] = useState(0); const [goodsList, setGoodsList] = useState([]); const showAlert = (msg: string) => { if (Platform.OS === 'web') window.alert(msg); else Alert.alert('提示', msg); }; useEffect(() => { if (visible && selectedItems.length > 0) { loadData(); } }, [visible, selectedItems]); const loadData = async () => { setLoading(true); try { // 获取默认地址 const addr = await getDefaultAddress(); setAddress(addr); // 获取提货预览 const ids = selectedItems.map(item => item.id); const res = await takePreview(ids, addr?.id || ''); if (res) { setExpressAmount(res.expressAmount || 0); } // 合并相同商品 const goodsMap: Record = {}; selectedItems.forEach((item) => { const key = `${item.spu.id}_${item.level}`; if (goodsMap[key]) { goodsMap[key].total += 1; } else { goodsMap[key] = { total: 1, data: { id: item.id, cover: item.spu.cover, spuId: item.spu.id, level: item.level, name: item.spu.name, }, }; } }); setGoodsList(Object.values(goodsMap)); } catch (e) { console.error('加载提货信息失败:', e); } setLoading(false); }; const goToAddress = () => { onClose(); router.push('/address?type=1' as any); }; /* * Handle Submit with Payment Choice */ const handleSubmit = async () => { if (!address) { showAlert('请选择收货地址'); return; } if (expressAmount > 0) { Alert.alert( '支付运费', `需支付运费 ¥${expressAmount}`, [ { text: '取消', style: 'cancel' }, { text: '钱包支付', onPress: () => processTakeApply('WALLET') }, { text: '支付宝支付', onPress: () => processTakeApply('ALIPAY_APP') } ] ); } else { processTakeApply('WALLET'); } }; const processTakeApply = async (paymentType: string) => { if (submitting) return; setSubmitting(true); try { const ids = selectedItems.map(item => item.id); const res: any = await takeApply(ids, address!.id, paymentType); console.log('Take Apply Res:', res, paymentType); if (paymentType === 'ALIPAY_APP' && res?.payInfo) { Alipay.setAlipayScheme('alipay2021005175632205'); const result = await Alipay.pay(res.payInfo); console.log('Alipay Result:', result); if (result?.resultStatus === '9000') { showAlert('提货成功'); onSuccess(); } else { showAlert('支付未完成'); } } else if (res) { // Wallet payment or free success showAlert('提货成功'); onSuccess(); } } catch (e) { console.error('提货失败:', e); // Usually axios interceptor handles error alerts, but just in case // showAlert('提货失败'); } setSubmitting(false); }; return ( {/* 标题 */} 提货 × {loading ? ( ) : ( <> {/* 商品列表 */} {goodsList.map((goods, idx) => ( x{goods.total} ))} {/* 运费 */} {expressAmount > 0 && ( 运费 ¥{expressAmount} )} {/* 收货地址 */} {!address ? ( 请填写收货地址 ) : ( {address.contactName} {address.contactNo} {address.province}{address.city}{address.district}{address.address} )} {/* 提交按钮 */} {submitting ? '提交中...' : '确定发货'} )} ); } const styles = StyleSheet.create({ overlay: { flex: 1, justifyContent: 'flex-end' }, overlayBg: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.5)' }, container: { backgroundColor: '#fff', borderTopLeftRadius: 15, borderTopRightRadius: 15, paddingHorizontal: 14 }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: 20, position: 'relative' }, title: { fontSize: 16, fontWeight: 'bold', color: '#000' }, closeBtn: { position: 'absolute', right: 0, top: 15, width: 24, height: 24, backgroundColor: '#ebebeb', borderRadius: 12, justifyContent: 'center', alignItems: 'center' }, closeBtnText: { fontSize: 18, color: '#a2a2a2', lineHeight: 20 }, loadingBox: { height: 200, justifyContent: 'center', alignItems: 'center' }, goodsSection: { paddingVertical: 10 }, goodsItem: { width: 79, height: 103, backgroundColor: '#fff', borderRadius: 6, marginRight: 8, alignItems: 'center', justifyContent: 'center', position: 'relative', borderWidth: 1, borderColor: '#eaeaea' }, goodsImg: { width: 73, height: 85 }, goodsCount: { position: 'absolute', top: 0, right: 0, backgroundColor: '#ff6b00', borderRadius: 2, paddingHorizontal: 4, paddingVertical: 2 }, goodsCountText: { color: '#fff', fontSize: 10, fontWeight: 'bold' }, feeRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 8 }, feeLabel: { fontSize: 14, color: '#333' }, feeValue: { fontSize: 14, color: '#ff6b00', fontWeight: 'bold' }, addressSection: { flexDirection: 'row', alignItems: 'center', paddingVertical: 10, borderTopWidth: 1, borderTopColor: '#f0f0f0' }, noAddress: { flex: 1, fontSize: 16, fontWeight: 'bold', color: '#333' }, addressInfo: { flex: 1 }, addressName: { fontSize: 14, color: '#333', fontWeight: 'bold' }, addressDetail: { fontSize: 12, color: '#666', marginTop: 4 }, arrowIcon: { fontSize: 20, color: '#999', marginLeft: 10 }, submitBtn: { alignItems: 'center', marginTop: 15 }, submitBtnBg: { width: 260, height: 60, justifyContent: 'center', alignItems: 'center' }, submitBtnText: { color: '#000', fontSize: 16, fontWeight: 'bold' }, });