import { Image } from "expo-image"; import { useLocalSearchParams, useRouter } from "expo-router"; import React, { useCallback, useEffect, useState } from "react"; import { ActivityIndicator, Alert, FlatList, ImageBackground, RefreshControl, StatusBar, StyleSheet, Text, TouchableOpacity, View, } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { Images } from "@/constants/images"; import { roomAuditPass, roomAuditRecord, roomAuditUnpass, } from "@/services/dimension"; interface AuditItem { id: string; avatar: string; nickname: string; auditStatus: number; // 0-待审核 1-拒绝 2-通过 } const TABS = [ { title: "待审核", value: 0 }, { title: "审核通过", value: 2 }, { title: "审核不通过", value: 1 }, ]; export default function AuditListScreen() { const { id: roomId } = useLocalSearchParams<{ id: string }>(); const router = useRouter(); const insets = useSafeAreaInsets(); const [activeTab, setActiveTab] = useState(0); const [list, setList] = useState([]); const [loading, setLoading] = useState(false); const [refreshing, setRefreshing] = useState(false); const [page, setPage] = useState(1); const [hasMore, setHasMore] = useState(true); const loadData = useCallback( async (pageNum: number, isRefresh = false) => { if (loading && !isRefresh) return; try { if (pageNum === 1) setLoading(true); const data = await roomAuditRecord( pageNum, 20, roomId as string, TABS[activeTab].value, ); const records = Array.isArray(data) ? data : data?.records || []; if (records.length < 20) setHasMore(false); if (pageNum === 1 || isRefresh) { setList(records); } else { setList((prev) => [...prev, ...records]); } } catch (e) { console.error("加载审核记录失败:", e); } finally { setLoading(false); setRefreshing(false); } }, [roomId, activeTab, loading], ); useEffect(() => { setPage(1); setList([]); setHasMore(true); loadData(1, true); }, [activeTab]); const handleRefresh = () => { setRefreshing(true); setPage(1); setHasMore(true); loadData(1, true); }; const handleLoadMore = () => { if (!loading && hasMore) { const np = page + 1; setPage(np); loadData(np); } }; const handlePass = async (item: AuditItem, index: number) => { try { const res = await roomAuditPass(item.id); if (res) { const newList = [...list]; newList[index] = { ...item, auditStatus: 2 }; setList(newList); } } catch (e) { Alert.alert("提示", "操作失败"); } }; const handleReject = async (item: AuditItem, index: number) => { try { const res = await roomAuditUnpass(item.id); if (res) { const newList = [...list]; newList[index] = { ...item, auditStatus: 1 }; setList(newList); } } catch (e) { Alert.alert("提示", "操作失败"); } }; const renderItem = ({ item, index, }: { item: AuditItem; index: number; }) => ( {item.nickname} {item.auditStatus === 0 ? ( <> handleReject(item, index)} > 拒绝 handlePass(item, index)} > 通过 ) : ( {item.auditStatus === 2 ? "通过" : "拒绝"} )} ); return ( {/* 顶部导航 */} router.back()} > 审核 {/* Tab 切换 */} {TABS.map((tab, index) => { const isActive = activeTab === index; return ( setActiveTab(index)} > {tab.title} {isActive && } ); })} {/* 列表 */} item.id || index.toString()} contentContainerStyle={styles.listContent} refreshControl={ } onEndReached={handleLoadMore} onEndReachedThreshold={0.3} ListFooterComponent={ loading && list.length > 0 ? ( ) : null } ListEmptyComponent={ !loading ? ( 暂无记录 ) : null } /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#1a1a2e" }, background: { flex: 1 }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 15, paddingBottom: 10, }, backBtn: { width: 40, height: 40, justifyContent: "center", alignItems: "center", }, backText: { color: "#fff", fontSize: 20 }, title: { color: "#fff", fontSize: 16, fontWeight: "bold" }, placeholder: { width: 40 }, // Tabs tabs: { flexDirection: "row", paddingHorizontal: 10, borderBottomWidth: 1, borderBottomColor: "rgba(255,255,255,0.15)", }, tabItem: { flex: 1, height: 44, justifyContent: "center", alignItems: "center", position: "relative", }, tabItemActive: {}, tabText: { color: "#999", fontSize: 14 }, tabTextActive: { color: "#fff", fontWeight: "bold" }, tabLine: { position: "absolute", bottom: 0, width: "60%", height: 2, backgroundColor: "#e79018", }, // List listContent: { padding: 15, paddingBottom: 100 }, cell: { flexDirection: "row", alignItems: "center", backgroundColor: "rgba(255,255,255,0.9)", borderRadius: 8, paddingHorizontal: 15, paddingVertical: 12, marginBottom: 10, }, avatar: { width: 40, height: 40, borderRadius: 4, borderWidth: 2, borderColor: "#000", marginRight: 12, }, nickname: { flex: 1, fontSize: 14, color: "#333", fontWeight: "500", }, actionArea: { flexDirection: "row", alignItems: "center", }, btn: { width: 68, height: 32, borderRadius: 4, justifyContent: "center", alignItems: "center", marginLeft: 8, }, rejectBtn: { backgroundColor: "#ff4d4f" }, passBtn: { backgroundColor: "#52c41a" }, btnText: { color: "#fff", fontSize: 13, fontWeight: "bold" }, statusText: { fontSize: 13, color: "#666", fontWeight: "500", }, emptyBox: { alignItems: "center", paddingTop: 80 }, emptyText: { color: "#999", fontSize: 14 }, });