From ccc797b1f7100647a77d730b0f7b700364db7fde Mon Sep 17 00:00:00 2001 From: Mac Date: Tue, 27 May 2025 01:54:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=AD=E7=89=A9=E8=BD=A6=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E8=B5=B7=E8=AE=A2=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/screens/CartScreen.tsx | 458 ++++++++++++---------- app/screens/loginList/EmailLoginModal.tsx | 7 + app/screens/loginList/PhoneLoginModal.tsx | 7 + app/screens/previewOrder/ShippingFee.tsx | 14 +- app/screens/productStatus/Status.tsx | 112 +++--- 5 files changed, 338 insertions(+), 260 deletions(-) diff --git a/app/screens/CartScreen.tsx b/app/screens/CartScreen.tsx index f5f3ec9..b92e969 100644 --- a/app/screens/CartScreen.tsx +++ b/app/screens/CartScreen.tsx @@ -490,6 +490,22 @@ export const CartScreen = () => { return; } + // 检查每个商品组的最小起订量 + for (const item of cartList) { + // 检查该商品组是否有选中的SKU + const hasSelectedSku = item.skus.some(sku => sku.selected === 1); + if (hasSelectedSku) { + const currentGroupTotal = calculateProductGroupTotalQuantity(item.cart_id); + if (currentGroupTotal < item.min_order_quantity) { + Alert.alert( + t("cart.notice"), + `${getSubjectTransLanguage(item)} ${t("cart.min_order")}${item.min_order_quantity}${t("cart.pieces")},${t("cart.current_quantity", "当前数量")}${currentGroupTotal}${t("cart.pieces")}` + ); + return; + } + } + } + // 检查最低订单金额 if (country_code !== 225) { // 只有当 country_code 不是 255 时才进行最低订单金额检查 @@ -578,6 +594,14 @@ export const CartScreen = () => { setMinQuantityModalVisible(true); }; + // 计算同一商品组的总数量 + const calculateProductGroupTotalQuantity = (cartId: number) => { + const product = cartList.find(item => item.cart_id === cartId); + if (!product) return 0; + + return product.skus.reduce((total, sku) => total + sku.quantity, 0); + }; + // 处理减少数量 const handleDecreaseQuantity = ( cartId: number, @@ -590,7 +614,11 @@ export const CartScreen = () => { return; } - if (currentQuantity > minOrderQuantity) { + // 计算减少1个数量后,该商品组的总数量 + const currentGroupTotal = calculateProductGroupTotalQuantity(cartId); + const newGroupTotal = currentGroupTotal - 1; + + if (newGroupTotal >= minOrderQuantity) { updateQuantity(cartId, cartItemId, currentQuantity - 1); } else { showMinQuantityModal(`${t("cart.notice")}:${t("cart.min_order")}${minOrderQuantity}${t("cart.pieces")}`); @@ -625,9 +653,16 @@ export const CartScreen = () => { } const { cartId, cartItemId } = editingItem; - const minOrderQuantity = cartList.find(item => item.cart_id === cartId)?.min_order_quantity || 1; + const product = cartList.find(item => item.cart_id === cartId); + const minOrderQuantity = product?.min_order_quantity || 1; + + // 计算修改数量后,该商品组的总数量 + const currentGroupTotal = calculateProductGroupTotalQuantity(cartId); + const currentSkuQuantity = product?.skus.find(sku => sku.cart_item_id === cartItemId)?.quantity || 0; + const quantityDifference = newQuantity - currentSkuQuantity; + const newGroupTotal = currentGroupTotal + quantityDifference; - if (newQuantity < minOrderQuantity) { + if (newGroupTotal < minOrderQuantity) { showMinQuantityModal(`${t("cart.notice")}:${t("cart.min_order")}${minOrderQuantity}${t("cart.pieces")}`); } else { updateQuantity(cartId, cartItemId, newQuantity); @@ -683,225 +718,231 @@ export const CartScreen = () => { {/* Panier (5) */} {cartList.map((item, index1) => ( - - - - - toggleSelection(String(item.cart_id), index1, null) - } - disabled={!user_id} - > - - {item.selected === 1 ? ( - - ) : ( - - )} - - - - - - - {getSubjectTransLanguage(item)} - - - {t("cart.min_order")}: {item.min_order_quantity} - {t("cart.pieces")} - - - - {item.skus.map((sku, index) => { - return ( - ( - handleDeleteSku( - item.cart_id, - sku.cart_item_id, - item.cart_id - )} - disabled={!user_id} - > - - {t("cart.delete")} - - - )} - > + + + + { - if (user_id) { - navigation.navigate("ProductDetail", { - offer_id: item.offer_id, - searchKeyword: item.subject, - price: sku.price, - }); - } - } } - style={[ - styles.productCardContainer5, - styles.productCardContainer4, - ]} + onPress={() => + toggleSelection(String(item.cart_id), index1, null) + } + disabled={!user_id} > - + + {item.selected === 1 ? ( + + ) : ( + + )} + + + + + + + {getSubjectTransLanguage(item)} + + + {t("cart.min_order")}: {calculateProductGroupTotalQuantity(item.cart_id)}/{item.min_order_quantity} + {t("cart.pieces")} + + + + {item.skus.map((sku, index) => { + return ( + ( user_id && toggleSelection( - String(sku.cart_item_id), - index1, - index + style={{ + backgroundColor: "#ff5217", + justifyContent: "center", + alignItems: "center", + width: 80, + }} + onPress={() => handleDeleteSku( + item.cart_id, + sku.cart_item_id, + item.cart_id )} disabled={!user_id} > - - {sku.selected === 1 ? ( - - ) : ( - - )} - {/* */} - + + {t("cart.delete")} + - - - - {/* 1. SKU attributes at the top */} - {sku.attributes[0]?.value && ( - - - {getAttributeTransLanguage(sku.attributes[0])}{" "} - {sku.attributes[1] ? "/" : ""}{" "} - {sku.attributes[1] ? getAttributeTransLanguage(sku.attributes[1]) : ""} - - - )} + )} + > + { + if (user_id) { + navigation.navigate("ProductDetail", { + offer_id: item.offer_id, + searchKeyword: item.subject, + price: sku.price, + }); + } + } } + style={[ + styles.productCardContainer5, + styles.productCardContainer4, + ]} + > + + user_id && toggleSelection( + String(sku.cart_item_id), + index1, + index + )} + disabled={!user_id} + > + + {sku.selected === 1 ? ( + + ) : ( + + )} + {/* */} + + + + + + {/* 1. SKU attributes at the top */} + {sku.attributes[0]?.value && ( + + + {getAttributeTransLanguage(sku.attributes[0])}{" "} + {sku.attributes[1] ? "/" : ""}{" "} + {sku.attributes[1] ? getAttributeTransLanguage(sku.attributes[1]) : ""} + + + )} - {/* 2. Price section - discount and actual price close together */} - - - {/* Discount price */} - - - - {sku.original_price} {sku.currency} - + {/* 2. Price section - discount and actual price close together */} + + + {/* Discount price */} + + + + {sku.original_price} {sku.currency} + + + + + + -{((1 - vip_discount) * 100).toFixed(0)}% + + - - - - -{((1 - vip_discount) * 100).toFixed(0)}% + + {/* Actual price - right below discount price */} + + + {sku.price} + + + {sku.currency} - {/* Actual price - right below discount price */} - - - {sku.price} - - - {sku.currency} - - - - - {/* 3. Quantity controls on the right */} - - user_id && handleDecreaseQuantity( - item.cart_id, - sku.cart_item_id, - sku.quantity, - item.min_order_quantity - )} - disabled={!user_id} - > - + user_id && handleDecreaseQuantity( + item.cart_id, + sku.cart_item_id, + sku.quantity, + item.min_order_quantity + )} + disabled={!user_id} > - - - - - user_id && handleQuantityPress( - item.cart_id, - sku.cart_item_id, - sku.quantity - )} - disabled={!user_id} - > - - {sku.quantity} - - - user_id && handleIncreaseQuantity( - item.cart_id, - sku.cart_item_id, - sku.quantity - )} - disabled={!user_id} - > - + - + + + user_id && handleQuantityPress( + item.cart_id, + sku.cart_item_id, + sku.quantity + )} + disabled={!user_id} > - + - - + + {sku.quantity} + + + user_id && handleIncreaseQuantity( + item.cart_id, + sku.cart_item_id, + sku.quantity + )} + disabled={!user_id} + > + + + + + + - - - - ); - })} + + + ); + })} + + {/* 商品组分隔线 */} + {index1 < cartList.length - 1 && ( + + )} ))} @@ -924,7 +965,7 @@ export const CartScreen = () => { {t("cart.min_order_quantity")} {convertedMinAmount !== null - ? `${convertedMinAmount.toFixed(2)} ${currency}` + ? `${(convertedMinAmount as number).toFixed(2)} ${currency}` : "50,000FCFA" } @@ -1890,4 +1931,9 @@ const styles = StyleSheet.create({ fontSize: fontSize(16), fontWeight: '600', }, + productGroupDivider: { + height: 5, + backgroundColor: '#f0f0f0', + width: '100%', + }, }); diff --git a/app/screens/loginList/EmailLoginModal.tsx b/app/screens/loginList/EmailLoginModal.tsx index 3a1e5f0..712309d 100644 --- a/app/screens/loginList/EmailLoginModal.tsx +++ b/app/screens/loginList/EmailLoginModal.tsx @@ -25,6 +25,7 @@ import type { NativeStackNavigationProp } from "@react-navigation/native-stack"; import { ForgotEmailPassword } from "./ForgotEmailPassword"; import BackIcon from "../../components/BackIcon"; import fontSize from "../../utils/fontsizeUtils"; +import { changeLanguage } from "../../i18n"; // Common email domains list const EMAIL_DOMAINS = [ @@ -183,6 +184,12 @@ const EmailLoginModal = ({ visible, onClose }: EmailLoginModalProps) => { const data = await settingApi.postFirstLogin(221); setSettings(data); const user = await userApi.getProfile(); + + // 根据用户的语言设置切换i18n语言 + if (user.language) { + await changeLanguage(user.language); + } + setUser(user); setLoading(false); navigation.navigate("MainTabs", { screen: "Home" }); diff --git a/app/screens/loginList/PhoneLoginModal.tsx b/app/screens/loginList/PhoneLoginModal.tsx index 1ea2e1c..7803231 100644 --- a/app/screens/loginList/PhoneLoginModal.tsx +++ b/app/screens/loginList/PhoneLoginModal.tsx @@ -29,6 +29,7 @@ import {ForgotPhonePassword} from "./ForgotPhonePassword"; import useBurialPointStore from "../../store/burialPoint"; import {getBurialPointData} from "../../store/burialPoint"; import fontSize from "../../utils/fontsizeUtils"; +import { changeLanguage } from "../../i18n"; type RootStackParamList = { Login: undefined; @@ -238,6 +239,12 @@ const PhoneLoginModal = ({ visible, onClose }: PhoneLoginModalProps) => { const data = await settingApi.postFirstLogin(selectedCountry?.country || 221); setSettings(data); const user = await userApi.getProfile(); + + // 根据用户的语言设置切换i18n语言 + if (user.language) { + await changeLanguage(user.language); + } + setUser(user); setLoading(false); navigation.replace("MainTabs", { screen: "Home" }); diff --git a/app/screens/previewOrder/ShippingFee.tsx b/app/screens/previewOrder/ShippingFee.tsx index e8ecf2a..3021389 100644 --- a/app/screens/previewOrder/ShippingFee.tsx +++ b/app/screens/previewOrder/ShippingFee.tsx @@ -30,6 +30,8 @@ import useUserStore from "../../store/user"; import useBurialPointStore from "../../store/burialPoint"; import { getBurialPointData } from "../../store/burialPoint"; import { useTranslation } from "react-i18next"; +import { getCurrentLanguage } from '../../i18n'; + type RootStackParamList = { ShippingFee: undefined; @@ -95,7 +97,7 @@ export const ShippingFee = () => { state.freightForwarderAddress.other_addresses.length > 0 ) { const firstItem = state.freightForwarderAddress.other_addresses[0]; - const label = firstItem.country + "|" + firstItem.city; + const label = (getCurrentLanguage() === 'fr' ? firstItem.country_name : firstItem.country_name_en) + " | " + firstItem.city; setWarehouse(label); setSelectedWarehouseLabel(label); setCountryCode(firstItem.country_code); @@ -138,7 +140,7 @@ export const ShippingFee = () => { const changeCountryHandel = async (value: string) => { if (value && freightForwarderAddress?.other_addresses) { const selectedWarehouse = freightForwarderAddress.other_addresses.find( - (item) => item.country + "|" + item.city === value + (item) => getCurrentLanguage() === 'fr' ? item.country_name : item.country_name_en+ " | " + item.city === value ); setSelectedWarehouse(selectedWarehouse); @@ -335,21 +337,21 @@ export const ShippingFee = () => { style={[ styles.optionItem, warehouse === - item.country + "|" + item.city && + (getCurrentLanguage() === 'fr' ? item.country_name : item.country_name_en+ " | " + item.city) && styles.selectedOption, ]} onPress={() => handleSelectWarehouse( item.country_code, - item.country + "|" + item.city + (getCurrentLanguage() === 'fr' ? item.country_name : item.country_name_en) + " | " + item.city ) } > - {item.country + "|" + item.city} + {(getCurrentLanguage() === 'fr' ? item.country_name : item.country_name_en) + " | " + item.city} {warehouse === - item.country + "|" + item.city && ( + (getCurrentLanguage() === 'fr' ? item.country_name : item.country_name_en) + " | " + item.city && ( )} diff --git a/app/screens/productStatus/Status.tsx b/app/screens/productStatus/Status.tsx index b552521..7546a30 100644 --- a/app/screens/productStatus/Status.tsx +++ b/app/screens/productStatus/Status.tsx @@ -224,56 +224,64 @@ export function Status() { }} > {orders?.items.map((item, index) => ( - - - - {item.order_id} - - - {getStatus(item.status)} - - - - {item.items.map((item, index) => ( - - - - - - - {getOrderTransLanguage(item) || item.product_name_fr} + + + + + + {item.order_id} + + + {getStatus(item.status)} + + + + {item.items.map((item, index) => ( + + + + + + + {getOrderTransLanguage(item) || item.product_name_fr} + + {item.sku_attributes?.map((attr, index) => ( + + {attr.attribute_name}:{attr.attribute_value} + + ))} + + + ))} + + + + {t("order.total_price")}: + + {item.actual_amount} {item?.currency} - {item.sku_attributes?.map((attr, index) => ( - - {attr.attribute_name}:{attr.attribute_value} - - ))} + handleOrderDetailsPress(item.order_id)} + > + + {t("order.view_details")} + + - ))} - - - - {t("order.total_price")}: - - {item.actual_amount} {item?.currency} - - handleOrderDetailsPress(item.order_id)} - > - - {t("order.view_details")} - - + {/* 订单分隔线 */} + {index < orders.items.length - 1 && ( + + )} ))} {loading && page > 1 && ( @@ -348,14 +356,17 @@ const styles = StyleSheet.create({ color: "#f77f3a", }, orderContent: { - padding: 20, flex: 1, + paddingTop: 20, }, - orderItem: { - width: "100%", + orderItemContainer: { backgroundColor: "white", borderRadius: 10, marginBottom: 10, + marginHorizontal: 20, + }, + orderItem: { + width: "100%", }, orderStatus: { width: "100%", @@ -445,4 +456,9 @@ const styles = StyleSheet.create({ paddingVertical: 10, alignItems: "center", }, + orderDivider: { + height: 5, + backgroundColor: "#f0f0f0", + width: "100%", + }, });