|
|
@ -7,6 +7,8 @@ import { |
|
|
|
TouchableOpacity, |
|
|
|
TouchableOpacity, |
|
|
|
ScrollView, |
|
|
|
ScrollView, |
|
|
|
Modal, |
|
|
|
Modal, |
|
|
|
|
|
|
|
TextInput, |
|
|
|
|
|
|
|
Alert, |
|
|
|
} from "react-native"; |
|
|
|
} from "react-native"; |
|
|
|
import BackIcon from "../components/BackIcon"; |
|
|
|
import BackIcon from "../components/BackIcon"; |
|
|
|
import fontSize from "../utils/fontsizeUtils"; |
|
|
|
import fontSize from "../utils/fontsizeUtils"; |
|
|
@ -38,6 +40,13 @@ export const CartScreen = () => { |
|
|
|
cartItemId: number; |
|
|
|
cartItemId: number; |
|
|
|
cartId1: number; |
|
|
|
cartId1: number; |
|
|
|
} | null>(null); |
|
|
|
} | null>(null); |
|
|
|
|
|
|
|
const [quantityInputVisible, setQuantityInputVisible] = useState(false); |
|
|
|
|
|
|
|
const [editingItem, setEditingItem] = useState<{ |
|
|
|
|
|
|
|
cartId: number; |
|
|
|
|
|
|
|
cartItemId: number; |
|
|
|
|
|
|
|
currentQuantity: number; |
|
|
|
|
|
|
|
} | null>(null); |
|
|
|
|
|
|
|
const [quantityInput, setQuantityInput] = useState(''); |
|
|
|
const navigation = useNavigation<NativeStackNavigationProp<any>>(); |
|
|
|
const navigation = useNavigation<NativeStackNavigationProp<any>>(); |
|
|
|
|
|
|
|
|
|
|
|
// 计算选中商品的总金额
|
|
|
|
// 计算选中商品的总金额
|
|
|
@ -338,6 +347,78 @@ export const CartScreen = () => { |
|
|
|
console.log(items); |
|
|
|
console.log(items); |
|
|
|
navigation.navigate("Recipient", { items }); |
|
|
|
navigation.navigate("Recipient", { items }); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 添加更新商品数量的方法
|
|
|
|
|
|
|
|
const updateQuantity = async (cartId: number, cartItemId: number, newQuantity: number) => { |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
// 更新本地状态
|
|
|
|
|
|
|
|
setCartList((prev) => { |
|
|
|
|
|
|
|
const newList = prev.map((item) => { |
|
|
|
|
|
|
|
if (item.cart_id === cartId) { |
|
|
|
|
|
|
|
return { |
|
|
|
|
|
|
|
...item, |
|
|
|
|
|
|
|
skus: item.skus.map((sku) => { |
|
|
|
|
|
|
|
if (sku.cart_item_id === cartItemId) { |
|
|
|
|
|
|
|
return { ...sku, quantity: newQuantity }; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return sku; |
|
|
|
|
|
|
|
}), |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return item; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
calculateTotalAmount(newList); |
|
|
|
|
|
|
|
return newList; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 调用API更新数量
|
|
|
|
|
|
|
|
await updateCartItem(cartId, { |
|
|
|
|
|
|
|
cart_item_id: cartItemId, |
|
|
|
|
|
|
|
quantity: newQuantity, |
|
|
|
|
|
|
|
selected: 1, |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
|
|
console.error("更新商品数量失败:", error); |
|
|
|
|
|
|
|
// 如果更新失败,回滚本地状态
|
|
|
|
|
|
|
|
getCart(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理减少数量
|
|
|
|
|
|
|
|
const handleDecreaseQuantity = (cartId: number, cartItemId: number, currentQuantity: number) => { |
|
|
|
|
|
|
|
if (currentQuantity > 1) { |
|
|
|
|
|
|
|
updateQuantity(cartId, cartItemId, currentQuantity - 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理增加数量
|
|
|
|
|
|
|
|
const handleIncreaseQuantity = (cartId: number, cartItemId: number, currentQuantity: number) => { |
|
|
|
|
|
|
|
updateQuantity(cartId, cartItemId, currentQuantity + 1); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理数量输入框确认
|
|
|
|
|
|
|
|
const handleQuantityInputConfirm = () => { |
|
|
|
|
|
|
|
if (!editingItem) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const newQuantity = parseInt(quantityInput); |
|
|
|
|
|
|
|
if (isNaN(newQuantity) || newQuantity < 1) { |
|
|
|
|
|
|
|
Alert.alert('提示', '请输入有效的数量'); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updateQuantity(editingItem.cartId, editingItem.cartItemId, newQuantity); |
|
|
|
|
|
|
|
setQuantityInputVisible(false); |
|
|
|
|
|
|
|
setEditingItem(null); |
|
|
|
|
|
|
|
setQuantityInput(''); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理点击数量显示
|
|
|
|
|
|
|
|
const handleQuantityPress = (cartId: number, cartItemId: number, currentQuantity: number) => { |
|
|
|
|
|
|
|
setEditingItem({ cartId, cartItemId, currentQuantity }); |
|
|
|
|
|
|
|
setQuantityInput(currentQuantity.toString()); |
|
|
|
|
|
|
|
setQuantityInputVisible(true); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return ( |
|
|
|
return ( |
|
|
|
<View style={styles.shoppingCartLayout}> |
|
|
|
<View style={styles.shoppingCartLayout}> |
|
|
|
<ScrollView |
|
|
|
<ScrollView |
|
|
@ -478,15 +559,24 @@ export const CartScreen = () => { |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
<View style={styles.orderQuantityContainer}> |
|
|
|
<View style={styles.orderQuantityContainer}> |
|
|
|
<View style={styles.svgContainer4}> |
|
|
|
<TouchableOpacity
|
|
|
|
<Text>-</Text> |
|
|
|
style={styles.svgContainer4} |
|
|
|
</View> |
|
|
|
onPress={() => handleDecreaseQuantity(item.cart_id, sku.cart_item_id, sku.quantity)} |
|
|
|
<View style={styles.quantityLabelContainer}> |
|
|
|
> |
|
|
|
<Text>{sku.quantity}</Text> |
|
|
|
<Text style={styles.quantityButtonText}>-</Text> |
|
|
|
</View> |
|
|
|
</TouchableOpacity> |
|
|
|
<View style={styles.svgContainer4}> |
|
|
|
<TouchableOpacity
|
|
|
|
<Text>+</Text> |
|
|
|
style={styles.quantityLabelContainer} |
|
|
|
</View> |
|
|
|
onPress={() => handleQuantityPress(item.cart_id, sku.cart_item_id, sku.quantity)} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<Text style={styles.quantityText}>{sku.quantity}</Text> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
|
|
|
style={styles.svgContainer4} |
|
|
|
|
|
|
|
onPress={() => handleIncreaseQuantity(item.cart_id, sku.cart_item_id, sku.quantity)} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<Text style={styles.quantityButtonText}>+</Text> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
@ -592,6 +682,46 @@ export const CartScreen = () => { |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
</Modal> |
|
|
|
</Modal> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* 数量输入弹窗 */} |
|
|
|
|
|
|
|
<Modal |
|
|
|
|
|
|
|
visible={quantityInputVisible} |
|
|
|
|
|
|
|
transparent |
|
|
|
|
|
|
|
animationType="fade" |
|
|
|
|
|
|
|
onRequestClose={() => setQuantityInputVisible(false)} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<View style={styles.overlay}> |
|
|
|
|
|
|
|
<View style={styles.popup}> |
|
|
|
|
|
|
|
<Text style={styles.promptText}>修改数量</Text> |
|
|
|
|
|
|
|
<TextInput |
|
|
|
|
|
|
|
style={styles.quantityInput} |
|
|
|
|
|
|
|
value={quantityInput} |
|
|
|
|
|
|
|
onChangeText={setQuantityInput} |
|
|
|
|
|
|
|
keyboardType="number-pad" |
|
|
|
|
|
|
|
maxLength={3} |
|
|
|
|
|
|
|
autoFocus |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
<View style={styles.buttonContainer}> |
|
|
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
|
|
|
style={[styles.cancelButton1, { width: '45%' }]} |
|
|
|
|
|
|
|
onPress={() => { |
|
|
|
|
|
|
|
setQuantityInputVisible(false); |
|
|
|
|
|
|
|
setEditingItem(null); |
|
|
|
|
|
|
|
setQuantityInput(''); |
|
|
|
|
|
|
|
}} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<Text style={styles.cancelText}>取消</Text> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
|
|
|
|
<TouchableOpacity
|
|
|
|
|
|
|
|
style={[styles.confirmButton, { width: '45%', backgroundColor: '#ff5100' }]} |
|
|
|
|
|
|
|
onPress={handleQuantityInputConfirm} |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<Text style={styles.confirmText}>确定</Text> |
|
|
|
|
|
|
|
</TouchableOpacity> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
</Modal> |
|
|
|
</View> |
|
|
|
</View> |
|
|
|
); |
|
|
|
); |
|
|
|
}; |
|
|
|
}; |
|
|
@ -1154,6 +1284,7 @@ const styles = StyleSheet.create({ |
|
|
|
paddingHorizontal: 20, |
|
|
|
paddingHorizontal: 20, |
|
|
|
alignItems: "center", |
|
|
|
alignItems: "center", |
|
|
|
gap: 21, |
|
|
|
gap: 21, |
|
|
|
|
|
|
|
width: '80%', |
|
|
|
}, |
|
|
|
}, |
|
|
|
image: { |
|
|
|
image: { |
|
|
|
width: 80, |
|
|
|
width: 80, |
|
|
@ -1170,21 +1301,24 @@ const styles = StyleSheet.create({ |
|
|
|
buttonContainer: { |
|
|
|
buttonContainer: { |
|
|
|
flexDirection: "row", |
|
|
|
flexDirection: "row", |
|
|
|
justifyContent: "center", |
|
|
|
justifyContent: "center", |
|
|
|
marginTop: 10, |
|
|
|
alignItems: "center", |
|
|
|
|
|
|
|
width: "100%", |
|
|
|
|
|
|
|
marginTop: 20, |
|
|
|
|
|
|
|
gap: 20, |
|
|
|
}, |
|
|
|
}, |
|
|
|
cancelButton1: { |
|
|
|
cancelButton1: { |
|
|
|
width: 160, |
|
|
|
minWidth: 120, |
|
|
|
height: 50, |
|
|
|
height: 50, |
|
|
|
borderRadius: 25, |
|
|
|
borderRadius: 30, |
|
|
|
backgroundColor: "#f2f3f5", |
|
|
|
backgroundColor: "#f2f3f5", |
|
|
|
justifyContent: "center", |
|
|
|
justifyContent: "center", |
|
|
|
alignItems: "center", |
|
|
|
alignItems: "center", |
|
|
|
}, |
|
|
|
}, |
|
|
|
confirmButton: { |
|
|
|
confirmButton: { |
|
|
|
width: 160, |
|
|
|
minWidth: 120, |
|
|
|
height: 50, |
|
|
|
height: 50, |
|
|
|
borderRadius: 25, |
|
|
|
borderRadius: 30, |
|
|
|
backgroundColor: "#002fa7", |
|
|
|
backgroundColor: "#ff5100", |
|
|
|
justifyContent: "center", |
|
|
|
justifyContent: "center", |
|
|
|
alignItems: "center", |
|
|
|
alignItems: "center", |
|
|
|
marginLeft: 20, |
|
|
|
marginLeft: 20, |
|
|
@ -1201,4 +1335,24 @@ const styles = StyleSheet.create({ |
|
|
|
color: "#ffffff", |
|
|
|
color: "#ffffff", |
|
|
|
fontFamily: "Source Han Sans CN", // 同上
|
|
|
|
fontFamily: "Source Han Sans CN", // 同上
|
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
quantityButtonText: { |
|
|
|
|
|
|
|
fontSize: fontSize(18), |
|
|
|
|
|
|
|
color: "#333", |
|
|
|
|
|
|
|
fontWeight: "500", |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
quantityText: { |
|
|
|
|
|
|
|
fontSize: fontSize(14), |
|
|
|
|
|
|
|
color: "#333", |
|
|
|
|
|
|
|
fontWeight: "500", |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
quantityInput: { |
|
|
|
|
|
|
|
width: '100%', |
|
|
|
|
|
|
|
height: 40, |
|
|
|
|
|
|
|
borderWidth: 1, |
|
|
|
|
|
|
|
borderColor: '#ddd', |
|
|
|
|
|
|
|
borderRadius: 5, |
|
|
|
|
|
|
|
paddingHorizontal: 10, |
|
|
|
|
|
|
|
fontSize: fontSize(16), |
|
|
|
|
|
|
|
textAlign: 'center', |
|
|
|
|
|
|
|
}, |
|
|
|
}); |
|
|
|
}); |
|
|
|