| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import { Images } from '@/constants/images';
- import { Image, ImageBackground } from 'expo-image';
- import React from 'react';
- import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
- interface FirstLastProps {
- data: any;
- box: any;
- onPrevBox?: () => void;
- onNextBox?: () => void;
- onChangeBox?: () => void;
- onProductClick?: (product: any) => void;
- }
- export default function FirstLast({ data, box, onPrevBox, onNextBox, onChangeBox, onProductClick }: FirstLastProps) {
- // Filter for special prizes: FIRST, LAST, LASTALL
- const prizeList = React.useMemo(() => {
- if (!box || !box.prizeList) return [];
- return box.prizeList.filter((item: any) =>
- ['FIRST', 'LAST', 'LASTALL'].includes(item.level)
- );
- }, [box]);
- if (!box) return null;
- return (
- <View style={styles.container}>
- <ImageBackground
- source={{ uri: Images.box.detail.firstBoxBg }}
- style={styles.bg}
- resizeMode="stretch"
- >
- {/* Title / Remain Info */}
- <View style={styles.header}>
- <View style={styles.remainInfo}>
- <Text style={styles.remainLabel}>当前盒子剩余:</Text>
- <Text style={styles.remainValue}>
- <Text style={styles.remainNum}>{box.leftQuantity}</Text>
- /{box.quantity}发
- </Text>
- </View>
- <Image
- source={{ uri: Images.box.detail.playMethod }}
- style={styles.ruleBtn}
- contentFit="contain"
- />
- </View>
- {/* Prize List (First/Last) */}
- <View style={styles.prizeContainer}>
- {prizeList.map((item: any, index: number) => (
- <TouchableOpacity
- key={index}
- style={styles.prizeItem}
- onPress={() => onProductClick && onProductClick(item.spu)}
- >
- <ImageBackground
- source={{ uri: Images.box.detail.firstItemBg }}
- style={styles.prizeItemBg}
- resizeMode="contain"
- >
- <Image source={{ uri: item.cover }} style={styles.prizeImg} contentFit="contain" />
-
- <View style={styles.prizeLabelContainer}>
- {item.level === 'FIRST' && (
- <Text style={[styles.prizeLabel, { backgroundColor: 'rgba(91, 189, 208, .8)' }]}>抢先赏</Text>
- )}
- {item.level === 'LAST' && (
- <Text style={[styles.prizeLabel, { backgroundColor: 'rgba(246, 44, 113, .8)' }]}>最终赏</Text>
- )}
- {item.level === 'LASTALL' && (
- <Text style={[styles.prizeLabel, { backgroundColor: 'rgba(44, 246, 74, .8)' }]}>全局赏</Text>
- )}
- </View>
-
- {/* User Avatar if someone won it? Legacy logic: v-if="item.nickname" */}
- {item.nickname && (
- <View style={styles.winnerBox}>
- <Image source={{ uri: item.avatar }} style={styles.winnerAvatar} />
- <Text style={styles.winnerName} numberOfLines={1}>{item.nickname}</Text>
- </View>
- )}
- </ImageBackground>
- </TouchableOpacity>
- ))}
- </View>
- {/* Controls */}
- <ImageBackground
- source={{ uri: Images.box.detail.funBoxBg }}
- style={styles.controlsBg}
- resizeMode="stretch"
- >
- <TouchableOpacity style={styles.controlBtn} onPress={onPrevBox}>
- <Text style={styles.controlText}>上一盒</Text>
- </TouchableOpacity>
- <TouchableOpacity style={styles.changeBtn} onPress={onChangeBox}>
- <Text style={[styles.controlText, { color: '#000' }]}>
- 换盒(<Text style={{ fontWeight: 'bold' }}>{box.number}</Text>/{box.lastNumber})
- </Text>
- </TouchableOpacity>
- <TouchableOpacity style={styles.controlBtn} onPress={onNextBox}>
- <Text style={styles.controlText}>下一盒</Text>
- </TouchableOpacity>
- </ImageBackground>
- </ImageBackground>
- </View>
- );
- }
- const styles = StyleSheet.create({
- container: {
- paddingHorizontal: 10,
- marginBottom: 10,
- },
- bg: {
- width: '100%',
- height: 193, // 386rpx / 2
- alignItems: 'center',
- },
- header: {
- width: '100%',
- flexDirection: 'row',
- justifyContent: 'space-between',
- paddingHorizontal: 20,
- paddingTop: 20,
- },
- remainInfo: {
- flexDirection: 'row',
- alignItems: 'center',
- },
- remainLabel: { color: '#fff', fontSize: 12 },
- remainValue: { color: '#fff', fontSize: 12 },
- remainNum: { fontSize: 16, fontWeight: 'bold' },
- ruleBtn: { width: 41, height: 17 },
-
- prizeContainer: {
- flexDirection: 'row',
- justifyContent: 'space-around',
- width: '80%',
- marginTop: 10,
- height: 70, // Adjust based on item size
- },
- prizeItem: {
- width: 63, // 126rpx / 2
- height: 65,
- },
- prizeItemBg: {
- flex: 1,
- alignItems: 'center',
- justifyContent: 'center',
- },
- prizeImg: {
- width: 60,
- height: 60,
- },
- prizeLabelContainer: {
- position: 'absolute',
- bottom: -8,
- width: '100%',
- alignItems: 'center',
- },
- prizeLabel: {
- fontSize: 10,
- color: '#fff',
- paddingHorizontal: 4,
- paddingVertical: 1,
- borderRadius: 4,
- overflow: 'hidden',
- },
- winnerBox: {
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
- justifyContent: 'center',
- alignItems: 'center',
- backgroundColor: 'rgba(0,0,0,0.6)',
- borderRadius: 30, // Circleish
- },
- winnerAvatar: { width: 24, height: 24, borderRadius: 12, borderWidth: 1, borderColor: '#FFE996' },
- winnerName: { color: '#FEC433', fontSize: 8, marginTop: 2, maxWidth: 50 },
- controlsBg: {
- width: 270, // 540rpx / 2
- height: 38, // 76rpx / 2
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- marginTop: 25,
- },
- controlBtn: {
- width: 90,
- height: '100%',
- justifyContent: 'center',
- alignItems: 'center',
- },
- changeBtn: {
- width: 110,
- height: '100%',
- justifyContent: 'center',
- alignItems: 'center',
- },
- controlText: {
- color: '#fff',
- fontSize: 14,
- fontWeight: '500',
- }
- });
|