Files
pad_scanner/lib/services/app_config_service.dart
Misaka_Company 077a1ab1b9 fix(settings): save all config atomically and strip trailing slash from API URL
- Save API URL and sound paths in a single load-modify-write cycle to
  prevent race conditions that wiped previously saved config
- Strip trailing slashes from API URL to avoid double-slash 404 errors
- Make AppConfigService.saveConfig public for batch config writes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-13 16:58:39 +08:00

54 lines
1.6 KiB
Dart

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:convert';
/// 应用全局配置服务 (替代 SharedPreferences)
/// 配置数据持久化为本地 JSON 文件,覆盖安装应用时数据不丢失。
class AppConfigService {
static const String _kConfigFileName = 'app_config.json';
static final Map<String, dynamic> _defaults = {'api_url': ''};
Future<String> get _filePath async {
final directory = await getApplicationDocumentsDirectory();
return '${directory.path}/$_kConfigFileName';
}
/// 读取完整配置字典
Future<Map<String, dynamic>> loadConfig() async {
try {
final file = File(await _filePath);
if (await file.exists()) {
final jsonString = await file.readAsString();
return jsonDecode(jsonString) as Map<String, dynamic>;
}
} catch (e) {
debugPrint('[AppConfig] 读取配置失败: $e');
}
return Map<String, dynamic>.from(_defaults);
}
/// 读取字符串配置项
Future<String?> getString(String key) async {
final config = await loadConfig();
return config[key] as String?;
}
/// 保存字符串配置项
Future<void> setString(String key, String value) async {
final config = await loadConfig();
config[key.toString()] = value.toString();
await saveConfig(config);
}
/// 完整写入 JSON 文件
Future<void> saveConfig(Map<String, dynamic> config) async {
try {
final file = File(await _filePath);
await file.writeAsString(jsonEncode(config));
} catch (e) {
debugPrint('[AppConfig] 保存配置失败: $e');
}
}
}