import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:math'; import 'package:webview_flutter/webview_flutter.dart'; // 【你要的导入】 import '../providers/user_provider.dart'; class SettingPage extends StatelessWidget { const SettingPage({super.key}); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: AppBar( title: const Text( "设置", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w600, ), ), centerTitle: true, backgroundColor: isDarkMode ? Colors.black : Colors.white, elevation: 0, foregroundColor: isDarkMode ? Colors.white : Colors.black87, ), body: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: Column( children: [ const SizedBox(height: 10), const _SettingItem( title: "缓存管理", icon: Icons.storage_rounded, hasSwitch: false, showTrailingText: true, ), const SizedBox(height: 12), const _SettingItem( title: "退出登录/清除账号", icon: Icons.logout_rounded, hasSwitch: false, isLogout: true, ), const SizedBox(height: 12), const _SettingItem( title: "隐私政策", icon: Icons.privacy_tip_rounded, hasSwitch: false, ), const SizedBox(height: 12), const _SettingItem( title: "关于我们", icon: Icons.info_outline_rounded, hasSwitch: false, ), const SizedBox(height: 30), ], ), ), ); } } class _SettingItem extends StatefulWidget { const _SettingItem({ required this.title, required this.icon, required this.hasSwitch, this.showTrailingText = false, this.isLogout = false, }); final String title; final IconData icon; final bool hasSwitch; final bool showTrailingText; final bool isLogout; @override State<_SettingItem> createState() => _SettingItemState(); } class _SettingItemState extends State<_SettingItem> { String cacheSize = "计算中..."; @override void initState() { super.initState(); if (widget.showTrailingText) { _getCacheSize(); } } Future _getCacheSize() async { try { final cacheDir = await getTemporaryDirectory(); final imageCacheDir = Directory("${cacheDir.path}/image_cache"); if (await imageCacheDir.exists()) { int totalBytes = 0; await for (var file in imageCacheDir.list(recursive: true)) { if (file is File) { totalBytes += await file.length(); } } cacheSize = _formatBytes(totalBytes); } else { cacheSize = "0 B"; } } catch (e) { cacheSize = "获取失败"; } if (mounted) setState(() {}); } Future _clearCache() async { try { final cacheDir = await getTemporaryDirectory(); final imageCacheDir = Directory("${cacheDir.path}/image_cache"); if (await imageCacheDir.exists()) { await imageCacheDir.delete(recursive: true); } setState(() { cacheSize = "0 B"; }); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("✅ 缓存已清空")), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("❌ 清空缓存失败")), ); } } } void _showClearCacheConfirm() { showCupertinoDialog( context: context, builder: (context) => CupertinoAlertDialog( title: const Text("确定清空缓存?"), content: const Text("清空后将重新加载图片等数据,无法恢复"), actions: [ CupertinoDialogAction( child: const Text("取消"), onPressed: () => Navigator.pop(context), ), CupertinoDialogAction( child: const Text("确定清空"), onPressed: () async { Navigator.pop(context); await _clearCache(); }, ), ], ), ); } Future _deleteAccount() async { showCupertinoDialog( context: context, builder: (context) => CupertinoAlertDialog( title: const Text("确定退出登录?"), content: const Text("将清除本地账号信息,需重新登录"), actions: [ CupertinoDialogAction( child: const Text("取消"), onPressed: () => Navigator.pop(context), ), CupertinoDialogAction( child: const Text("确定退出"), onPressed: () async { Navigator.pop(context); await UserProvider.instance.logout(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text("✅ 已退出登录,账号已清除")), ); } }, ), ], ), ); } // ================== 打开 WebView 页面 ================== void _openWebView(String title, String url) { Navigator.push( context, MaterialPageRoute( builder: (context) => Scaffold( appBar: AppBar(title: Text(title)), body: WebViewWidget( controller: WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..loadRequest(Uri.parse(url)), ), ), ), ); } String _formatBytes(int bytes) { if (bytes <= 0) return "0 B"; const suffixes = ["B", "KB", "MB", "GB"]; var i = (log(bytes) / log(1024)).floor(); return '${(bytes / pow(1024, i)).toStringAsFixed(2)} ${suffixes[i]}'; } @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return GestureDetector( onTap: () { if (widget.showTrailingText) { _showClearCacheConfirm(); } else if (widget.isLogout) { _deleteAccount(); } else if (widget.title == "隐私政策") { _openWebView("隐私政策", "https://union.godserver.cn/document"); } else if (widget.title == "关于我们") { _openWebView("关于我们", "https://union.godserver.cn/thank"); } }, child: Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 16), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Icon( widget.icon, color: isDarkMode ? Colors.white : Colors.black87, size: 22, ), const SizedBox(width: 14), Text( widget.title, style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, fontSize: 16, fontWeight: FontWeight.w500, ), ), ], ), widget.hasSwitch ? const _SimpleSwitch() : widget.showTrailingText ? Text( cacheSize, style: TextStyle( color: isDarkMode ? Colors.white54 : Colors.black54, fontSize: 14, ), ) : widget.isLogout ? const SizedBox() : Icon( Icons.arrow_forward_ios_rounded, color: isDarkMode ? Colors.white54 : Colors.black54, size: 16, ), ], ), ), ); } } class _SimpleSwitch extends StatefulWidget { const _SimpleSwitch(); @override State<_SimpleSwitch> createState() => _SimpleSwitchState(); } class _SimpleSwitchState extends State<_SimpleSwitch> { bool isEnabled = true; @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return CupertinoSwitch( value: isEnabled, onChanged: (val) { setState(() => isEnabled = val); }, activeColor: isDarkMode ? Colors.white : Colors.blueAccent, trackColor: isDarkMode ? Colors.white38 : Colors.grey[300], thumbColor: isDarkMode ? Colors.white : Colors.white, ); } }