Browse Source

修改支付金额,货币转换

main
Your Name 3 weeks ago
parent
commit
bc18141cfc
  1. 43
      App.tsx
  2. 7
      app.json
  3. 9
      app/navigation/RootNavigation.ts
  4. 51
      app/screens/ProfileScreen.tsx
  5. 21
      app/screens/SearchResultScreen.tsx
  6. 59
      app/screens/pay/Pay.tsx
  7. 554
      app/screens/previewOrder/PaymentMethod.tsx
  8. 210
      app/screens/previewOrder/ShippingFee.tsx
  9. 6
      app/screens/previewOrder/perviewOrder.tsx
  10. 6
      app/services/api/payApi.ts

43
App.tsx

@ -7,11 +7,13 @@ import useBurialPointStore from "./app/store/burialPoint";
import { AuthProvider, useAuth } from "./app/contexts/AuthContext"; import { AuthProvider, useAuth } from "./app/contexts/AuthContext";
import { GestureHandlerRootView } from "react-native-gesture-handler"; import { GestureHandlerRootView } from "react-native-gesture-handler";
import { AppNavigator } from "./app/navigation/AppNavigator"; import { AppNavigator } from "./app/navigation/AppNavigator";
import { View, ActivityIndicator } from "react-native"; import { View, ActivityIndicator, Alert } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
import "./app/i18n"; import "./app/i18n";
import * as Linking from 'expo-linking';
// 定义全局事件处理支付成功
export const PAYMENT_SUCCESS_EVENT = 'PAYMENT_SUCCESS_EVENT';
function AppContent() { function AppContent() {
const { setUser } = useUserStore(); const { setUser } = useUserStore();
@ -47,6 +49,43 @@ function AppContent() {
initApp(); initApp();
}, []); }, []);
// 添加深度链接处理
useEffect(() => {
// 处理深度链接
const handleDeepLink = ({ url }: { url: string }) => {
console.log('Global deep link received:', url);
if (
url.startsWith('myapp://payment-success') ||
url.startsWith('exp://192.168.0.101:8084/--/payment-success')
) {
// 解析参数
const parsed = Linking.parse(url);
const params = parsed.queryParams || {};
const paymentId = params.paymentId || '';
const token = params.token || '';
const payerId = params.PayerID || '';
Alert.alert(
'支付成功!',
`支付ID: ${paymentId}\nToken: ${token}\nPayerID: ${payerId}`
);
// 这里可以做页面跳转或业务处理
}
};
// 注册深度链接监听器
const subscription = Linking.addEventListener('url', handleDeepLink);
// 处理应用冷启动的深度链接
Linking.getInitialURL().then((url) => {
if (url && url.startsWith('myapp://payment-success')) {
handleDeepLink({ url });
}
});
return () => subscription.remove();
}, []);
if (isLoading) { if (isLoading) {
return ( return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>

7
app.json

@ -7,7 +7,8 @@
"icon": "./assets/icon.png", "icon": "./assets/icon.png",
"userInterfaceStyle": "light", "userInterfaceStyle": "light",
"newArchEnabled": true, "newArchEnabled": true,
"scheme": "auth0sample", "scheme": "myapp",
"deepLinking": true,
"splash": { "splash": {
"image": "./assets/splash-icon.png", "image": "./assets/splash-icon.png",
"resizeMode": "contain", "resizeMode": "contain",
@ -20,7 +21,7 @@
"CFBundleURLTypes": [ "CFBundleURLTypes": [
{ {
"CFBundleURLSchemes": [ "CFBundleURLSchemes": [
"auth0sample" "myapp"
] ]
} }
] ]
@ -41,7 +42,7 @@
"action": "VIEW", "action": "VIEW",
"data": [ "data": [
{ {
"scheme": "auth0sample" "scheme": "myapp"
} }
], ],
"category": [ "category": [

9
app/navigation/RootNavigation.ts

@ -0,0 +1,9 @@
import { createNavigationContainerRef } from '@react-navigation/native';
export const navigationRef = createNavigationContainerRef<any>();
export function navigate(name: string, params?: object) {
if (navigationRef.isReady()) {
navigationRef.navigate(name, params);
}
}

51
app/screens/ProfileScreen.tsx

@ -10,6 +10,7 @@ import {
Platform, Platform,
StatusBar, StatusBar,
SafeAreaView, SafeAreaView,
Linking,
} from "react-native"; } from "react-native";
import SettingsIcon from "../components/SettingsIcon"; import SettingsIcon from "../components/SettingsIcon";
import fontSize from "../utils/fontsizeUtils"; import fontSize from "../utils/fontsizeUtils";
@ -87,7 +88,9 @@ export const ProfileScreen = () => {
<Text style={styles.uniqueHeaderTextStyle}> <Text style={styles.uniqueHeaderTextStyle}>
{user?.username} {user?.username}
</Text> </Text>
<Text style={styles.elegantText}>ID: {user?.user_id}</Text> <Text style={styles.elegantText}>
ID: {user?.user_id}
</Text>
</View> </View>
<TouchableOpacity <TouchableOpacity
style={styles.transactionSummaryBox} style={styles.transactionSummaryBox}
@ -111,7 +114,9 @@ export const ProfileScreen = () => {
<View style={styles.promoCardContainerVip}> <View style={styles.promoCardContainerVip}>
<View style={styles.VipCard}> <View style={styles.VipCard}>
<View style={styles.Vip}> <View style={styles.Vip}>
<Text style={styles.goldenItalicHeading}>VIP{user?.vip_level}</Text> <Text style={styles.goldenItalicHeading}>
VIP{user?.vip_level}
</Text>
<Image <Image
source={require("../../assets/img/折扣VIP1 (1).png")} source={require("../../assets/img/折扣VIP1 (1).png")}
style={styles.VipImg} style={styles.VipImg}
@ -119,7 +124,9 @@ export const ProfileScreen = () => {
</View> </View>
<View style={styles.progressBar}> <View style={styles.progressBar}>
<View style={styles.progressBarFill}> <View style={styles.progressBarFill}>
<Text style={styles.progressBarText}>40000/50000</Text> <Text style={styles.progressBarText}>
40000/50000
</Text>
</View> </View>
<View style={styles.progressBarLine}></View> <View style={styles.progressBarLine}></View>
</View> </View>
@ -132,7 +139,9 @@ export const ProfileScreen = () => {
</View> </View>
<TouchableOpacity <TouchableOpacity
style={styles.vipExplanationButton} style={styles.vipExplanationButton}
onPress={() => navigation.navigate("MemberIntroduction")} onPress={() =>
navigation.navigate("MemberIntroduction")
}
> >
<Text style={styles.vipExplanationButtonText}> <Text style={styles.vipExplanationButtonText}>
@ -169,7 +178,10 @@ export const ProfileScreen = () => {
style={styles.profileImage} style={styles.profileImage}
/> />
</View> </View>
<TouchableOpacity style={styles.loginButton} onPress={handleLogin}> <TouchableOpacity
style={styles.loginButton}
onPress={handleLogin}
>
<Text style={styles.loginButtonText}></Text> <Text style={styles.loginButtonText}></Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
@ -179,6 +191,14 @@ export const ProfileScreen = () => {
<View style={styles.verticalCenterImageGallery}> <View style={styles.verticalCenterImageGallery}>
<TouchableOpacity onPress={handleLogin}> <TouchableOpacity onPress={handleLogin}>
<Text></Text> <Text></Text>
<TouchableOpacity
style={styles.loginButton}
onPress={() =>
Linking.openURL("exp://192.168.0.101:8084/--/payment-success")
}
>
<Text style={styles.loginButtonText}></Text>
</TouchableOpacity>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
@ -194,7 +214,9 @@ export const ProfileScreen = () => {
<Text style={styles.groupItemTitleText}></Text> <Text style={styles.groupItemTitleText}></Text>
<TouchableOpacity <TouchableOpacity
style={styles.groupItemTitleTextTout} style={styles.groupItemTitleTextTout}
onPress={() => navigation.navigate("Status", { status: null })} onPress={() =>
navigation.navigate("Status", { status: null })
}
> >
<Text style={styles.groupItemTitleTextTout1}></Text> <Text style={styles.groupItemTitleTextTout1}></Text>
<LeftArrowIcon size={fontSize(14)} color="#8f8684" /> <LeftArrowIcon size={fontSize(14)} color="#8f8684" />
@ -208,14 +230,18 @@ export const ProfileScreen = () => {
style={styles.groupItemContent} style={styles.groupItemContent}
onPress={() => onPress={() =>
item.status !== null item.status !== null
? navigation.navigate("Status", { status: item.status }) ? navigation.navigate("Status", {
status: item.status,
})
: null : null
} }
> >
<View style={styles.groupItemContentIcon}> <View style={styles.groupItemContentIcon}>
<item.icon size={fontSize(38)} color="#707070" /> <item.icon size={fontSize(38)} color="#707070" />
</View> </View>
<Text style={styles.groupItemContentText}>{item.text}</Text> <Text style={styles.groupItemContentText}>
{item.text}
</Text>
</TouchableOpacity> </TouchableOpacity>
))} ))}
</View> </View>
@ -234,7 +260,10 @@ export const ProfileScreen = () => {
style={styles.groupItemContentIcon} style={styles.groupItemContentIcon}
onPress={() => navigation.navigate("BrowseHistoryScreen")} onPress={() => navigation.navigate("BrowseHistoryScreen")}
> >
<DocumentApprovedIcon size={fontSize(38)} color="#707070" /> <DocumentApprovedIcon
size={fontSize(38)}
color="#707070"
/>
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.groupItemContentText}></Text> <Text style={styles.groupItemContentText}></Text>
</View> </View>
@ -275,7 +304,7 @@ const styles = StyleSheet.create({
}, },
safeAreaContent: { safeAreaContent: {
flex: 1, flex: 1,
paddingTop: Platform.OS === 'android' ? 0 : 0, paddingTop: Platform.OS === "android" ? 0 : 0,
}, },
flexColumnContainer1: { flexColumnContainer1: {
flex: 1, flex: 1,
@ -457,7 +486,7 @@ const styles = StyleSheet.create({
right: 19, right: 19,
backgroundColor: "#3A3128", backgroundColor: "#3A3128",
borderRadius: 10, borderRadius: 10,
marginBottom: Platform.OS === 'ios' ? -18 : -15, marginBottom: Platform.OS === "ios" ? -18 : -15,
zIndex: 1, zIndex: 1,
}, },
promoCardContainer2: { promoCardContainer2: {

21
app/screens/SearchResultScreen.tsx

@ -518,16 +518,14 @@ export const SearchResultScreen = ({ route, navigation }: SearchResultScreenProp
/> />
{searchText.length > 0 && ( {searchText.length > 0 && (
<TouchableOpacity <TouchableOpacity
onPress={() => setSearchText("")}
style={styles.clearButton} style={styles.clearButton}
onPress={() => setSearchText("")}
hitSlop={{ top: 10, right: 10, bottom: 10, left: 10 }}
> >
<IconComponent name="close-circle" size={18} color="#999" /> <IconComponent name="close-circle" size={18} color="#999" />
</TouchableOpacity> </TouchableOpacity>
)} )}
</View> </View>
<TouchableOpacity style={styles.searchButton} onPress={handleSearch}>
<Text style={styles.searchButtonText}>{t("cancel")}</Text>
</TouchableOpacity>
</View> </View>
{/* 标签筛选 */} {/* 标签筛选 */}
@ -805,7 +803,6 @@ const styles = StyleSheet.create({
paddingHorizontal: 8, paddingHorizontal: 8,
height: widthUtils(40, 40).height, height: widthUtils(40, 40).height,
marginHorizontal: 8, marginHorizontal: 8,
position: "relative",
}, },
searchInput: { searchInput: {
flex: 1, flex: 1,
@ -813,14 +810,18 @@ const styles = StyleSheet.create({
fontSize: isSmallScreen ? 14 : 16, fontSize: isSmallScreen ? 14 : 16,
color: "#333", color: "#333",
height: widthUtils(40, 40).height, height: widthUtils(40, 40).height,
paddingRight: 32, paddingRight: 30,
}, },
clearButton: { clearButton: {
position: "absolute", position: "absolute",
right: 8, right: 10,
top: "50%", top: '50%',
transform: [{ translateY: -9 }], marginTop: -10,
padding: 4, width: 20,
height: 20,
alignItems: 'center',
justifyContent: 'center',
zIndex: 20,
}, },
searchButton: { searchButton: {
paddingVertical: 4, paddingVertical: 4,

59
app/screens/pay/Pay.tsx

@ -1,8 +1,10 @@
import { View, StyleSheet } from 'react-native'; import { View, StyleSheet, Alert } from 'react-native';
import { useRoute, RouteProp } from '@react-navigation/native'; import { useRoute, RouteProp, useNavigation } from '@react-navigation/native';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { payApi, PaymentInfoResponse } from '../../services/api/payApi'; import { payApi, PaymentInfoResponse } from '../../services/api/payApi';
import { WebView } from "react-native-webview"; import { WebView } from "react-native-webview";
import * as Linking from 'expo-linking';
import { navigate } from '../../navigation/RootNavigation';
type PayScreenRouteProp = RouteProp<{ type PayScreenRouteProp = RouteProp<{
Pay: { payUrl: string }; Pay: { payUrl: string };
@ -11,17 +13,46 @@ type PayScreenRouteProp = RouteProp<{
export const Pay = () => { export const Pay = () => {
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const route = useRoute<PayScreenRouteProp>(); const route = useRoute<PayScreenRouteProp>();
const navigation = useNavigation();
const {payUrl} = route.params; const {payUrl} = route.params;
const [payInfo, setPayInfo] = useState<PaymentInfoResponse>(); const [payInfo, setPayInfo] = useState<PaymentInfoResponse>();
useEffect(() => { useEffect(() => {
console.log(route.params); console.log(route.params);
console.log(payUrl); console.log(payUrl);
},[]) // 设置处理深度链接的监听器
const handleDeepLink = ({ url }: { url: string }) => {
console.log('Deep link received:', url);
if (
url.startsWith('myapp://payment-success') ||
url.startsWith('exp://192.168.0.101:8084/--/payment-success')
) {
const parsed = Linking.parse(url);
const params = parsed.queryParams || {};
navigate('PaymentSuccessScreen', params);
}
};
// 添加深度链接事件监听器
const subscription = Linking.addEventListener('url', handleDeepLink);
return () => {
// 清理订阅
subscription.remove();
};
}, []);
const handleNavigationStateChange = (navState: any) => { const handleNavigationStateChange = (navState: any) => {
console.log(navState); console.log(navState);
// 检查URL是否包含支付成功的回调参数
const { url } = navState;
if (url && url.includes('payment_success=true')) {
// 如果网页URL中包含成功参数,可以在这里处理
Alert.alert('检测到支付成功!');
// navigation.navigate('PaymentConfirmation');
}
} }
return <View style={{ flex: 1 }}> return <View style={{ flex: 1 }}>
{payUrl ? ( {payUrl ? (
@ -38,9 +69,25 @@ export const Pay = () => {
originWhitelist={['*']} originWhitelist={['*']}
userAgent="Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Mobile Safari/537.36" userAgent="Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Mobile Safari/537.36"
onShouldStartLoadWithRequest={(request) => { onShouldStartLoadWithRequest={(request) => {
console.log(request); console.log('Load request:', request);
// 检查URL是否是支付成功的深度链接
const { url } = request;
if (
url && (
url.startsWith('myapp://payment-success') ||
url.startsWith('exp://192.168.0.101:8084/--/payment-success')
)
) {
// 解析参数
const parsed = Linking.parse(url);
const params = parsed.queryParams || {};
// 跳转到支付成功页面
navigate('PaymentSuccessScreen', params);
return false; // 不在WebView中加载
}
// 允许所有请求 // 允许所有其他请求
return true; return true;
}} }}
/> />

554
app/screens/previewOrder/PaymentMethod.tsx

@ -9,7 +9,7 @@ import {
Alert, Alert,
ActivityIndicator, ActivityIndicator,
StatusBar, StatusBar,
SafeAreaView SafeAreaView,
} from "react-native"; } from "react-native";
import { payApi, PaymentMethodsResponse } from "../../services/api/payApi"; import { payApi, PaymentMethodsResponse } from "../../services/api/payApi";
import fontSize from "../../utils/fontsizeUtils"; import fontSize from "../../utils/fontsizeUtils";
@ -22,13 +22,14 @@ import { useRoute, RouteProp } from "@react-navigation/native";
import useUserStore from "../../store/user"; import useUserStore from "../../store/user";
import { createOrderDataType } from "../../types/createOrder"; import { createOrderDataType } from "../../types/createOrder";
import useBurialPointStore from "../../store/burialPoint"; import useBurialPointStore from "../../store/burialPoint";
import {getBurialPointData} from "../../store/burialPoint"; import { getBurialPointData } from "../../store/burialPoint";
import { import {
ordersApi, ordersApi,
OrderData, CreateOrderRequest, Order, OrderData,
CreateOrderRequest,
Order,
} from "../../services/api/orders"; } from "../../services/api/orders";
// Define route params type // Define route params type
type PaymentMethodRouteParams = { type PaymentMethodRouteParams = {
freight_forwarder_address_id?: number; freight_forwarder_address_id?: number;
@ -36,7 +37,12 @@ type PaymentMethodRouteParams = {
// Define the root navigation params // Define the root navigation params
type RootStackParamList = { type RootStackParamList = {
PreviewOrder: {data:Order,payMethod:string,currency:string,amount:number}; PreviewOrder: {
data: Order;
payMethod: string;
currency: string;
amount: number;
};
Pay: { order_id: string }; Pay: { order_id: string };
ShippingFee: { freight_forwarder_address_id?: number }; ShippingFee: { freight_forwarder_address_id?: number };
PaymentMethod: { freight_forwarder_address_id?: number }; PaymentMethod: { freight_forwarder_address_id?: number };
@ -79,7 +85,11 @@ const PaymentMethodItem = ({
eur: number; eur: number;
}; };
totalAmount?: number; totalAmount?: number;
convertedAmount?: number; convertedAmount?: {
converted_amount: number;
item_key: string;
original_amount: number;
}[];
isConverting?: boolean; isConverting?: boolean;
}) => ( }) => (
<View> <View>
@ -110,16 +120,21 @@ const PaymentMethodItem = ({
</TouchableOpacity> </TouchableOpacity>
{/* Show currency selector directly under PayPal when selected */} {/* Show currency selector directly under PayPal when selected */}
{isSelected && option.label === "Paypal" && selectedCurrency && onSelectCurrency && exchangeRates && totalAmount && ( {isSelected &&
<CurrencySelector option.label === "Paypal" &&
selectedCurrency={selectedCurrency} selectedCurrency &&
onSelectCurrency={onSelectCurrency} onSelectCurrency &&
exchangeRates={exchangeRates} exchangeRates &&
totalAmount={totalAmount} totalAmount && (
convertedAmount={convertedAmount} <CurrencySelector
isConverting={isConverting} selectedCurrency={selectedCurrency}
/> onSelectCurrency={onSelectCurrency}
)} exchangeRates={exchangeRates}
totalAmount={totalAmount}
convertedAmount={convertedAmount}
isConverting={isConverting}
/>
)}
</View> </View>
); );
@ -132,7 +147,11 @@ interface CurrencySelectorProps {
eur: number; eur: number;
}; };
totalAmount: number; totalAmount: number;
convertedAmount?: number; convertedAmount?: {
converted_amount: number;
item_key: string;
original_amount: number;
}[];
isConverting?: boolean; isConverting?: boolean;
} }
@ -141,7 +160,7 @@ const CurrencySelector = ({
onSelectCurrency, onSelectCurrency,
exchangeRates, exchangeRates,
totalAmount, totalAmount,
convertedAmount = 0, convertedAmount = [],
isConverting = false, isConverting = false,
}: CurrencySelectorProps) => ( }: CurrencySelectorProps) => (
<View style={styles.currencySelectorContainer}> <View style={styles.currencySelectorContainer}>
@ -168,13 +187,20 @@ const CurrencySelector = ({
</View> </View>
<View style={styles.totalContainer}> <View style={styles.totalContainer}>
{!isConverting && ( {!isConverting && (
<Text style={styles.totalText}> <Text style={styles.totalText}>
{selectedCurrency === "USD" ? "$" : "€"}{convertedAmount} {selectedCurrency === "USD" ? "$" : "€"}
</Text> {convertedAmount
.reduce((acc, item) => acc + item.converted_amount, 0)
.toFixed(2)}
</Text>
)} )}
{isConverting && ( {isConverting && (
<ActivityIndicator size="small" color="#ff6000" style={styles.loadingIndicator} /> <ActivityIndicator
size="small"
color="#ff6000"
style={styles.loadingIndicator}
/>
)} )}
</View> </View>
</View> </View>
@ -206,14 +232,16 @@ export const PaymentMethod = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { user } = useUserStore(); const { user } = useUserStore();
const [createOrderData, setCreateOrderData] = useState<createOrderDataType>(); const [createOrderData, setCreateOrderData] = useState<createOrderDataType>();
const { items, orderData,setOrderData,resetOrder } = useCreateOrderStore(); const { items, orderData, setOrderData, resetOrder } = useCreateOrderStore();
const [selectedCurrency, setSelectedCurrency] = useState("USD"); const [selectedCurrency, setSelectedCurrency] = useState("USD");
const [convertedAmount, setConvertedAmount] = useState(0); const [convertedAmount, setConvertedAmount] = useState<
{ converted_amount: number; item_key: string; original_amount: number }[]
>([]);
const [isConverting, setIsConverting] = useState(false); const [isConverting, setIsConverting] = useState(false);
const [createLoading, setCreateLoading] = useState(false); const [createLoading, setCreateLoading] = useState(false);
const [exchangeRates] = useState({ const [exchangeRates] = useState({
usd: 580.00, usd: 580.0,
eur: 655.96 eur: 655.96,
}); });
const [totalAmount, setTotalAmount] = useState(121.97); const [totalAmount, setTotalAmount] = useState(121.97);
const { logPaymentConfirm } = useBurialPointStore(); const { logPaymentConfirm } = useBurialPointStore();
@ -222,32 +250,27 @@ export const PaymentMethod = () => {
}; };
const onSelectPayment = (paymentId: string) => { const onSelectPayment = (paymentId: string) => {
if(paymentId === "Paypal"){ if (paymentId === "Paypal") {
setIsConverting(true); setIsConverting(true);
const data = { const data = {
from_currency: user.currency,
to_currency: selectedCurrency,
amounts:[
{
}
]
}
payApi.convertCurrency({
from_currency: user.currency, from_currency: user.currency,
to_currency: selectedCurrency, to_currency: selectedCurrency,
amount: ( amounts: {
(previewOrder?.total_amount || 0) + total_amount: previewOrder?.total_amount || 0,
(createOrderData?.domestic_shipping_fee || 0) + domestic_shipping_fee: createOrderData?.domestic_shipping_fee || 0,
(createOrderData?.shipping_fee || 0) shipping_fee: createOrderData?.shipping_fee || 0,
), },
}).then((res) => { };
setConvertedAmount(res.converted_amount); payApi
setIsConverting(false); .convertCurrency(data)
}).catch(error => { .then((res) => {
console.error("Currency conversion failed:", error); setConvertedAmount(res.converted_amounts_list);
setIsConverting(false); setIsConverting(false);
}); })
.catch((error) => {
console.error("Currency conversion failed:", error);
setIsConverting(false);
});
} }
setSelectedPayment(paymentId); setSelectedPayment(paymentId);
@ -255,23 +278,26 @@ export const PaymentMethod = () => {
const onSelectCurrency = (currency: string) => { const onSelectCurrency = (currency: string) => {
setSelectedCurrency(currency); setSelectedCurrency(currency);
// Call the API to convert the currency
setIsConverting(true); setIsConverting(true);
payApi.convertCurrency({ const data = {
from_currency: user.currency, from_currency: user.currency,
to_currency: currency, to_currency: currency,
amount: ( amounts: {
(previewOrder?.total_amount || 0) + total_amount: previewOrder?.total_amount || 0,
(createOrderData?.domestic_shipping_fee || 0) + domestic_shipping_fee: createOrderData?.domestic_shipping_fee || 0,
(createOrderData?.shipping_fee || 0) shipping_fee: createOrderData?.shipping_fee || 0,
), },
}).then((res) => { };
setConvertedAmount(res.converted_amount); payApi
setIsConverting(false); .convertCurrency(data)
}).catch(error => { .then((res) => {
console.error("Currency conversion failed:", error); setConvertedAmount(res.converted_amounts_list);
setIsConverting(false); setIsConverting(false);
}); })
.catch((error) => {
console.error("Currency conversion failed:", error);
setIsConverting(false);
});
}; };
const getPaymentMethods = async () => { const getPaymentMethods = async () => {
@ -371,7 +397,7 @@ export const PaymentMethod = () => {
attribute_name: attr.attribute_name, attribute_name: attr.attribute_name,
attribute_value: attr.value, attribute_value: attr.value,
})), })),
sku_image:item.sku_image_url, sku_image: item.sku_image_url,
quantity: item.quantity, quantity: item.quantity,
unit_price: item.unit_price, unit_price: item.unit_price,
total_price: item.total_price, total_price: item.total_price,
@ -379,67 +405,125 @@ export const PaymentMethod = () => {
if (createOrderData) { if (createOrderData) {
createOrderData.items = items; createOrderData.items = items;
createOrderData.payment_method = selectedPayment; createOrderData.payment_method = selectedPayment;
createOrderData.total_amount = selectedPayment === 'Paypal' ? convertedAmount : createOrderData.total_amount =
Number(((previewOrder?.total_amount || 0) + (orderData?.domestic_shipping_fee || 0) selectedPayment === "Paypal"
+ (orderData?.shipping_fee || 0)).toFixed(2)); ? convertedAmount.reduce(
createOrderData.actual_amount = selectedPayment === 'Paypal' ? convertedAmount : (acc, item) => acc + item.converted_amount,
Number(((previewOrder?.total_amount || 0) + (orderData?.domestic_shipping_fee || 0) 0
+ (orderData?.shipping_fee || 0)).toFixed(2)); )
createOrderData.currency = selectedPayment === 'Paypal' ? selectedCurrency : user.currency; : Number(
(
(previewOrder?.total_amount || 0) +
(orderData?.domestic_shipping_fee || 0) +
(orderData?.shipping_fee || 0)
).toFixed(2)
);
createOrderData.actual_amount =
selectedPayment === "Paypal"
? convertedAmount.reduce(
(acc, item) => acc + item.converted_amount,
0
)
: Number(
(
(previewOrder?.total_amount || 0) +
(orderData?.domestic_shipping_fee || 0) +
(orderData?.shipping_fee || 0)
).toFixed(2)
);
createOrderData.currency =
selectedPayment === "Paypal" ? selectedCurrency : user.currency;
createOrderData.domestic_shipping_fee =
selectedPayment === "Paypal"
? convertedAmount.find(
(item) => item.item_key === "domestic_shipping_fee"
)?.converted_amount || 0
: orderData?.domestic_shipping_fee;
createOrderData.shipping_fee =
selectedPayment === "Paypal"
? convertedAmount.find(
(item) => item.item_key === "shipping_fee"
)?.converted_amount || 0
: orderData?.shipping_fee;
} }
setOrderData(createOrderData || {}); setOrderData(createOrderData || {});
const data = { const data = {
pay_method: selectedPayment, pay_method: selectedPayment,
offline_payment: currentTab === 'offline' ? 0 : 1, offline_payment: currentTab === "offline" ? 0 : 1,
all_price: selectedPayment === 'Paypal' ? convertedAmount : all_price:
Number(((previewOrder?.total_amount || 0) + (orderData?.domestic_shipping_fee || 0) selectedPayment === "Paypal"
+ (orderData?.shipping_fee || 0)).toFixed(2)), ? convertedAmount.reduce(
all_quantity:previewOrder?.items?.reduce((acc,item) => acc + item.quantity,0), (acc, item) => acc + item.converted_amount,
0
)
: Number(
(
(previewOrder?.total_amount || 0) +
(orderData?.domestic_shipping_fee || 0) +
(orderData?.shipping_fee || 0)
).toFixed(2)
),
all_quantity: previewOrder?.items?.reduce(
(acc, item) => acc + item.quantity,
0
),
currency: selectedCurrency, currency: selectedCurrency,
shipping_method: orderData?.transport_type || 0, shipping_method: orderData?.transport_type || 0,
shipping_price_outside: orderData?.shipping_fee || 0, shipping_price_outside: orderData?.shipping_fee || 0,
shipping_price_within: orderData?.domestic_shipping_fee || 0, shipping_price_within: orderData?.domestic_shipping_fee || 0,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
pay_product:JSON.stringify(previewOrder?.items.map(item => { pay_product: JSON.stringify(
return { previewOrder?.items.map((item) => {
offer_id: item.offer_id, return {
price: item.unit_price, offer_id: item.offer_id,
all_price: previewOrder.total_amount, price: item.unit_price,
currency: previewOrder.currency, all_price:
convertedAmount.find((item) => item.item_key === "total_amount")
sku: item.attributes.map(sku => { ?.converted_amount || 0,
return { currency: previewOrder.currency,
sku_id: item.sku_id,
value: sku.value
};
}),
quantity: item.quantity,
product_name: item.product_name,
timestamp: new Date(),
product_img: item.sku_image_url
};
}))
} sku: item.attributes.map((sku) => {
logPaymentConfirm(data,navigation.getState().routes[navigation.getState().index - 1]?.name as string) return {
sku_id: item.sku_id,
value: sku.value,
};
}),
quantity: item.quantity,
product_name: item.product_name,
timestamp: new Date(),
product_img: item.sku_image_url,
};
})
),
};
logPaymentConfirm(
data,
navigation.getState().routes[navigation.getState().index - 1]
?.name as string
);
console.log(getBurialPointData()); console.log(getBurialPointData());
setCreateLoading(true) setCreateLoading(true);
try { try {
const res = await ordersApi.createOrder(createOrderData as CreateOrderRequest) const res = await ordersApi.createOrder(
setCreateLoading(false) createOrderData as CreateOrderRequest
navigation.navigate("PreviewOrder",{data:res,payMethod:selectedPayment,currency:selectedCurrency,amount:convertedAmount}); );
resetOrder() setCreateLoading(false);
}catch(e) { navigation.navigate("PreviewOrder", {
setCreateLoading(false) data: res,
Alert.alert('Error', 'Failed to get preview order'); payMethod: selectedPayment,
}finally { currency: selectedCurrency,
setCreateLoading(false) amount: convertedAmount.find((item) => item.item_key === "total_amount")?.converted_amount || 0,
});
resetOrder();
} catch (e) {
setCreateLoading(false);
Alert.alert("Error", "Failed to get preview order");
} finally {
setCreateLoading(false);
} }
}; };
return ( return (
@ -454,7 +538,6 @@ export const PaymentMethod = () => {
<BackIcon size={22} /> <BackIcon size={22} />
</TouchableOpacity> </TouchableOpacity>
<Text style={styles.headerTitle}></Text> <Text style={styles.headerTitle}></Text>
<View style={{ width: 20 }} />
</View> </View>
{loading ? ( {loading ? (
@ -476,8 +559,7 @@ export const PaymentMethod = () => {
currentTab === tab.id && styles.tabActive, currentTab === tab.id && styles.tabActive,
]} ]}
onPress={() => { onPress={() => {
setCurrentTab(tab.id);
setCurrentTab(tab.id)
}} }}
> >
<Text <Text
@ -567,7 +649,9 @@ export const PaymentMethod = () => {
</View> </View>
<View style={styles.itemPrices}> <View style={styles.itemPrices}>
<Text style={styles.itemPrice}>${item?.total_price}</Text> <Text style={styles.itemPrice}>
${item?.total_price}
</Text>
</View> </View>
</View> </View>
))} ))}
@ -580,7 +664,16 @@ export const PaymentMethod = () => {
<Text></Text> <Text></Text>
<View> <View>
<Text> <Text>
{previewOrder?.total_amount || 0} {previewOrder?.currency} {selectedPayment === "Paypal"
? convertedAmount.find(
(item) => item.item_key === "total_amount"
)?.converted_amount || 0
: previewOrder?.total_amount || 0}{" "}
{selectedPayment === "Paypal"
? selectedCurrency === "USD"
? "USD"
: "EUR"
: previewOrder?.currency}
</Text> </Text>
</View> </View>
</View> </View>
@ -588,8 +681,16 @@ export const PaymentMethod = () => {
<Text></Text> <Text></Text>
<View> <View>
<Text> <Text>
{createOrderData?.domestic_shipping_fee || 0}{" "} {selectedPayment === "Paypal"
{previewOrder?.currency} ? convertedAmount.find(
(item) => item.item_key === "domestic_shipping_fee"
)?.converted_amount || 0
: orderData?.domestic_shipping_fee || 0}{" "}
{selectedPayment === "Paypal"
? selectedCurrency === "USD"
? "USD"
: "EUR"
: previewOrder?.currency}
</Text> </Text>
</View> </View>
</View> </View>
@ -598,7 +699,16 @@ export const PaymentMethod = () => {
<Text></Text> <Text></Text>
<View> <View>
<Text> <Text>
{createOrderData?.shipping_fee || 0} {previewOrder?.currency} {selectedPayment === "Paypal"
? convertedAmount.find(
(item) => item.item_key === "shipping_fee"
)?.converted_amount || 0
: orderData?.shipping_fee || 0}{" "}
{selectedPayment === "Paypal"
? selectedCurrency === "USD"
? "USD"
: "EUR"
: previewOrder?.currency}
</Text> </Text>
</View> </View>
</View> </View>
@ -617,86 +727,81 @@ export const PaymentMethod = () => {
Total Total
</Text> </Text>
{ {selectedPayment === "Paypal" &&
selectedPayment === 'Paypal' && selectedCurrency !== user.currency && ( selectedCurrency !== user.currency && (
<View style={{flexDirection:'row'}}> <View style={{ flexDirection: "row" }}>
<Text <Text
style={{ style={{
fontSize: fontSize(18), fontSize: fontSize(18),
fontWeight: "600", fontWeight: "600",
color: "#151515", color: "#151515",
textDecorationLine: 'line-through' textDecorationLine: "line-through",
}} }}
> >
{(
{( (previewOrder?.total_amount || 0) +
(previewOrder?.total_amount || 0) + (createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.domestic_shipping_fee || 0) + (createOrderData?.shipping_fee || 0)
(createOrderData?.shipping_fee || 0) ).toFixed(2)}{" "}
).toFixed(2)}{" "} {previewOrder?.currency}
{previewOrder?.currency} </Text>
</Text>
<Text
style={{
fontSize: fontSize(18),
fontWeight: "600",
color: "#ff6000",
marginLeft:10
}}
>
{convertedAmount}{selectedCurrency === "USD" ? "USD" : "EUR"}
</Text>
</View>
)
}
{
selectedPayment === 'Paypal' && selectedCurrency === user.currency && (
<View style={{flexDirection:'row'}}>
<Text
style={{
fontSize: fontSize(18),
fontWeight: "600",
color: "#ff6000",
}}
>
{(
(previewOrder?.total_amount || 0) +
(createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.shipping_fee || 0)
).toFixed(2)}{" "}
{previewOrder?.currency}
</Text>
</View>
)
}
{ <Text
selectedPayment !== 'Paypal'&& ( style={{
<Text fontSize: fontSize(18),
style={{ fontWeight: "600",
fontSize: fontSize(18), color: "#ff6000",
fontWeight: "600", marginLeft: 10,
color: "#ff6000", }}
}} >
> {convertedAmount
.reduce(
(acc, item) => acc + item.converted_amount,
0
)
.toFixed(2)}
{selectedCurrency === "USD" ? "USD" : "EUR"}
</Text>
</View>
)}
{( {selectedPayment === "Paypal" &&
(previewOrder?.total_amount || 0) + selectedCurrency === user.currency && (
(createOrderData?.domestic_shipping_fee || 0) + <View style={{ flexDirection: "row" }}>
(createOrderData?.shipping_fee || 0) <Text
).toFixed(2)}{" "} style={{
{previewOrder?.currency} fontSize: fontSize(18),
</Text> fontWeight: "600",
) color: "#ff6000",
} }}
>
{convertedAmount
.reduce(
(acc, item) => acc + item.converted_amount,
0
)
.toFixed(2)}
{selectedCurrency === "USD" ? "USD" : "EUR"}
</Text>
</View>
)}
{selectedPayment !== "Paypal" && (
<Text
style={{
fontSize: fontSize(18),
fontWeight: "600",
color: "#ff6000",
}}
>
{(
(previewOrder?.total_amount || 0) +
(createOrderData?.domestic_shipping_fee || 0) +
(createOrderData?.shipping_fee || 0)
).toFixed(2)}{" "}
{previewOrder?.currency}
</Text>
)}
</View> </View>
</View> </View>
</View> </View>
@ -705,12 +810,17 @@ export const PaymentMethod = () => {
<View style={styles.bottomBar}> <View style={styles.bottomBar}>
<TouchableOpacity <TouchableOpacity
style={styles.submitButton} style={[
styles.submitButton,
(!selectedPayment || createLoading || isConverting) && styles.disabledButton
]}
onPress={handleSubmit} onPress={handleSubmit}
disabled={!selectedPayment || createLoading} disabled={!selectedPayment || createLoading || isConverting}
> >
{createLoading ? ( {createLoading ? (
<ActivityIndicator size="small" color="#fff" /> <ActivityIndicator size="small" color="#fff" />
) : isConverting ? (
<Text style={styles.submitButtonText}>...</Text>
) : ( ) : (
<Text style={styles.submitButtonText}></Text> <Text style={styles.submitButtonText}></Text>
)} )}
@ -724,7 +834,7 @@ export const PaymentMethod = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
safeArea: { safeArea: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
safeAreaContent: { safeAreaContent: {
flex: 1, flex: 1,
@ -732,7 +842,7 @@ const styles = StyleSheet.create({
}, },
container: { container: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
sectionHeader: { sectionHeader: {
flexDirection: "row", flexDirection: "row",
@ -818,7 +928,6 @@ const styles = StyleSheet.create({
borderRadius: 4, borderRadius: 4,
marginRight: 8, marginRight: 8,
marginBottom: 4, marginBottom: 4,
}, },
operatorText: { operatorText: {
fontSize: fontSize(12), fontSize: fontSize(12),
@ -850,13 +959,11 @@ const styles = StyleSheet.create({
justifyContent: "center", justifyContent: "center",
position: "relative", position: "relative",
backgroundColor: "#fff", backgroundColor: "#fff",
}, },
backIconContainer: { backIconContainer: {
position: "absolute", position: "absolute",
left: 15, left: 15,
backgroundColor: "#fff", backgroundColor: "#fff",
}, },
titleHeading: { titleHeading: {
fontWeight: "600", fontWeight: "600",
@ -864,7 +971,6 @@ const styles = StyleSheet.create({
lineHeight: 22, lineHeight: 22,
fontFamily: "PingFang SC", fontFamily: "PingFang SC",
color: "black", color: "black",
}, },
// Order Summary Styles // Order Summary Styles
section: { section: {
@ -1096,8 +1202,8 @@ const styles = StyleSheet.create({
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: "#EEEEEE", borderTopColor: "#EEEEEE",
paddingTop: 10, paddingTop: 10,
flexDirection: 'row', flexDirection: "row",
alignItems: 'center', alignItems: "center",
}, },
totalText: { totalText: {
fontSize: fontSize(16), fontSize: fontSize(16),
@ -1108,23 +1214,28 @@ const styles = StyleSheet.create({
marginLeft: 10, marginLeft: 10,
}, },
header: { header: {
flexDirection: 'row', flexDirection: "row",
alignItems: 'center', alignItems: "center",
justifyContent: "center",
padding: 10, padding: 10,
position: "relative",
}, },
backButton: { backButton: {
padding: 5, padding: 5,
position: "absolute",
left: 10,
zIndex: 1,
}, },
headerTitle: { headerTitle: {
fontSize: fontSize(18), fontSize: fontSize(20),
fontWeight: '600', fontWeight: "600",
marginLeft: 10, textAlign: "center",
}, },
paymentContainer: { paymentContainer: {
padding: 15, padding: 15,
}, },
tabs: { tabs: {
flexDirection: 'row', flexDirection: "row",
marginBottom: 15, marginBottom: 15,
}, },
tab: { tab: {
@ -1134,24 +1245,27 @@ const styles = StyleSheet.create({
}, },
tabActive: { tabActive: {
borderBottomWidth: 2, borderBottomWidth: 2,
borderBottomColor: '#FF5100', borderBottomColor: "#FF5100",
}, },
bottomBar: { bottomBar: {
padding: 15, padding: 15,
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: '#f5f5f5', borderTopColor: "#f5f5f5",
}, },
submitButton: { submitButton: {
width: '100%', width: "100%",
height: 50, height: 50,
justifyContent: 'center', justifyContent: "center",
alignItems: 'center', alignItems: "center",
backgroundColor: '#FF5100', backgroundColor: "#FF5100",
borderRadius: 25, borderRadius: 25,
}, },
submitButtonText: { submitButtonText: {
color: 'white', color: "white",
fontSize: fontSize(16), fontSize: fontSize(16),
fontWeight: '600', fontWeight: "600",
},
disabledButton: {
backgroundColor: '#ccc',
}, },
}); });

210
app/screens/previewOrder/ShippingFee.tsx

@ -1,4 +1,4 @@
import React from 'react'; import React from "react";
import { import {
View, View,
Text, Text,
@ -26,11 +26,11 @@ import usePreviewShippingStore from "../../store/previewShipping";
import { getSubjectTransLanguage } from "../../utils/languageUtils"; import { getSubjectTransLanguage } from "../../utils/languageUtils";
import BackIcon from "../../components/BackIcon"; import BackIcon from "../../components/BackIcon";
import { useNavigation, useRoute, RouteProp } from "@react-navigation/native"; import { useNavigation, useRoute, RouteProp } from "@react-navigation/native";
import useCreateOrderStore from "../../store/createOrder"; import useCreateOrderStore from "../../store/createOrder";
import { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { NativeStackNavigationProp } from "@react-navigation/native-stack";
import useUserStore from "../../store/user"; import useUserStore from "../../store/user";
import useBurialPointStore from "../../store/burialPoint"; import useBurialPointStore from "../../store/burialPoint";
import {getBurialPointData} from "../../store/burialPoint"; import { getBurialPointData } from "../../store/burialPoint";
type RootStackParamList = { type RootStackParamList = {
ShippingFee: undefined; ShippingFee: undefined;
PaymentMethod: { freight_forwarder_address_id: number }; PaymentMethod: { freight_forwarder_address_id: number };
@ -42,9 +42,9 @@ type ShippingFeeParams = {
}; };
}; };
export const ShippingFee = () => { export const ShippingFee = () => {
const navigation = useNavigation<NativeStackNavigationProp<RootStackParamList>>(); const navigation =
useNavigation<NativeStackNavigationProp<RootStackParamList>>();
const route = const route =
useRoute<RouteProp<Record<string, ShippingFeeParams>, string>>(); useRoute<RouteProp<Record<string, ShippingFeeParams>, string>>();
const { const {
@ -65,15 +65,16 @@ export const ShippingFee = () => {
const [selectedWarehouse, setSelectedWarehouse] = useState<Address>(); const [selectedWarehouse, setSelectedWarehouse] = useState<Address>();
const [domesticShippingFeeData, setDomesticShippingFeeData] = const [domesticShippingFeeData, setDomesticShippingFeeData] =
useState<DomesticShippingFeeData>(); useState<DomesticShippingFeeData>();
const [isDomesticShippingLoading, setIsDomesticShippingLoading] = useState(false); const [isDomesticShippingLoading, setIsDomesticShippingLoading] =
const [count,setCount] = useState<string>(); useState(false);
const [count, setCount] = useState<string>();
const [apiResponses, setApiResponses] = useState({ const [apiResponses, setApiResponses] = useState({
shippingFees: false, shippingFees: false,
domesticShippingFees: false domesticShippingFees: false,
}); });
const { setOrderData ,orderData,items} = useCreateOrderStore(); const { setOrderData, orderData, items } = useCreateOrderStore();
const [countryCode,setCountryCode] = useState<number>(); const [countryCode, setCountryCode] = useState<number>();
const userStore = useUserStore(); const userStore = useUserStore();
const { logShippingConfirm } = useBurialPointStore(); const { logShippingConfirm } = useBurialPointStore();
const getFreightForwarderAddress = async () => { const getFreightForwarderAddress = async () => {
@ -106,15 +107,15 @@ export const ShippingFee = () => {
useEffect(() => { useEffect(() => {
if (state.shippingFees) { if (state.shippingFees) {
setShippingFeeData(state.shippingFees); setShippingFeeData(state.shippingFees);
setCount('正在计算运费,请不要关闭app'); setCount("正在计算运费,请不要关闭app");
setApiResponses(prev => ({...prev, shippingFees: true})); setApiResponses((prev) => ({ ...prev, shippingFees: true }));
} }
}, [state.shippingFees]); }, [state.shippingFees]);
useEffect(() => { useEffect(() => {
if (state.domesticShippingFees) { if (state.domesticShippingFees) {
setDomesticShippingFeeData(state.domesticShippingFees); setDomesticShippingFeeData(state.domesticShippingFees);
setApiResponses(prev => ({...prev, domesticShippingFees: true})); setApiResponses((prev) => ({ ...prev, domesticShippingFees: true }));
} }
}, [state.domesticShippingFees]); }, [state.domesticShippingFees]);
@ -150,11 +151,11 @@ export const ShippingFee = () => {
if (data.items && data.freight_forwarder_address_id) { if (data.items && data.freight_forwarder_address_id) {
// Set loading state to true before making API calls // Set loading state to true before making API calls
setIsDomesticShippingLoading(true); setIsDomesticShippingLoading(true);
setCount('正在计算运费,请不要关闭app'); setCount("正在计算运费,请不要关闭app");
// Reset API response tracking // Reset API response tracking
setApiResponses({ setApiResponses({
shippingFees: false, shippingFees: false,
domesticShippingFees: false domesticShippingFees: false,
}); });
calculateShippingFee(data); calculateShippingFee(data);
@ -172,35 +173,45 @@ export const ShippingFee = () => {
}; };
const handleSubmit = () => { const handleSubmit = () => {
if (!isDomesticShippingLoading && domesticShippingFeeData?.total_shipping_fee != null) { if (
!isDomesticShippingLoading &&
domesticShippingFeeData?.total_shipping_fee != null
) {
setOrderData({ setOrderData({
...orderData, ...orderData,
transport_type: shippingMethod === "sea" ? 0 : 1, transport_type: shippingMethod === "sea" ? 0 : 1,
domestic_shipping_fee: domesticShippingFeeData?.total_shipping_fee, domestic_shipping_fee: domesticShippingFeeData?.total_shipping_fee,
shipping_fee: shippingMethod === "sea" shipping_fee:
? shippingFeeData?.total_shipping_fee_sea shippingMethod === "sea"
: shippingFeeData?.total_shipping_fee_air, ? shippingFeeData?.total_shipping_fee_sea
receiver_address:selectedWarehouseLabel : shippingFeeData?.total_shipping_fee_air,
receiver_address: selectedWarehouseLabel,
}); });
const data = { const data = {
shipping_method: shippingMethod === "sea" ? 0 : 1, shipping_method: shippingMethod === "sea" ? 0 : 1,
shipping_price_outside: shippingMethod === "sea" shipping_price_outside:
? (shippingFeeData?.total_shipping_fee_sea || 0) shippingMethod === "sea"
: (shippingFeeData?.total_shipping_fee_air || 0), ? shippingFeeData?.total_shipping_fee_sea || 0
: shippingFeeData?.total_shipping_fee_air || 0,
shipping_price_within: domesticShippingFeeData?.total_shipping_fee || 0, shipping_price_within: domesticShippingFeeData?.total_shipping_fee || 0,
currency: userStore.user?.currency || '', currency: userStore.user?.currency || "",
forwarder_name: selectedWarehouse?.forwarder_name || '', forwarder_name: selectedWarehouse?.forwarder_name || "",
country_city: selectedWarehouseLabel, country_city: selectedWarehouseLabel,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
} };
logShippingConfirm(data,navigation.getState().routes[navigation.getState().index - 1]?.name as string) logShippingConfirm(
data,
navigation.getState().routes[navigation.getState().index - 1]
?.name as string
);
console.log(getBurialPointData()); console.log(getBurialPointData());
navigation.navigate("PaymentMethod", {freight_forwarder_address_id: selectedWarehouse?.address_id || 0}); navigation.navigate("PaymentMethod", {
}else{ freight_forwarder_address_id: selectedWarehouse?.address_id || 0,
});
} else {
Alert.alert("请选择运输方式"); Alert.alert("请选择运输方式");
} }
}; };
return ( return (
@ -248,7 +259,8 @@ export const ShippingFee = () => {
key={option.id} key={option.id}
style={[ style={[
styles.shippingCard, styles.shippingCard,
shippingMethod === option.id && styles.shippingCardSelected, shippingMethod === option.id &&
styles.shippingCardSelected,
]} ]}
onPress={() => { onPress={() => {
setShippingMethod(option.id); setShippingMethod(option.id);
@ -261,7 +273,9 @@ export const ShippingFee = () => {
)} )}
<Text style={styles.shippingIcon}>{option.icon}</Text> <Text style={styles.shippingIcon}>{option.icon}</Text>
<Text style={styles.shippingLabel}>{option.label}</Text> <Text style={styles.shippingLabel}>{option.label}</Text>
<Text style={styles.shippingDetail}>{option.detail}</Text> <Text style={styles.shippingDetail}>
{option.detail}
</Text>
</TouchableOpacity> </TouchableOpacity>
))} ))}
</View> </View>
@ -275,7 +289,9 @@ export const ShippingFee = () => {
</View> </View>
<View style={{ marginTop: 12 }}> <View style={{ marginTop: 12 }}>
<View style={styles.selectBox}> <View style={styles.selectBox}>
<Text style={styles.selectLabel}>Select a warehouse:</Text> <Text style={styles.selectLabel}>
Select a warehouse:
</Text>
<TouchableOpacity <TouchableOpacity
style={styles.selectWrapper} style={styles.selectWrapper}
onPress={() => setModalVisible(true)} onPress={() => setModalVisible(true)}
@ -311,13 +327,16 @@ export const ShippingFee = () => {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<FlatList <FlatList
data={freightForwarderAddress?.other_addresses || []} data={
freightForwarderAddress?.other_addresses || []
}
keyExtractor={(item, index) => index.toString()} keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => ( renderItem={({ item }) => (
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.optionItem, styles.optionItem,
warehouse === item.country + "|" + item.city && warehouse ===
item.country + "|" + item.city &&
styles.selectedOption, styles.selectedOption,
]} ]}
onPress={() => onPress={() =>
@ -330,7 +349,8 @@ export const ShippingFee = () => {
<Text style={styles.optionText}> <Text style={styles.optionText}>
{item.country + "|" + item.city} {item.country + "|" + item.city}
</Text> </Text>
{warehouse === item.country + "|" + item.city && ( {warehouse ===
item.country + "|" + item.city && (
<Text style={styles.checkmark}></Text> <Text style={styles.checkmark}></Text>
)} )}
</TouchableOpacity> </TouchableOpacity>
@ -345,18 +365,24 @@ export const ShippingFee = () => {
{warehouse && ( {warehouse && (
<View style={styles.shippingInfo}> <View style={styles.shippingInfo}>
<Text style={styles.shippingInfoRow}> <Text style={styles.shippingInfoRow}>
<Text style={styles.shippingInfoLabel}>: </Text> <Text style={styles.shippingInfoLabel}>
:{" "}
</Text>
<Text <Text
style={{ flex: 1, textAlign: "left", marginLeft: 10 }} style={{
flex: 1,
textAlign: "left",
marginLeft: 10,
}}
> >
{shippingMethod === "sea" {shippingMethod === "sea" ? "45天" : "20天"}
? "45天"
: "20天"}
</Text> </Text>
</Text> </Text>
<View style={styles.shippingInfoRow}> <View style={styles.shippingInfoRow}>
<Text style={styles.shippingInfoLabel}>: </Text> <Text style={styles.shippingInfoLabel}>
:{" "}
</Text>
<Text <Text
style={{ style={{
color: "#ff6000", color: "#ff6000",
@ -367,36 +393,71 @@ export const ShippingFee = () => {
}} }}
> >
{isDomesticShippingLoading ? ( {isDomesticShippingLoading ? (
<Text style={{ color: "#ff6000",alignItems:"center" }}>{count} <ActivityIndicator size="small" color="#ff6000" style={{ marginLeft: 5 }} /></Text> <Text
style={{
color: "#ff6000",
alignItems: "center",
}}
>
{count}{" "}
<ActivityIndicator
size="small"
color="#ff6000"
style={{ marginLeft: 5 }}
/>
</Text>
) : ( ) : (
<Text style={{ color: "#ff6000" }}> <Text style={{ color: "#ff6000" }}>
{((domesticShippingFeeData?.total_shipping_fee || 0) + (shippingMethod === "sea" {domesticShippingFeeData?.total_shipping_fee ||
? (shippingFeeData?.total_shipping_fee_sea || 0) 0}{" "}
: (shippingFeeData?.total_shipping_fee_air || 0))).toFixed(2)} {''} {userStore.user?.currency} {userStore.user?.currency}
</Text> </Text>
)} )}
</Text> </Text>
{/* <Text style={{ color: "#ff6000" }}>(Cash on Delivery)</Text> */}
</View> </View>
{/* {isDomesticShippingLoading ? (
<View style={styles.shippingInfoRow}> <View style={styles.shippingInfoRow}>
<Text style={styles.shippingInfoLabel}>: </Text> <Text style={styles.shippingInfoLabel}>
<Text :{" "}
style={{ </Text>
color: "#ff6000", <Text
flex: 1, style={{
textAlign: "left", color: "#ff6000",
marginLeft: 10, flex: 1,
fontWeight: "600", textAlign: "left",
}} marginLeft: 10,
> fontWeight: "600",
{shippingMethod === "sea" }}
? shippingFeeData?.total_shipping_fee_sea >
: shippingFeeData?.total_shipping_fee_air} {count}{" "}
</Text> <ActivityIndicator
size="small"
</View> */} color="#ff6000"
style={{ marginLeft: 5 }}
/>
</Text>
</View>
) : (
<View style={styles.shippingInfoRow}>
<Text style={styles.shippingInfoLabel}>
:{" "}
</Text>
<Text
style={{
color: "#ff6000",
flex: 1,
textAlign: "left",
marginLeft: 10,
fontWeight: "600",
}}
>
{shippingMethod === "sea"
? shippingFeeData?.total_shipping_fee_sea
: shippingFeeData?.total_shipping_fee_air}{" "}
{userStore.user?.currency}
</Text>
</View>
)}
</View> </View>
)} )}
</View> </View>
@ -406,11 +467,16 @@ export const ShippingFee = () => {
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.primaryButtonStyle, styles.primaryButtonStyle,
(isDomesticShippingLoading || domesticShippingFeeData?.total_shipping_fee == null) isDomesticShippingLoading ||
? styles.disabledButtonStyle : {} domesticShippingFeeData?.total_shipping_fee == null
? styles.disabledButtonStyle
: {},
]} ]}
onPress={handleSubmit} onPress={handleSubmit}
disabled={isDomesticShippingLoading || domesticShippingFeeData?.total_shipping_fee == null} disabled={
isDomesticShippingLoading ||
domesticShippingFeeData?.total_shipping_fee == null
}
> >
<Text style={styles.buttonText}></Text> <Text style={styles.buttonText}></Text>
</TouchableOpacity> </TouchableOpacity>
@ -427,15 +493,15 @@ export const ShippingFee = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
safeArea: { safeArea: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
safeAreaContent: { safeAreaContent: {
flex: 1, flex: 1,
paddingTop: Platform.OS === 'android' ? 0 : 0, paddingTop: Platform.OS === "android" ? 0 : 0,
}, },
container: { container: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
section: { section: {
backgroundColor: "#fff", backgroundColor: "#fff",

6
app/screens/previewOrder/perviewOrder.tsx

@ -181,7 +181,7 @@ export const PreviewOrder = () => {
<View style={styles.infoRow}> <View style={styles.infoRow}>
<Text style={styles.infoLabel}></Text> <Text style={styles.infoLabel}></Text>
<Text style={styles.infoValue}> <Text style={styles.infoValue}>
{route.params.data.actual_amount || "N/A"} {user.currency} {route.params.amount || "N/A"} {route.params.data.currency}
</Text> </Text>
</View> </View>
@ -192,7 +192,7 @@ export const PreviewOrder = () => {
route.params.data.domestic_shipping_fee + route.params.data.domestic_shipping_fee +
route.params.data.shipping_fee route.params.data.shipping_fee
).toFixed(2) || "N/A"}{" "} ).toFixed(2) || "N/A"}{" "}
{user.currency} {route.params.data.currency}
</Text> </Text>
</View> </View>
</View> </View>
@ -203,7 +203,7 @@ export const PreviewOrder = () => {
<View style={styles.totalRow}> <View style={styles.totalRow}>
<Text style={styles.totalLabel}></Text> <Text style={styles.totalLabel}></Text>
<Text style={styles.totalValue}> <Text style={styles.totalValue}>
{route.params.amount} {route.params.currency} {route.params.data.actual_amount} {route.params.data.currency}
</Text> </Text>
</View> </View>
</View> </View>

6
app/services/api/payApi.ts

@ -33,7 +33,11 @@ export interface PayInfoBody {
export interface ConvertCurrencyBody { export interface ConvertCurrencyBody {
from_currency: string; from_currency: string;
to_currency: string; to_currency: string;
amount: number; amounts: {
total_amount?: number;
domestic_shipping_fee?: number;
shipping_fee?: number;
};
} }

Loading…
Cancel
Save