import { Stack, useRouter } from 'expo-router'; import React, { useEffect, useState } from 'react'; import { FlatList, ImageBackground, RefreshControl, SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import services from '../../services/api'; const TABS = [ { title: '全部', value: '' }, { title: '收入', value: 'IN' }, { title: '支出', value: 'OUT' }, ]; // Define types interface TransactionItem { itemId: string; itemDesc: string; createTime: string; type: string; money: number; } export default function WalletScreen() { const router = useRouter(); const [balance, setBalance] = useState('0.00'); const [activeTab, setActiveTab] = useState(TABS[0]); const [transactions, setTransactions] = useState([]); const [loading, setLoading] = useState(false); const [refreshing, setRefreshing] = useState(false); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const fetchWalletInfo = async () => { try { const res = await services.wallet.info('CASH'); if (res && res.balance) { setBalance(res.balance); } } catch (error) { console.error('Failed to fetch wallet info', error); } }; const fetchTransactions = async (pageNum = 1, isRefresh = false) => { if (loading) return; setLoading(true); try { const res = await services.wallet.bill(pageNum, 20, 'CASH', activeTab.value); if (res && res.records) { if (isRefresh) { setTransactions(res.records); } else { setTransactions(prev => [...prev, ...res.records]); } setHasMore(res.records.length >= 20); setPage(pageNum); } else { if (isRefresh) setTransactions([]); setHasMore(false); } } catch (error) { console.error('Failed to fetch transactions', error); } finally { setLoading(false); setRefreshing(false); } }; useEffect(() => { fetchWalletInfo(); fetchTransactions(1, true); }, [activeTab]); const onRefresh = () => { setRefreshing(true); fetchWalletInfo(); fetchTransactions(1, true); }; const loadMore = () => { if (hasMore && !loading) { fetchTransactions(page + 1); } }; const renderItem = ({ item }: { item: TransactionItem }) => ( {item.itemDesc} {item.createTime} {item.type === 'IN' ? '+' : '-'}{item.money} ); return ( {/* Info Card */} {balance} 余额 router.push('/wallet/withdraw')} > 我要提现 router.push('/wallet/recharge')} > 充值 {/* Tabs */} {TABS.map((tab, index) => ( setActiveTab(tab)} > {tab.title} ))} {/* Transaction List */} item.itemId || Math.random().toString()} contentContainerStyle={styles.listContent} refreshControl={ } onEndReached={loadMore} onEndReachedThreshold={0.5} // ListFooterComponent={loading && !refreshing ? : null} ListEmptyComponent={!loading ? 暂无记录 : null} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, infoCard: { marginHorizontal: 14, marginTop: 12, marginBottom: 15, borderRadius: 10, height: 139, backgroundColor: '#3d3f41', alignItems: 'center', justifyContent: 'center', }, balanceContainer: { alignItems: 'center', marginTop: 10, }, balanceAmount: { fontSize: 30, fontWeight: 'bold', color: '#fff', }, balanceLabel: { fontSize: 12, color: 'rgba(255,255,255,0.8)', marginTop: 2, marginBottom: 15, }, actionButtons: { flexDirection: 'row', justifyContent: 'space-around', width: '75%', }, btnWithdraw: { width: 90, height: 32, borderRadius: 16, borderWidth: 1, borderColor: '#fff', justifyContent: 'center', alignItems: 'center', }, btnWithdrawText: { color: '#fff', fontSize: 14, }, btnRecharge: { width: 90, height: 32, borderRadius: 16, backgroundColor: '#fff', justifyContent: 'center', alignItems: 'center', }, btnRechargeText: { color: '#3d3f41', fontSize: 14, }, tabsContainer: { flexDirection: 'row', justifyContent: 'flex-start', paddingHorizontal: 15, marginBottom: 10, }, tabItem: { width: '32%', paddingVertical: 10, alignItems: 'center', justifyContent: 'center', }, tabText: { color: '#3d3f41', fontSize: 14, }, activeTabText: { fontWeight: 'bold', fontSize: 15, // Add underline or color change if needed, logic in Uniapp was mostly bold }, listContainer: { flex: 1, marginHorizontal: 14, marginBottom: 14, borderRadius: 10, backgroundColor: '#fff', overflow: 'hidden', }, listContent: { paddingBottom: 20, }, cell: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 18, paddingHorizontal: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, itemDesc: { fontSize: 14, fontWeight: 'bold', color: '#666666', }, itemTime: { fontSize: 10, color: '#999', marginTop: 4, }, itemAmount: { fontSize: 16, }, amountIn: { color: '#ff9600', // Uniapp color-theme }, amountOut: { color: '#666666', // Uniapp color-1 }, emptyContainer: { padding: 60, alignItems: 'center', }, emptyText: { color: '#999', }, });