import { Ionicons } from '@expo/vector-icons'; import { useRouter } from 'expo-router'; import React, { useCallback, useEffect, useState } from 'react'; import { ActivityIndicator, FlatList, Image, ImageBackground, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Images } from '@/constants/images'; import { getStore } from '@/services/award'; import event from '@/utils/event'; const StoreChooseScreen = () => { const router = useRouter(); const insets = useSafeAreaInsets(); const [list, setList] = useState([]); const [selectedIds, setSelectedIds] = useState([]); const [loading, setLoading] = useState(false); const [refreshing, setRefreshing] = useState(false); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const [tabIndex, setTabIndex] = useState(0); const tabs = [ { title: '全部', value: '' }, { title: '普通', value: 'D' }, { title: '隐藏', value: 'C' }, { title: '欧皇', value: 'B' }, { title: '超神', value: 'A' }, ]; const loadData = useCallback(async (isRefresh = false) => { if (loading) return; const curPage = isRefresh ? 1 : page; setLoading(true); console.log('Fetching store data:', curPage, tabs[tabIndex].value); try { const data = await getStore(curPage, 20, 0, tabs[tabIndex].value); console.log('Store data received:', data); let records = []; if (Array.isArray(data)) { records = data; } else if (data && data.records) { records = data.records; } console.log('Parsed records length:', records.length); if (records.length > 0) { setList(prev => (isRefresh ? records : [...prev, ...records])); setHasMore(records.length === 20); // Assuming page size is 20 setPage(curPage + 1); } else { setList(prev => (isRefresh ? [] : prev)); setHasMore(false); } } catch (err) { console.error('Fetch store error:', err); // Alert.alert('Error', '加载数据失败'); // Optional: show alert } finally { setLoading(false); setRefreshing(false); } }, [loading, page, tabIndex]); useEffect(() => { loadData(true); }, [tabIndex]); const onRefresh = () => { setRefreshing(true); loadData(true); }; const onEndReached = () => { if (hasMore && !loading) { loadData(); } }; const toggleSelect = (id: string) => { setSelectedIds(prev => prev.includes(id) ? prev.filter(i => i !== id) : [...prev, id] ); }; const handleConfirm = () => { if (selectedIds.length === 0) { router.back(); return; } const selectedGoods = list.filter(item => selectedIds.includes(item.id)); event.emit(event.keys.STORE_CHOOSE, selectedGoods); router.back(); }; const handleSelectAll = () => { if (list.length === 0) return; const allSelected = list.every(item => selectedIds.includes(item.id)); if (allSelected) { setSelectedIds([]); } else { const allIds = list.map(item => item.id); setSelectedIds(allIds); } }; const renderItem = ({ item }: { item: any }) => { const isSelected = selectedIds.includes(item.id); return ( toggleSelect(item.id)} > {item.spu.name} {item.magicAmount} 果实 {isSelected && } ); }; return ( router.back()}> 选择商品 {tabs.map((tab, index) => ( setTabIndex(index)} > {tab.title} ))} item.id.toString()} contentContainerStyle={styles.listContent} onRefresh={onRefresh} refreshing={refreshing} onEndReached={onEndReached} onEndReachedThreshold={0.5} ListEmptyComponent={ !loading ? ( 暂无商品 ) : null } ListFooterComponent={() => loading && ( )} /> 0 && selectedIds.length === list.length ? Images.mine.checkAll : Images.mine.checkAll }} style={[styles.selectAllIcon, { opacity: list.length > 0 && selectedIds.length === list.length ? 1 : 0.5 }]} resizeMode="contain" /> 确认选择 ({selectedIds.length}) ); }; const styles = StyleSheet.create({ container: { flex: 1, }, background: { flex: 1, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 15, height: 90, }, backBtn: { width: 40, height: 40, justifyContent: 'center', }, title: { fontSize: 18, fontWeight: 'bold', color: '#fff', }, placeholder: { width: 40, }, tabBar: { flexDirection: 'row', justifyContent: 'space-around', paddingVertical: 10, backgroundColor: 'rgba(0,0,0,0.3)', }, tabItem: { paddingVertical: 6, paddingHorizontal: 12, borderRadius: 15, }, tabItemActive: { backgroundColor: 'rgba(248, 214, 104, 0.2)', }, tabText: { color: '#ccc', fontSize: 14, }, tabTextActive: { color: '#F8D668', fontWeight: 'bold', }, listContent: { padding: 15, paddingBottom: 100, }, card: { flexDirection: 'row', backgroundColor: '#fff', borderRadius: 8, padding: 10, marginBottom: 12, alignItems: 'center', position: 'relative', }, goodsImg: { width: 80, height: 80, borderRadius: 4, }, info: { flex: 1, marginLeft: 12, height: 80, justifyContent: 'space-around', }, goodsName: { fontSize: 14, color: '#333', fontWeight: 'bold', }, tagRow: { flexDirection: 'row', alignItems: 'center', }, magicText: { color: '#666', fontSize: 12, }, checkbox: { width: 20, height: 20, borderRadius: 10, borderWidth: 1, borderColor: '#ddd', justifyContent: 'center', alignItems: 'center', position: 'absolute', right: 10, top: 10, }, checkboxSelected: { backgroundColor: '#F8D668', borderColor: '#F8D668', }, footer: { position: 'absolute', bottom: 0, left: 0, right: 0, alignItems: 'center', paddingTop: 10, backgroundColor: 'rgba(0,0,0,0.5)', }, submitBtn: { width: 240, height: 60, }, submitBtnBg: { width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center', }, submitBtnText: { fontSize: 15, fontWeight: '800', color: '#fff', }, emptyContainer: { alignItems: 'center', paddingTop: 100, }, emptyText: { color: '#999', fontSize: 14, }, selectAllBtn: { position: 'absolute', top: -50, right: 20, flexDirection: 'row', alignItems: 'center', }, selectAllIcon: { width: 30, height: 30, marginRight: 5, }, selectAllText: { color: '#fff', fontSize: 14, fontWeight: 'bold', }, }); export default StoreChooseScreen;