Browse Source

解决合并冲突

main
unknown 2 weeks ago
parent
commit
38bdb694ed
  1. 1
      app.json
  2. 7
      app/locales/en/translation.json
  3. 3
      app/locales/fr/translation.json
  4. 37
      app/screens/BalanceScreen/BalanceScreen.tsx
  5. 139
      app/screens/loginList/index.tsx
  6. 11
      app/screens/previewOrder/perviewOrder.tsx
  7. 430
      app/screens/productStatus/OrderDatails.tsx
  8. 6
      app/services/api/login.ts
  9. 5
      done.txt
  10. 19
      package-lock.json
  11. 2
      package.json
  12. 10
      yarn.lock

1
app.json

@ -59,6 +59,7 @@
}, },
"plugins": [ "plugins": [
"expo-video", "expo-video",
"expo-apple-authentication",
[ [
"expo-build-properties", "expo-build-properties",
{ {

7
app/locales/en/translation.json

@ -110,6 +110,10 @@
"login_required_subtitle": "Login to use chat features", "login_required_subtitle": "Login to use chat features",
"login_now": "Login Now" "login_now": "Login Now"
}, },
"login":{
"error":"Login failed, please try again",
"success":"Login successfully"
},
"banner": { "banner": {
"today": "Today", "today": "Today",
"shipping": { "shipping": {
@ -357,7 +361,8 @@
}, },
"order.preview": { "order.preview": {
"login_required": "Please login first", "login_required": "Please login first",
"payment_failed": "Payment failed", "payment_failed": "Payment failed, please try again",
"Insufficient_balance": "Insufficient balance",
"pay_now": "Pay Now", "pay_now": "Pay Now",
"payment_method": "Payment Method", "payment_method": "Payment Method",
"enter_phone": "Please enter phone number", "enter_phone": "Please enter phone number",

3
app/locales/fr/translation.json

@ -293,6 +293,7 @@
"order.preview": { "order.preview": {
"login_required": "Veuillez vous connecter d'abord", "login_required": "Veuillez vous connecter d'abord",
"payment_failed": "Le paiement a échoué", "payment_failed": "Le paiement a échoué",
"Insufficient_balance": "Solde insuffisant",
"pay_now": "Payer maintenant", "pay_now": "Payer maintenant",
"payment_method": "Mode de paiement", "payment_method": "Mode de paiement",
"enter_phone": "Veuillez saisir le numéro de téléphone", "enter_phone": "Veuillez saisir le numéro de téléphone",
@ -324,6 +325,8 @@
}, },
"login": { "login": {
"logInOrSignUp": "Se connecter ou s'inscrire", "logInOrSignUp": "Se connecter ou s'inscrire",
"error":"Échec de la connexion, veuillez réessayer",
"success":"Connexion réussie",
"phoneNumber": "Numéro de téléphone", "phoneNumber": "Numéro de téléphone",
"enterPassword": "Veuillez réentrer votre mot de passe", "enterPassword": "Veuillez réentrer votre mot de passe",
"passwordIncorrect": "Mot de passe incorrect, veuillez confirmer votre mot de passe.", "passwordIncorrect": "Mot de passe incorrect, veuillez confirmer votre mot de passe.",

37
app/screens/BalanceScreen/BalanceScreen.tsx

@ -27,6 +27,7 @@ import BackIcon from "../../components/BackIcon";
import useUserStore from "../../store/user"; import useUserStore from "../../store/user";
import { Transaction, payApi } from "../../services/api/payApi"; import { Transaction, payApi } from "../../services/api/payApi";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { userApi } from "../../services";
type BalanceScreenNavigationProp = NativeStackNavigationProp< type BalanceScreenNavigationProp = NativeStackNavigationProp<
RootStackParamList, RootStackParamList,
@ -35,7 +36,7 @@ type BalanceScreenNavigationProp = NativeStackNavigationProp<
export const BalanceScreen = () => { export const BalanceScreen = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { user } = useUserStore(); const { user, setUser } = useUserStore();
const navigation = useNavigation<BalanceScreenNavigationProp>(); const navigation = useNavigation<BalanceScreenNavigationProp>();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
const [rechargeHistory, setRechargeHistory] = useState<Transaction[]>([]); const [rechargeHistory, setRechargeHistory] = useState<Transaction[]>([]);
@ -66,7 +67,7 @@ export const BalanceScreen = () => {
if (refresh) { if (refresh) {
setRechargeHistory(response.items); setRechargeHistory(response.items);
} else { } else {
setRechargeHistory(prev => [...prev, ...response.items]); setRechargeHistory((prev) => [...prev, ...response.items]);
} }
setCurrentPage(page); setCurrentPage(page);
@ -85,6 +86,9 @@ export const BalanceScreen = () => {
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
userApi.getProfile().then((res) => {
setUser(res);
});
fetchRechargeHistory(1, true); fetchRechargeHistory(1, true);
}, []) }, [])
); );
@ -93,17 +97,12 @@ export const BalanceScreen = () => {
<View style={styles.transactionHistoryList} key={item.transaction_id}> <View style={styles.transactionHistoryList} key={item.transaction_id}>
<View style={styles.transactionDetailsPanel}> <View style={styles.transactionDetailsPanel}>
<View style={styles.transactionDetailsRow}> <View style={styles.transactionDetailsRow}>
<Text style={styles.transactionDescriptionBold}> <Text style={styles.transactionDescriptionBold}>{item.type}</Text>
{item.type}
</Text>
<Text <Text
style={[ style={[
styles.transactionAmountDisplay, styles.transactionAmountDisplay,
{ {
color: color: Number(item.amount) < 0 ? "#0035a4" : "#ff5217",
Number(item.amount) < 0
? "#0035a4"
: "#ff5217",
}, },
]} ]}
> >
@ -111,12 +110,8 @@ export const BalanceScreen = () => {
</Text> </Text>
</View> </View>
<View style={styles.transactionInfoRow}> <View style={styles.transactionInfoRow}>
<Text style={styles.transactionDate}> <Text style={styles.transactionDate}>{item.timestamp}</Text>
{item.timestamp} <Text style={styles.shipmentReference}>{item.type}</Text>
</Text>
<Text style={styles.shipmentReference}>
{item.type}
</Text>
</View> </View>
</View> </View>
</View> </View>
@ -150,7 +145,9 @@ export const BalanceScreen = () => {
<FlatList <FlatList
data={rechargeHistory} data={rechargeHistory}
renderItem={renderTransactionItem} renderItem={renderTransactionItem}
keyExtractor={(item) => item.transaction_id.toString()} keyExtractor={(item, index) =>
item.transaction_id.toString() + index
}
onEndReached={handleLoadMore} onEndReached={handleLoadMore}
onEndReachedThreshold={0.5} onEndReachedThreshold={0.5}
ListFooterComponent={renderFooter} ListFooterComponent={renderFooter}
@ -174,7 +171,9 @@ export const BalanceScreen = () => {
<View style={styles.totalBalanceCard}> <View style={styles.totalBalanceCard}>
<View style={styles.cardContainer}> <View style={styles.cardContainer}>
<View style={styles.financialInfoContainer}> <View style={styles.financialInfoContainer}>
<Text style={styles.largeBlackText}>{user?.balance}</Text> <Text style={styles.largeBlackText}>
{user?.balance}
</Text>
<View style={styles.svgContainer}></View> <View style={styles.svgContainer}></View>
</View> </View>
<View style={styles.totalSoldInfoContainer}> <View style={styles.totalSoldInfoContainer}>
@ -470,7 +469,7 @@ const styles = StyleSheet.create({
}, },
loaderContainer: { loaderContainer: {
paddingVertical: 20, paddingVertical: 20,
alignItems: 'center', alignItems: "center",
justifyContent: 'center', justifyContent: "center",
}, },
}); });

139
app/screens/loginList/index.tsx

@ -17,25 +17,32 @@ import type { NativeStackNavigationProp } from "@react-navigation/native-stack";
import fontSize from "../../utils/fontsizeUtils"; import fontSize from "../../utils/fontsizeUtils";
import EmailLoginModal from "./EmailLoginModal"; import EmailLoginModal from "./EmailLoginModal";
import PhoneLoginModal from "./PhoneLoginModal"; import PhoneLoginModal from "./PhoneLoginModal";
import { loginApi } from "../../services/api/login";
import { userApi } from "../../services";
import useUserStore from "../../store/user";
// 使用标准的ES6模块导入 // 使用标准的ES6模块导入
import { GoogleSignin, GoogleSigninButton, statusCodes } from '@react-native-google-signin/google-signin'; // import {
// GoogleSignin,
// statusCodes,
// } from "@react-native-google-signin/google-signin";
const isDevelopment = __DEV__; // 开发模式检测 const isDevelopment = __DEV__; // 开发模式检测
// 移出条件块,始终尝试配置 Google 登录 // 移出条件块,始终尝试配置 Google 登录
try { // try {
// 配置 Google 登录 // // 配置 Google 登录
GoogleSignin.configure({ // GoogleSignin.configure({
iosClientId: "YOUR_IOS_CLIENT_ID_HERE.apps.googleusercontent.com", // iOS CLIENT_ID // iosClientId: "YOUR_IOS_CLIENT_ID_HERE.apps.googleusercontent.com", // iOS CLIENT_ID
webClientId: "449517618313-av37nffa7rqkefu0ajh5auou3pb0mt51.apps.googleusercontent.com", // <-- 更新为此 Web Client ID // webClientId:
scopes: ['profile', 'email'], // "449517618313-av37nffa7rqkefu0ajh5auou3pb0mt51.apps.googleusercontent.com", // <-- 更新为此 Web Client ID
offlineAccess: false, // <-- 确保为 false 或移除 // scopes: ["profile", "email"],
forceCodeForRefreshToken: false, // <-- 确保为 false 或移除 // offlineAccess: false, // <-- 确保为 false 或移除
}); // forceCodeForRefreshToken: false, // <-- 确保为 false 或移除
} catch (error) { // });
console.log('Google Sign-in模块配置错误:', error); // 稍微修改了日志信息 // } catch (error) {
} // console.log("Google Sign-in模块配置错误:", error); // 稍微修改了日志信息
// }
type RootStackParamList = { type RootStackParamList = {
Login: undefined; Login: undefined;
@ -51,6 +58,7 @@ type LoginScreenProps = {
}; };
export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => { export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => {
const { setUser } = useUserStore();
const { t } = useTranslation(); const { t } = useTranslation();
const navigation = const navigation =
useNavigation<NativeStackNavigationProp<RootStackParamList>>(); useNavigation<NativeStackNavigationProp<RootStackParamList>>();
@ -97,63 +105,52 @@ export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => {
// 处理谷歌登录 // 处理谷歌登录
const handleGoogleLogin = async () => { const handleGoogleLogin = async () => {
try { // try {
// 开发模式下的模拟登录
// 注释掉开发模式下的模拟登录,以便进行真实登录测试 // if (!GoogleSignin || typeof GoogleSignin.signIn !== "function") {
/* // console.log("Google Sign-in模块未正确初始化或配置失败");
if (isDevelopment) { // return;
console.log('开发模式:模拟Google登录成功'); // }
const mockUserInfo = {
user: { // await GoogleSignin.hasPlayServices();
id: 'dev_user_123', // const userInfo = await GoogleSignin.signIn();
name: 'Test User', // console.log("Google 登录成功:", userInfo);
email: 'test@example.com', // try {
photo: null, // const res = await loginApi.googleLogin(userInfo);
}, // const user = await userApi.getProfile();
}; // setUser(user);
console.log('模拟用户信息:', mockUserInfo);
// 这里可以处理登录成功后的逻辑
// 比如导航到主页面或保存用户信息
// navigation.navigate("MainTabs", { screen: "Home" }); // navigation.navigate("MainTabs", { screen: "Home" });
// } catch (err) {
return; // console.log("Google 登录失败:", err);
} // navigation.navigate("Login");
*/ // }
// 生产模式下的真实Google登录 (现在开发模式也会执行) // // 这里可以处理登录成功后的逻辑
if (!GoogleSignin || typeof GoogleSignin.signIn !== 'function') { // // 比如导航到主页面或保存用户信息
console.log('Google Sign-in模块未正确初始化或配置失败'); // // navigation.navigate("MainTabs", { screen: "Home" });
return; // } catch (error: any) {
} // console.log("Google 登录错误:", error);
await GoogleSignin.hasPlayServices(); // // 开发模式下的错误处理
const userInfo = await GoogleSignin.signIn(); // if (isDevelopment) {
console.log('Google 登录成功:', userInfo); // console.log("开发模式:忽略Google登录错误,但已尝试真实登录"); // 修改日志,表明已尝试真实登录
// return;
// 这里可以处理登录成功后的逻辑 // }
// 比如导航到主页面或保存用户信息
// navigation.navigate("MainTabs", { screen: "Home" }); // if (statusCodes && error.code === statusCodes.SIGN_IN_CANCELLED) {
// console.log("用户取消登录");
} catch (error: any) { // } else if (statusCodes && error.code === statusCodes.IN_PROGRESS) {
console.log('Google 登录错误:', error); // console.log("登录正在进行中");
// } else if (
// 开发模式下的错误处理 // statusCodes &&
if (isDevelopment) { // error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE
console.log('开发模式:忽略Google登录错误,但已尝试真实登录'); // 修改日志,表明已尝试真实登录 // ) {
return; // console.log("Play Services 不可用");
} // } else {
// console.log("其他错误:", error.message);
if (statusCodes && error.code === statusCodes.SIGN_IN_CANCELLED) { // navigation.navigate("Login");
console.log('用户取消登录'); // }
} else if (statusCodes && error.code === statusCodes.IN_PROGRESS) { // }
console.log('登录正在进行中');
} else if (statusCodes && error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
console.log('Play Services 不可用');
} else {
console.log('其他错误:', error.message);
}
}
}; };
// 处理Facebook登录 // 处理Facebook登录
@ -263,7 +260,9 @@ export const LoginScreen = ({ onClose, isModal }: LoginScreenProps) => {
/> />
</View> </View>
<Text style={styles.loginButtonText}> <Text style={styles.loginButtonText}>
{isDevelopment ? '🧪 ' + t("continueWithGoogle") + ' (测试模式)' : t("continueWithGoogle")} {isDevelopment
? "🧪 " + t("continueWithGoogle") + " (测试模式)"
: t("continueWithGoogle")}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>

11
app/screens/previewOrder/perviewOrder.tsx

@ -41,6 +41,7 @@ type RootStackParamList = {
}; };
Pay: { payUrl: string; method: string; order_id: string }; Pay: { payUrl: string; method: string; order_id: string };
OrderDetails: { orderId?: number }; OrderDetails: { orderId?: number };
PaymentSuccessScreen: any;
}; };
export const PreviewOrder = () => { export const PreviewOrder = () => {
@ -58,7 +59,7 @@ export const PreviewOrder = () => {
if (!user.user_id) { if (!user.user_id) {
return Alert.alert(t("order.preview.login_required")); return Alert.alert(t("order.preview.login_required"));
} }
if (route.params.payMethod === "Brainnel Pay(Mobile Money)") { if (route.params.payMethod === "mobile_money") {
setShowPhoneInput(true); setShowPhoneInput(true);
} else { } else {
setShowPhoneInput(false); setShowPhoneInput(false);
@ -105,6 +106,14 @@ export const PreviewOrder = () => {
.getPayInfo(data) .getPayInfo(data)
.then((res) => { .then((res) => {
if (res.success) { if (res.success) {
if (route.params.payMethod === "balance") {
if (res.success) {
navigation.navigate("PaymentSuccessScreen", res);
return;
} else {
Alert.alert(t("order.preview.Insufficient_balance"));
}
}
logPreviewOrder( logPreviewOrder(
navigation.getState().routes[navigation.getState().index - 1] navigation.getState().routes[navigation.getState().index - 1]
?.name as string ?.name as string

430
app/screens/productStatus/OrderDatails.tsx

@ -181,7 +181,7 @@ export const OrderDetails = () => {
{ {
OrderDetails: { OrderDetails: {
orderId: string; orderId: string;
status:number status: number;
}; };
}, },
"OrderDetails" "OrderDetails"
@ -189,7 +189,8 @@ export const OrderDetails = () => {
>(); >();
const [orderDetails, setOrderDetails] = useState<OrderDetailsType>(); const [orderDetails, setOrderDetails] = useState<OrderDetailsType>();
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const { deleteOrder, changeOrder,updateOrderShippingInfo } = useOrderListStore(); const { deleteOrder, changeOrder, updateOrderShippingInfo } =
useOrderListStore();
const [showPaymentModal, setShowPaymentModal] = useState(false); const [showPaymentModal, setShowPaymentModal] = useState(false);
const [selectedPayment, setSelectedPayment] = useState<string | null>(null); const [selectedPayment, setSelectedPayment] = useState<string | null>(null);
const [currentTab, setCurrentTab] = useState("online"); const [currentTab, setCurrentTab] = useState("online");
@ -205,16 +206,22 @@ export const OrderDetails = () => {
label: t("order.payment.offline"), label: t("order.payment.offline"),
options: [ options: [
{ id: "cash", label: t("order.payment.cash") || "Cash", key: "cash" }, { id: "cash", label: t("order.payment.cash") || "Cash", key: "cash" },
{ id: "bank", label: t("order.payment.bank") || "Bank Transfer", key: "bank" } {
id: "bank",
label: t("order.payment.bank") || "Bank Transfer",
key: "bank",
},
], ],
}, },
]); ]);
const [selectedCurrency, setSelectedCurrency] = useState("USD"); const [selectedCurrency, setSelectedCurrency] = useState("USD");
const [convertedAmount, setConvertedAmount] = useState<{ const [convertedAmount, setConvertedAmount] = useState<
{
converted_amount: number; converted_amount: number;
item_key: string; item_key: string;
original_amount: number; original_amount: number;
}[]>([]); }[]
>([]);
const [isConverting, setIsConverting] = useState(false); const [isConverting, setIsConverting] = useState(false);
const { user } = useUserStore(); const { user } = useUserStore();
const [isPaymentLoading, setIsPaymentLoading] = useState(false); const [isPaymentLoading, setIsPaymentLoading] = useState(false);
@ -247,22 +254,29 @@ export const OrderDetails = () => {
getOrderDetails(); getOrderDetails();
// 获取支付方式 // 获取支付方式
payApi.getCountryPaymentMethods().then((res) => { payApi
.getCountryPaymentMethods()
.then((res) => {
if (res && res.current_country_methods) { if (res && res.current_country_methods) {
setPaymentMethods(res.current_country_methods); setPaymentMethods(res.current_country_methods);
// 更新在线支付选项 // 更新在线支付选项
setTabs(prev => { setTabs((prev) => {
const updatedTabs = [...prev]; const updatedTabs = [...prev];
const onlineTabIndex = updatedTabs.findIndex(tab => tab.id === "online"); const onlineTabIndex = updatedTabs.findIndex(
(tab) => tab.id === "online"
);
if (onlineTabIndex !== -1) { if (onlineTabIndex !== -1) {
// 将API返回的支付方式转换为选项格式 // 将API返回的支付方式转换为选项格式
const options: PaymentOption[] = res.current_country_methods.map(method => ({ const options: PaymentOption[] = res.current_country_methods.map(
(method) => ({
id: method.key, id: method.key,
label: method.key.charAt(0).toUpperCase() + method.key.slice(1), // 首字母大写 label:
key: method.key method.key.charAt(0).toUpperCase() + method.key.slice(1), // 首字母大写
})); key: method.key,
})
);
updatedTabs[onlineTabIndex].options = options; updatedTabs[onlineTabIndex].options = options;
} }
@ -270,7 +284,8 @@ export const OrderDetails = () => {
return updatedTabs; return updatedTabs;
}); });
} }
}).catch(error => { })
.catch((error) => {
console.error("获取支付方式失败:", error); console.error("获取支付方式失败:", error);
}); });
}, []); }, []);
@ -372,34 +387,64 @@ export const OrderDetails = () => {
order_id: orderDetails.order_id, order_id: orderDetails.order_id,
payment_method: selectedPayment, payment_method: selectedPayment,
currency: selectedPayment === "paypal" ? selectedCurrency : user.currency, currency: selectedPayment === "paypal" ? selectedCurrency : user.currency,
total_amount: selectedPayment === "paypal" total_amount:
? convertedAmount.reduce((acc, item) => acc + item.converted_amount, 0) selectedPayment === "paypal"
? convertedAmount.reduce(
(acc, item) => acc + item.converted_amount,
0
)
: orderDetails?.total_amount || 0, : orderDetails?.total_amount || 0,
actual_amount: selectedPayment === "paypal" actual_amount:
? convertedAmount.reduce((acc, item) => acc + item.converted_amount, 0) selectedPayment === "paypal"
? convertedAmount.reduce(
(acc, item) => acc + item.converted_amount,
0
)
: orderDetails?.actual_amount || 0, : orderDetails?.actual_amount || 0,
shipping_fee: selectedPayment === "paypal" shipping_fee:
? convertedAmount.find(item => item.item_key === "shipping_fee")?.converted_amount || 0 selectedPayment === "paypal"
? convertedAmount.find((item) => item.item_key === "shipping_fee")
?.converted_amount || 0
: orderDetails?.shipping_fee || 0, : orderDetails?.shipping_fee || 0,
domestic_shipping_fee: selectedPayment === "paypal" domestic_shipping_fee:
? convertedAmount.find(item => item.item_key === "domestic_shipping_fee")?.converted_amount || 0 selectedPayment === "paypal"
: orderDetails?.domestic_shipping_fee || 0 ? convertedAmount.find(
(item) => item.item_key === "domestic_shipping_fee"
)?.converted_amount || 0
: orderDetails?.domestic_shipping_fee || 0,
}; };
try { try {
await ordersApi.updateOrderPaymentMethod(paymentData) await ordersApi.updateOrderPaymentMethod(paymentData);
const payData = { const payData = {
order_id: orderDetails.order_id, order_id: orderDetails.order_id,
method: selectedPayment, method: selectedPayment,
currency: selectedPayment === "paypal" ? selectedCurrency : user.currency, currency:
amount: selectedPayment === "paypal" selectedPayment === "paypal" ? selectedCurrency : user.currency,
? convertedAmount.reduce((acc, item) => acc + item.converted_amount, 0) amount:
: orderDetails?.total_amount || 0 selectedPayment === "paypal"
? convertedAmount.reduce(
(acc, item) => acc + item.converted_amount,
0
)
: orderDetails?.total_amount || 0,
}; };
payApi payApi
.getPayInfo(payData) .getPayInfo(payData)
.then((res) => { .then((res) => {
if (res.success) { if (res.success) {
if (selectedPayment === "balance") {
setIsPaymentLoading(false);
setShowPaymentModal(false);
if (res.success) {
navigation.navigate("PaymentSuccessScreen", res);
return;
} else {
Alert.alert(t("order.preview.Insufficient_balance"));
return;
}
}
setIsPaymentLoading(false); setIsPaymentLoading(false);
setShowPaymentModal(false); setShowPaymentModal(false);
navigation.navigate("Pay", { navigation.navigate("Pay", {
@ -418,7 +463,6 @@ export const OrderDetails = () => {
.finally(() => { .finally(() => {
setIsPaymentLoading(false); setIsPaymentLoading(false);
}); });
} catch (error) { } catch (error) {
Alert.alert(t("error"), t("order.error.payment_update")); Alert.alert(t("error"), t("order.error.payment_update"));
setIsPaymentLoading(false); setIsPaymentLoading(false);
@ -433,10 +477,7 @@ export const OrderDetails = () => {
// 验证电话号码(添加更严格的验证) // 验证电话号码(添加更严格的验证)
if (!phoneNumber || phoneNumber.length < 8) { if (!phoneNumber || phoneNumber.length < 8) {
Alert.alert( Alert.alert(t("error"), t("order.error.invalid_phone"));
t("error"),
t("order.error.invalid_phone")
);
return; return;
} }
@ -452,7 +493,7 @@ export const OrderDetails = () => {
actual_amount: paymentParams.amount, actual_amount: paymentParams.amount,
shipping_fee: 0, shipping_fee: 0,
domestic_shipping_fee: 0, domestic_shipping_fee: 0,
phone: phoneNumber phone: phoneNumber,
}; };
// 更新订单支付方式 // 更新订单支付方式
@ -464,7 +505,7 @@ export const OrderDetails = () => {
method: paymentParams.payment_method, method: paymentParams.payment_method,
currency: paymentParams.currency, currency: paymentParams.currency,
amount: paymentParams.amount, amount: paymentParams.amount,
phone: phoneNumber phone: phoneNumber,
}; };
const response = await payApi.getPayInfo(payData); const response = await payApi.getPayInfo(payData);
@ -557,7 +598,9 @@ export const OrderDetails = () => {
<View style={styles.orderStatusContent}> <View style={styles.orderStatusContent}>
<View style={styles.orderStatusTitle}> <View style={styles.orderStatusTitle}>
<OrderIcon size={20} color="#3D3D3D" /> <OrderIcon size={20} color="#3D3D3D" />
<Text style={styles.orderStatusTitleText}>{t("order.status")}</Text> <Text style={styles.orderStatusTitleText}>
{t("order.status")}
</Text>
</View> </View>
<View style={styles.orderStatusContentPreview}> <View style={styles.orderStatusContentPreview}>
@ -568,7 +611,7 @@ export const OrderDetails = () => {
t("order.status.waiting_shipment"), t("order.status.waiting_shipment"),
t("order.status.in_transit"), t("order.status.in_transit"),
t("order.status.waiting_receipt"), t("order.status.waiting_receipt"),
t("order.status.completed") t("order.status.completed"),
]} ]}
/> />
</View> </View>
@ -579,7 +622,9 @@ export const OrderDetails = () => {
<View style={styles.orderStatusContent}> <View style={styles.orderStatusContent}>
<View style={styles.orderStatusTitle}> <View style={styles.orderStatusTitle}>
<InfoIcon size={20} color="#3D3D3D" /> <InfoIcon size={20} color="#3D3D3D" />
<Text style={styles.orderStatusTitleText}>{t("order.information")}</Text> <Text style={styles.orderStatusTitleText}>
{t("order.information")}
</Text>
</View> </View>
<View style={styles.orderStatusContentPreview}> <View style={styles.orderStatusContentPreview}>
<View style={styles.orderId}> <View style={styles.orderId}>
@ -589,15 +634,21 @@ export const OrderDetails = () => {
</Text> </Text>
</View> </View>
<View style={styles.orderId}> <View style={styles.orderId}>
<Text style={styles.orderIdText}>{t("order.create_time")}</Text> <Text style={styles.orderIdText}>
{t("order.create_time")}
</Text>
<Text style={styles.orderIdText1}> <Text style={styles.orderIdText1}>
{orderDetails.create_time} {orderDetails.create_time}
</Text> </Text>
</View> </View>
<View style={styles.orderId}> <View style={styles.orderId}>
<Text style={styles.orderIdText}>{t("order.shipping_type")}</Text> <Text style={styles.orderIdText}>
{t("order.shipping_type")}
</Text>
<Text style={styles.orderIdText1}> <Text style={styles.orderIdText1}>
{orderDetails.shipping_type === 0 ? t("order.shipping.sea") : t("order.shipping.air")} {orderDetails.shipping_type === 0
? t("order.shipping.sea")
: t("order.shipping.air")}
</Text> </Text>
</View> </View>
</View> </View>
@ -608,7 +659,9 @@ export const OrderDetails = () => {
<View style={styles.orderStatusContent}> <View style={styles.orderStatusContent}>
<View style={styles.orderStatusTitle}> <View style={styles.orderStatusTitle}>
<AddressIcon size={22} color={"#3D3D3D"} /> <AddressIcon size={22} color={"#3D3D3D"} />
<Text style={styles.orderStatusTitleText}>{t("order.delivery_info")}</Text> <Text style={styles.orderStatusTitleText}>
{t("order.delivery_info")}
</Text>
</View> </View>
<View style={styles.orderStatusContentPreview}> <View style={styles.orderStatusContentPreview}>
<View style={styles.orderStatusContentPreviewInformation}> <View style={styles.orderStatusContentPreviewInformation}>
@ -747,7 +800,9 @@ export const OrderDetails = () => {
<TouchableOpacity style={styles.addCard}> <TouchableOpacity style={styles.addCard}>
<View style={styles.addCardBox}> <View style={styles.addCardBox}>
<CardIcon size={16} color="#0098ef" /> <CardIcon size={16} color="#0098ef" />
<Text style={styles.addCardText}>{t("order.add_to_cart")}</Text> <Text style={styles.addCardText}>
{t("order.add_to_cart")}
</Text>
</View> </View>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
@ -758,7 +813,9 @@ export const OrderDetails = () => {
<View style={styles.orderStatusContent}> <View style={styles.orderStatusContent}>
<View style={styles.orderStatusTitle}> <View style={styles.orderStatusTitle}>
<PowerIcon size={20} color="#3D3D3D" /> <PowerIcon size={20} color="#3D3D3D" />
<Text style={styles.orderStatusTitleText}>{t("order.price_details")}</Text> <Text style={styles.orderStatusTitleText}>
{t("order.price_details")}
</Text>
</View> </View>
<View style={styles.orderStatusContentPreview}> <View style={styles.orderStatusContentPreview}>
{/* <View style={styles.orderId}> {/* <View style={styles.orderId}>
@ -791,7 +848,8 @@ export const OrderDetails = () => {
</View> </View>
<View> <View>
<Text style={styles.orderRemakeText}> <Text style={styles.orderRemakeText}>
+ ${orderDetails.shipping_fee} {t("order.estimated_shipping")} + ${orderDetails.shipping_fee}{" "}
{t("order.estimated_shipping")}
(COD) (COD)
</Text> </Text>
</View> </View>
@ -806,7 +864,9 @@ export const OrderDetails = () => {
style={styles.bottomButton1} style={styles.bottomButton1}
onPress={() => setShowCancelModal(true)} onPress={() => setShowCancelModal(true)}
> >
<Text style={styles.bottomButtonText1}>{t("order.cancel")}</Text> <Text style={styles.bottomButtonText1}>
{t("order.cancel")}
</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={styles.bottomButton} style={styles.bottomButton}
@ -827,7 +887,9 @@ export const OrderDetails = () => {
callPhone("15903995548"); callPhone("15903995548");
}} }}
> >
<Text style={styles.bottomButtonText1}>{t("order.contact_shipping")}</Text> <Text style={styles.bottomButtonText1}>
{t("order.contact_shipping")}
</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={styles.bottomButton} style={styles.bottomButton}
@ -836,15 +898,22 @@ export const OrderDetails = () => {
navigation.goBack(); navigation.goBack();
}} }}
> >
<Text style={styles.bottomButtonText}>{t("order.cancel")}</Text> <Text style={styles.bottomButtonText}>
{t("order.cancel")}
</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
)} )}
{/* 代收货 */} {/* 代收货 */}
{orderDetails.order_status === 2 && ( {orderDetails.order_status === 2 && (
<View style={styles.bottomButtons}> <View style={styles.bottomButtons}>
<TouchableOpacity style={styles.bottomButton1} onPress={() => {}}> <TouchableOpacity
<Text style={styles.bottomButtonText1}>{t("order.check_logistics")}</Text> style={styles.bottomButton1}
onPress={() => {}}
>
<Text style={styles.bottomButtonText1}>
{t("order.check_logistics")}
</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style={styles.bottomButton} style={styles.bottomButton}
@ -854,13 +923,15 @@ export const OrderDetails = () => {
shipping_info: { shipping_info: {
shipping_company: "string", shipping_company: "string",
shipping_no: "string", shipping_no: "string",
shipping_info: {} shipping_info: {},
} },
}); });
navigation.goBack(); navigation.goBack();
}} }}
> >
<Text style={styles.bottomButtonText}>{t("order.confirm_receipt")}</Text> <Text style={styles.bottomButtonText}>
{t("order.confirm_receipt")}
</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
)} )}
@ -874,21 +945,32 @@ export const OrderDetails = () => {
navigation.goBack(); navigation.goBack();
}} }}
> >
<Text style={styles.bottomButtonText1}>{t("order.cancel")}</Text> <Text style={styles.bottomButtonText1}>
{t("order.cancel")}
</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity style={styles.bottomButton}> <TouchableOpacity style={styles.bottomButton}>
<Text style={styles.bottomButtonText}>{t("order.pay_now")}</Text> <Text style={styles.bottomButtonText}>
{t("order.pay_now")}
</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
)} )}
{/* 已取消 */} {/* 已取消 */}
{orderDetails.order_status === 4 && ( {orderDetails.order_status === 4 && (
<View style={styles.bottomButtons}> <View style={styles.bottomButtons}>
<TouchableOpacity style={styles.bottomButton1} onPress={() => {}}> <TouchableOpacity
<Text style={styles.bottomButtonText1}>{t("order.add_to_cart")}</Text> style={styles.bottomButton1}
onPress={() => {}}
>
<Text style={styles.bottomButtonText1}>
{t("order.add_to_cart")}
</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity style={styles.bottomButton}> <TouchableOpacity style={styles.bottomButton}>
<Text style={styles.bottomButtonText}>{t("order.reorder")}</Text> <Text style={styles.bottomButtonText}>
{t("order.reorder")}
</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
)} )}
@ -902,14 +984,16 @@ export const OrderDetails = () => {
visible={showPaymentModal} visible={showPaymentModal}
transparent={true} transparent={true}
animationType="slide" animationType="slide"
onRequestClose={() => setShowPaymentModal(false)} onRequestClose={() => setShowPaymentModal(false)}
> >
<View style={styles.modalOverlay}> <View style={styles.modalOverlay}>
<View style={styles.modalContent}> <View style={styles.modalContent}>
<View style={styles.modalHeader}> <View style={styles.modalHeader}>
<Text style={styles.modalTitle}>{t("order.select_payment")}</Text> <Text style={styles.modalTitle}>{t("order.select_payment")}</Text>
<TouchableOpacity onPress={() => setShowPaymentModal(false)} style={styles.closeButtonContainer}> <TouchableOpacity
onPress={() => setShowPaymentModal(false)}
style={styles.closeButtonContainer}
>
<Text style={styles.closeButtonText}>×</Text> <Text style={styles.closeButtonText}>×</Text>
</TouchableOpacity> </TouchableOpacity>
</View> </View>
@ -918,17 +1002,28 @@ export const OrderDetails = () => {
{tabs.map((tab) => ( {tabs.map((tab) => (
<TouchableOpacity <TouchableOpacity
key={tab.id} key={tab.id}
style={[styles.tab, currentTab === tab.id && styles.tabActive]} style={[
styles.tab,
currentTab === tab.id && styles.tabActive,
]}
onPress={() => setCurrentTab(tab.id)} onPress={() => setCurrentTab(tab.id)}
> >
<Text style={[styles.tabText, currentTab === tab.id && styles.tabTextActive]}> <Text
style={[
styles.tabText,
currentTab === tab.id && styles.tabTextActive,
]}
>
{tab.label} {tab.label}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
))} ))}
</View> </View>
<ScrollView showsVerticalScrollIndicator={false} style={styles.paymentOptions}> <ScrollView
showsVerticalScrollIndicator={false}
style={styles.paymentOptions}
>
{currentTab === "online" ? ( {currentTab === "online" ? (
<> <>
{tabs {tabs
@ -947,7 +1042,8 @@ export const OrderDetails = () => {
/> />
</View> </View>
<Text style={styles.balanceText}> <Text style={styles.balanceText}>
{t("order.balance_remaining") || "Balance remaining"} {t("order.balance_remaining") ||
"Balance remaining"}
{"\n"} {"\n"}
{user.balance} {user.balance}
{user.currency} {user.currency}
@ -960,39 +1056,74 @@ export const OrderDetails = () => {
style={{ width: 80, height: 30, resizeMode: 'contain', marginRight: 10 }} style={{ width: 80, height: 30, resizeMode: 'contain', marginRight: 10 }}
/> />
{option.key === "mobile_money" && ( {option.key === "mobile_money" && (
<View style={styles.mobileMoneyTextContainer}> <View
{paymentMethods.find(method => method.key === option.key)?.value && style={styles.mobileMoneyTextContainer}
Array.isArray(paymentMethods.find(method => method.key === option.key)?.value) ? ( >
(paymentMethods.find(method => method.key === option.key)?.value as string[]).map((item, index) => ( {paymentMethods.find(
<View key={index} style={styles.mobileMoneyImgContainer}> (method) => method.key === option.key
)?.value &&
Array.isArray(
paymentMethods.find(
(method) => method.key === option.key
)?.value
) ? (
(
paymentMethods.find(
(method) =>
method.key === option.key
)?.value as string[]
).map((item, index) => (
<View
key={index}
style={
styles.mobileMoneyImgContainer
}
>
<Image <Image
source={payMap(item) as any} source={payMap(item) as any}
style={{ width: 60, height: 22, resizeMode: 'contain' }} style={styles.mobileMoneyImg}
/> />
</View> </View>
)) ))
) : ( ) : (
<Text style={styles.mobileMoneyText}> <Text style={styles.mobileMoneyText}>
{paymentMethods.find(method => method.key === option.key)?.value as string} {
</Text> paymentMethods.find(
) (method) =>
method.key === option.key
)?.value as string
} }
</Text>
)}
</View> </View>
)} )}
</View> </View>
)} )}
</View> </View>
</View> </View>
<TouchableOpacity onPress={() => onSelectPayment(option.id)}> <TouchableOpacity
onPress={() => onSelectPayment(option.id)}
>
<View style={styles.checkboxContainer}> <View style={styles.checkboxContainer}>
<CircleOutlineIcon <CircleOutlineIcon
size={fontSize(24)} size={fontSize(24)}
strokeColor={selectedPayment === option.id ? "#007efa" : "#C6C6C6"} strokeColor={
fillColor={selectedPayment === option.id ? "#007efa" : "transparent"} selectedPayment === option.id
? "#007efa"
: "#C6C6C6"
}
fillColor={
selectedPayment === option.id
? "#007efa"
: "transparent"
}
/> />
{selectedPayment === option.id && ( {selectedPayment === option.id && (
<View style={styles.checkmarkContainer}> <View style={styles.checkmarkContainer}>
<CheckIcon size={fontSize(12)} color="#FFFFFF" /> <CheckIcon
size={fontSize(12)}
color="#FFFFFF"
/>
</View> </View>
)} )}
</View> </View>
@ -1000,24 +1131,29 @@ export const OrderDetails = () => {
</View> </View>
{/* PayPal Currency Selection */} {/* PayPal Currency Selection */}
{selectedPayment === "paypal" && option.id === "paypal" && isPaypalExpanded && ( {selectedPayment === "paypal" &&
option.id === "paypal" &&
isPaypalExpanded && (
<View style={styles.paypalExpandedContainer}> <View style={styles.paypalExpandedContainer}>
<View style={styles.paypalCurrencyContainer}> <View style={styles.paypalCurrencyContainer}>
<Text style={styles.currencyTitle}> <Text style={styles.currencyTitle}>
{t("order.select_currency") || "Select Currency"} {t("order.select_currency") ||
"Select Currency"}
</Text> </Text>
<View style={styles.currencyButtonsContainer}> <View style={styles.currencyButtonsContainer}>
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.currencyButton, styles.currencyButton,
selectedCurrency === "USD" && styles.currencyButtonActive, selectedCurrency === "USD" &&
styles.currencyButtonActive,
]} ]}
onPress={() => onSelectCurrency("USD")} onPress={() => onSelectCurrency("USD")}
> >
<Text <Text
style={[ style={[
styles.currencyButtonText, styles.currencyButtonText,
selectedCurrency === "USD" && styles.currencyButtonTextActive, selectedCurrency === "USD" &&
styles.currencyButtonTextActive,
]} ]}
> >
USD USD
@ -1026,14 +1162,16 @@ export const OrderDetails = () => {
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.currencyButton, styles.currencyButton,
selectedCurrency === "EUR" && styles.currencyButtonActive, selectedCurrency === "EUR" &&
styles.currencyButtonActive,
]} ]}
onPress={() => onSelectCurrency("EUR")} onPress={() => onSelectCurrency("EUR")}
> >
<Text <Text
style={[ style={[
styles.currencyButtonText, styles.currencyButtonText,
selectedCurrency === "EUR" && styles.currencyButtonTextActive, selectedCurrency === "EUR" &&
styles.currencyButtonTextActive,
]} ]}
> >
EUR EUR
@ -1044,7 +1182,10 @@ export const OrderDetails = () => {
{/* 显示转换后的金额 */} {/* 显示转换后的金额 */}
{isConverting ? ( {isConverting ? (
<View style={styles.convertingContainer}> <View style={styles.convertingContainer}>
<ActivityIndicator size="small" color="#007efa" /> <ActivityIndicator
size="small"
color="#007efa"
/>
<Text style={styles.convertingText}> <Text style={styles.convertingText}>
{t("order.converting") || "Converting..."} {t("order.converting") || "Converting..."}
</Text> </Text>
@ -1052,11 +1193,15 @@ export const OrderDetails = () => {
) : convertedAmount.length > 0 ? ( ) : convertedAmount.length > 0 ? (
<View style={styles.convertedAmountContainer}> <View style={styles.convertedAmountContainer}>
<Text style={styles.convertedAmountLabel}> <Text style={styles.convertedAmountLabel}>
{t("order.equivalent_amount") || "Equivalent Amount:"} {t("order.equivalent_amount") ||
"Equivalent Amount:"}
</Text> </Text>
<Text style={styles.convertedAmountValue}> <Text style={styles.convertedAmountValue}>
{convertedAmount {convertedAmount
.find((item) => item.item_key === "total_amount") .find(
(item) =>
item.item_key === "total_amount"
)
?.converted_amount.toFixed(2)}{" "} ?.converted_amount.toFixed(2)}{" "}
{selectedCurrency} {selectedCurrency}
</Text> </Text>
@ -1096,15 +1241,22 @@ export const OrderDetails = () => {
<CircleOutlineIcon <CircleOutlineIcon
size={fontSize(24)} size={fontSize(24)}
strokeColor={ strokeColor={
selectedPayment === option.id ? "#007efa" : undefined selectedPayment === option.id
? "#007efa"
: undefined
} }
fillColor={ fillColor={
selectedPayment === option.id ? "#007efa" : undefined selectedPayment === option.id
? "#007efa"
: undefined
} }
/> />
{selectedPayment === option.id && ( {selectedPayment === option.id && (
<View style={styles.checkmarkContainer}> <View style={styles.checkmarkContainer}>
<CheckIcon size={fontSize(12)} color="#FFFFFF" /> <CheckIcon
size={fontSize(12)}
color="#FFFFFF"
/>
</View> </View>
)} )}
</View> </View>
@ -1128,7 +1280,8 @@ export const OrderDetails = () => {
<TouchableOpacity <TouchableOpacity
style={[ style={[
styles.confirmButton, styles.confirmButton,
(isConfirmButtonDisabled() || isPaymentLoading) && styles.confirmButtonDisabled, (isConfirmButtonDisabled() || isPaymentLoading) &&
styles.confirmButtonDisabled,
]} ]}
onPress={handlePaymentConfirm} onPress={handlePaymentConfirm}
disabled={isConfirmButtonDisabled() || isPaymentLoading} disabled={isConfirmButtonDisabled() || isPaymentLoading}
@ -1202,7 +1355,7 @@ export const OrderDetails = () => {
const styles = StyleSheet.create<Styles>({ const styles = StyleSheet.create<Styles>({
safeArea: { safeArea: {
flex: 1, flex: 1,
backgroundColor: '#fff', backgroundColor: "#fff",
}, },
safeAreaContent: { safeAreaContent: {
flex: 1, flex: 1,
@ -1461,39 +1614,38 @@ const styles = StyleSheet.create<Styles>({
}, },
modalOverlay: { modalOverlay: {
flex: 1, flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.5)', backgroundColor: "rgba(0, 0, 0, 0.5)",
justifyContent: 'center', justifyContent: "flex-end",
alignItems: 'center',
}, },
modalContent: { modalContent: {
backgroundColor: '#fff', backgroundColor: "#fff",
borderTopLeftRadius: 20, borderTopLeftRadius: 20,
borderTopRightRadius: 20, borderTopRightRadius: 20,
padding: 20, padding: 20,
maxHeight: '80%', maxHeight: "80%",
}, },
modalHeader: { modalHeader: {
flexDirection: 'row', flexDirection: "row",
justifyContent: 'space-between', justifyContent: "space-between",
alignItems: 'center', alignItems: "center",
marginBottom: 20, marginBottom: 20,
}, },
modalTitle: { modalTitle: {
fontSize: fontSize(18), fontSize: fontSize(18),
fontWeight: '600', fontWeight: "600",
}, },
closeButtonContainer: { closeButtonContainer: {
padding: 5, padding: 5,
}, },
closeButtonText: { closeButtonText: {
fontSize: fontSize(24), fontSize: fontSize(24),
color: '#999', color: "#999",
}, },
tabContainer: { tabContainer: {
flexDirection: 'row', flexDirection: "row",
marginBottom: 15, marginBottom: 15,
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: '#f5f5f5', borderBottomColor: "#f5f5f5",
}, },
tab: { tab: {
paddingVertical: 10, paddingVertical: 10,
@ -1502,31 +1654,31 @@ const styles = StyleSheet.create<Styles>({
}, },
tabActive: { tabActive: {
borderBottomWidth: 2, borderBottomWidth: 2,
borderBottomColor: '#FF5100', borderBottomColor: "#FF5100",
}, },
tabText: { tabText: {
fontSize: fontSize(16), fontSize: fontSize(16),
color: '#666', color: "#666",
}, },
tabTextActive: { tabTextActive: {
color: '#FF5100', color: "#FF5100",
fontWeight: '500', fontWeight: "500",
}, },
paymentOptions: { paymentOptions: {
maxHeight: 300, maxHeight: 300,
}, },
cardContainer: { cardContainer: {
flexDirection: 'row', flexDirection: "row",
alignItems: 'center', alignItems: "center",
justifyContent: 'space-between', justifyContent: "space-between",
padding: 15, padding: 15,
backgroundColor: '#F8F8F8', backgroundColor: "#F8F8F8",
borderRadius: 8, borderRadius: 8,
marginBottom: 10, marginBottom: 10,
}, },
iconRow: { iconRow: {
flexDirection: 'row', flexDirection: "row",
alignItems: 'center', alignItems: "center",
flex: 1, flex: 1,
}, },
imageContainer: { imageContainer: {
@ -1559,11 +1711,11 @@ const styles = StyleSheet.create<Styles>({
}, },
currencyTitle: { currencyTitle: {
fontSize: fontSize(14), fontSize: fontSize(14),
color: '#666', color: "#666",
marginBottom: 10, marginBottom: 10,
}, },
paypalExpandedContainer: { paypalExpandedContainer: {
backgroundColor: '#f8f8f8', backgroundColor: "#f8f8f8",
borderRadius: 8, borderRadius: 8,
marginTop: -5, marginTop: -5,
marginBottom: 10, marginBottom: 10,
@ -1574,7 +1726,7 @@ const styles = StyleSheet.create<Styles>({
padding: 10, padding: 10,
}, },
currencyButtonsContainer: { currencyButtonsContainer: {
flexDirection: 'row', flexDirection: "row",
marginBottom: 10, marginBottom: 10,
}, },
currencyButton: { currencyButton: {
@ -1582,30 +1734,30 @@ const styles = StyleSheet.create<Styles>({
paddingHorizontal: 15, paddingHorizontal: 15,
borderRadius: 20, borderRadius: 20,
borderWidth: 1, borderWidth: 1,
borderColor: '#ddd', borderColor: "#ddd",
marginRight: 10, marginRight: 10,
}, },
currencyButtonActive: { currencyButtonActive: {
backgroundColor: '#FFF0E8', backgroundColor: "#FFF0E8",
borderColor: '#FF5100', borderColor: "#FF5100",
}, },
currencyButtonText: { currencyButtonText: {
fontSize: fontSize(14), fontSize: fontSize(14),
color: '#333', color: "#333",
}, },
currencyButtonTextActive: { currencyButtonTextActive: {
color: '#FF5100', color: "#FF5100",
fontWeight: '600', fontWeight: "600",
}, },
convertingContainer: { convertingContainer: {
flexDirection: 'row', flexDirection: "row",
alignItems: 'center', alignItems: "center",
justifyContent: 'flex-end', justifyContent: "flex-end",
marginTop: 10, marginTop: 10,
}, },
convertingText: { convertingText: {
fontSize: fontSize(14), fontSize: fontSize(14),
color: '#999', color: "#999",
marginLeft: 10, marginLeft: 10,
}, },
convertedAmountContainer: { convertedAmountContainer: {
@ -1613,23 +1765,23 @@ const styles = StyleSheet.create<Styles>({
}, },
convertedAmountLabel: { convertedAmountLabel: {
fontSize: fontSize(14), fontSize: fontSize(14),
color: '#666', color: "#666",
marginBottom: 5, marginBottom: 5,
}, },
convertedAmountValue: { convertedAmountValue: {
fontSize: fontSize(16), fontSize: fontSize(16),
fontWeight: '600', fontWeight: "600",
color: '#FF5100', color: "#FF5100",
}, },
actionButtonsContainer: { actionButtonsContainer: {
marginTop: 20, marginTop: 20,
paddingTop: 20, paddingTop: 20,
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: '#f5f5f5', borderTopColor: "#f5f5f5",
}, },
actionButtons: { actionButtons: {
flexDirection: 'row', flexDirection: "row",
justifyContent: 'space-between', justifyContent: "space-between",
}, },
cancelButton: { cancelButton: {
flex: 1, flex: 1,
@ -1637,28 +1789,28 @@ const styles = StyleSheet.create<Styles>({
marginRight: 10, marginRight: 10,
borderRadius: 25, borderRadius: 25,
borderWidth: 1, borderWidth: 1,
borderColor: '#999', borderColor: "#999",
alignItems: 'center', alignItems: "center",
}, },
confirmButton: { confirmButton: {
flex: 1, flex: 1,
padding: 15, padding: 15,
marginLeft: 10, marginLeft: 10,
borderRadius: 25, borderRadius: 25,
backgroundColor: '#FF5100', backgroundColor: "#FF5100",
alignItems: 'center', alignItems: "center",
}, },
confirmButtonDisabled: { confirmButtonDisabled: {
backgroundColor: '#ccc', backgroundColor: "#ccc",
}, },
buttonTextDark: { buttonTextDark: {
fontSize: fontSize(16), fontSize: fontSize(16),
color: '#666', color: "#666",
}, },
buttonTextWhite: { buttonTextWhite: {
fontSize: fontSize(16), fontSize: fontSize(16),
color: '#fff', color: "#fff",
fontWeight: '600', fontWeight: "600",
}, },
operatorImage: { operatorImage: {
width: 80, width: 80,

6
app/services/api/login.ts

@ -0,0 +1,6 @@
import apiService from "./apiClient";
export const loginApi = {
googleLogin: (data: any) =>
apiService.post("/api/users/auth/callback/google", data),
};

5
done.txt

@ -0,0 +1,5 @@
1. 余额支付 (订单详情,支付)
2. 查看物流
3. 取消订单
4. 运费计算
5. 询盘的图搜转成base64

19
package-lock.json generated

@ -39,6 +39,7 @@
"react-i18next": "^15.4.1", "react-i18next": "^15.4.1",
"react-native": "0.76.9", "react-native": "0.76.9",
"react-native-dropdown-picker": "^5.4.6", "react-native-dropdown-picker": "^5.4.6",
"react-native-fbsdk-next": "^13.4.1",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
"react-native-image-viewing": "^0.2.2", "react-native-image-viewing": "^0.2.2",
"react-native-image-zoom-viewer": "^3.0.1", "react-native-image-zoom-viewer": "^3.0.1",
@ -14505,6 +14506,24 @@
"react-native": "*" "react-native": "*"
} }
}, },
"node_modules/react-native-fbsdk-next": {
"version": "13.4.1",
"resolved": "https://registry.npmmirror.com/react-native-fbsdk-next/-/react-native-fbsdk-next-13.4.1.tgz",
"integrity": "sha512-Cto+oF0FJyvxKDjKyLKI5DgnLCeeRlXvVQb8qw0XesT1Xune1ijDWAnvt9fy6wXJ4G7K510xKkcSUsbK/KyPhg==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"peerDependencies": {
"expo": ">=47.0.0",
"react-native": ">=0.63.3"
},
"peerDependenciesMeta": {
"expo": {
"optional": true
}
}
},
"node_modules/react-native-gesture-handler": { "node_modules/react-native-gesture-handler": {
"version": "2.20.2", "version": "2.20.2",
"resolved": "https://registry.npmmirror.com/react-native-gesture-handler/-/react-native-gesture-handler-2.20.2.tgz", "resolved": "https://registry.npmmirror.com/react-native-gesture-handler/-/react-native-gesture-handler-2.20.2.tgz",

2
package.json

@ -27,6 +27,7 @@
"axios": "^1.8.4", "axios": "^1.8.4",
"events": "^3.3.0", "events": "^3.3.0",
"expo": "~52.0.41", "expo": "~52.0.41",
"expo-apple-authentication": "~7.1.3",
"expo-auth-session": "~6.0.3", "expo-auth-session": "~6.0.3",
"expo-build-properties": "~0.13.3", "expo-build-properties": "~0.13.3",
"expo-crypto": "~14.0.2", "expo-crypto": "~14.0.2",
@ -44,6 +45,7 @@
"react-i18next": "^15.4.1", "react-i18next": "^15.4.1",
"react-native": "0.76.9", "react-native": "0.76.9",
"react-native-dropdown-picker": "^5.4.6", "react-native-dropdown-picker": "^5.4.6",
"react-native-fbsdk-next": "^13.4.1",
"react-native-gesture-handler": "~2.20.2", "react-native-gesture-handler": "~2.20.2",
"react-native-image-viewing": "^0.2.2", "react-native-image-viewing": "^0.2.2",
"react-native-image-zoom-viewer": "^3.0.1", "react-native-image-zoom-viewer": "^3.0.1",

10
yarn.lock

@ -4805,6 +4805,11 @@ expect@^29.0.0, expect@^29.7.0:
jest-message-util "^29.7.0" jest-message-util "^29.7.0"
jest-util "^29.7.0" jest-util "^29.7.0"
expo-apple-authentication@~7.1.3:
version "7.1.3"
resolved "https://registry.npmmirror.com/expo-apple-authentication/-/expo-apple-authentication-7.1.3.tgz#3d4ec9fa29ff336eba9b280e7db110639ae7e020"
integrity sha512-TRaF513oDGjGx3hRiAwkMiSnKLN8BIR9Se5Gi3ttz2UUgP9y+tNHV6Ji6/oztJo9ON7zerHg2mn5Y+3B8c2vTQ==
expo-application@~6.0.2: expo-application@~6.0.2:
version "6.0.2" version "6.0.2"
resolved "https://registry.npmmirror.com/expo-application/-/expo-application-6.0.2.tgz" resolved "https://registry.npmmirror.com/expo-application/-/expo-application-6.0.2.tgz"
@ -7812,6 +7817,11 @@ react-native-dropdown-picker@^5.4.6:
resolved "https://registry.npmmirror.com/react-native-dropdown-picker/-/react-native-dropdown-picker-5.4.6.tgz" resolved "https://registry.npmmirror.com/react-native-dropdown-picker/-/react-native-dropdown-picker-5.4.6.tgz"
integrity sha512-T1XBHbE++M6aRU3wFYw3MvcOuabhWZ29RK/Ivdls2r1ZkZ62iEBZknLUPeVLMX3x6iUxj4Zgr3X2DGlEGXeHsA== integrity sha512-T1XBHbE++M6aRU3wFYw3MvcOuabhWZ29RK/Ivdls2r1ZkZ62iEBZknLUPeVLMX3x6iUxj4Zgr3X2DGlEGXeHsA==
react-native-fbsdk-next@^13.4.1:
version "13.4.1"
resolved "https://registry.npmmirror.com/react-native-fbsdk-next/-/react-native-fbsdk-next-13.4.1.tgz"
integrity sha512-Cto+oF0FJyvxKDjKyLKI5DgnLCeeRlXvVQb8qw0XesT1Xune1ijDWAnvt9fy6wXJ4G7K510xKkcSUsbK/KyPhg==
react-native-gesture-handler@~2.20.2: react-native-gesture-handler@~2.20.2:
version "2.20.2" version "2.20.2"
resolved "https://registry.npmmirror.com/react-native-gesture-handler/-/react-native-gesture-handler-2.20.2.tgz" resolved "https://registry.npmmirror.com/react-native-gesture-handler/-/react-native-gesture-handler-2.20.2.tgz"

Loading…
Cancel
Save