import { log, logger, LogEntry } from '@/utils/logger'; import { Ionicons } from '@expo/vector-icons'; import { useRouter } from 'expo-router'; import React, { useEffect, useState } from 'react'; import { Alert, FlatList, RefreshControl, Share, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; export default function LogsScreen() { const router = useRouter(); const insets = useSafeAreaInsets(); const [logs, setLogs] = useState([]); const [refreshing, setRefreshing] = useState(false); const loadLogs = async () => { try { const allLogs = await logger.getAllLogs(); // 按时间倒序排列,最新的在前面 setLogs(allLogs.reverse()); } catch (error) { log.error('加载日志失败', error); } }; const onRefresh = async () => { setRefreshing(true); await loadLogs(); setRefreshing(false); }; const handleClearLogs = () => { Alert.alert( '清除日志', '确定要清除所有日志吗?此操作不可恢复。', [ { text: '取消', style: 'cancel' }, { text: '确定', style: 'destructive', onPress: async () => { await logger.clearLogs(); setLogs([]); log.info('日志已清除'); }, }, ] ); }; const handleExportLogs = async () => { try { const exportData = await logger.exportLogs(); await Share.share({ message: exportData, title: '应用日志导出', }); } catch (error) { log.error('导出日志失败', error); Alert.alert('错误', '导出日志失败'); } }; useEffect(() => { loadLogs(); // 添加测试日志 log.info('进入日志页面'); }, []); const formatTimestamp = (timestamp: number) => { const date = new Date(timestamp); return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', }); }; const getLevelColor = (level: string) => { switch (level) { case 'ERROR': return '#FF4444'; case 'WARN': return '#FF8800'; case 'INFO': return '#0088FF'; case 'DEBUG': return '#888888'; default: return '#333333'; } }; const getLevelIcon = (level: string) => { switch (level) { case 'ERROR': return 'close-circle'; case 'WARN': return 'warning'; case 'INFO': return 'information-circle'; case 'DEBUG': return 'bug'; default: return 'ellipse'; } }; const renderLogItem = ({ item }: { item: LogEntry }) => ( {item.level} {formatTimestamp(item.timestamp)} {item.message} {item.data && ( {JSON.stringify(item.data, null, 2)} )} ); return ( {/* Header */} router.back()} style={styles.backButton}> 日志 ({logs.length}) {/* Logs List */} item.id} style={styles.logsList} contentContainerStyle={styles.logsContent} refreshControl={ } ListEmptyComponent={ 暂无日志 { log.debug('测试调试日志'); log.info('测试信息日志'); log.warn('测试警告日志'); log.error('测试错误日志'); setTimeout(loadLogs, 100); }} > 生成测试日志 } /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#F8F9FA', }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 16, paddingVertical: 12, backgroundColor: '#FFFFFF', borderBottomWidth: 1, borderBottomColor: '#E5E7EB', }, backButton: { width: 40, height: 40, justifyContent: 'center', alignItems: 'center', }, title: { fontSize: 18, fontWeight: 'bold', color: '#2C3E50', flex: 1, marginLeft: 8, }, headerActions: { flexDirection: 'row', alignItems: 'center', }, actionButton: { width: 36, height: 36, justifyContent: 'center', alignItems: 'center', marginLeft: 8, }, logsList: { flex: 1, }, logsContent: { padding: 16, }, logItem: { backgroundColor: '#FFFFFF', padding: 12, marginBottom: 8, borderRadius: 8, borderLeftWidth: 3, borderLeftColor: '#E5E7EB', shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.05, shadowRadius: 2, elevation: 1, }, logHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6, }, logLevelContainer: { flexDirection: 'row', alignItems: 'center', }, logIcon: { marginRight: 4, }, logLevel: { fontSize: 12, fontWeight: 'bold', fontFamily: 'monospace', }, timestamp: { fontSize: 11, color: '#9CA3AF', fontFamily: 'monospace', }, logMessage: { fontSize: 14, color: '#374151', lineHeight: 20, fontFamily: 'monospace', }, logData: { fontSize: 12, color: '#6B7280', marginTop: 8, padding: 8, backgroundColor: '#F3F4F6', borderRadius: 4, fontFamily: 'monospace', }, emptyContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', paddingVertical: 48, }, emptyText: { fontSize: 16, color: '#9CA3AF', marginTop: 12, marginBottom: 24, }, testButton: { backgroundColor: '#9370DB', paddingHorizontal: 20, paddingVertical: 10, borderRadius: 8, }, testButtonText: { color: '#FFFFFF', fontSize: 14, fontWeight: '600', }, });