import { Image } from 'expo-image'; import { useRouter } from 'expo-router'; import React, { useEffect, useState } from 'react'; import { ActivityIndicator, Alert, ScrollView, StatusBar, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { get, post } from '@/services/http'; interface BoxItem { id: string; boxName: string; boxCover: string; } const getMyBoxes = async () => { const res = await get('/api/nestedBox/myBoxes'); return res.data; }; const openBoxes = async (boxIds: string) => { const res = await post('/api/nestedBox/openBox', { boxIds }); return res; }; export default function BoxListScreen() { const router = useRouter(); const insets = useSafeAreaInsets(); const [loading, setLoading] = useState(true); const [list, setList] = useState([]); const [selectedIds, setSelectedIds] = useState([]); const loadData = async () => { setLoading(true); try { const res = await getMyBoxes(); setList(res || []); } catch (error) { console.error('加载宝箱列表失败:', error); } setLoading(false); }; useEffect(() => { loadData(); }, []); const toggleSelect = (id: string) => { setSelectedIds(prev => prev.includes(id) ? prev.filter(i => i !== id) : [...prev, id] ); }; const selectAll = () => { if (selectedIds.length === list.length) { setSelectedIds([]); } else { setSelectedIds(list.map(item => item.id)); } }; const handleOpen = async () => { if (selectedIds.length === 0) { Alert.alert('提示', '请先选择宝箱'); return; } try { const res = await openBoxes(selectedIds.join(',')); if (res.code === 0) { Alert.alert('成功', '开启成功'); setSelectedIds([]); loadData(); } } catch (error) { console.error('开启失败:', error); } }; return ( router.back()}> 宝箱 {loading ? ( ) : ( {list.map(item => ( toggleSelect(item.id)} > {item.boxName} {selectedIds.includes(item.id) && ( )} ))} )} {selectedIds.length === list.length ? '取消全选' : '全选'} 开启宝箱 {selectedIds.length > 0 ? `(${selectedIds.length})` : ''} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#1a1a2e' }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 15, paddingBottom: 10 }, backText: { color: '#fff', fontSize: 24 }, title: { color: '#fff', fontSize: 18, fontWeight: 'bold' }, content: { flex: 1, padding: 10 }, grid: { flexDirection: 'row', flexWrap: 'wrap' }, item: { width: '33%', padding: 5, position: 'relative' }, itemSelected: { opacity: 0.7 }, itemImage: { width: '100%', aspectRatio: 1, borderRadius: 8 }, itemName: { color: '#fff', fontSize: 12, textAlign: 'center', marginTop: 5 }, checkMark: { position: 'absolute', top: 10, right: 10, backgroundColor: '#ff6600', width: 24, height: 24, borderRadius: 12, justifyContent: 'center', alignItems: 'center' }, checkText: { color: '#fff', fontSize: 14 }, footer: { flexDirection: 'row', paddingHorizontal: 15, paddingTop: 10, backgroundColor: 'rgba(0,0,0,0.8)' }, selectAllBtn: { flex: 1, backgroundColor: '#666', paddingVertical: 12, borderRadius: 8, marginRight: 10, alignItems: 'center' }, openBtn: { flex: 2, backgroundColor: '#ff6600', paddingVertical: 12, borderRadius: 8, alignItems: 'center' }, btnText: { color: '#fff', fontSize: 16, fontWeight: 'bold' }, });