import ServiceAward from '@/services/award'; import { Ionicons } from '@expo/vector-icons'; import React, { forwardRef, useImperativeHandle, useState } from 'react'; import { ActivityIndicator, FlatList, Image, Modal, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; export interface WishMaterialModalRef { show: (callback: (selected: any[]) => void) => void; close: () => void; } export const WishMaterialModal = forwardRef((props, ref) => { const [visible, setVisible] = useState(false); const [list, setList] = useState([]); const [selectedIds, setSelectedIds] = useState([]); const [loading, setLoading] = useState(false); const [onConfirm, setOnConfirm] = useState<((selected: any[]) => void) | null>(null); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); useImperativeHandle(ref, () => ({ show: (callback) => { setVisible(true); setOnConfirm(() => callback); setPage(1); setList([]); setSelectedIds([]); loadData(1); }, close: () => setVisible(false), })); const loadData = async (curPage: number) => { setLoading(true); try { // Fetch inventory/store items const data = await ServiceAward.getStore(curPage, 20); const records = (Array.isArray(data) ? data : data?.records) || []; if (records.length > 0) { setList(prev => curPage === 1 ? records : [...prev, ...records]); setHasMore(records.length === 20); } else { setList(prev => curPage === 1 ? [] : prev); setHasMore(false); } } catch (error) { console.error(error); } finally { setLoading(false); } }; const handleLoadMore = () => { if (!loading && hasMore) { const nextPage = page + 1; setPage(nextPage); loadData(nextPage); } }; const toggleSelect = (id: string) => { // Multi-select allowed? Usually yes for materials. setSelectedIds(prev => prev.includes(id) ? prev.filter(i => i !== id) : [...prev, id] ); }; const handleConfirm = () => { const selectedGoods = list.filter(item => selectedIds.includes(item.id)); if (onConfirm) { onConfirm(selectedGoods); } setVisible(false); }; const renderItem = ({ item }: { item: any }) => { const isSelected = selectedIds.includes(item.id); return ( toggleSelect(item.id)}> {item.spu.name} 价值: {item.magicAmount} 果实 {isSelected && } ); }; if (!visible) return null; return ( setVisible(false)}> 选择添加材料 setVisible(false)} style={styles.closeBtn}> item.id} onEndReached={handleLoadMore} onEndReachedThreshold={0.3} contentContainerStyle={styles.listContent} ListFooterComponent={() => loading && } ListEmptyComponent={暂无可用商品} /> 确认添加 ({selectedIds.length}) ); }); export default WishMaterialModal; const styles = StyleSheet.create({ overlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'flex-end', }, container: { backgroundColor: '#fff', borderTopLeftRadius: 20, borderTopRightRadius: 20, height: '70%', paddingBottom: 30, }, header: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', padding: 15, borderBottomWidth: 1, borderBottomColor: '#eee', }, headerTitle: { fontSize: 18, fontWeight: 'bold', color: '#333', }, closeBtn: { position: 'absolute', right: 15, }, listContent: { padding: 15, }, item: { flexDirection: 'row', alignItems: 'center', padding: 10, marginBottom: 10, backgroundColor: '#f9f9f9', borderRadius: 8, }, itemImg: { width: 60, height: 60, borderRadius: 4, }, itemInfo: { flex: 1, marginLeft: 10, }, itemName: { fontSize: 14, color: '#333', fontWeight: 'bold', }, itemMagic: { fontSize: 12, color: '#666', marginTop: 5, }, checkbox: { width: 22, height: 22, borderRadius: 11, borderWidth: 1, borderColor: '#ccc', justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', }, checkboxSelected: { backgroundColor: '#FFAD00', borderColor: '#FFAD00', }, confirmBtn: { backgroundColor: '#FFAD00', marginHorizontal: 20, paddingVertical: 12, borderRadius: 25, alignItems: 'center', marginTop: 10, }, confirmText: { color: '#fff', fontSize: 16, fontWeight: 'bold', }, emptyText: { textAlign: 'center', marginTop: 50, color: '#999', }, });