|
|
@@ -1,7 +1,7 @@
|
|
|
import { Image } from 'expo-image';
|
|
|
import { useRouter } from 'expo-router';
|
|
|
import React from 'react';
|
|
|
-import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
+import { ImageBackground, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
|
|
|
import { Images } from '@/constants/images';
|
|
|
|
|
|
@@ -28,22 +28,22 @@ interface ProductListProps {
|
|
|
}
|
|
|
|
|
|
// 等级配置 - 对应小程序的 LEVEL_MAP
|
|
|
-const LEVEL_CONFIG: Record<string, { title: string; color: string; bgColor: string }> = {
|
|
|
- A: { title: '超神款', color: '#fff', bgColor: '#FF4444' },
|
|
|
- B: { title: '欧皇款', color: '#fff', bgColor: '#FF9900' },
|
|
|
- C: { title: '隐藏款', color: '#fff', bgColor: '#9966FF' },
|
|
|
- D: { title: '普通款', color: '#fff', bgColor: '#00CCFF' },
|
|
|
+const LEVEL_CONFIG: Record<string, { title: string; color: string; bgColor: string; productItem: string }> = {
|
|
|
+ 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) => {
|
|
|
- // 将小数转换为百分比,保留两位小数
|
|
|
- const percent = val * 100;
|
|
|
- // 如果是整数则不显示小数点
|
|
|
- if (percent === Math.floor(percent)) {
|
|
|
- return String(Math.floor(percent));
|
|
|
+ // 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(/\.$/, '');
|
|
|
}
|
|
|
- // 保留两位小数,去除末尾的0
|
|
|
- return percent.toFixed(2).replace(/\.?0+$/, '');
|
|
|
+ return str;
|
|
|
};
|
|
|
|
|
|
export const ProductList: React.FC<ProductListProps> = ({ products, levelList, poolId }) => {
|
|
|
@@ -68,8 +68,8 @@ export const ProductList: React.FC<ProductListProps> = ({ products, levelList, p
|
|
|
|
|
|
// 点击产品跳转到详情页
|
|
|
const handleProductPress = (item: ProductItem) => {
|
|
|
- // 找到该产品在原始列表中的索引
|
|
|
- const index = products.findIndex((p) => p.id === item.id);
|
|
|
+ // 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 },
|
|
|
@@ -101,23 +101,33 @@ export const ProductList: React.FC<ProductListProps> = ({ products, levelList, p
|
|
|
return (
|
|
|
<TouchableOpacity
|
|
|
key={item.id || index}
|
|
|
- style={styles.productItem}
|
|
|
onPress={() => handleProductPress(item)}
|
|
|
activeOpacity={0.8}
|
|
|
>
|
|
|
- {/* 商品图片 */}
|
|
|
- <View style={styles.productImageBox}>
|
|
|
- <Image
|
|
|
- source={{ uri: cover }}
|
|
|
- style={styles.productImage}
|
|
|
- contentFit="contain"
|
|
|
- />
|
|
|
- </View>
|
|
|
- {/* 等级标签 - 显示概率和等级名称 */}
|
|
|
- <View style={[styles.levelTag, { backgroundColor: config.bgColor }]}>
|
|
|
- <Text style={styles.levelTagLabel}>概率</Text>
|
|
|
- <Text style={styles.levelTagText}>{ignoreRatio0(item.probability)}%</Text>
|
|
|
- </View>
|
|
|
+ <ImageBackground
|
|
|
+ source={{ uri: Images.box.detail.levelBoxBg }}
|
|
|
+ style={styles.productItem}
|
|
|
+ resizeMode="stretch"
|
|
|
+ >
|
|
|
+ {/* 商品图片 */}
|
|
|
+ <Image
|
|
|
+ source={{ uri: cover }}
|
|
|
+ style={styles.productImage}
|
|
|
+ contentFit="contain"
|
|
|
+ />
|
|
|
+
|
|
|
+ {/* 概率标签背景 */}
|
|
|
+ <ImageBackground
|
|
|
+ source={{ uri: config.productItem }}
|
|
|
+ style={styles.levelTagBg}
|
|
|
+ resizeMode="stretch"
|
|
|
+ >
|
|
|
+ <View style={styles.levelTagContent}>
|
|
|
+ <Text style={styles.levelTagLabel}>概率:</Text>
|
|
|
+ <Text style={styles.levelTagText}>{ignoreRatio0(item.probability)}%</Text>
|
|
|
+ </View>
|
|
|
+ </ImageBackground>
|
|
|
+ </ImageBackground>
|
|
|
</TouchableOpacity>
|
|
|
);
|
|
|
})}
|
|
|
@@ -195,37 +205,33 @@ const styles = StyleSheet.create({
|
|
|
paddingHorizontal: 5,
|
|
|
},
|
|
|
productItem: {
|
|
|
- width: 90,
|
|
|
+ width: 88,
|
|
|
+ height: 110,
|
|
|
marginRight: 10,
|
|
|
alignItems: 'center',
|
|
|
},
|
|
|
- productImageBox: {
|
|
|
- width: 90,
|
|
|
- height: 90,
|
|
|
- backgroundColor: '#fff',
|
|
|
- borderRadius: 4,
|
|
|
- overflow: 'hidden',
|
|
|
- },
|
|
|
productImage: {
|
|
|
- width: 90,
|
|
|
+ width: 88,
|
|
|
height: 90,
|
|
|
},
|
|
|
- levelTag: {
|
|
|
- width: 80,
|
|
|
- height: 26,
|
|
|
- borderRadius: 2,
|
|
|
- flexDirection: 'row',
|
|
|
+ levelTagBg: {
|
|
|
+ width: 88,
|
|
|
+ height: 53,
|
|
|
+ marginTop: -18,
|
|
|
justifyContent: 'center',
|
|
|
- alignItems: 'center',
|
|
|
- marginTop: -8,
|
|
|
+ paddingTop: 12,
|
|
|
+ },
|
|
|
+ levelTagContent: {
|
|
|
+ flexDirection: 'row',
|
|
|
+ justifyContent: 'center',
|
|
|
+ alignItems: 'center',
|
|
|
},
|
|
|
levelTagLabel: {
|
|
|
- fontSize: 10,
|
|
|
- color: '#fff',
|
|
|
- marginRight: 2,
|
|
|
+ fontSize: 8,
|
|
|
+ color: '#fff',
|
|
|
},
|
|
|
levelTagText: {
|
|
|
- fontSize: 12,
|
|
|
+ fontSize: 9,
|
|
|
color: '#fff',
|
|
|
fontWeight: 'bold',
|
|
|
},
|