import React, { useState, useEffect } from 'react'; import { StyleSheet, Text, View, TextInput, TouchableOpacity, Alert, ActivityIndicator, ScrollView, } from 'react-native'; import { AppSettings } from '../types/config'; import { getSettings, saveSettings, downloadConfig, getConfig, clearCachedConfig, } from '../services/configService'; import { useTasks } from '../context/TasksContext'; export default function SettingsScreen() { const { refreshConfig } = useTasks(); const [settings, setSettings] = useState({ configFileName: '', serverUrl: '', }); const [loading, setLoading] = useState(false); const [configStatus, setConfigStatus] = useState('未加载'); // 组件加载时获取设置 useEffect(() => { loadSettings(); checkConfigStatus(); }, []); const loadSettings = async () => { try { const currentSettings = await getSettings(); setSettings(currentSettings); } catch (error) { Alert.alert('错误', '加载设置失败'); } }; const checkConfigStatus = async () => { const config = await getConfig(); if (config) { setConfigStatus( `已加载 (版本: ${config.version}, 任务数: ${ config.tasks?.length || 0 })`, ); } else { setConfigStatus('未加载'); } }; const handleSaveSettings = async () => { if (!settings.configFileName.trim()) { Alert.alert('错误', '请输入配置文件名'); return; } if (!settings.serverUrl.trim()) { Alert.alert('错误', '请输入服务器地址'); return; } try { await saveSettings(settings); Alert.alert('成功', '设置已保存'); } catch (error) { Alert.alert('错误', '保存设置失败'); } }; const handleRefreshLocalConfig = async () => { setLoading(true); try { // 清除缓存并重新加载本地配置 await clearCachedConfig(); await refreshConfig(); await checkConfigStatus(); Alert.alert('成功', '本地配置已刷新!'); } catch (error) { console.error('刷新本地配置失败:', error); Alert.alert('错误', '刷新本地配置失败'); } finally { setLoading(false); } }; const handleDownloadConfig = async () => { if (!settings.configFileName.trim()) { Alert.alert('错误', '请先输入配置文件名'); return; } if (!settings.serverUrl.trim()) { Alert.alert('错误', '请先输入服务器地址'); return; } setLoading(true); try { // 先保存设置 await saveSettings(settings); // 下载配置文件 const config = await downloadConfig( settings.serverUrl, settings.configFileName, ); Alert.alert( '成功', `配置文件下载成功!\n版本: ${config.version}\n任务数量: ${ config.tasks?.length || 0 }`, [ { text: '确定', onPress: async () => { await refreshConfig(); checkConfigStatus(); }, }, ], ); } catch (error) { Alert.alert( '下载失败', error instanceof Error ? error.message : '未知错误', ); } finally { setLoading(false); } }; const handleClearCache = async () => { Alert.alert( '确认清除', '确定要清除缓存的配置文件吗?系统将重新加载本地 config.json 文件。', [ { text: '取消', style: 'cancel' }, { text: '确定', onPress: async () => { setLoading(true); try { await clearCachedConfig(); await refreshConfig(); checkConfigStatus(); Alert.alert('成功', '缓存已清除,已重新加载配置'); } catch (error) { Alert.alert('错误', '清除缓存失败'); } finally { setLoading(false); } }, }, ], ); }; const handleTestConnection = async () => { if (!settings.serverUrl.trim()) { Alert.alert('错误', '请先输入服务器地址'); return; } setLoading(true); try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); const response = await fetch(`${settings.serverUrl}/health`, { method: 'GET', signal: controller.signal, }); clearTimeout(timeoutId); if (response.ok) { Alert.alert('连接成功', '服务器连接正常'); } else { Alert.alert('连接失败', `HTTP ${response.status}`); } } catch (error) { Alert.alert('连接失败', '无法连接到服务器'); } finally { setLoading(false); } }; return ( {loading && ( 处理中... )} {/* 配置状态 */} 配置状态 {configStatus} {/* 配置文件设置 */} 配置文件 配置文件名: setSettings(prev => ({ ...prev, configFileName: text })) } placeholder="config" placeholderTextColor="#999" autoCapitalize="none" /> 下载配置文件 刷新本地配置 清除缓存 {/* 服务器设置 */} 服务器设置 服务器地址: setSettings(prev => ({ ...prev, serverUrl: text })) } placeholder="http://localhost:3000/api" placeholderTextColor="#999" autoCapitalize="none" keyboardType="url" /> 测试连接 保存设置 {/* 说明信息 */} 使用说明 配置文件加载优先级: 1. 缓存的服务器配置(从服务器下载的配置) 2. 本地 config.json 文件 3. 空数据(如果都没有找到) • 点击"下载配置文件"从服务器获取最新配置 • 点击"清除缓存"强制重新加载本地配置文件 ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#f5f5f5', }, content: { padding: 20, }, title: { fontSize: 24, fontWeight: 'bold', textAlign: 'center', marginBottom: 30, color: '#333', }, section: { backgroundColor: 'white', borderRadius: 10, padding: 20, marginBottom: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.1, shadowRadius: 3.84, elevation: 5, }, sectionTitle: { fontSize: 18, fontWeight: 'bold', marginBottom: 15, color: '#333', }, inputGroup: { marginBottom: 15, }, label: { fontSize: 16, marginBottom: 8, color: '#333', fontWeight: '500', }, inputRow: { flexDirection: 'row', alignItems: 'center', }, textInput: { flex: 1, borderWidth: 1, borderColor: '#ddd', borderRadius: 8, padding: 12, fontSize: 16, backgroundColor: '#fafafa', }, extension: { marginLeft: 8, fontSize: 16, color: '#666', fontWeight: '500', }, statusRow: { flexDirection: 'row', alignItems: 'center', marginBottom: 15, }, statusLabel: { fontSize: 16, color: '#333', fontWeight: '500', }, statusText: { fontSize: 16, color: '#007AFF', marginLeft: 8, }, button: { borderRadius: 8, padding: 12, alignItems: 'center', minHeight: 48, justifyContent: 'center', }, downloadButton: { backgroundColor: '#007AFF', flex: 1, marginRight: 10, }, refreshButton: { backgroundColor: '#32D74B', flex: 1, }, testButton: { backgroundColor: '#34C759', flex: 1, marginRight: 10, }, saveButton: { backgroundColor: '#FF9500', flex: 1, }, buttonText: { color: 'white', fontSize: 16, fontWeight: '600', }, buttonRow: { flexDirection: 'row', marginTop: 10, }, infoSection: { backgroundColor: 'white', borderRadius: 10, padding: 20, marginBottom: 20, }, infoTitle: { fontSize: 18, fontWeight: 'bold', marginBottom: 15, color: '#333', }, infoText: { fontSize: 14, lineHeight: 20, color: '#666', marginBottom: 5, }, loadingOverlay: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(255, 255, 255, 0.8)', justifyContent: 'center', alignItems: 'center', zIndex: 1, }, loadingText: { marginTop: 10, fontSize: 16, color: '#007AFF', }, clearButton: { backgroundColor: '#FF3B30', }, });