import { Image } from 'expo-image'; import React, { useEffect, useState } from 'react'; import { Alert, Modal, Platform, ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Images } from '@/constants/images'; import { transferOrderSubmit } from '@/services/user'; interface GroupedGoods { total: number; data: { id: string; cover: string; spuId: string; level: string; }; } interface TransferModalProps { visible: boolean; selectedItems: Array<{ id: string; spu: { id: string; name: string; cover: string }; level: string; }>; onClose: () => void; onSuccess: () => void; } export default function TransferModal({ visible, selectedItems, onClose, onSuccess, }: TransferModalProps) { const insets = useSafeAreaInsets(); const [recipientId, setRecipientId] = useState(''); const [checked, setChecked] = useState(true); const [submitting, setSubmitting] = useState(false); 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) { // 合并同款商品 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, }, }; } }); setGoodsList(Object.values(goodsMap)); setRecipientId(''); } }, [visible, selectedItems]); const handleSubmit = async () => { if (!recipientId.trim()) { showAlert('请输入受赠人ID'); return; } if (!checked) { showAlert('请阅读并同意《转赠风险及责任声明》'); return; } if (submitting) return; setSubmitting(true); try { const inventoryIds = selectedItems.map((item) => item.id); const levels = selectedItems.map((item) => item.level); const res: any = await transferOrderSubmit({ inventoryIds, levels, toUserShortId: recipientId.trim(), }); if (res && res.success) { showAlert('转赠成功'); onClose(); onSuccess(); } else { showAlert(res?.msg || res?.message || '转赠失败'); } } catch (err) { console.error('转赠失败:', err); showAlert('转赠失败,请稍后再试'); } setSubmitting(false); }; return ( {/* 标题 */} 转赠 × {/* 商品列表 */} {goodsList.map((goods, idx) => ( x{goods.total} ))} {/* 受赠人ID输入 */} 受赠人ID {/* 转赠声明 */} {}}> 已阅读并同意 《转赠风险及责任声明》 setChecked(!checked)} > {checked && } {/* 提交按钮 */} {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', paddingTop: 22, paddingBottom: 5, 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 }, 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' }, inputSection: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', backgroundColor: '#f8f8f8', borderRadius: 6, paddingHorizontal: 10, paddingVertical: 10, marginVertical: 15, shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.05, shadowRadius: 3, }, inputLabel: { fontSize: 14, fontWeight: '500', color: '#333', }, input: { flex: 1, marginLeft: 10, textAlign: 'right', height: 30, fontSize: 14, color: '#666', }, agreementRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingVertical: 10, }, agreementText: { flexDirection: 'row', alignItems: 'center', }, agreementLabel: { fontSize: 12, color: '#333', }, agreementLink: { fontSize: 12, color: '#ff9600', }, radio: { width: 20, height: 20, borderRadius: 10, borderWidth: 2, borderColor: '#ccc', justifyContent: 'center', alignItems: 'center', }, radioChecked: { backgroundColor: '#ff9600', borderColor: '#ff9600', }, radioIcon: { color: '#fff', fontSize: 12, fontWeight: 'bold', }, submitBtn: { backgroundColor: '#ff9600', borderRadius: 22, height: 44, justifyContent: 'center', alignItems: 'center', marginTop: 5, }, submitBtnText: { color: '#fff', fontSize: 16, fontWeight: 'bold', }, fill: { height: 25 }, });