import React, { useEffect } from "react"; import { View, Text, Image, StyleSheet, TouchableOpacity, ScrollView, } from "react-native"; import widthUtils from "../utils/widthUtils"; import fontSize from "../utils/fontsizeUtils"; import CloseIcon from "../components/CloseIcon"; import { ProductDetailParams, ProductGroupList, SkuAttribute, Sku, } from "../services/api/productApi"; import { cartApi } from "../services/api/cart"; import { useState } from "react"; interface ProductCardProps { onClose: () => void; product: ProductDetailParams; groupList: ProductGroupList[]; } const ProductCard: React.FC = ({ onClose, product: localProduct, groupList: localGroupList, }: { onClose: () => void; product: ProductDetailParams; groupList: ProductGroupList[]; }) => { const [groupList, setGroupList] = useState(localGroupList); const [product, setProduct] = useState(localProduct); const [imgTitle, setImgTitle] = useState(""); const [sizeList, setSizeList] = useState([]); const [sizeTitle, setSizeTitle] = useState(""); const [size, setSize] = useState(""); const [hasImg, setHasImg] = useState(); const [noImgList, setNoImgList] = useState([]); const [price, setPrice] = useState(0); const [selectedSize, setSelectedSize] = useState(0); const [totalPrice, setTotalPrice] = useState(0); const [flag, setFlag] = useState(false); useEffect(() => { setPrice(product.price as number); const imageItem = groupList.filter((item) => item.has_image); if (imageItem.length > 0) { setSizeTitle(imageItem[imageItem.length - 1].attribute_name); imageItem.forEach((item) => { const colorItem = item.attributes.filter( (attribute) => attribute.has_color ); if (colorItem.length > 0) { setImgTitle(colorItem[0].sku_image_url); } }); setFlag(true); } else { setFlag(false); } if (imageItem.length === 0) { setImgTitle(product.product_image_urls[0]); } const sizeItem = groupList.filter((item) => !item.has_image); if (sizeItem.length > 0) { setSizeTitle(sizeItem[sizeItem.length - 1].attribute_name); } const noImg = groupList .find((item) => !item.has_image) ?.attributes.find((item) => item.has_color); setSize(noImg?.value ?? ""); const shotData = groupList.sort((a, b) => (a.has_image ? -1 : 1)); if (shotData.length > 1) { const hasImg = shotData[0]; if (hasImg) { // 创建一个深拷贝,避免修改原始数据 const processedImg = { ...hasImg }; processedImg.attributes = hasImg.attributes.map((attr) => ({ ...attr, list: [], })); // 处理每个属性,添加匹配的SKU到list processedImg.attributes.forEach((attribute) => { product.skus.forEach((sku) => { // 检查SKU是否包含当前属性值 const matchedAttr = sku.attributes.find( (attr) => attr.value === attribute.value ); if (matchedAttr) { // 创建SKU的复制,不修改原始SKU const skuCopy = { ...sku }; // 过滤属性,创建新的属性数组而不是修改原始数组 skuCopy.attributes = sku.attributes .filter((attr) => attr.value !== attribute.value) .map((attr) => ({ ...attr })); // 复制每个属性对象 // 将处理后的SKU添加到list attribute.list.push(skuCopy); } }); }); setHasImg(processedImg); } else { setHasImg(groupList[0]); } } else { setNoImgList(product.skus); } const img = groupList .find((item) => item.has_image) ?.attributes.find((item) => item.has_color); setSize(img?.value ?? ""); // 找到有图片的属性组 }, [groupList, product]); // 添加依赖,确保数据变化时重新处理 const handleColorSelect = (colorId: string, index: number) => { if (!hasImg) return; // setPrice(price ?? 0); // 创建attributes的深拷贝 const newAttributes = hasImg.attributes.map((attr, i) => { if (i === index) { // 当前选中项设为true return { ...attr, has_color: true }; } else { // 其他项设为false return { ...attr, has_color: false }; } }); const price = newAttributes[index].list[0].offer_price; setPrice( price ?? product.sale_info.price_range_list[ product.sale_info.price_range_list.length - 1 ].price ); // 更新hasImg状态 setHasImg({ ...hasImg, attributes: newAttributes, }); }; const handleSizeSelect = (value: string, type: string, index: number) => { if (!hasImg) return; const data = hasImg.attributes.find((item) => item.has_color); if (data) { // 创建hasImg的深拷贝 const newHasImg = { ...hasImg }; // 找到有颜色的属性索引 const colorIndex = newHasImg.attributes.findIndex( (item) => item.has_color ); if (colorIndex !== -1) { // 创建属性数组的深拷贝 newHasImg.attributes = [...newHasImg.attributes]; // 创建特定属性的深拷贝 newHasImg.attributes[colorIndex] = { ...newHasImg.attributes[colorIndex], }; // 创建list数组的深拷贝 newHasImg.attributes[colorIndex].list = [ ...(newHasImg.attributes[colorIndex].list || []), ]; // 创建特定list项的深拷贝 if (index < newHasImg.attributes[colorIndex].list.length) { newHasImg.attributes[colorIndex].list[index] = { ...newHasImg.attributes[colorIndex].list[index], }; // 修改size值 if (type === "+") { newHasImg.attributes[colorIndex].size = (newHasImg.attributes[colorIndex].size ?? 0) + 1; newHasImg.attributes[colorIndex].list[index].size = (newHasImg.attributes[colorIndex].list[index].size ?? 0) + 1; } else { newHasImg.attributes[colorIndex].size = (newHasImg.attributes[colorIndex].size ?? 0) - 1; newHasImg.attributes[colorIndex].list[index].size = (newHasImg.attributes[colorIndex].list[index].size ?? 0) - 1; if (newHasImg.attributes[colorIndex].list[index].size < 0) { newHasImg.attributes[colorIndex].list[index].size = 0; } if (newHasImg.attributes[colorIndex].size < 0) { newHasImg.attributes[colorIndex].size = 0; } } // 更新hasImg状态 setHasImg(newHasImg); calculateTotalSize(newHasImg); } } } }; // 无图片的加减 const handleNoImgSizeSelect = ( value: string, type: string, index: number ) => { if (!noImgList) return; console.log(noImgList); if (type === "+") { noImgList[index].size = (noImgList[index].size ?? 0) + 1; } else { noImgList[index].size = (noImgList[index].size ?? 0) - 1; } if (noImgList[index].size < 0) { noImgList[index].size = 0; } setNoImgList([...noImgList]); let total = 0; let priceSum = 0; console.log(product); noImgList.forEach((item) => { console.log(item.size); console.log(item.offer_price); total += item.size ?? 0; priceSum += (item.offer_price ?? product.sale_info.price_range_list[ product.sale_info.price_range_list.length - 1 ].price) * (item.size ?? 0); }); setSelectedSize(total); setTotalPrice(priceSum); }; // 计算所有size的总和 const calculateTotalSize = (hasImgData: ProductGroupList | undefined) => { if (!hasImgData) return; let total = 0; let priceSum = 0; hasImgData.attributes.forEach((attr) => { attr.list?.forEach((item) => { const itemSize = item.size ?? 0; total += itemSize; priceSum += (item.offer_price ?? product.sale_info.price_range_list[ product.sale_info.price_range_list.length - 1 ].price) * itemSize; }); }); setSelectedSize(total); setTotalPrice(priceSum); }; // 加入购物车 const addCartHandel = () => { if (groupList.length > 1) { const selectedSku = hasImg?.attributes.filter((item) => (item.size ?? 0) > 0) || []; const skus: { sku_id: number; quantity: number }[] = []; selectedSku.forEach((item) => { item.list.forEach((item) => { if ((item.size ?? 0) > 0) { skus.push({ sku_id: item.sku_id, quantity: item.size as number, }); } }); }); const data = { offer_id: product.offer_id, skus, }; cartApi(data).then((res) => { console.log(res); }); } else if (groupList.length === 1) { const selectedSku = noImgList.filter((item) => (item.size ?? 0) > 0) || []; const skus: { sku_id: number; quantity: number }[] = []; selectedSku.forEach((item) => { skus.push({ sku_id: item.sku_id, quantity: item.size as number, }); }); const data = { offer_id: product.offer_id, skus, }; cartApi(data).then((res) => { console.log(res); }); } }; return ( {/* SVG commented out as requested */} {/* */} {price} FCFA -5% {/* SVG commented out as requested */} {/* */} VIP 3072 FCFA ≥2 Pièces 2500 FCFA ≥50 Pièces 2099 FCFA ≥100 Pièces {hasImg && groupList.length > 1 && hasImg.has_image && ( {hasImg?.attribute_name}: {size} {hasImg.attributes.map((attribute, index1) => ( handleColorSelect(attribute.value, index1) } > {(attribute.size ?? 0) > 0 && ( x{attribute.size} )} {attribute.value} ))} {sizeTitle} {/* 显示属性列表 */} {hasImg.attributes .find((item) => item.has_color) ?.list.map((list, index1) => ( {(list?.size ?? 0) > 0 && ( x{list?.size} )} {list?.attributes[0]?.value} 库存 {list?.amount_on_sale} handleSizeSelect( list?.attributes[0]?.value, "-", index1 ) } > - {list?.size ?? 0} handleSizeSelect( list?.attributes[0]?.value, "+", index1 ) } > + ))} )} {noImgList && groupList.length === 1 && !flag && ( {sizeTitle}: {size} {/* 显示属性列表 */} {noImgList?.map((list, index1) => ( {(list?.size ?? 0) > 0 && ( x{list?.size} )} {list?.attributes[0]?.value} 库存 {list?.amount_on_sale} handleNoImgSizeSelect( list?.attributes[0]?.value, "-", index1 ) } > - {list?.size ?? 0} handleNoImgSizeSelect( list?.attributes[0]?.value, "+", index1 ) } > + ))} )} {noImgList && groupList.length === 1 && flag && ( {sizeTitle}: {size} {/* 显示属性列表 */} {noImgList?.map((list, index1) => ( {(list?.size ?? 0) > 0 && ( x{list?.size} )} {list?.attributes[0]?.value} 库存 {list?.amount_on_sale} handleNoImgSizeSelect( list?.attributes[0]?.value, "-", index1 ) } > - {list?.size ?? 0} handleNoImgSizeSelect( list?.attributes[0]?.value, "+", index1 ) } > + ))} )} 总数量:{selectedSize} Total: {totalPrice.toFixed(2)} FCFA 加入购物车 ); }; const styles = StyleSheet.create({ container: { width: "100%", backgroundColor: "white", height: "100%", }, productCardContainer3: { flexDirection: "column", alignItems: "stretch", justifyContent: "flex-start", width: "100%", paddingTop: 15, paddingRight: 19, paddingLeft: 19, height: "100%", }, pricingCard: { paddingTop: 5, paddingBottom: 5, height: "100%", }, flexRowAlignedEndFullWidth: { flexDirection: "row", alignItems: "flex-end", justifyContent: "flex-start", width: "100%", }, productCardContainer: { flexBasis: widthUtils(80, 80).width, paddingTop: 5, }, cardContainer: { width: "100%", backgroundColor: "#e0e0e0", borderRadius: 5, }, flexColumnEndAlign2: { flexDirection: "column", alignItems: "flex-end", justifyContent: "flex-start", width: "100%", height: widthUtils(80, 80).height, borderRadius: 5, }, flexColumnImg: { width: "100%", height: "100%", borderRadius: 5, }, productCardContainer2: { flexBasis: widthUtils(295, 295).width, marginLeft: 15, }, productCardContainer1: { flexDirection: "row", alignItems: "flex-end", justifyContent: "flex-start", }, priceInfoContainer1: { flexDirection: "row", alignItems: "center", justifyContent: "flex-start", }, highlightedText: { padding: 0, margin: 0, fontWeight: "700", fontSize: fontSize(30), fontFamily: "Segoe UI", color: "#ff5100", }, priceInfoContainer2: { flexDirection: "row", alignItems: "flex-start", justifyContent: "flex-start", marginLeft: 1, }, orangeHeading: { padding: 0, paddingBottom: 14, margin: 0, fontWeight: "700", fontSize: 14, fontFamily: "Segoe UI", color: "#ff5100", }, percentageChangeContainer: { flexDirection: "column", alignItems: "center", justifyContent: "flex-start", marginLeft: 14.5, }, discountPercentageTextStyle: { padding: 0, margin: 0, fontStyle: "italic", fontWeight: "900", fontSize: 11, fontFamily: "Segoe UI", color: "#4e2000", }, vipButtonContainer: { flexDirection: "row", alignItems: "center", justifyContent: "flex-start", marginLeft: 1.25, }, vipButton: { width: 55, minWidth: 55, height: 21, marginLeft: -2.5, backgroundColor: "#3b3b3b", borderWidth: 0, borderRadius: 5, borderBottomLeftRadius: 0, }, italicBoldSegoeVip: { fontStyle: "italic", fontWeight: "900", fontSize: 14, fontFamily: "Segoe UI", }, pricingCardContainer: { flexDirection: "row", gap: widthUtils(29.5, 29.5).width, alignItems: "flex-start", justifyContent: "space-between", width: "100%", paddingRight: 15, paddingBottom: 3, paddingLeft: 11, marginTop: 7, backgroundColor: "#f3f4f8", borderRadius: 5, }, priceInfoContainer: { flexDirection: "row", alignItems: "center", justifyContent: "flex-start", }, priceHighlightedText: { padding: 0, margin: 0, fontWeight: "700", fontSize: fontSize(16), fontFamily: "Segoe UI", color: "#373737", }, priceTagBold: { padding: 0, margin: 0, fontWeight: "700", fontSize: fontSize(11), fontFamily: "Segoe UI", color: "#373737", }, productPriceTier: { padding: 0, margin: 0, marginTop: -4, fontWeight: "400", fontSize: fontSize(12), fontFamily: "PingFang SC", color: "#373737", }, productDetailsContainer: { width: "100%", marginTop: 24, height: "100%", }, primaryTextHeading: { padding: 0, margin: 0, fontWeight: "600", fontSize: 16, lineHeight: 20, fontFamily: "Segoe UI", color: "black", }, colorPaletteContainer1: { marginTop: 12, }, cardContainerWithTitle: { flexDirection: "column", alignItems: "stretch", justifyContent: "flex-start", width: 90, height: 116, paddingBottom: 5, backgroundColor: "#f4f4f4", borderRadius: 5, }, cardContainerWithImage: { flexDirection: "row", alignItems: "flex-start", justifyContent: "flex-start", borderRadius: 5, width: 90, height: 90, }, imageContainer: { width: "100%", height: "100%", borderWidth: 0, resizeMode: "cover", }, profileCard: { alignSelf: "center", padding: 0, margin: 0, marginTop: 1, fontWeight: "400", fontFamily: "Segoe UI", color: "black", height: 26, textAlign: "center", width: 90, fontSize: fontSize(18), }, closeIconContainer: { position: "absolute", top: 15, right: 15, zIndex: 1, }, selectedColorImageContainer: { borderWidth: 1, borderColor: "#ff5217", }, topLeftBadge: { position: "absolute", top: -6, left: -1, width: 30, height: 16, borderRadius: 8, backgroundColor: "#ff5323", zIndex: 1, alignItems: "center", justifyContent: "center", }, topLeftBadgeText: { color: "white", fontSize: 10, fontWeight: "400", fontFamily: "Segoe UI", textAlign: "center", lineHeight: 16, }, specifications: { width: "100%", flex: 1, paddingVertical: 20, }, specificationsList: { marginTop: 10, }, specificationsItem: { paddingVertical: 5, flexDirection: "row", justifyContent: "space-between", alignItems: "center", }, sizeText: { fontSize: 16, fontWeight: "600", fontFamily: "Segoe UI", color: "black", width: "100%", }, selectedNumText: { width: 30, height: 16, backgroundColor: "#ff5217", borderRadius: 5, color: "white", textAlign: "center", fontSize: 12, fontWeight: "600", fontFamily: "Segoe UI", marginRight: 5, lineHeight: 18, }, amountText: { fontSize: 16, fontWeight: "600", fontFamily: "Segoe UI", color: "#bdbdbd", }, numberContainer: { flexDirection: "row", alignItems: "center", }, numText: { width: 40, height: 24, textAlign: "center", fontSize: 16, fontWeight: "600", fontFamily: "Segoe UI", color: "black", backgroundColor: "#f4f4f4", borderRadius: 5, lineHeight: 28, marginHorizontal: 5, }, bottomFixedContainer: { position: "absolute", bottom: 0, left: 0, width: "100%", height: 118, backgroundColor: "white", borderTopWidth: 1, borderTopColor: "#f4f4f4", elevation: 5, shadowColor: "#000", shadowOffset: { width: 0, height: -2 }, shadowOpacity: 0.1, shadowRadius: 3, paddingHorizontal: 19, paddingVertical: 15, }, bottomFixedContainer1: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingTop: 10, paddingBottom: 10, }, bottomFixedContainerText: { fontSize: 14, fontWeight: "600", fontFamily: "PingFang SC", color: "black", }, bottomFixedContainer2: { width: "100%", height: 40, backgroundColor: "#ff5217", borderRadius: 25, alignItems: "center", justifyContent: "center", }, bottomFixedContainerButtonText: { fontSize: 14, fontWeight: "600", fontFamily: "PingFang SC", color: "white", }, }); export default ProductCard;