|
|
@ -33,6 +33,56 @@ import { |
|
|
|
DomesticShippingFeeData, |
|
|
|
DomesticShippingFeeData, |
|
|
|
} from "../../services/api/orders"; |
|
|
|
} from "../../services/api/orders"; |
|
|
|
import AsyncStorage from "@react-native-async-storage/async-storage"; |
|
|
|
import AsyncStorage from "@react-native-async-storage/async-storage"; |
|
|
|
|
|
|
|
import { payApi, PaymentMethodsResponse } from "../../services/api/payApi"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface PaymentOption { |
|
|
|
|
|
|
|
id: string; |
|
|
|
|
|
|
|
label: string; |
|
|
|
|
|
|
|
icon: string; |
|
|
|
|
|
|
|
value?: string | string[]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interface PaymentTab { |
|
|
|
|
|
|
|
id: string; |
|
|
|
|
|
|
|
label: string; |
|
|
|
|
|
|
|
options: PaymentOption[]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const PaymentMethodItem = ({ option, isSelected, onSelect }: {
|
|
|
|
|
|
|
|
option: PaymentOption;
|
|
|
|
|
|
|
|
isSelected: boolean;
|
|
|
|
|
|
|
|
onSelect: () => void;
|
|
|
|
|
|
|
|
}) => ( |
|
|
|
|
|
|
|
<TouchableOpacity |
|
|
|
|
|
|
|
style={[ |
|
|
|
|
|
|
|
styles.paymentOption, |
|
|
|
|
|
|
|
isSelected && styles.paymentSelected |
|
|
|
|
|
|
|
]} |
|
|
|
|
|
|
|
onPress={onSelect} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<View style={styles.paymentContent}> |
|
|
|
|
|
|
|
<View style={styles.defaultPaymentContainer}> |
|
|
|
|
|
|
|
<Text style={styles.paymentIcon}>{option.icon}</Text> |
|
|
|
|
|
|
|
<Text style={styles.paymentLabel}>{option.label}</Text> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
{Array.isArray(option.value) && option.value.length > 0 && ( |
|
|
|
|
|
|
|
<View style={styles.operatorContainer}> |
|
|
|
|
|
|
|
{option.value.map((op: string) => ( |
|
|
|
|
|
|
|
<View key={op} style={styles.operatorBox}> |
|
|
|
|
|
|
|
<Text style={styles.operatorText}>{op}</Text> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
))} |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
<View style={styles.radioButton}> |
|
|
|
|
|
|
|
<View style={[ |
|
|
|
|
|
|
|
styles.radioInner, |
|
|
|
|
|
|
|
isSelected && styles.radioInnerSelected |
|
|
|
|
|
|
|
]} /> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
export function Recipient({ |
|
|
|
export function Recipient({ |
|
|
|
route, |
|
|
|
route, |
|
|
@ -61,17 +111,21 @@ export function Recipient({ |
|
|
|
useState<AddressDataItem>(); |
|
|
|
useState<AddressDataItem>(); |
|
|
|
const [domesticShippingFee, setDomesticShippingFee] = |
|
|
|
const [domesticShippingFee, setDomesticShippingFee] = |
|
|
|
useState<DomesticShippingFeeData>(); |
|
|
|
useState<DomesticShippingFeeData>(); |
|
|
|
const [tabs, setTabs] = useState([ |
|
|
|
const [tabs, setTabs] = useState<PaymentTab[]>([ |
|
|
|
{ |
|
|
|
{ |
|
|
|
id: "Online Payment", |
|
|
|
id: "online", |
|
|
|
label: "Online Payment", |
|
|
|
label: "Online Payment", |
|
|
|
|
|
|
|
options: [] |
|
|
|
}, |
|
|
|
}, |
|
|
|
{ |
|
|
|
{ |
|
|
|
id: "Offline Payment", |
|
|
|
id: "offline", |
|
|
|
label: "Offline Payment", |
|
|
|
label: "Offline Payment", |
|
|
|
}, |
|
|
|
options: [] |
|
|
|
|
|
|
|
} |
|
|
|
]); |
|
|
|
]); |
|
|
|
const [currentTab, setCurrentTab] = useState("Online Paymen"); |
|
|
|
const [currentTab, setCurrentTab] = useState("online"); |
|
|
|
|
|
|
|
const [selectedPayment, setSelectedPayment] = useState<string | null>(null); |
|
|
|
|
|
|
|
const [paymentMethods, setPaymentMethods] = useState<PaymentMethodsResponse>(); |
|
|
|
|
|
|
|
|
|
|
|
const getAddress = async () => { |
|
|
|
const getAddress = async () => { |
|
|
|
const response = await addressApi.addressesDefault(); |
|
|
|
const response = await addressApi.addressesDefault(); |
|
|
@ -106,8 +160,55 @@ export function Recipient({ |
|
|
|
items: route.params.items, |
|
|
|
items: route.params.items, |
|
|
|
}; |
|
|
|
}; |
|
|
|
const response = await ordersApi.calcDomesticShippingFee(data); |
|
|
|
const response = await ordersApi.calcDomesticShippingFee(data); |
|
|
|
|
|
|
|
// 转换响应数据以匹配 DomesticShippingFeeData 类型
|
|
|
|
|
|
|
|
const domesticShippingFeeData: DomesticShippingFeeData = { |
|
|
|
|
|
|
|
total_shipping_fee: response.total_shipping_fee_air || 0, |
|
|
|
|
|
|
|
currency: response.currency || '', |
|
|
|
|
|
|
|
// 添加其他必要的属性
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
setDomesticShippingFee(domesticShippingFeeData); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
setDomesticShippingFee(response); |
|
|
|
const getPaymentMethods = async () => { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const response = await payApi.getCountryPaymentMethods(); |
|
|
|
|
|
|
|
setPaymentMethods(response); |
|
|
|
|
|
|
|
// 设置默认支付方式选项
|
|
|
|
|
|
|
|
setTabs([ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
id: "online", |
|
|
|
|
|
|
|
label: "Online Payment", |
|
|
|
|
|
|
|
options: response.current_country_methods.map(method => ({ |
|
|
|
|
|
|
|
id: method.key, |
|
|
|
|
|
|
|
label: method.key, |
|
|
|
|
|
|
|
icon: getPaymentIcon(method.key), |
|
|
|
|
|
|
|
value: method.value |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
id: "offline", |
|
|
|
|
|
|
|
label: "Offline Payment", |
|
|
|
|
|
|
|
options: [] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
]); |
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
console.error('获取支付方式失败:', error); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getPaymentIcon = (key: string): string => { |
|
|
|
|
|
|
|
switch (key) { |
|
|
|
|
|
|
|
case 'Brainnel Pay(Mobile Money)': |
|
|
|
|
|
|
|
return '💳'; |
|
|
|
|
|
|
|
case 'Wave': |
|
|
|
|
|
|
|
return '💸'; |
|
|
|
|
|
|
|
case 'Paypal': |
|
|
|
|
|
|
|
return '🅿️'; |
|
|
|
|
|
|
|
case 'Bank Card Payment': |
|
|
|
|
|
|
|
return '💳'; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return '💰'; |
|
|
|
|
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
useEffect(() => { |
|
|
@ -116,6 +217,7 @@ export function Recipient({ |
|
|
|
getOrders(); |
|
|
|
getOrders(); |
|
|
|
getFreightForwarderAddress(); |
|
|
|
getFreightForwarderAddress(); |
|
|
|
getDomesticShippingFee(); |
|
|
|
getDomesticShippingFee(); |
|
|
|
|
|
|
|
getPaymentMethods(); |
|
|
|
const listener = (data: any) => { |
|
|
|
const listener = (data: any) => { |
|
|
|
if (data.type === "add") { |
|
|
|
if (data.type === "add") { |
|
|
|
data.address_id = new Date().getTime(); |
|
|
|
data.address_id = new Date().getTime(); |
|
|
@ -136,30 +238,32 @@ export function Recipient({ |
|
|
|
const [mobileNumber, setMobileNumber] = useState(""); |
|
|
|
const [mobileNumber, setMobileNumber] = useState(""); |
|
|
|
const [countryCode, setCountryCode] = useState("225"); |
|
|
|
const [countryCode, setCountryCode] = useState("225"); |
|
|
|
|
|
|
|
|
|
|
|
const balance = 245.0; |
|
|
|
|
|
|
|
const exchangeRates = { usd: 1, eur: 0.885 }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getOrderAmount = () => { |
|
|
|
|
|
|
|
// 模拟总金额,可加入实际订单计算逻辑
|
|
|
|
|
|
|
|
const baseAmount = parseFloat(shippingFee.replace("$", "")) || 0; |
|
|
|
|
|
|
|
return 100 + baseAmount; // 示例:商品 $100 + 运费
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [couponModalVisible, setCouponModalVisible] = useState(false); |
|
|
|
const [couponModalVisible, setCouponModalVisible] = useState(false); |
|
|
|
const [appliedCoupons, setAppliedCoupons] = useState([]); |
|
|
|
const [appliedCoupons, setAppliedCoupons] = useState<{ |
|
|
|
|
|
|
|
code: string; |
|
|
|
|
|
|
|
name: string; |
|
|
|
|
|
|
|
discount: number; |
|
|
|
|
|
|
|
type: 'percent' | 'fixed'; |
|
|
|
|
|
|
|
}[]>([]); |
|
|
|
const [orderTotal, setOrderTotal] = useState(121.97); |
|
|
|
const [orderTotal, setOrderTotal] = useState(121.97); |
|
|
|
const [originalTotal] = useState(121.97); |
|
|
|
const [originalTotal] = useState(121.97); |
|
|
|
const [subtotal] = useState(96.47); |
|
|
|
const [subtotal] = useState(96.47); |
|
|
|
const [domesticShipping] = useState(25.5); |
|
|
|
const [domesticShipping] = useState(25.5); |
|
|
|
const [internationalShipping] = useState(45.0); |
|
|
|
const [internationalShipping] = useState(45.0); |
|
|
|
|
|
|
|
|
|
|
|
const validCoupons = { |
|
|
|
const validCoupons: { |
|
|
|
|
|
|
|
[key: string]: { |
|
|
|
|
|
|
|
discount: number; |
|
|
|
|
|
|
|
type: 'percent' | 'fixed'; |
|
|
|
|
|
|
|
name: string; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} = { |
|
|
|
WELCOME10: { discount: 10, type: "percent", name: "Welcome 10% Off" }, |
|
|
|
WELCOME10: { discount: 10, type: "percent", name: "Welcome 10% Off" }, |
|
|
|
SAVE20: { discount: 20, type: "fixed", name: "$20 Off" }, |
|
|
|
SAVE20: { discount: 20, type: "fixed", name: "$20 Off" }, |
|
|
|
FREESHIP: { discount: 25.5, type: "fixed", name: "Free Domestic Shipping" }, |
|
|
|
FREESHIP: { discount: 25.5, type: "fixed", name: "Free Domestic Shipping" }, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const addCoupon = (code) => { |
|
|
|
const addCoupon = (code: string) => { |
|
|
|
if (appliedCoupons.find((c) => c.code === code)) { |
|
|
|
if (appliedCoupons.find((c) => c.code === code)) { |
|
|
|
alert("This coupon is already applied."); |
|
|
|
alert("This coupon is already applied."); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -180,13 +284,13 @@ export function Recipient({ |
|
|
|
updateTotalWithDiscounts(newCoupons); |
|
|
|
updateTotalWithDiscounts(newCoupons); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const removeCoupon = (code) => { |
|
|
|
const removeCoupon = (code: string) => { |
|
|
|
const newCoupons = appliedCoupons.filter((c) => c.code !== code); |
|
|
|
const newCoupons = appliedCoupons.filter((c) => c.code !== code); |
|
|
|
setAppliedCoupons(newCoupons); |
|
|
|
setAppliedCoupons(newCoupons); |
|
|
|
updateTotalWithDiscounts(newCoupons); |
|
|
|
updateTotalWithDiscounts(newCoupons); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const updateTotalWithDiscounts = (coupons) => { |
|
|
|
const updateTotalWithDiscounts = (coupons: typeof appliedCoupons) => { |
|
|
|
let totalDiscount = 0; |
|
|
|
let totalDiscount = 0; |
|
|
|
|
|
|
|
|
|
|
|
coupons.forEach((coupon) => { |
|
|
|
coupons.forEach((coupon) => { |
|
|
@ -202,7 +306,7 @@ export function Recipient({ |
|
|
|
setOrderTotal(newTotal); |
|
|
|
setOrderTotal(newTotal); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const isCouponApplied = (code) => { |
|
|
|
const isCouponApplied = (code: string) => { |
|
|
|
return appliedCoupons.some((c) => c.code === code); |
|
|
|
return appliedCoupons.some((c) => c.code === code); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -405,103 +509,38 @@ export function Recipient({ |
|
|
|
<Text style={styles.sectionIcon}>💳</Text> |
|
|
|
<Text style={styles.sectionIcon}>💳</Text> |
|
|
|
<Text style={styles.sectionTitle}>Payment Method</Text> |
|
|
|
<Text style={styles.sectionTitle}>Payment Method</Text> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
<View style={styles.paymentOptions}> |
|
|
|
|
|
|
|
<View style={styles.paymentOption}> |
|
|
|
|
|
|
|
<Text style={styles.paymentLabel}>Online Payment</Text> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
<View style={styles.paymentOption}> |
|
|
|
|
|
|
|
<Text style={styles.paymentLabel}>Offline Payment</Text> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
<View> |
|
|
|
|
|
|
|
{/* {[ |
|
|
|
|
|
|
|
{ id: "balance", icon: "💰", label: "Account Balance" }, |
|
|
|
|
|
|
|
{ id: "mobile_money", icon: "📱", label: "Mobile Money" }, |
|
|
|
|
|
|
|
{ id: "paypal", icon: "🅿️", label: "PayPal" }, |
|
|
|
|
|
|
|
{ id: "card", icon: "💳", label: "Credit/Debit Card" }, |
|
|
|
|
|
|
|
].map((option) => ( |
|
|
|
|
|
|
|
<TouchableOpacity |
|
|
|
|
|
|
|
key={option.id} |
|
|
|
|
|
|
|
style={[ |
|
|
|
|
|
|
|
styles.paymentOption, |
|
|
|
|
|
|
|
paymentMethod === option.id && styles.paymentSelected, |
|
|
|
|
|
|
|
]} |
|
|
|
|
|
|
|
onPress={() => { |
|
|
|
|
|
|
|
setPaymentMethod(option.id); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<Text style={styles.paymentIcon}>{option.icon}</Text> |
|
|
|
|
|
|
|
<Text style={styles.paymentLabel}>{option.label}</Text> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
|
|
|
|
))} */} |
|
|
|
|
|
|
|
{tabs.map((item, index) => ( |
|
|
|
|
|
|
|
<TouchableOpacity |
|
|
|
|
|
|
|
key={index} |
|
|
|
|
|
|
|
onPress={() => { |
|
|
|
|
|
|
|
setCurrentTab(item.id); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<View style={styles.tabContainer}> |
|
|
|
|
|
|
|
<Text style={styles.paymentLabel}>{item.label}</Text> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
|
|
|
|
))} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* Mobile Money 表单 */} |
|
|
|
|
|
|
|
{paymentMethod === "mobile_money" && ( |
|
|
|
|
|
|
|
<View style={styles.mobileForm}> |
|
|
|
|
|
|
|
<Text style={styles.formLabel}>Mobile Number</Text> |
|
|
|
|
|
|
|
<View style={{ flexDirection: "row", alignItems: "center" }}> |
|
|
|
|
|
|
|
<TouchableOpacity |
|
|
|
|
|
|
|
onPress={() => { |
|
|
|
|
|
|
|
const next = |
|
|
|
|
|
|
|
countryCode === "225" |
|
|
|
|
|
|
|
? "234" |
|
|
|
|
|
|
|
: countryCode === "234" |
|
|
|
|
|
|
|
? "233" |
|
|
|
|
|
|
|
: "225"; |
|
|
|
|
|
|
|
setCountryCode(next); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<Text style={styles.countryCode}>{countryCode}</Text> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
|
|
|
|
<TextInput |
|
|
|
|
|
|
|
style={[styles.input, { flex: 1, marginLeft: 10 }]} |
|
|
|
|
|
|
|
keyboardType="phone-pad" |
|
|
|
|
|
|
|
placeholder="Enter your number" |
|
|
|
|
|
|
|
value={mobileNumber} |
|
|
|
|
|
|
|
onChangeText={setMobileNumber} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
)} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* PayPal Currency 切换 */} |
|
|
|
{/* 选项卡 */} |
|
|
|
{paymentMethod === "paypal" && ( |
|
|
|
<View style={styles.tabContainer}> |
|
|
|
<View style={{ marginTop: 12 }}> |
|
|
|
{tabs.map((tab) => ( |
|
|
|
<Text style={styles.formLabel}>Select Currency</Text> |
|
|
|
|
|
|
|
<View style={{ flexDirection: "row", marginTop: 8 }}> |
|
|
|
|
|
|
|
{["usd", "eur"].map((cur) => ( |
|
|
|
|
|
|
|
<TouchableOpacity |
|
|
|
<TouchableOpacity |
|
|
|
key={cur} |
|
|
|
key={tab.id} |
|
|
|
onPress={() => { |
|
|
|
|
|
|
|
setCurrency(cur); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
style={[ |
|
|
|
style={[ |
|
|
|
styles.currencyButton, |
|
|
|
styles.tabButton, |
|
|
|
currency === cur && styles.currencyButtonSelected, |
|
|
|
currentTab === tab.id && styles.tabButtonActive |
|
|
|
]} |
|
|
|
]} |
|
|
|
|
|
|
|
onPress={() => setCurrentTab(tab.id)} |
|
|
|
> |
|
|
|
> |
|
|
|
<Text |
|
|
|
<Text style={[ |
|
|
|
style={{ color: currency === cur ? "#ff6000" : "#333" }} |
|
|
|
styles.tabText, |
|
|
|
> |
|
|
|
currentTab === tab.id && styles.tabTextActive |
|
|
|
{cur.toUpperCase()} |
|
|
|
]}> |
|
|
|
|
|
|
|
{tab.label} |
|
|
|
</Text> |
|
|
|
</Text> |
|
|
|
</TouchableOpacity> |
|
|
|
</TouchableOpacity> |
|
|
|
))} |
|
|
|
))} |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
|
|
|
|
)} |
|
|
|
{/* 支付选项 */} |
|
|
|
|
|
|
|
<View style={styles.paymentOptions}> |
|
|
|
|
|
|
|
{tabs.find(tab => tab.id === currentTab)?.options.map((option) => ( |
|
|
|
|
|
|
|
<PaymentMethodItem |
|
|
|
|
|
|
|
key={option.id} |
|
|
|
|
|
|
|
option={option} |
|
|
|
|
|
|
|
isSelected={selectedPayment === option.id} |
|
|
|
|
|
|
|
onSelect={() => setSelectedPayment(option.id)} |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
))} |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
|
|
|
|
|
|
|
@ -918,8 +957,75 @@ export function Recipient({ |
|
|
|
<TouchableOpacity |
|
|
|
<TouchableOpacity |
|
|
|
style={styles.bottomButton} |
|
|
|
style={styles.bottomButton} |
|
|
|
disabled={!domesticShippingFee?.currency} |
|
|
|
disabled={!domesticShippingFee?.currency} |
|
|
|
onPress={() => { |
|
|
|
onPress={async () => { |
|
|
|
console.log(123); |
|
|
|
if (!defaultAddress) { |
|
|
|
|
|
|
|
alert('请添加收件人信息'); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!selectedPayment) { |
|
|
|
|
|
|
|
alert('请选择支付方式'); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(orderData); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 构建订单数据
|
|
|
|
|
|
|
|
const submitOrderData = { |
|
|
|
|
|
|
|
address_id: defaultAddress.address_id, |
|
|
|
|
|
|
|
items: orderData?.items.map(item => ({ |
|
|
|
|
|
|
|
offer_id: item.offer_id, |
|
|
|
|
|
|
|
cart_item_id: item.cart_item_id, |
|
|
|
|
|
|
|
sku_id: item.sku_id, |
|
|
|
|
|
|
|
product_name: item.product_name, |
|
|
|
|
|
|
|
product_name_en: item.product_name_en, |
|
|
|
|
|
|
|
product_name_ar: item.product_name_ar, |
|
|
|
|
|
|
|
product_name_fr: item.product_name_fr, |
|
|
|
|
|
|
|
product_image: item.sku_image_url, |
|
|
|
|
|
|
|
sku_attributes: item.attributes.map(attr => ({ |
|
|
|
|
|
|
|
attribute_name: attr.attribute_name, |
|
|
|
|
|
|
|
attribute_value: attr.value |
|
|
|
|
|
|
|
})), |
|
|
|
|
|
|
|
quantity: item.quantity, |
|
|
|
|
|
|
|
unit_price: item.unit_price, |
|
|
|
|
|
|
|
total_price: item.total_price |
|
|
|
|
|
|
|
})) || [], |
|
|
|
|
|
|
|
buyer_message: "", |
|
|
|
|
|
|
|
payment_method: selectedPayment, |
|
|
|
|
|
|
|
create_payment: true, |
|
|
|
|
|
|
|
total_amount: orderData?.total_amount || 0, |
|
|
|
|
|
|
|
actual_amount: ( |
|
|
|
|
|
|
|
(orderData?.total_amount ?? 0) + |
|
|
|
|
|
|
|
(shippingMethod === 'sea'
|
|
|
|
|
|
|
|
? orderData?.shipping_fee_sea ?? 0
|
|
|
|
|
|
|
|
: orderData?.shipping_fee_air ?? 0) + |
|
|
|
|
|
|
|
(domesticShippingFee?.total_shipping_fee ?? 0) |
|
|
|
|
|
|
|
), |
|
|
|
|
|
|
|
discount_amount: 0, |
|
|
|
|
|
|
|
shipping_fee: shippingMethod === 'sea'
|
|
|
|
|
|
|
|
? orderData?.shipping_fee_sea ?? 0
|
|
|
|
|
|
|
|
: orderData?.shipping_fee_air ?? 0, |
|
|
|
|
|
|
|
domestic_shipping_fee: domesticShippingFee?.total_shipping_fee || 0, |
|
|
|
|
|
|
|
currency: domesticShippingFee?.currency || 'USD', |
|
|
|
|
|
|
|
receiver_address: `${defaultAddress.country} ${defaultAddress.province || ''} ${defaultAddress.city || ''} ${defaultAddress.detail_address || ''}` |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 打印订单数据
|
|
|
|
|
|
|
|
console.log('订单数据:', JSON.stringify(submitOrderData, null, 2)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建订单请求(暂时注释)
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const response = await ordersApi.createOrder(submitOrderData); |
|
|
|
|
|
|
|
console.log('订单创建成功:', response); |
|
|
|
|
|
|
|
if (response.payment_url) { |
|
|
|
|
|
|
|
// 处理支付链接
|
|
|
|
|
|
|
|
console.log('支付链接:', response.payment_url); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
navigation.navigate('ConfirmOrder', { orderId: response.order_id }); |
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
console.error('创建订单失败:', error); |
|
|
|
|
|
|
|
alert('创建订单失败,请重试'); |
|
|
|
|
|
|
|
} |
|
|
|
}} |
|
|
|
}} |
|
|
|
> |
|
|
|
> |
|
|
|
<View style={styles.bottomButtonContent}> |
|
|
|
<View style={styles.bottomButtonContent}> |
|
|
@ -974,10 +1080,8 @@ const styles = StyleSheet.create({ |
|
|
|
fontWeight: "500", |
|
|
|
fontWeight: "500", |
|
|
|
}, |
|
|
|
}, |
|
|
|
paymentOptions: { |
|
|
|
paymentOptions: { |
|
|
|
flexDirection: "row", |
|
|
|
marginTop: 12, |
|
|
|
justifyContent: "space-between", |
|
|
|
flexDirection: 'column', |
|
|
|
alignItems: "center", |
|
|
|
|
|
|
|
width: "100%", |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
recipientInfo: { |
|
|
|
recipientInfo: { |
|
|
|
backgroundColor: "#fff", |
|
|
|
backgroundColor: "#fff", |
|
|
@ -1062,7 +1166,6 @@ const styles = StyleSheet.create({ |
|
|
|
color: "#777", |
|
|
|
color: "#777", |
|
|
|
fontWeight: "500", |
|
|
|
fontWeight: "500", |
|
|
|
fontSize: fontSize(13), |
|
|
|
fontSize: fontSize(13), |
|
|
|
color: "#333", |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
modalOverlay: { |
|
|
|
modalOverlay: { |
|
|
@ -1121,24 +1224,47 @@ const styles = StyleSheet.create({ |
|
|
|
fontWeight: "500", |
|
|
|
fontWeight: "500", |
|
|
|
}, |
|
|
|
}, |
|
|
|
paymentOption: { |
|
|
|
paymentOption: { |
|
|
|
flexDirection: "row", |
|
|
|
flexDirection: 'row', |
|
|
|
alignItems: "center", |
|
|
|
alignItems: 'center', |
|
|
|
|
|
|
|
padding: 16, |
|
|
|
|
|
|
|
marginBottom: 12, |
|
|
|
borderWidth: 1, |
|
|
|
borderWidth: 1, |
|
|
|
borderColor: "#ddd", |
|
|
|
borderColor: '#eee', |
|
|
|
padding: 12, |
|
|
|
borderRadius: 8, |
|
|
|
borderRadius: 6, |
|
|
|
backgroundColor: '#fff', |
|
|
|
width: "50%", |
|
|
|
width: '100%', |
|
|
|
}, |
|
|
|
}, |
|
|
|
paymentSelected: { |
|
|
|
paymentSelected: { |
|
|
|
borderColor: "#ff6000", |
|
|
|
backgroundColor: '#fff8f3', |
|
|
|
backgroundColor: "#fff8f3", |
|
|
|
borderColor: '#ff8c47', |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
paymentIcon: { fontSize: fontSize(20), marginRight: 10 }, |
|
|
|
paymentIcon: { fontSize: fontSize(24), marginRight: 8 }, |
|
|
|
paymentLabel: { fontSize: fontSize(14), fontWeight: "500" }, |
|
|
|
paymentLabel: { fontSize: fontSize(16), fontWeight: '500' }, |
|
|
|
tabContainer: { |
|
|
|
tabContainer: { |
|
|
|
width: 100, |
|
|
|
flexDirection: 'row', |
|
|
|
flexDirection: "row", |
|
|
|
marginBottom: 16, |
|
|
|
|
|
|
|
backgroundColor: '#f5f5f5', |
|
|
|
|
|
|
|
borderRadius: 8, |
|
|
|
|
|
|
|
padding: 4, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
tabButton: { |
|
|
|
|
|
|
|
flex: 1, |
|
|
|
|
|
|
|
paddingVertical: 12, |
|
|
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
|
|
borderRadius: 6, |
|
|
|
|
|
|
|
marginRight: 4, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
tabButtonActive: { |
|
|
|
|
|
|
|
backgroundColor: '#fff', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
tabText: { |
|
|
|
|
|
|
|
fontSize: fontSize(14), |
|
|
|
|
|
|
|
color: '#666', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
tabTextActive: { |
|
|
|
|
|
|
|
color: '#000', |
|
|
|
|
|
|
|
fontWeight: '500', |
|
|
|
}, |
|
|
|
}, |
|
|
|
mobileForm: { marginTop: 12 }, |
|
|
|
mobileForm: { marginTop: 12 }, |
|
|
|
countryCode: { |
|
|
|
countryCode: { |
|
|
@ -1674,4 +1800,91 @@ const styles = StyleSheet.create({ |
|
|
|
fontSize: fontSize(16), |
|
|
|
fontSize: fontSize(16), |
|
|
|
fontWeight: "500", |
|
|
|
fontWeight: "500", |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
paymentContent: { |
|
|
|
|
|
|
|
flex: 1, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
brainnelHeader: { |
|
|
|
|
|
|
|
flexDirection: 'row', |
|
|
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
|
|
marginBottom: 8, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
paymentLogo: { |
|
|
|
|
|
|
|
height: 30, |
|
|
|
|
|
|
|
width: 100, |
|
|
|
|
|
|
|
resizeMode: 'contain', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
paymentDescription: { |
|
|
|
|
|
|
|
fontSize: fontSize(12), |
|
|
|
|
|
|
|
color: '#666', |
|
|
|
|
|
|
|
marginLeft: 8, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
operatorContainer: { |
|
|
|
|
|
|
|
flexDirection: 'row', |
|
|
|
|
|
|
|
flexWrap: 'wrap', |
|
|
|
|
|
|
|
gap: 8, |
|
|
|
|
|
|
|
marginTop: 8, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
operatorBox: { |
|
|
|
|
|
|
|
padding: 8, |
|
|
|
|
|
|
|
backgroundColor: '#f5f5f5', |
|
|
|
|
|
|
|
borderRadius: 4, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
soldesContainer: { |
|
|
|
|
|
|
|
flexDirection: 'row', |
|
|
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
balanceText: { |
|
|
|
|
|
|
|
marginLeft: 8, |
|
|
|
|
|
|
|
fontSize: fontSize(14), |
|
|
|
|
|
|
|
color: '#666', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
cardTypesContainer: { |
|
|
|
|
|
|
|
flexDirection: 'row', |
|
|
|
|
|
|
|
gap: 8, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
cardTypeIcon: { |
|
|
|
|
|
|
|
height: 24, |
|
|
|
|
|
|
|
width: 36, |
|
|
|
|
|
|
|
resizeMode: 'contain', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
radioButton: { |
|
|
|
|
|
|
|
width: 20, |
|
|
|
|
|
|
|
height: 20, |
|
|
|
|
|
|
|
borderRadius: 10, |
|
|
|
|
|
|
|
borderWidth: 2, |
|
|
|
|
|
|
|
borderColor: '#ddd', |
|
|
|
|
|
|
|
justifyContent: 'center', |
|
|
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
radioInner: { |
|
|
|
|
|
|
|
width: 10, |
|
|
|
|
|
|
|
height: 10, |
|
|
|
|
|
|
|
borderRadius: 5, |
|
|
|
|
|
|
|
backgroundColor: 'transparent', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
radioInnerSelected: { |
|
|
|
|
|
|
|
backgroundColor: '#ff8c47', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
cardHeader: { |
|
|
|
|
|
|
|
flexDirection: 'row', |
|
|
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
|
|
marginBottom: 8, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
cardTypeBox: { |
|
|
|
|
|
|
|
padding: 6, |
|
|
|
|
|
|
|
backgroundColor: '#f5f5f5', |
|
|
|
|
|
|
|
borderRadius: 4, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
cardTypeText: { |
|
|
|
|
|
|
|
fontSize: fontSize(12), |
|
|
|
|
|
|
|
color: '#666', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
defaultPaymentContainer: { |
|
|
|
|
|
|
|
flexDirection: 'row', |
|
|
|
|
|
|
|
alignItems: 'center', |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
operatorText: { |
|
|
|
|
|
|
|
fontSize: fontSize(12), |
|
|
|
|
|
|
|
color: '#666', |
|
|
|
|
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
|