import { Image } from 'expo-image'; import React, { forwardRef, useImperativeHandle, useMemo, useState } from 'react'; import { Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; interface PrizeItem { id: string; name: string; cover: string; level: string; price?: number; probability?: number; } interface GoodsItem { id: string; name: string; cover: string; level: string; price?: number; probability?: number; } interface DetailsPopupProps {} export interface DetailsPopupRef { open: (item: GoodsItem, prizes: PrizeItem[]) => void; close: () => void; } export const DetailsPopup = forwardRef((_, ref) => { const [visible, setVisible] = useState(false); const [info, setInfo] = useState(null); const [prizes, setPrizes] = useState([]); // 按等级分类奖品 const { cellAList, cellBList, cellCList, cellDList, cellAprobability, cellBprobability, cellCprobability, cellDprobability } = useMemo(() => { const result = { cellAList: [] as PrizeItem[], cellBList: [] as PrizeItem[], cellCList: [] as PrizeItem[], cellDList: [] as PrizeItem[], cellAprobability: 0, cellBprobability: 0, cellCprobability: 0, cellDprobability: 0, }; prizes.forEach((item) => { switch (item.level) { case 'A': result.cellAList.push(item); result.cellAprobability += item.probability || 0; break; case 'B': result.cellBList.push(item); result.cellBprobability += item.probability || 0; break; case 'C': result.cellCList.push(item); result.cellCprobability += item.probability || 0; break; case 'D': result.cellDList.push(item); result.cellDprobability += item.probability || 0; break; } }); return result; }, [prizes]); useImperativeHandle(ref, () => ({ open: (item: GoodsItem, prizeList: PrizeItem[]) => { setInfo(item); setPrizes(prizeList); setVisible(true); }, close: () => setVisible(false), })); const isGuaranteed = info?.level === 'NESTED_BOX_GUARANTEED'; return ( setVisible(false)}> {/* 顶部标题区 */} {info?.name} {isGuaranteed ? 'D赏' : '全局赏'} {/* 主图展示区 */} 指导价: ¥ {info?.price || 0} 概率: {((info?.probability || 0) * 100).toFixed(2)}% 1~3抽完赠机送 {/* 奖品列表 - 仅非保底款显示 */} {!isGuaranteed && ( {/* A赏 */} {cellAList.length > 0 && ( A赏 概率{(cellAprobability * 100).toFixed(2)}% {cellAList.map((item, index) => ( ¥{item.price || 0} {item.name} ))} )} {/* B赏 */} {cellBList.length > 0 && ( B赏 概率{(cellBprobability * 100).toFixed(2)}% {cellBList.map((item, index) => ( ¥{item.price || 0} {item.name} ))} )} {/* C赏 */} {cellCList.length > 0 && ( C赏 概率{(cellCprobability * 100).toFixed(2)}% {cellCList.map((item, index) => ( ¥{item.price || 0} {item.name} ))} )} {/* D赏 */} {cellDList.length > 0 && ( D赏 概率{(cellDprobability * 100).toFixed(2)}% {cellDList.map((item, index) => ( ¥{item.price || 0} {item.name} ))} )} )} {/* 关闭按钮 */} setVisible(false)}> × ); }); const styles = StyleSheet.create({ overlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'center', alignItems: 'center', padding: 20, }, container: { width: '100%', maxWidth: 310, backgroundColor: '#ffb300', borderRadius: 10, overflow: 'hidden', maxHeight: '80%', }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', padding: 15, }, title: { fontSize: 18, fontWeight: 'bold', color: '#000', flex: 1, marginRight: 10, }, levelBadge: { paddingHorizontal: 12, paddingVertical: 4, borderRadius: 2, }, levelD: { backgroundColor: '#6340FF', borderWidth: 1, borderColor: '#A2BBFF', }, levelAll: { backgroundColor: '#A3E100', borderWidth: 1, borderColor: '#EAFFB1', }, levelText: { fontSize: 12, fontWeight: 'bold', color: '#fff', }, mainContent: { backgroundColor: '#fff', padding: 15, flexDirection: 'row', }, productImage: { width: 100, height: 100, borderRadius: 6, borderWidth: 2, borderColor: '#E0E0E0', overflow: 'hidden', }, image: { width: '100%', height: '100%', }, priceInfo: { flex: 1, paddingLeft: 15, justifyContent: 'center', }, priceItem: { flexDirection: 'row', alignItems: 'center', marginBottom: 8, }, label: { fontSize: 14, color: '#333', }, value: { fontSize: 14, color: '#333', fontWeight: 'bold', }, tips: { fontSize: 13, color: '#FF9500', marginTop: 4, }, prizeScroll: { maxHeight: 325, backgroundColor: '#fff', }, prizeSection: { marginTop: 15, }, sectionHeader: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 15, marginBottom: 10, }, levelTag: { paddingHorizontal: 8, paddingVertical: 3, borderRadius: 3, borderWidth: 1.5, borderColor: '#000', marginRight: 10, }, levelTagA: { backgroundColor: '#FFD700', }, levelTagB: { backgroundColor: '#FFA500', }, levelTagText: { fontSize: 14, fontWeight: 'bold', color: '#000', }, probability: { fontSize: 14, color: '#000', }, prizeList: { paddingHorizontal: 15, paddingBottom: 15, }, prizeItem: { marginRight: 10, alignItems: 'center', }, prizeImageBox: { width: 80, height: 80, borderRadius: 6, borderWidth: 2, borderColor: '#000', overflow: 'hidden', position: 'relative', }, prizeImage: { width: '100%', height: '100%', }, itemPrice: { position: 'absolute', bottom: 0, left: 0, right: 0, backgroundColor: 'rgba(0,0,0,0.5)', paddingVertical: 2, }, itemPriceText: { fontSize: 10, color: '#fff', textAlign: 'center', }, prizeName: { marginTop: 5, fontSize: 12, color: '#000', textAlign: 'center', width: 80, }, closeBtn: { position: 'absolute', right: 10, top: 10, width: 24, height: 24, justifyContent: 'center', alignItems: 'center', }, closeBtnText: { fontSize: 20, color: '#333', fontWeight: 'bold', }, });