import { Image } from 'expo-image'; import { useRouter } from 'expo-router'; import React from 'react'; import { ImageBackground, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { Images } from '@/constants/images'; interface ProductItem { id: string; name: string; cover: string; level: string; probability: number; price?: number; quantity?: number; spu?: { id: string; cover: string; name: string; }; } interface ProductListProps { products: ProductItem[]; levelList?: any[]; poolId: string; price: number; } // 等级配置 - 对应小程序的 LEVEL_MAP const LEVEL_CONFIG: Record = { A: { title: '超神款', color: '#fff', bgColor: '#FF4444', productItem: Images.box.detail.productItemA }, B: { title: '欧皇款', color: '#fff', bgColor: '#FF9900', productItem: Images.box.detail.productItemB }, C: { title: '隐藏款', color: '#fff', bgColor: '#9966FF', productItem: Images.box.detail.productItemC }, D: { title: '普通款', color: '#fff', bgColor: '#00CCFF', productItem: Images.box.detail.productItemD }, }; const ignoreRatio0 = (val: number) => { // Revert to original logic: Do NOT multiply. Assume API sends WYSIWYG value (e.g. 99.05 or 0.001) // Just format string to remove trailing zeros. let str = String(val); // Match original logic: strip trailing zeros if decimal if (str.indexOf('.') > -1) { str = str.replace(/0+$/, '').replace(/\.$/, ''); } return str; }; export const ProductList: React.FC = ({ products, levelList, poolId }) => { const router = useRouter(); // 按等级分组 const groupedProducts = products.reduce( (acc, item) => { const level = item.level || 'D'; if (!acc[level]) acc[level] = []; acc[level].push(item); return acc; }, {} as Record ); // 计算各等级概率 const getLevelProbability = (level: string) => { const item = levelList?.find((e) => e.level === level); return item ? `${item.probability}%` : '0%'; }; // 点击产品跳转到详情页 const handleProductPress = (item: ProductItem) => { // Look up by object reference to handle duplicate IDs correctly const index = products.indexOf(item); router.push({ pathname: '/award-detail/swipe' as any, params: { poolId, index: index >= 0 ? index : 0 }, }); }; const renderLevelSection = (level: string, items: ProductItem[]) => { const config = LEVEL_CONFIG[level] || LEVEL_CONFIG['D']; return ( {/* 等级标题行 */} {config.title} 概率: {getLevelProbability(level)} {/* 商品横向滚动列表 */} {items.map((item, index) => { const cover = item.spu?.cover || item.cover; return ( handleProductPress(item)} activeOpacity={0.8} > {/* 商品图片 */} {/* 概率标签背景 */} 概率: {ignoreRatio0(item.probability)}% ); })} ); }; const levelOrder = ['A', 'B', 'C', 'D']; return ( {/* 标题 */} {levelOrder.map((level) => { const items = groupedProducts[level]; if (!items || items.length === 0) return null; return renderLevelSection(level, items); })} ); }; const styles = StyleSheet.create({ container: { paddingHorizontal: 10, marginTop: -40, }, titleBox: { alignItems: 'center', marginBottom: 15, }, titleImg: { width: 121, height: 29, }, levelBox: { marginBottom: 20, }, levelTitleRow: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingHorizontal: 14, paddingBottom: 10, position: 'relative', }, levelTitle: { fontSize: 18, fontWeight: 'bold', textAlign: 'center', textShadowColor: '#000', textShadowOffset: { width: 1, height: 1 }, textShadowRadius: 1, }, levelProportion: { position: 'absolute', right: 0, bottom: 10, flexDirection: 'row', alignItems: 'center', }, probabilityLabel: { fontSize: 12, color: '#ffc901', }, probabilityValue: { fontSize: 12, color: '#fff', }, scrollContent: { paddingHorizontal: 5, }, productItem: { width: 88, height: 110, marginRight: 10, alignItems: 'center', }, productImage: { width: 88, height: 90, }, levelTagBg: { width: 88, height: 53, marginTop: -18, justifyContent: 'center', paddingTop: 12, }, levelTagContent: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', }, levelTagLabel: { fontSize: 8, color: '#fff', }, levelTagText: { fontSize: 9, color: '#fff', fontWeight: 'bold', }, });