import { Image } from 'expo-image'; import { useRouter } from 'expo-router'; import React, { useCallback, useEffect, useState } from 'react'; import { ActivityIndicator, FlatList, ImageBackground, RefreshControl, StatusBar, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Images } from '@/constants/images'; import { getFeedbackList, getPoolList, PoolItem } from '@/services/award'; const typeList = [ { label: '全部', value: '', type: 0, img: Images.box.type1, imgOn: Images.box.type1On }, { label: '高保赏', value: 'UNLIMITED', type: 2, img: Images.box.type3, imgOn: Images.box.type3On }, { label: '高爆赏', value: 'UNLIMITED', type: 1, img: Images.box.type2, imgOn: Images.box.type2On }, { label: '擂台赏', value: 'YFS_PRO', type: 7, img: Images.box.type5, imgOn: Images.box.type5On }, { label: '一番赏', value: 'YFS_PRO', type: 0, img: Images.box.type4, imgOn: Images.box.type4On }, ]; interface BarrageItem { id: string; content: string; nickname?: string; } export default function BoxScreen() { const router = useRouter(); const insets = useSafeAreaInsets(); const [keyword, setKeyword] = useState(''); const [typeIndex, setTypeIndex] = useState(0); const [priceSort, setPriceSort] = useState(0); const [list, setList] = useState([]); const [loading, setLoading] = useState(false); const [refreshing, setRefreshing] = useState(false); const [current, setCurrent] = useState(1); const [total, setTotal] = useState(0); const [hasMore, setHasMore] = useState(true); const [barrageList, setBarrageList] = useState([]); // 加载弹幕 const loadBarrage = useCallback(async () => { try { const res = await getFeedbackList(); if (res.data) { setBarrageList(res.data); } } catch (error) { console.error('加载弹幕失败:', error); } }, []); const loadData = useCallback(async (isRefresh = false) => { if (loading) return; const page = isRefresh ? 1 : current; if (!isRefresh && !hasMore) return; setLoading(true); try { const selectedType = typeList[typeIndex]; const res = await getPoolList({ current: page, size: 10, mode: selectedType.value || undefined, type: selectedType.type, keyword: keyword || undefined, priceSort: priceSort || undefined, }); if (res.success && res.data) { const newList = isRefresh ? res.data : [...list, ...res.data]; setList(newList); setTotal(res.count || 0); setCurrent(page + 1); setHasMore(newList.length < (res.count || 0)); } } catch (error) { console.error('加载奖池列表失败:', error); } setLoading(false); setRefreshing(false); }, [current, hasMore, loading, typeIndex, list, keyword, priceSort]); useEffect(() => { loadData(true); loadBarrage(); }, [typeIndex, priceSort]); // 执行搜索 const handleSearch = () => { setList([]); setCurrent(1); setHasMore(true); // 需要延迟一下让状态更新 setTimeout(() => { loadData(true); }, 100); }; const handleRefresh = () => { setRefreshing(true); loadData(true); }; const handleLoadMore = () => { if (!loading && hasMore) { loadData(false); } }; const handleTypeChange = (index: number) => { setTypeIndex(index); setList([]); setCurrent(1); setHasMore(true); }; const handlePriceSort = () => { setPriceSort((prev) => (prev + 1) % 3); }; const handleItemPress = (item: PoolItem) => { // 检查商品状态 if (item.status !== undefined && item.status !== 1) return; console.log('点击商品:', item.id, 'mode:', item.mode, 'type:', item.type); // 根据类型跳转到不同页面 - 按照小程序逻辑 if (item.type === 7) { // 擂台赏跳转到 boxInBox 页面 router.push({ pathname: '/boxInBox', params: { poolId: item.id } } as any); } else if (item.mode === 'UNLIMITED') { // 高爆赏/高保赏 router.push({ pathname: '/award-detail', params: { poolId: item.id } } as any); } else if (item.mode === 'YFS_PRO') { // 一番赏 router.push({ pathname: '/award-detail-yfs', params: { poolId: item.id } } as any); } else { // 其他商品 router.push(`/product/${item.id}` as any); } }; const renderItem = ({ item }: { item: PoolItem }) => ( handleItemPress(item)} activeOpacity={0.8} > {item.name} ¥ {item.price}起 ); const renderHeader = () => ( {/* 占位空间 - 给顶部搜索栏留出空间 */} {/* 顶部主图 - 绝对定位,叠在背景上 */} {/* 占位空间 - 主图高度 */} {/* 弹幕区域 */} {barrageList.length > 0 && ( {barrageList.slice(0, 3).map((item, index) => ( {item.content} ))} {barrageList.slice(3, 6).map((item, index) => ( {item.content} ))} )} ); // 分类筛选单独渲染 const renderTypeSection = () => ( {typeList.map((item, index) => ( handleTypeChange(index)} activeOpacity={0.7} > ))} ); const renderFooter = () => { if (!loading) return null; return ( 加载中... ); }; const renderEmpty = () => { if (loading) return null; return ( 暂无数据 ); }; return ( {/* 顶部搜索栏 */} {keyword.length > 0 && ( 搜索 )} {/* 列表 */} item.id} ListHeaderComponent={() => ( <> {renderHeader()} {renderTypeSection()} )} ListFooterComponent={renderFooter} ListEmptyComponent={renderEmpty} contentContainerStyle={styles.listContent} showsVerticalScrollIndicator={false} refreshControl={ } onEndReached={handleLoadMore} onEndReachedThreshold={0.3} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#1a1a2e', }, background: { flex: 1, }, header: { position: 'relative', zIndex: 11, flexDirection: 'row', alignItems: 'center', paddingHorizontal: 15, paddingBottom: 10, }, logo: { width: 67, height: 25, marginRight: 20, }, searchBar: { flex: 1, flexDirection: 'row', alignItems: 'center', backgroundColor: 'rgba(255,255,255,0.38)', borderRadius: 180, paddingHorizontal: 15, height: 28, }, searchIcon: { width: 15, height: 15, marginRight: 5, }, searchInput: { flex: 1, color: '#fff', fontSize: 12, padding: 0, }, searchBtn: { paddingHorizontal: 8, paddingVertical: 2, }, searchBtnText: { color: '#fff', fontSize: 12, }, mainImageContainer: { position: 'absolute', left: 0, top: 0, zIndex: 2, width: '100%', height: 395, }, mainImage: { width: '100%', height: '100%', }, typeSection: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 10, paddingVertical: 10, position: 'relative', zIndex: 10, backgroundColor: 'transparent', }, typeList: { flexDirection: 'row', justifyContent: 'flex-start', flex: 1, }, typeItem: { width: 60, height: 30, marginRight: 5, }, typeImage: { width: '100%', height: '100%', }, sortBtn: { width: 40, height: 30, alignItems: 'center', justifyContent: 'center', }, sortIcon: { width: 30, height: 30, }, listContent: { paddingHorizontal: 10, paddingBottom: 100, }, itemContainer: { marginBottom: 8, }, itemBg: { width: '100%', height: 210, padding: 8, }, itemImage: { width: '100%', height: 142, borderRadius: 0, }, itemInfo: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingHorizontal: 15, paddingTop: 15, }, itemName: { flex: 1, color: '#fff', fontSize: 14, }, itemPrice: { color: '#ff0000', fontSize: 12, fontWeight: 'bold', marginLeft: 10, }, priceUnit: { fontSize: 12, marginRight: 2, }, footer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingVertical: 15, }, footerText: { color: 'rgba(255,255,255,0.6)', fontSize: 12, marginLeft: 8, }, empty: { alignItems: 'center', paddingVertical: 50, }, emptyText: { color: 'rgba(255,255,255,0.6)', fontSize: 14, }, barrageSection: { marginVertical: 10, paddingHorizontal: 10, }, barrageRow: { flexDirection: 'row', marginBottom: 5, }, barrageItem: { backgroundColor: 'rgba(0,0,0,0.5)', borderRadius: 15, paddingHorizontal: 12, paddingVertical: 6, marginRight: 8, maxWidth: 150, }, barrageText: { color: '#fff', fontSize: 12, }, });