import { useRouter } from 'expo-router'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { ActivityIndicator, FlatList, ImageBackground, RefreshControl, StatusBar, StyleSheet, Text, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Banner } from '@/components/home/Banner'; import { GoodsCard } from '@/components/home/GoodsCard'; import { IPFilter } from '@/components/home/IPFilter'; import { QuickEntry } from '@/components/home/QuickEntry'; import { SearchBar } from '@/components/home/SearchBar'; import { Images } from '@/constants/images'; // API 服务 import { getIPList, IPItem } from '@/services/award'; import { BannerItem, getPageConfig, TabItem } from '@/services/base'; import { getGoodsList, GoodsItem, GoodsListParams } from '@/services/mall'; export default function HomeScreen() { const insets = useSafeAreaInsets(); const router = useRouter(); const [refreshing, setRefreshing] = useState(false); const [loading, setLoading] = useState(true); const [listLoading, setListLoading] = useState(false); // 数据状态 const [goods, setGoods] = useState([]); const [banners, setBanners] = useState([]); const [tabs, setTabs] = useState([]); const [ipList, setIpList] = useState([]); const [ipIndex, setIpIndex] = useState(0); // 搜索参数 const [searchParams, setSearchParams] = useState({ current: 1, size: 15, keyword: '', worksId: '', }); // 加载商品列表 const loadGoods = useCallback(async (params: GoodsListParams, append = false) => { try { if (!append) setListLoading(true); const data = await getGoodsList(params); if (append) { setGoods((prev) => [...prev, ...data]); } else { setGoods(data); } } catch (error) { console.error('加载商品失败:', error); } finally { if (!append) setListLoading(false); } }, []); // 加载 IP 列表 const loadIPList = useCallback(async () => { try { const data = await getIPList(); const allIP: IPItem = { id: '', name: '所有IP' }; setIpList([allIP, ...data.filter((item) => item !== null)]); } catch (error) { console.error('加载IP列表失败:', error); } }, []); // 加载页面配置 const loadPageConfig = useCallback(async () => { try { const bannerConfig = await getPageConfig('index_banner'); if (bannerConfig?.components?.[0]?.elements) { setBanners(bannerConfig.components[0].elements); } const iconConfig = await getPageConfig('index_icon'); if (iconConfig?.components?.[0]?.elements) { setTabs(iconConfig.components[0].elements); } } catch (error) { console.error('加载页面配置失败:', error); } }, []); // 初始化数据 const initData = useCallback(async () => { setLoading(true); await Promise.all([loadGoods(searchParams), loadIPList(), loadPageConfig()]); setLoading(false); }, []); useEffect(() => { initData(); }, []); // 下拉刷新 const onRefresh = async () => { setRefreshing(true); const newParams = { ...searchParams, current: 1 }; setSearchParams(newParams); await Promise.all([loadGoods(newParams), loadIPList(), loadPageConfig()]); setRefreshing(false); }; // 搜索 const handleSearch = async (keyword: string) => { const newParams = { ...searchParams, keyword, current: 1 }; setSearchParams(newParams); await loadGoods(newParams); }; // Banner 点击 const handleBannerPress = (item: BannerItem) => { console.log('Banner pressed:', item); }; // 功能入口点击 const handleQuickEntryPress = (item: TabItem) => { console.log('Quick entry pressed:', item); }; // IP 筛选 const handleIPSelect = (item: IPItem, index: number) => { // 立即更新 UI,不等待网络请求 setIpIndex(index); setGoods([]); // 清空列表,给予用户切换反馈 (或者可以保留旧数据直到新数据到来,取决于需求,清空通常感觉更"快"因为有反馈) // 异步加载数据 requestAnimationFrame(async () => { const newParams = { ...searchParams, worksId: item.id, current: 1 }; setSearchParams(newParams); await loadGoods(newParams); }); }; // 商品点击 const handleGoodsPress = (item: GoodsItem) => { router.push(`/product/${item.id}` as any); }; // 列表头部组件 const ListHeader = useMemo(() => { return ( <> {/* 搜索栏 */} {/* Banner 轮播 */} {banners.length > 0 && } {/* 功能入口 */} {tabs.length > 0 && } {/* IP 分类筛选 */} {ipList.length > 0 && ( )} ); }, [banners, tabs, ipList, ipIndex]); // 依赖项 const renderItem = useCallback(({ item }: { item: GoodsItem }) => { return ; }, []); const ListEmptyComponent = useMemo(() => { if (listLoading) { return ( 加载商品中... ); } if (!loading && goods.length === 0) { return ( 暂无商品 ) } return null; }, [listLoading, loading, goods.length]); if (loading) { return ( 加载中... ); } return ( item.id} ListHeaderComponent={ListHeader} numColumns={2} columnWrapperStyle={styles.columnWrapper} contentContainerStyle={{ paddingTop: insets.top + 10, paddingBottom: 20 }} showsVerticalScrollIndicator={false} refreshControl={ } ListEmptyComponent={ListEmptyComponent} onEndReachedThreshold={0.5} // onEndReached={() => { /* Implement pagination if needed */ }} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#000', }, background: { flex: 1, }, section: { paddingHorizontal: 10, }, loadingContainer: { flex: 1, backgroundColor: '#1a1a2e', justifyContent: 'center', alignItems: 'center', }, loadingListContainer: { padding: 20, alignItems: 'center', }, loadingText: { color: '#fff', marginTop: 10, fontSize: 14, }, columnWrapper: { justifyContent: 'space-between', paddingHorizontal: 10, }, emptyContainer: { padding: 50, alignItems: 'center', }, emptyText: { color: '#999', fontSize: 14, }, });