1489 lines
47 KiB
Dart
1489 lines
47 KiB
Dart
import 'dart:ui';
|
|
import 'dart:io' as io show Platform;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:platform_info/platform_info.dart';
|
|
import 'package:flutter_udid/flutter_udid.dart';
|
|
import '../../../config/app_config.dart';
|
|
import '../../../constants/app_constants.dart';
|
|
import '../../../models/colors/theme_colors.dart';
|
|
import '../../../controllers/shared_preferences_storage_controller.dart';
|
|
import '../../../services/get/theme_controller.dart';
|
|
|
|
/// 时间: 2026-03-26
|
|
/// 功能: 应用信息页面
|
|
/// 介绍: 展示应用版本、技术栈、构建信息、设备信息等
|
|
/// 最新变化: 添加 UDID 显示
|
|
|
|
class AppInfoPage extends StatefulWidget {
|
|
const AppInfoPage({super.key});
|
|
|
|
@override
|
|
State<AppInfoPage> createState() => _AppInfoPageState();
|
|
}
|
|
|
|
class _AppInfoPageState extends State<AppInfoPage> {
|
|
String _udid = '获取中...';
|
|
bool _isDeveloperMode = false;
|
|
int _tapCount = 0;
|
|
DateTime? _lastTapTime;
|
|
final ThemeController _themeController = Get.find<ThemeController>();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadUdid();
|
|
_loadDeveloperMode();
|
|
}
|
|
|
|
Future<void> _loadUdid() async {
|
|
try {
|
|
final String udid = await FlutterUdid.udid;
|
|
if (mounted) {
|
|
setState(() {
|
|
_udid = udid;
|
|
});
|
|
}
|
|
} catch (e) {
|
|
if (mounted) {
|
|
setState(() {
|
|
_udid = '获取失败';
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> _loadDeveloperMode() async {
|
|
final isEnabled = await SharedPreferencesStorageController.getBool(
|
|
'developer_mode_enabled',
|
|
defaultValue: false,
|
|
);
|
|
if (mounted) {
|
|
setState(() {
|
|
_isDeveloperMode = isEnabled;
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> _saveDeveloperMode(bool enabled) async {
|
|
await SharedPreferencesStorageController.setBool(
|
|
'developer_mode_enabled',
|
|
enabled,
|
|
);
|
|
}
|
|
|
|
void _onFrameworkTap() {
|
|
final now = DateTime.now();
|
|
if (_lastTapTime != null && now.difference(_lastTapTime!).inSeconds > 2) {
|
|
_tapCount = 0;
|
|
}
|
|
_lastTapTime = now;
|
|
_tapCount++;
|
|
|
|
if (_tapCount >= 5 && !_isDeveloperMode) {
|
|
setState(() {
|
|
_isDeveloperMode = true;
|
|
});
|
|
_saveDeveloperMode(true);
|
|
_tapCount = 0;
|
|
final primaryColor = _themeController.currentThemeColor;
|
|
Get.snackbar(
|
|
'提示',
|
|
'开发者模式激活',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
colorText: primaryColor,
|
|
duration: const Duration(seconds: 2),
|
|
borderRadius: 8,
|
|
margin: const EdgeInsets.all(16),
|
|
);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Obx(() {
|
|
final isDark = _themeController.isDarkMode;
|
|
final primaryColor = _themeController.currentThemeColor;
|
|
return Scaffold(
|
|
backgroundColor: isDark
|
|
? const Color(0xFF1A1A1A)
|
|
: const Color(0xFFF5F5F5),
|
|
appBar: AppBar(
|
|
title: Text(
|
|
'应用信息',
|
|
style: TextStyle(color: primaryColor, fontWeight: FontWeight.bold),
|
|
),
|
|
backgroundColor: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
elevation: 0,
|
|
centerTitle: true,
|
|
leading: IconButton(
|
|
icon: Icon(Icons.arrow_back, color: primaryColor),
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
),
|
|
actions: [
|
|
if (_isDeveloperMode)
|
|
IconButton(
|
|
icon: const Icon(Icons.bug_report, color: Colors.green),
|
|
onPressed: () {
|
|
final primaryColor = _themeController.currentThemeColor;
|
|
Get.snackbar(
|
|
'提示',
|
|
'调试信息已激活',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
colorText: primaryColor,
|
|
duration: const Duration(seconds: 2),
|
|
borderRadius: 8,
|
|
margin: const EdgeInsets.all(16),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
body: ListView(
|
|
padding: const EdgeInsets.all(16),
|
|
children: [
|
|
_buildHeaderCard(primaryColor),
|
|
const SizedBox(height: 16),
|
|
_buildTechStackCard(isDark),
|
|
const SizedBox(height: 16),
|
|
_buildBuildInfoCard(context, isDark, primaryColor),
|
|
const SizedBox(height: 16),
|
|
_buildServerInfoCard(isDark),
|
|
const SizedBox(height: 16),
|
|
_buildDeviceInfoCard(context, isDark, primaryColor),
|
|
const SizedBox(height: 16),
|
|
_buildUpdateLogCard(isDark),
|
|
const SizedBox(height: 24),
|
|
_buildBottomIndicator(isDark),
|
|
],
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
Widget _buildHeaderCard(Color primaryColor) {
|
|
return ClipRRect(
|
|
borderRadius: BorderRadius.circular(16),
|
|
child: BackdropFilter(
|
|
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(24),
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
colors: [
|
|
primaryColor.withValues(alpha: 0.66),
|
|
primaryColor.withValues(alpha: 0.7),
|
|
primaryColor.withValues(alpha: 0.99),
|
|
],
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
),
|
|
borderRadius: BorderRadius.circular(16),
|
|
border: Border.all(
|
|
color: Colors.white.withValues(alpha: 0.3),
|
|
width: 1,
|
|
),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: primaryColor.withValues(alpha: 0.35),
|
|
blurRadius: 20,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
width: 70,
|
|
height: 70,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white.withValues(alpha: 0.25),
|
|
borderRadius: BorderRadius.circular(18),
|
|
border: Border.all(
|
|
color: Colors.white.withValues(alpha: 0.3),
|
|
),
|
|
),
|
|
child: const Center(
|
|
child: Text('📱', style: TextStyle(fontSize: 36)),
|
|
),
|
|
),
|
|
const SizedBox(width: 20),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text(
|
|
'情景诗词',
|
|
style: TextStyle(
|
|
fontSize: 26,
|
|
fontWeight: FontWeight.bold,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text(
|
|
'Poes · 应用信息',
|
|
style: TextStyle(
|
|
fontSize: 13,
|
|
color: Colors.white.withValues(alpha: 0.85),
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 12,
|
|
vertical: 6,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white.withValues(alpha: 0.2),
|
|
borderRadius: BorderRadius.circular(16),
|
|
border: Border.all(
|
|
color: Colors.white.withValues(alpha: 0.25),
|
|
),
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(
|
|
Icons.info_outline,
|
|
size: 14,
|
|
color: Colors.white.withValues(alpha: 0.9),
|
|
),
|
|
const SizedBox(width: 6),
|
|
GestureDetector(
|
|
onTap: _onFrameworkTap,
|
|
child: const Text(
|
|
'框架 1.4',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 8,
|
|
vertical: 2,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: _isDeveloperMode
|
|
? Colors.green.withValues(alpha: 0.3)
|
|
: Colors.white.withValues(alpha: 0.2),
|
|
borderRadius: BorderRadius.circular(4),
|
|
),
|
|
child: Obx(
|
|
() => Text(
|
|
'软件版本 ${AppConfig.appVersion}',
|
|
style: TextStyle(
|
|
fontSize: 10,
|
|
color: _isDeveloperMode
|
|
? Colors.green
|
|
: Colors.white,
|
|
fontWeight: _isDeveloperMode
|
|
? FontWeight.bold
|
|
: FontWeight.normal,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTechStackCard(bool isDark) {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: isDark
|
|
? Colors.black.withValues(alpha: 0.3)
|
|
: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: Colors.blue.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Icon(Icons.code, color: Colors.blue[700], size: 20),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
'技术栈',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Divider(height: 1, color: isDark ? Colors.grey[800] : null),
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: GridView.count(
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
crossAxisCount: 2,
|
|
mainAxisSpacing: 12,
|
|
crossAxisSpacing: 12,
|
|
childAspectRatio: 2.2,
|
|
children: [
|
|
_buildTechStackItem(
|
|
'Dart',
|
|
'编程语言',
|
|
Icons.flutter_dash,
|
|
Colors.blue,
|
|
isDark,
|
|
),
|
|
_buildTechStackItem(
|
|
'Getx',
|
|
'状态管理库',
|
|
Icons.code,
|
|
Colors.teal,
|
|
isDark,
|
|
),
|
|
_buildTechStackItem(
|
|
'SP',
|
|
'本地存储',
|
|
Icons.storage,
|
|
Colors.orange,
|
|
isDark,
|
|
),
|
|
_buildTechStackItem(
|
|
'dio',
|
|
'网络处理',
|
|
Icons.network_check,
|
|
Colors.purple,
|
|
isDark,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildBuildInfoCard(
|
|
BuildContext context,
|
|
bool isDark,
|
|
Color primaryColor,
|
|
) {
|
|
String buildSdk = 'Unknown';
|
|
try {
|
|
final String osName = io.Platform.operatingSystem;
|
|
if (osName == 'ohos' ||
|
|
osName == 'harmonyos' ||
|
|
osName == 'openharmony') {
|
|
buildSdk = 'Deveco API 23';
|
|
} else if (io.Platform.isAndroid) {
|
|
buildSdk = 'Android Target 36';
|
|
} else if (io.Platform.isWindows) {
|
|
buildSdk = 'Win10 SDK';
|
|
} else if (io.Platform.isIOS) {
|
|
buildSdk = 'iOS 26';
|
|
} else if (io.Platform.isMacOS) {
|
|
buildSdk = 'macOS 18';
|
|
} else if (io.Platform.isLinux) {
|
|
buildSdk = 'Linux 20';
|
|
} else {
|
|
buildSdk = 'PHP 7.4';
|
|
}
|
|
} catch (e) {
|
|
buildSdk = 'PHP 7.4';
|
|
}
|
|
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: isDark
|
|
? Colors.black.withValues(alpha: 0.3)
|
|
: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: primaryColor.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Icon(Icons.build, color: primaryColor, size: 20),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
'构建信息',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Divider(height: 1, color: isDark ? Colors.grey[800] : null),
|
|
Obx(
|
|
() => _buildCopyableItem(
|
|
context,
|
|
'版本号',
|
|
AppConfig.appVersion,
|
|
Icons.verified,
|
|
isDark,
|
|
),
|
|
),
|
|
Obx(
|
|
() => _buildCopyableItem(
|
|
context,
|
|
'Builder version',
|
|
AppConfig.appVersionCode.toString(),
|
|
Icons.developer_mode,
|
|
isDark,
|
|
),
|
|
),
|
|
_buildInfoItem(
|
|
'打包时间',
|
|
DateTime.now().toString().split(' ').first,
|
|
Icons.schedule,
|
|
isDark,
|
|
),
|
|
_buildInfoItem('Build SDK', buildSdk, Icons.new_releases, isDark),
|
|
_buildLicenseItem(context, isDark, primaryColor),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildLicenseItem(
|
|
BuildContext context,
|
|
bool isDark,
|
|
Color primaryColor,
|
|
) {
|
|
return InkWell(
|
|
onTap: () => _showFlutterLicense(context, isDark, primaryColor),
|
|
borderRadius: BorderRadius.circular(8),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
child: Row(
|
|
children: [
|
|
Icon(Icons.gavel, size: 20, color: primaryColor),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'开源框架',
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
'Flutter SDK',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[500] : Colors.grey[500],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.chevron_right,
|
|
size: 20,
|
|
color: isDark ? Colors.grey[600] : Colors.grey[400],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _showFlutterLicense(
|
|
BuildContext context,
|
|
bool isDark,
|
|
Color primaryColor,
|
|
) {
|
|
final licenses = [
|
|
{'name': 'Flutter SDK', 'license': 'BSD 3-Clause'},
|
|
{'name': 'OpenHarmony SDK', 'license': 'Apache 2.0'},
|
|
{'name': 'Cupertino Icons', 'license': 'MIT'},
|
|
{'name': 'Shared Preferences', 'license': 'BSD 3-Clause'},
|
|
{'name': 'Dio', 'license': 'MIT'},
|
|
{'name': 'GetX', 'license': 'MIT'},
|
|
{'name': 'Platform Info', 'license': 'MIT'},
|
|
{'name': 'flutter_udid', 'license': 'MIT'},
|
|
];
|
|
|
|
showDialog(
|
|
context: context,
|
|
builder: (context) => AlertDialog(
|
|
backgroundColor: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
title: Row(
|
|
children: [
|
|
Icon(Icons.description, color: primaryColor),
|
|
const SizedBox(width: 8),
|
|
Text(
|
|
'开源框架',
|
|
style: TextStyle(color: isDark ? Colors.white : Colors.black),
|
|
),
|
|
],
|
|
),
|
|
content: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: licenses.map((item) {
|
|
return Container(
|
|
margin: const EdgeInsets.only(bottom: 8),
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF3A3A3A) : Colors.grey[50],
|
|
borderRadius: BorderRadius.circular(8),
|
|
border: Border.all(
|
|
color: isDark
|
|
? Colors.grey[700]!.withValues(alpha: 0.2)
|
|
: Colors.grey.withValues(alpha: 0.2),
|
|
),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(6),
|
|
decoration: BoxDecoration(
|
|
color: primaryColor.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(6),
|
|
),
|
|
child: Icon(Icons.widgets, size: 16, color: primaryColor),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
item['name']!,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
item['license']!,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark
|
|
? Colors.grey[400]
|
|
: Colors.grey[500],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: Text('关闭', style: TextStyle(color: primaryColor)),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildServerInfoCard(bool isDark) {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: isDark
|
|
? Colors.black.withValues(alpha: 0.3)
|
|
: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: Colors.orange.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Icon(Icons.dns, color: Colors.orange[700], size: 20),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
'后端服务',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Divider(height: 1, color: isDark ? Colors.grey[800] : null),
|
|
_buildInfoItem('后端语言', 'PHP', Icons.php, isDark),
|
|
_buildInfoItem('Web服务器', 'Nginx', Icons.web, isDark),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDeviceInfoCard(
|
|
BuildContext context,
|
|
bool isDark,
|
|
Color primaryColor,
|
|
) {
|
|
final platform = Platform.instance;
|
|
|
|
bool isHarmonyOS = false;
|
|
String platformName = 'Unknown';
|
|
|
|
try {
|
|
final String osName = io.Platform.operatingSystem;
|
|
final String osVersion = io.Platform.operatingSystemVersion.toLowerCase();
|
|
|
|
if (osName == 'ohos' || osName == 'harmonyos' || osName == 'harmonyos') {
|
|
platformName = 'HarmonyOS';
|
|
isHarmonyOS = true;
|
|
} else if (io.Platform.isAndroid) {
|
|
platformName = 'Android';
|
|
if (osVersion.contains('harmony') ||
|
|
osVersion.contains('ohos') ||
|
|
osVersion.contains('openharmony')) {
|
|
platformName = 'HarmonyOS';
|
|
isHarmonyOS = true;
|
|
}
|
|
} else if (io.Platform.isIOS) {
|
|
platformName = 'iOS';
|
|
} else if (io.Platform.isMacOS) {
|
|
platformName = 'macOS';
|
|
} else if (io.Platform.isWindows) {
|
|
platformName = 'Windows';
|
|
} else if (io.Platform.isLinux) {
|
|
platformName = 'Linux';
|
|
} else if (io.Platform.isFuchsia) {
|
|
platformName = 'Fuchsia';
|
|
} else {
|
|
platformName = osName[0].toUpperCase() + osName.substring(1);
|
|
}
|
|
} catch (e) {
|
|
platformName = switch (platform.operatingSystem) {
|
|
const OperatingSystem.android() => 'Android',
|
|
const OperatingSystem.fuchsia() => 'Fuchsia',
|
|
const OperatingSystem.iOS() => 'iOS',
|
|
const OperatingSystem.linux() => 'Linux',
|
|
const OperatingSystem.macOS() => 'macOS',
|
|
const OperatingSystem.windows() => 'Windows',
|
|
const OperatingSystem.unknown() || _ => 'Unknown',
|
|
};
|
|
}
|
|
|
|
final String designStyle =
|
|
platform.when<String?>(
|
|
material: () => isHarmonyOS ? 'HarmonyOS Design' : 'Material Design',
|
|
cupertino: () => 'Cupertino Design',
|
|
orElse: () => null,
|
|
) ??
|
|
'Unknown';
|
|
|
|
String deviceType = '未知设备';
|
|
if (isHarmonyOS) {
|
|
final String osName = io.Platform.operatingSystem;
|
|
if (osName == 'ohos') {
|
|
deviceType = 'OHOS';
|
|
} else if (osName == 'harmonyos') {
|
|
deviceType = 'HarmonyOS';
|
|
} else if (osName == 'openharmony') {
|
|
deviceType = 'OpenHarmony';
|
|
} else {
|
|
deviceType = 'HarmonyOS';
|
|
}
|
|
} else {
|
|
deviceType =
|
|
platform.when<String?>(
|
|
mobile: () => '移动设备',
|
|
desktop: () => '桌面设备',
|
|
js: () => 'Web浏览器',
|
|
orElse: () => null,
|
|
) ??
|
|
'未知设备';
|
|
}
|
|
|
|
final String buildMode = switch (platform.buildMode) {
|
|
BuildMode$Debug _ => 'Debug',
|
|
BuildMode$Profile _ => 'Profile',
|
|
BuildMode$Release _ => 'Release',
|
|
};
|
|
|
|
final String runtimeEnv =
|
|
platform.when<String?>(
|
|
vm: () => 'VM (Dart)',
|
|
js: () => 'JS (Web)',
|
|
orElse: () => null,
|
|
) ??
|
|
'Unknown';
|
|
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: isDark
|
|
? Colors.black.withValues(alpha: 0.3)
|
|
: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: primaryColor.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Icon(Icons.devices, color: primaryColor, size: 20),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
'设备信息',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Divider(height: 1, color: isDark ? Colors.grey[800] : null),
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
|
|
child: GridView.count(
|
|
shrinkWrap: true,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
crossAxisCount: 2,
|
|
mainAxisSpacing: 12,
|
|
crossAxisSpacing: 12,
|
|
childAspectRatio: 2.0,
|
|
children: [
|
|
_buildGridInfoItem(
|
|
'操作系统',
|
|
platformName,
|
|
Icons.phone_iphone,
|
|
isDark,
|
|
primaryColor,
|
|
),
|
|
if (!isHarmonyOS) ...[
|
|
_buildGridInfoItem(
|
|
'设计风格',
|
|
designStyle,
|
|
Icons.palette,
|
|
isDark,
|
|
primaryColor,
|
|
),
|
|
],
|
|
_buildGridInfoItem(
|
|
'设备类型',
|
|
deviceType,
|
|
Icons.devices,
|
|
isDark,
|
|
primaryColor,
|
|
),
|
|
_buildGridInfoItem(
|
|
'构建模式',
|
|
buildMode,
|
|
Icons.build,
|
|
isDark,
|
|
primaryColor,
|
|
),
|
|
_buildGridInfoItem(
|
|
'运行环境',
|
|
runtimeEnv,
|
|
Icons.code,
|
|
isDark,
|
|
primaryColor,
|
|
),
|
|
_buildGridCopyableItem(
|
|
context,
|
|
'Flutter UUID',
|
|
_udid,
|
|
Icons.perm_identity,
|
|
isDark,
|
|
primaryColor,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
|
child: Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF3A3A3A) : Colors.grey[50],
|
|
borderRadius: BorderRadius.circular(8),
|
|
border: Border.all(
|
|
color: isDark
|
|
? Colors.grey[700]!.withValues(alpha: 0.2)
|
|
: Colors.grey.withValues(alpha: 0.2),
|
|
),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Icon(
|
|
Icons.info_outline,
|
|
size: 16,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[600],
|
|
),
|
|
const SizedBox(width: 8),
|
|
Text(
|
|
'设备详细信息',
|
|
style: TextStyle(
|
|
fontSize: 13,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.grey[300] : Colors.grey[700],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'窗口尺寸: ${MediaQuery.of(context).size.width.toStringAsFixed(0)} x ${MediaQuery.of(context).size.height.toStringAsFixed(0)}',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[600],
|
|
),
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
'像素密度: ${MediaQuery.of(context).devicePixelRatio.toStringAsFixed(2)} (越大越好)',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[600],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildUpdateLogCard(bool isDark) {
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: isDark
|
|
? Colors.black.withValues(alpha: 0.3)
|
|
: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: Colors.blue.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Icon(
|
|
Icons.new_releases,
|
|
color: Colors.blue[700],
|
|
size: 20,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
'软件更新日志',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Divider(height: 1, color: isDark ? Colors.grey[800] : null),
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
_buildUpdateItem('版本 1.4.1', '2026-04-03', [
|
|
'新增:从 pubspec.yaml 动态获取版本号',
|
|
'新增:响应式版本号显示',
|
|
'优化:解决 package_info_plus 依赖冲突',
|
|
'修复:版本号不显示的问题',
|
|
], isDark),
|
|
const SizedBox(height: 16),
|
|
_buildUpdateItem('版本 1.3.59', '2026-04-03', [
|
|
'修复:出处字段被时间提示语遮挡的问题',
|
|
'修复:时间提示语布局遮挡问题',
|
|
'优化:诗词卡片内容布局',
|
|
], isDark),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildUpdateItem(
|
|
String version,
|
|
String date,
|
|
List<String> changes,
|
|
bool isDark,
|
|
) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF3A3A3A) : Colors.grey[50],
|
|
borderRadius: BorderRadius.circular(8),
|
|
border: Border.all(
|
|
color: isDark
|
|
? Colors.grey[700]!.withValues(alpha: 0.2)
|
|
: Colors.grey.withValues(alpha: 0.2),
|
|
),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
version,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.bold,
|
|
color: isDark ? Colors.white : Colors.black87,
|
|
),
|
|
),
|
|
Text(
|
|
date,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[600],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: changes.map((change) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const SizedBox(width: 8),
|
|
Text(
|
|
'• ',
|
|
style: TextStyle(
|
|
color: isDark ? Colors.blue[300] : Colors.blue,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
change,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[300] : Colors.grey[700],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}).toList(),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDesignStyleCard(bool isDark) {
|
|
final platform = Platform.instance;
|
|
final String designStyle =
|
|
platform.when<String?>(
|
|
material: () => 'Material Design',
|
|
cupertino: () => 'Cupertino Design',
|
|
orElse: () => null,
|
|
) ??
|
|
'Unknown';
|
|
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: isDark
|
|
? Colors.black.withValues(alpha: 0.3)
|
|
: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: Colors.pink.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Icon(Icons.palette, color: Colors.pink[700], size: 20),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Text(
|
|
'设计风格',
|
|
style: TextStyle(
|
|
fontSize: 16,
|
|
fontWeight: FontWeight.bold,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Divider(height: 1, color: isDark ? Colors.grey[800] : null),
|
|
_buildInfoItem('当前风格', designStyle, Icons.style, isDark),
|
|
_buildInfoItem('设计语言', 'Flutter', Icons.design_services, isDark),
|
|
_buildInfoItem('交互模式', '触摸优先', Icons.touch_app, isDark),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 2x2 网格技术栈项
|
|
Widget _buildTechStackItem(
|
|
String title,
|
|
String value,
|
|
IconData icon,
|
|
Color color,
|
|
bool isDark,
|
|
) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: color.withValues(alpha: 0.1),
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(color: color.withValues(alpha: 0.2)),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: color.withValues(alpha: 0.2),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Icon(icon, color: color, size: 20),
|
|
),
|
|
const SizedBox(width: 10),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
value,
|
|
style: TextStyle(
|
|
fontSize: 11,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[600],
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 网格布局版本的信息项
|
|
Widget _buildGridInfoItem(
|
|
String title,
|
|
String value,
|
|
IconData icon,
|
|
bool isDark,
|
|
Color primaryColor,
|
|
) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF3A3A3A) : Colors.grey[50],
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(
|
|
color: isDark
|
|
? Colors.grey[700]!.withValues(alpha: 0.2)
|
|
: Colors.grey.withValues(alpha: 0.1),
|
|
),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Icon(icon, size: 18, color: primaryColor),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[700],
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text(
|
|
value,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: isDark ? Colors.white : Colors.black87,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
maxLines: 1,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// 网格布局版本的可复制信息项
|
|
Widget _buildGridCopyableItem(
|
|
BuildContext context,
|
|
String title,
|
|
String value,
|
|
IconData icon,
|
|
bool isDark,
|
|
Color primaryColor,
|
|
) {
|
|
return InkWell(
|
|
onTap: () => _copyToClipboard(context, value),
|
|
borderRadius: BorderRadius.circular(12),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF3A3A3A) : Colors.grey[50],
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(
|
|
color: isDark
|
|
? Colors.grey[700]!.withValues(alpha: 0.2)
|
|
: Colors.grey.withValues(alpha: 0.1),
|
|
),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Icon(icon, size: 16, color: primaryColor),
|
|
const SizedBox(width: 6),
|
|
Expanded(
|
|
child: Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[700],
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.content_copy,
|
|
size: 14,
|
|
color: primaryColor.withValues(alpha: 0.6),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 6),
|
|
Text(
|
|
value,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w600,
|
|
color: isDark ? Colors.white : Colors.black87,
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildInfoItem(
|
|
String title,
|
|
String value,
|
|
IconData icon,
|
|
bool isDark,
|
|
) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
child: Row(
|
|
children: [
|
|
Icon(
|
|
icon,
|
|
size: 20,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[600],
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
value,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[500],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildCopyableItem(
|
|
BuildContext context,
|
|
String title,
|
|
String value,
|
|
IconData icon,
|
|
bool isDark,
|
|
) {
|
|
return InkWell(
|
|
onTap: () => _copyToClipboard(context, value),
|
|
borderRadius: BorderRadius.circular(8),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
child: Row(
|
|
children: [
|
|
Icon(
|
|
icon,
|
|
size: 20,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[600],
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: isDark ? Colors.white : Colors.black,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
value,
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[400] : Colors.grey[500],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.content_copy,
|
|
size: 16,
|
|
color: isDark ? Colors.grey[600] : Colors.grey[400],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _copyToClipboard(BuildContext context, String text) {
|
|
Clipboard.setData(ClipboardData(text: text));
|
|
final primaryColor = _themeController.currentThemeColor;
|
|
Get.snackbar(
|
|
'复制成功',
|
|
'$text 已复制到剪贴板',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
colorText: primaryColor,
|
|
duration: const Duration(seconds: 2),
|
|
borderRadius: 8,
|
|
margin: const EdgeInsets.all(16),
|
|
icon: Icon(Icons.check_circle, color: primaryColor, size: 20),
|
|
);
|
|
}
|
|
|
|
Widget _buildBottomIndicator(bool isDark) {
|
|
return Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(16),
|
|
decoration: BoxDecoration(
|
|
color: isDark ? const Color(0xFF2A2A2A) : Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: isDark
|
|
? Colors.black.withValues(alpha: 0.3)
|
|
: Colors.black.withValues(alpha: 0.05),
|
|
blurRadius: 10,
|
|
offset: const Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
children: [
|
|
Icon(
|
|
Icons.code,
|
|
size: 24,
|
|
color: isDark ? Colors.grey[600] : Colors.grey[400],
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'用心开发,只为更好的体验',
|
|
style: TextStyle(
|
|
fontSize: 12,
|
|
color: isDark ? Colors.grey[500] : Colors.grey[500],
|
|
),
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
'© 2026 ${AppConfig.appName}',
|
|
style: TextStyle(
|
|
fontSize: 11,
|
|
color: isDark ? Colors.grey[600] : Colors.grey[400],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|