import 'dart:convert'; import 'package:get/get.dart'; import 'package:nomo/app/base/base_controller.dart'; import 'package:nomo/app/data/sp/ix_sp.dart'; import 'package:nomo/app/constants/sp_keys.dart'; import 'package:nomo/app/controllers/base_core_api.dart'; import 'package:nomo/utils/log/logger.dart'; /// 分流隧道模式枚举 enum SplitTunnelingMode { exclude, // 排除选中的应用 include, // 仅包含选中的应用 none, // 不选择任何应用 } /// 应用数据模型 class AppInfo { final String name; final String packageName; final String icon; AppInfo({required this.name, required this.packageName, required this.icon}); } class SplittunnelingSelectappController extends BaseController { // 排除模式选中的应用列表 final RxList excludeSelectedApps = [].obs; // 包含模式选中的应用列表 final RxList includeSelectedApps = [].obs; // 所有应用列表 final RxList allApps = [].obs; // 当前模式 final Rx currentMode = SplitTunnelingMode.exclude.obs; static const String TAG = 'SplittunnelingSelectappController'; @override void onInit() { super.onInit(); _loadCachedData(); getApps(); } /// 加载缓存数据 void _loadCachedData() { // 加载缓存的应用数据 final cachedAppsJson = IXSP.getString(SPKeys.splittunnelingCachedApps); if (cachedAppsJson != null) { try { final cachedApps = jsonDecode(cachedAppsJson) as List; final apps = cachedApps .map( (app) => AppInfo( name: app['name'], packageName: app['packageName'], icon: app['icon'], ), ) .toList(); allApps.value = apps; setSuccess(); } catch (e) { log(TAG, '加载缓存应用数据失败: $e'); } } // 加载当前模式 currentMode.value = Get.arguments as SplitTunnelingMode; _loadSelectedApps(currentMode.value); } /// 初始化应用数据 Future getApps() async { // 如果已经有缓存数据,先显示缓存,然后异步更新 if (allApps.isNotEmpty) { setSuccess(); } else { setLoading(); } final newApps = []; final appsJson = await BaseCoreApi().getApps(); if (appsJson != null) { final apps = jsonDecode(appsJson); for (dynamic app in apps) { if (app is Map) { String appName = app['appName']; String packageName = app['packageName']; String icon = app['icon']; newApps.add( AppInfo(name: appName, packageName: packageName, icon: icon), ); } } // 更新应用列表 allApps.value = newApps; // 缓存应用数据 _cacheAppsData(newApps); // 重新加载选中的应用(因为应用列表可能已更新) _loadSelectedApps(currentMode.value); if (allApps.isNotEmpty) { setSuccess(); } else { setEmpty(); } } } /// 缓存应用数据 void _cacheAppsData(List apps) { try { final appsJson = jsonEncode( apps .map( (app) => { 'name': app.name, 'packageName': app.packageName, 'icon': app.icon, }, ) .toList(), ); IXSP.setString(SPKeys.splittunnelingCachedApps, appsJson); } catch (e) { log(TAG, '缓存应用数据失败: $e'); } } /// 加载选中的应用 void _loadSelectedApps(SplitTunnelingMode mode) { final key = mode == SplitTunnelingMode.exclude ? SPKeys.splittunnelingExcludeSelectedApps : SPKeys.splittunnelingIncludeSelectedApps; final selectedAppsJson = IXSP.getString(key); if (selectedAppsJson != null) { try { final selectedPackageNames = jsonDecode(selectedAppsJson) as List; // 按照保存的顺序重建列表 final selectedAppsList = []; for (final packageName in selectedPackageNames) { final app = allApps.firstWhere( (app) => app.packageName == packageName, orElse: () => AppInfo(name: '', packageName: packageName, icon: ''), ); if (app.name.isNotEmpty) { // 只添加有效的应用 selectedAppsList.add(app); } } if (mode == SplitTunnelingMode.exclude) { excludeSelectedApps.value = selectedAppsList; } else { includeSelectedApps.value = selectedAppsList; } } catch (e) { log( TAG, '加载${mode == SplitTunnelingMode.exclude ? "排除" : "包含"}模式选中应用数据失败: $e', ); } } } /// 保存选中的应用 void _saveSelectedApps(SplitTunnelingMode mode) { try { final selectedApps = mode == SplitTunnelingMode.exclude ? excludeSelectedApps : includeSelectedApps; final selectedPackageNames = selectedApps .map((app) => app.packageName) .toList(); final selectedAppsJson = jsonEncode(selectedPackageNames); final key = mode == SplitTunnelingMode.exclude ? SPKeys.splittunnelingExcludeSelectedApps : SPKeys.splittunnelingIncludeSelectedApps; IXSP.setString(key, selectedAppsJson); } catch (e) { log( TAG, '保存${mode == SplitTunnelingMode.exclude ? "排除" : "包含"}模式选中应用数据失败: $e', ); } } /// 切换应用选择状态 void toggleAppSelection(AppInfo app) { if (currentMode.value == SplitTunnelingMode.exclude) { if (excludeSelectedApps.contains(app)) { excludeSelectedApps.remove(app); } else { excludeSelectedApps.add(app); } _saveSelectedApps(SplitTunnelingMode.exclude); } else { if (includeSelectedApps.contains(app)) { includeSelectedApps.remove(app); } else { includeSelectedApps.add(app); } _saveSelectedApps(SplitTunnelingMode.include); } } /// 检查应用是否已选择 bool isAppSelected(AppInfo app) { if (currentMode.value == SplitTunnelingMode.exclude) { return excludeSelectedApps.contains(app); } else { return includeSelectedApps.contains(app); } } /// 取消选择所有应用 void deselectAllApps() { if (currentMode.value == SplitTunnelingMode.exclude) { excludeSelectedApps.clear(); _saveSelectedApps(SplitTunnelingMode.exclude); } else { includeSelectedApps.clear(); _saveSelectedApps(SplitTunnelingMode.include); } } /// 选择所有应用 void selectAllApps() { if (currentMode.value == SplitTunnelingMode.exclude) { excludeSelectedApps.value = List.from(allApps); _saveSelectedApps(SplitTunnelingMode.exclude); } else { includeSelectedApps.value = List.from(allApps); _saveSelectedApps(SplitTunnelingMode.include); } } /// 获取当前模式选中的应用列表 List get selectedApps { return currentMode.value == SplitTunnelingMode.exclude ? excludeSelectedApps : includeSelectedApps; } /// 获取未选择的应用列表 List get unselectedApps { return allApps.where((app) => !isAppSelected(app)).toList(); } }