release 1.3.1
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
import 'dart:async' show StreamSubscription;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_application_2/controllers/history_controller.dart';
|
||||
import 'package:poes/controllers/history_controller.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
import '../../../utils/http/poetry_api.dart';
|
||||
import '../../../services/network_listener_service.dart';
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.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 '../../../controllers/shared_preferences_storage_controller.dart';
|
||||
|
||||
@@ -263,7 +264,7 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Text(
|
||||
'软件版本 1.5',
|
||||
'软件版本 ${AppConfig.appVersion}',
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: _isDeveloperMode
|
||||
@@ -419,7 +420,12 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
_buildCopyableItem(context, '版本号', '1.2', Icons.verified),
|
||||
_buildCopyableItem(
|
||||
context,
|
||||
'版本号',
|
||||
AppConfig.appVersion,
|
||||
Icons.verified,
|
||||
),
|
||||
_buildCopyableItem(
|
||||
context,
|
||||
'Builder version',
|
||||
@@ -735,21 +741,34 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
_buildInfoItem('操作系统', platformName, Icons.phone_iphone),
|
||||
if (!isHarmonyOS) ...[
|
||||
_buildInfoItem('设计风格', designStyle, Icons.palette),
|
||||
],
|
||||
_buildInfoItem('设备类型', deviceType, Icons.devices),
|
||||
_buildInfoItem('构建模式', buildMode, Icons.build),
|
||||
_buildInfoItem('运行环境', runtimeEnv, Icons.code),
|
||||
_buildCopyableItem(
|
||||
context,
|
||||
'Flutter UDID',
|
||||
_udid,
|
||||
Icons.perm_identity,
|
||||
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),
|
||||
if (!isHarmonyOS) ...[
|
||||
_buildGridInfoItem('设计风格', designStyle, Icons.palette),
|
||||
],
|
||||
_buildGridInfoItem('设备类型', deviceType, Icons.devices),
|
||||
_buildGridInfoItem('构建模式', buildMode, Icons.build),
|
||||
_buildGridInfoItem('运行环境', runtimeEnv, Icons.code),
|
||||
_buildGridCopyableItem(
|
||||
context,
|
||||
'Flutter UUID',
|
||||
_udid,
|
||||
Icons.perm_identity,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12),
|
||||
@@ -855,12 +874,12 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
'优化:左侧进度条位置',
|
||||
'新增:协议内容焦点功能',
|
||||
]),
|
||||
const SizedBox(height: 16),
|
||||
_buildUpdateItem('版本 1.2.38', '2026-03-27', [
|
||||
'优化:引导页滑动逻辑',
|
||||
'新增:页面进度指示器',
|
||||
'更新:滑动提示文本',
|
||||
]),
|
||||
// const SizedBox(height: 16),
|
||||
// _buildUpdateItem('版本 1.2.38', '2026-03-27', [
|
||||
// '优化:引导页滑动逻辑',
|
||||
// '新增:页面进度指示器',
|
||||
// '更新:滑动提示文本',
|
||||
// ]),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -994,6 +1013,109 @@ class _AppInfoPageState extends State<AppInfoPage> {
|
||||
);
|
||||
}
|
||||
|
||||
// 网格布局版本的信息项
|
||||
Widget _buildGridInfoItem(String title, String value, IconData icon) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[50],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Colors.grey.withValues(alpha: 0.1)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(icon, size: 18, color: AppConstants.primaryColor),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[700],
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 网格布局版本的可复制信息项
|
||||
Widget _buildGridCopyableItem(
|
||||
BuildContext context,
|
||||
String title,
|
||||
String value,
|
||||
IconData icon,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: () => _copyToClipboard(context, value),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[50],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(color: Colors.grey.withValues(alpha: 0.1)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(icon, size: 18, color: AppConstants.primaryColor),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.grey[700],
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.content_copy,
|
||||
size: 14,
|
||||
color: AppConstants.primaryColor.withValues(alpha: 0.6),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildInfoItem(String title, String value, IconData icon) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
|
||||
@@ -36,12 +36,12 @@ class _BugListPageState extends State<BugListPage> {
|
||||
'id': 2,
|
||||
'title': '软件页面刷新率只有60帧',
|
||||
'description': '软件外120帧,打开软件后,刷新率只有60帧',
|
||||
'severity': 'high',
|
||||
'status': 'resolved',
|
||||
'severity': 'low',
|
||||
'status': 'in_progress',
|
||||
'solution': '新版已修复',
|
||||
'reproduction': '1. 极少鸿蒙用户仍会出现刷新率只有60帧,无原生刷新率',
|
||||
'resolveTime': '2026-04-10',
|
||||
'reportTime': '2026-03-20',
|
||||
'reportTime': '03-20',
|
||||
'affectedUsers': '鸿蒙5/6用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
'reproductionExpanded': false, // 复现步骤展开状态
|
||||
@@ -65,7 +65,7 @@ class _BugListPageState extends State<BugListPage> {
|
||||
'id': 4,
|
||||
'title': '软件横屏后,部分页面无法点击',
|
||||
'description': '暂未适配横屏',
|
||||
'severity': 'medium',
|
||||
'severity': 'high',
|
||||
'status': 'pending',
|
||||
'solution': '增加重试机制和离线缓存功能',
|
||||
'reproduction': '1. 开启屏幕旋转,手机横屏',
|
||||
@@ -81,9 +81,9 @@ class _BugListPageState extends State<BugListPage> {
|
||||
'description': '在其他页面点击创建添加笔记,笔记时间显示异常',
|
||||
'severity': 'low',
|
||||
'status': 'resolved',
|
||||
'solution': '优化字体大小适配逻辑,确保所有页面正确显示',
|
||||
'reproduction': '1. 进入设置页面\n2. 调整字体大小为最大值\n3. 浏览各个页面,观察文字是否显示完整',
|
||||
'resolveTime': '2026-03-26',
|
||||
'solution': '',
|
||||
'reproduction': '',
|
||||
'resolveTime': '已解决',
|
||||
'reportTime': '2026-03-18',
|
||||
'affectedUsers': '少数用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
@@ -93,11 +93,11 @@ class _BugListPageState extends State<BugListPage> {
|
||||
'id': 6,
|
||||
'title': '离线状态错误',
|
||||
'description': '断网或网络异常,软件内未正确获取到',
|
||||
'severity': 'low',
|
||||
'status': 'resolved',
|
||||
'solution': '优化字体大小适配逻辑,确保所有页面正确显示',
|
||||
'severity': 'pending',
|
||||
'status': 'in_progress',
|
||||
'solution': '在线状态未识别到网络打开',
|
||||
'reproduction': '1. 用户关闭在线状态,软件部分页面显示',
|
||||
'resolveTime': '2026-03-26',
|
||||
'resolveTime': '下个版本',
|
||||
'reportTime': '2026-03-18',
|
||||
'affectedUsers': '少数用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
@@ -107,12 +107,12 @@ class _BugListPageState extends State<BugListPage> {
|
||||
'id': 7,
|
||||
'title': '主页点击“上一条” 显示无上一条',
|
||||
'description': '未读取到历史记录',
|
||||
'severity': 'low',
|
||||
'status': 'resolved',
|
||||
'solution': '优化字体大小适配逻辑,确保所有页面正确显示',
|
||||
'reproduction': '1. 用户关闭在线状态,软件部分页面显示',
|
||||
'resolveTime': '2026-03-26',
|
||||
'reportTime': '2026-03-18',
|
||||
'severity': 'high',
|
||||
'status': 'in_progress',
|
||||
'solution': '已知bug, 概率触发',
|
||||
'reproduction': '1. 主页 点击 上一条',
|
||||
'resolveTime': '暂无修复计划',
|
||||
'reportTime': '03-18',
|
||||
'affectedUsers': '全部用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
'reproductionExpanded': false, // 复现步骤展开状态
|
||||
@@ -122,10 +122,10 @@ class _BugListPageState extends State<BugListPage> {
|
||||
'title': '软件冷启动出现长时间白屏',
|
||||
'description': '未读取到历史记录',
|
||||
'severity': 'low',
|
||||
'status': 'resolved',
|
||||
'solution': '闪白屏',
|
||||
'reproduction': '首次按钮,系统设置页面清理poes数据 大版本更新',
|
||||
'resolveTime': '2026-03-26',
|
||||
'status': 'in_progress',
|
||||
'solution': '建议锁后台,或者后台挂起',
|
||||
'reproduction': '首次按钮,系统设置页面清理数据 大版本更新',
|
||||
'resolveTime': '下个版本',
|
||||
'reportTime': '2026-03-18',
|
||||
'affectedUsers': '少数用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
@@ -135,12 +135,12 @@ class _BugListPageState extends State<BugListPage> {
|
||||
{
|
||||
'id': 9,
|
||||
'title': '软件黑屏',
|
||||
'description': '未读取到历史记录',
|
||||
'description': '多次点击同一个路由按钮5次以上',
|
||||
'severity': 'low',
|
||||
'status': 'resolved',
|
||||
'solution': '优化字体大小适配逻辑,确保所有页面正确显示',
|
||||
'status': '',
|
||||
'solution': '概率触发',
|
||||
'reproduction': '极短时间内瞬发点击同一个按钮3次以上 页面路由加载异常',
|
||||
'resolveTime': '2026-03-26',
|
||||
'resolveTime': '新版已修复',
|
||||
'reportTime': '2026-03-18',
|
||||
'affectedUsers': '少数用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
@@ -152,11 +152,11 @@ class _BugListPageState extends State<BugListPage> {
|
||||
'title': '桌面卡片 天气温度显示999',
|
||||
'description': '未读取到历史记录',
|
||||
'severity': 'low',
|
||||
'status': 'resolved',
|
||||
'status': '',
|
||||
'solution': '用户短时间内多次刷新获取api数据,导致服务器启动防止cc自我保护机制,不会此ip下放数据',
|
||||
'reproduction': '极短时间内瞬发点击同一个按钮3次以上 页面路由加载异常',
|
||||
'resolveTime': '2026-03-26',
|
||||
'reportTime': '2026-03-18',
|
||||
'reproduction': '天气频繁切换,导致温度显示异常999',
|
||||
'resolveTime': '下个版本',
|
||||
'reportTime': '2026-03',
|
||||
'affectedUsers': '少数用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
'reproductionExpanded': false, // 复现步骤展开状态
|
||||
@@ -164,13 +164,13 @@ class _BugListPageState extends State<BugListPage> {
|
||||
{
|
||||
'id': 11,
|
||||
'title': '桌面卡片 设置页面闪白屏',
|
||||
'description': '未读取到历史记录',
|
||||
'description': '软件自身优化问题',
|
||||
'severity': 'low',
|
||||
'status': 'resolved',
|
||||
'status': 'pending',
|
||||
'solution': '用户短时间内多次刷新获取api数据,导致服务器启动防止cc自我保护机制,不会此ip下放数据',
|
||||
'reproduction': '极短时间内瞬发点击同一个按钮3次以上 页面路由加载异常',
|
||||
'resolveTime': '2026-03-26',
|
||||
'reportTime': '2026-03-18',
|
||||
'resolveTime': '下个版本',
|
||||
'reportTime': '03-18',
|
||||
'affectedUsers': '少数用户',
|
||||
'expanded': false, // 解决方案展开状态
|
||||
'reproductionExpanded': false, // 复现步骤展开状态
|
||||
@@ -225,9 +225,11 @@ class _BugListPageState extends State<BugListPage> {
|
||||
String _getSeverityText(String severity) {
|
||||
switch (severity) {
|
||||
case 'high':
|
||||
// 高优先级默认红色
|
||||
return '高';
|
||||
case 'medium':
|
||||
return '中';
|
||||
|
||||
case 'low':
|
||||
return '低';
|
||||
default:
|
||||
@@ -238,13 +240,17 @@ class _BugListPageState extends State<BugListPage> {
|
||||
Color _getStatusColor(String status) {
|
||||
switch (status) {
|
||||
case 'resolved':
|
||||
// 已解决状态默认绿色
|
||||
return Colors.green;
|
||||
case 'in_progress':
|
||||
// 解决中状态默认蓝色
|
||||
return Colors.blue;
|
||||
case 'pending':
|
||||
// 待解决状态默认橙色
|
||||
return Colors.orange;
|
||||
default:
|
||||
return Colors.grey;
|
||||
// 未知状态默认灰色
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
import '../../../services/wakelock_service.dart';
|
||||
import '../guide/beginner_page.dart';
|
||||
import 'dart:io' as io;
|
||||
|
||||
class PopMenu extends StatelessWidget {
|
||||
@@ -146,12 +147,11 @@ class PopMenu extends StatelessWidget {
|
||||
_buildBottomSheetItem(context, '分享软件', Icons.share, () {
|
||||
shareApp(context);
|
||||
}),
|
||||
_buildBottomSheetItem(
|
||||
context,
|
||||
'使用教程',
|
||||
Icons.screen_lock_rotation,
|
||||
() => toggleScreenWake(context),
|
||||
),
|
||||
_buildBottomSheetItem(context, '使用教程', Icons.menu_book, () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(builder: (_) => const BeginnerPage()),
|
||||
);
|
||||
}),
|
||||
_buildBottomSheetItem(context, '取消', Icons.settings, onSettings),
|
||||
const SizedBox(height: 20),
|
||||
_buildBottomSheetItem(context, '返回桌面', Icons.exit_to_app, () {
|
||||
|
||||
@@ -167,8 +167,8 @@ class _ManuscriptPageState extends State<ManuscriptPage> {
|
||||
if (!_formKey.currentState!.validate()) return;
|
||||
|
||||
if (!_nameChecked) {
|
||||
await _checkName();
|
||||
if (!_nameChecked) return;
|
||||
_showSnackBar('请先检测诗词是否存在', isError: true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_nameExists) {
|
||||
@@ -561,13 +561,43 @@ class _ManuscriptPageState extends State<ManuscriptPage> {
|
||||
),
|
||||
if (_nameChecked) _buildSimilarityInfo(),
|
||||
const SizedBox(height: 8),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: TextButton.icon(
|
||||
onPressed: _isCheckingName ? null : _checkName,
|
||||
icon: const Icon(Icons.search, size: 18),
|
||||
label: const Text('检测是否存在'),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
_nameChecked
|
||||
? (_nameExists ? Icons.close : Icons.check_circle)
|
||||
: Icons.pending,
|
||||
size: 18,
|
||||
color: _nameChecked
|
||||
? (_nameExists
|
||||
? AppConstants.errorColor
|
||||
: AppConstants.successColor)
|
||||
: Colors.grey[400],
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
_nameChecked ? (_nameExists ? '未通过' : '已检测') : '未检测',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: _nameChecked
|
||||
? (_nameExists
|
||||
? AppConstants.errorColor
|
||||
: AppConstants.successColor)
|
||||
: Colors.grey[400],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
TextButton.icon(
|
||||
onPressed: _isCheckingName ? null : _checkName,
|
||||
icon: const Icon(Icons.search, size: 18),
|
||||
label: const Text('检测是否存在'),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
|
||||
/// 时间: 2026-03-27
|
||||
@@ -17,6 +20,13 @@ class AppDataPage extends StatefulWidget {
|
||||
class _AppDataPageState extends State<AppDataPage> {
|
||||
int _sharedPrefsCount = 0;
|
||||
bool _isLoading = true;
|
||||
String _packageSize = '计算中...';
|
||||
String _cacheSize = '计算中...';
|
||||
String _dataSize = '计算中...';
|
||||
String _totalSize = '计算中...';
|
||||
int _packageBytes = 0;
|
||||
int _cacheBytes = 0;
|
||||
int _dataBytes = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -27,12 +37,137 @@ class _AppDataPageState extends State<AppDataPage> {
|
||||
Future<void> _loadDataInfo() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final keys = prefs.getKeys();
|
||||
|
||||
await Future.wait([
|
||||
_calculatePackageSize(),
|
||||
_calculateCacheSize(),
|
||||
_calculateDataSize(),
|
||||
]);
|
||||
|
||||
_calculateTotalSize();
|
||||
|
||||
setState(() {
|
||||
_sharedPrefsCount = keys.length;
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
Future<int> _getDirectorySize(Directory dir) async {
|
||||
int totalSize = 0;
|
||||
try {
|
||||
if (await dir.exists()) {
|
||||
await for (FileSystemEntity entity in dir.list(recursive: true)) {
|
||||
if (entity is File) {
|
||||
try {
|
||||
totalSize += await entity.length();
|
||||
} catch (e) {
|
||||
debugPrint('获取文件大小失败: ${entity.path}, $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('计算目录大小失败: ${dir.path}, $e');
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
String _formatBytes(int bytes) {
|
||||
if (bytes <= 0) return '0 B';
|
||||
const suffixes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
int i = (bytes.bitLength - 1) ~/ 10;
|
||||
double size = bytes / (1 << (i * 10));
|
||||
return '${size.toStringAsFixed(i == 0 ? 0 : 2)} ${suffixes[i]}';
|
||||
}
|
||||
|
||||
Future<void> _calculatePackageSize() async {
|
||||
try {
|
||||
int totalSize = 0;
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final appDocDir = await getApplicationDocumentsDirectory();
|
||||
final supportDir = await getApplicationSupportDirectory();
|
||||
|
||||
final parentDir = tempDir.parent;
|
||||
if (await parentDir.exists()) {
|
||||
await for (FileSystemEntity entity in parentDir.list()) {
|
||||
if (entity is Directory) {
|
||||
final dirName = entity.path.split(Platform.pathSeparator).last;
|
||||
if (!dirName.startsWith('.')) {
|
||||
totalSize += await _getDirectorySize(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_packageBytes = totalSize;
|
||||
_packageSize = _formatBytes(totalSize);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('计算软件包大小失败: $e');
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_packageSize = '获取失败';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _calculateCacheSize() async {
|
||||
try {
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final size = await _getDirectorySize(tempDir);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_cacheBytes = size;
|
||||
_cacheSize = _formatBytes(size);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('计算缓存大小失败: $e');
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_cacheSize = '获取失败';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _calculateDataSize() async {
|
||||
try {
|
||||
int totalSize = 0;
|
||||
final appDocDir = await getApplicationDocumentsDirectory();
|
||||
final supportDir = await getApplicationSupportDirectory();
|
||||
|
||||
totalSize += await _getDirectorySize(appDocDir);
|
||||
totalSize += await _getDirectorySize(supportDir);
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_dataBytes = totalSize;
|
||||
_dataSize = _formatBytes(totalSize);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('计算数据大小失败: $e');
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_dataSize = '获取失败';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _calculateTotalSize() {
|
||||
const int appBaseSize = 10 * 1024 * 1024; // 10MB
|
||||
final totalBytes = _packageBytes + _cacheBytes + _dataBytes + appBaseSize;
|
||||
setState(() {
|
||||
_totalSize = _formatBytes(totalBytes);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _clearSharedPreferences() async {
|
||||
final confirmed = await _showConfirmDialog(
|
||||
'清空配置数据',
|
||||
@@ -140,6 +275,55 @@ class _AppDataPageState extends State<AppDataPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _nativeClearData() async {
|
||||
final confirmed = await _showConfirmDialog(
|
||||
'系统层清理数据',
|
||||
'⚠️ 危险操作 ⚠️\n\n确定要系统层清理数据吗?\n\n这将删除:\n• 应用文档目录所有文件\n• 应用支持目录所有文件\n• 应用缓存目录所有文件\n\n此操作将直接删除文件系统数据,不可撤销!',
|
||||
);
|
||||
|
||||
if (confirmed != true) return;
|
||||
|
||||
final doubleConfirmed = await _showConfirmDialog(
|
||||
'再次确认',
|
||||
'这是系统层面文件系统删除!\n\n删除后数据将无法恢复,确定继续吗?',
|
||||
);
|
||||
|
||||
if (doubleConfirmed != true) return;
|
||||
|
||||
try {
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
final appDocDir = await getApplicationDocumentsDirectory();
|
||||
final supportDir = await getApplicationSupportDirectory();
|
||||
|
||||
debugPrint('开始清理...');
|
||||
debugPrint('临时目录: ${tempDir.path}');
|
||||
debugPrint('文档目录: ${appDocDir.path}');
|
||||
debugPrint('支持目录: ${supportDir.path}');
|
||||
|
||||
await _deleteDirectory(tempDir);
|
||||
await _deleteDirectory(appDocDir);
|
||||
await _deleteDirectory(supportDir);
|
||||
|
||||
debugPrint('原生清理完成');
|
||||
|
||||
if (mounted) {
|
||||
Navigator.of(context).pop();
|
||||
Future.delayed(const Duration(milliseconds: 300), () {
|
||||
if (mounted) {
|
||||
_showExitConfirmDialog();
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('原生清理失败: $e');
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('清理失败: $e'), backgroundColor: Colors.red),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _clearCache() async {
|
||||
final confirmed = await _showConfirmDialog(
|
||||
'清空缓存',
|
||||
@@ -148,13 +332,49 @@ class _AppDataPageState extends State<AppDataPage> {
|
||||
|
||||
if (confirmed != true) return;
|
||||
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: const Text('缓存已清空'),
|
||||
backgroundColor: AppConstants.primaryColor,
|
||||
),
|
||||
);
|
||||
try {
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
if (await tempDir.exists()) {
|
||||
await _deleteDirectory(tempDir);
|
||||
}
|
||||
|
||||
await _calculateCacheSize();
|
||||
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: const Text('缓存已清空'),
|
||||
backgroundColor: AppConstants.primaryColor,
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('清空缓存失败: $e');
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('清空失败: $e'), backgroundColor: Colors.red),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _deleteDirectory(Directory dir) async {
|
||||
try {
|
||||
if (await dir.exists()) {
|
||||
await for (FileSystemEntity entity in dir.list()) {
|
||||
if (entity is File) {
|
||||
try {
|
||||
await entity.delete();
|
||||
} catch (e) {
|
||||
debugPrint('删除文件失败: ${entity.path}, $e');
|
||||
}
|
||||
} else if (entity is Directory) {
|
||||
await _deleteDirectory(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('删除目录失败: ${dir.path}, $e');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,6 +441,46 @@ class _AppDataPageState extends State<AppDataPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showExitConfirmDialog() async {
|
||||
final confirmed = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
title: Row(
|
||||
children: [
|
||||
Icon(Icons.power_settings_new, color: Colors.deepOrange[700]),
|
||||
const SizedBox(width: 8),
|
||||
const Expanded(child: Text('关闭应用', style: TextStyle(fontSize: 18))),
|
||||
],
|
||||
),
|
||||
content: const Text('数据清理完成!\n\n建议关闭应用后重新启动,\n以确保应用正常运行。\n\n是否现在关闭应用?'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
child: Text('稍后关闭', style: TextStyle(color: Colors.grey[600])),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.deepOrange[700],
|
||||
foregroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: const Text('立即关闭'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (confirmed == true) {
|
||||
if (mounted) {
|
||||
SystemNavigator.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _showSnackBar(String message) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
@@ -303,13 +563,15 @@ class _AppDataPageState extends State<AppDataPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildDataItem('📦 软件包', '情景诗词 v1.2.19'),
|
||||
_buildDataItem('📦 软件包', _packageSize),
|
||||
_buildDivider(),
|
||||
_buildDataItem('📱 配置项数量', '$_sharedPrefsCount 项'),
|
||||
_buildDivider(),
|
||||
_buildDataItem('💾 缓存大小', '计算中...'),
|
||||
_buildDataItem('💾 缓存大小', _cacheSize),
|
||||
_buildDivider(),
|
||||
_buildDataItem('📊 数据库大小', '计算中...'),
|
||||
_buildDataItem('📊 数据大小', _dataSize),
|
||||
_buildDivider(),
|
||||
_buildDataItem('📁 占用空间', _totalSize),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -506,6 +768,14 @@ class _AppDataPageState extends State<AppDataPage> {
|
||||
Colors.red,
|
||||
_clearAllData,
|
||||
),
|
||||
_buildDivider(),
|
||||
_buildActionButton(
|
||||
'🔧 原生清理数据',
|
||||
'删除应用数据目录所有文件',
|
||||
Icons.system_security_update_warning,
|
||||
Colors.orange,
|
||||
_nativeClearData,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,860 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
import 'sp-guide.dart';
|
||||
|
||||
class BeginnerPage extends StatefulWidget {
|
||||
const BeginnerPage({super.key});
|
||||
|
||||
@override
|
||||
State<BeginnerPage> createState() => _BeginnerPageState();
|
||||
}
|
||||
|
||||
class _BeginnerPageState extends State<BeginnerPage>
|
||||
with TickerProviderStateMixin {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
late AnimationController _fadeController;
|
||||
late Animation<double> _fadeAnimation;
|
||||
double _progress = 0.0;
|
||||
|
||||
final List<Map<String, dynamic>> _tutorialSections = [
|
||||
{
|
||||
'title': '首页功能',
|
||||
'icon': Icons.home,
|
||||
'emoji': '🏠',
|
||||
'color': AppConstants.primaryColor,
|
||||
'features': [
|
||||
'精美卡片展示',
|
||||
'智能推荐:根据时间和情景推荐合适的诗词',
|
||||
'诗词详情:显示标题、作者、朝代、正文、注释和赏析',
|
||||
'精选诗句:突出显示经典名句',
|
||||
'下拉刷新:刷新诗词内容',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '发现页面',
|
||||
'icon': Icons.explore,
|
||||
'emoji': '🔍',
|
||||
'color': const Color(0xFF00BCD4),
|
||||
'features': [
|
||||
'分类浏览:按朝代、作者、主题等分类浏览',
|
||||
'热门诗词:查看最受欢迎的诗词',
|
||||
'活跃排行:查看活跃度最高的诗词',
|
||||
'搜索功能:通过关键词搜索诗词',
|
||||
'Tab切换:分类、热门、搜索标签页',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '足迹页面',
|
||||
'icon': Icons.history,
|
||||
'emoji': '📚',
|
||||
'color': const Color(0xFFFF9800),
|
||||
'features': [
|
||||
'收藏管理:查看和管理所有收藏的诗词',
|
||||
'笔记功能:创建和管理诗词笔记',
|
||||
'分类展示:全部、点赞、笔记等分类',
|
||||
'搜索功能:搜索收藏内容',
|
||||
'视图切换:网格和列表视图',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '个人中心',
|
||||
'icon': Icons.person,
|
||||
'emoji': '👤',
|
||||
'color': const Color(0xFF4CAF50),
|
||||
'features': [
|
||||
'个人信息:编辑昵称、头像等',
|
||||
'统计数据:今日浏览、累计浏览、今日点赞等',
|
||||
'数据隐藏:可隐藏统计和答题数据',
|
||||
'用户计划:加入用户体验计划',
|
||||
'功能入口:设置、了解我们、权限管理等',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '诗词阅读',
|
||||
'icon': Icons.menu_book,
|
||||
'emoji': '📖',
|
||||
'color': const Color(0xFF9C27B0),
|
||||
'features': [
|
||||
'加载诗词:点击卡片任意区域加载下一条',
|
||||
'查看详情:显示完整诗词信息',
|
||||
'点赞诗词:点击心形图标',
|
||||
'切换诗词:上一条/下一条按钮',
|
||||
'长按复制:长按复制诗词内容',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '收藏功能',
|
||||
'icon': Icons.favorite,
|
||||
'emoji': '❤️',
|
||||
'color': const Color(0xFFE91E63),
|
||||
'features': [
|
||||
'一键收藏:点击收藏图标',
|
||||
'收藏列表:在足迹页查看',
|
||||
'取消收藏:再次点击收藏图标',
|
||||
'收藏统计:显示收藏数量',
|
||||
'创建笔记:从诗词创建笔记',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '搜索功能',
|
||||
'icon': Icons.search,
|
||||
'emoji': '🔎',
|
||||
'color': const Color(0xFF009688),
|
||||
'features': [
|
||||
'关键词搜索:输入关键词搜索',
|
||||
'分类筛选:按分类筛选结果',
|
||||
'热门搜索:查看热门搜索词',
|
||||
'搜索历史:保留搜索记录',
|
||||
'实时搜索:输入即时搜索',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '答题挑战',
|
||||
'icon': Icons.quiz,
|
||||
'emoji': '🎮',
|
||||
'color': const Color(0xFFFF5722),
|
||||
'features': [
|
||||
'答题挑战:参与诗词答题',
|
||||
'题目随机化:使用Fisher-Yates算法',
|
||||
'答题记录:记录历史和成绩',
|
||||
'答题统计:正确率等数据',
|
||||
'提示功能:遇到困难可获取提示',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '离线模式',
|
||||
'icon': Icons.wifi_off,
|
||||
'emoji': '📴',
|
||||
'color': const Color(0xFF607D8B),
|
||||
'features': [
|
||||
'离线数据下载:支持下载诗词和答题',
|
||||
'下载选项:20/30/60/100条可选',
|
||||
'后台下载:返回上一页继续下载',
|
||||
'缓存管理:清空缓存可选择内容',
|
||||
'自动切换:无网络自动切换',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '个性化设置',
|
||||
'icon': Icons.palette,
|
||||
'emoji': '🎨',
|
||||
'color': const Color(0xFF3F51B5),
|
||||
'features': [
|
||||
'主题切换:浅色/深色主题',
|
||||
'卡片样式:三种样式可选',
|
||||
'颜色自定义:主题色和背景色',
|
||||
'圆角调整:卡片圆角大小',
|
||||
'字体大小:调整字体大小',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '投稿功能',
|
||||
'icon': Icons.send,
|
||||
'emoji': '📝',
|
||||
'color': const Color(0xFF00BCD4),
|
||||
'features': [
|
||||
'诗词投稿:向软件投稿诗词',
|
||||
'投稿表单:填写诗词信息',
|
||||
'投稿记录:查看历史投稿',
|
||||
'相似度检测:防止重复投稿',
|
||||
'清空记录:清空投稿历史',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '投票功能',
|
||||
'icon': Icons.how_to_vote,
|
||||
'emoji': '🗳️',
|
||||
'color': const Color(0xFF795548),
|
||||
'features': [
|
||||
'用户投票:参与功能投票',
|
||||
'投票结果:查看统计',
|
||||
'登录注册:用户身份',
|
||||
'自动注册:简化流程',
|
||||
'投票详情:查看选项',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '桌面卡片',
|
||||
'icon': Icons.wb_sunny,
|
||||
'emoji': '🌤️',
|
||||
'color': const Color(0xFFFFC107),
|
||||
'features': [
|
||||
'天气显示:显示当前天气',
|
||||
'城市显示:所在城市',
|
||||
'十二时辰:中国传统计时',
|
||||
'时间标签:子丑寅卯辰巳午未申酉戌亥',
|
||||
'智能更新:自动更新时间',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '图片分享',
|
||||
'icon': Icons.share,
|
||||
'emoji': '📸',
|
||||
'color': const Color(0xFF03A9F4),
|
||||
'features': [
|
||||
'诗词分享:生成图片分享',
|
||||
'软件分享:分享给朋友',
|
||||
'复制功能:复制内容',
|
||||
'高清图片:生成高质量图片',
|
||||
'跨平台:支持多平台分享',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '数据管理',
|
||||
'icon': Icons.storage,
|
||||
'emoji': '💾',
|
||||
'color': const Color(0xFF8BC34A),
|
||||
'features': [
|
||||
'数据统计:显示数据占用',
|
||||
'清空数据:清空应用数据',
|
||||
'数据备份:备份数据',
|
||||
'缓存管理:管理缓存',
|
||||
'离线数据:管理离线数据',
|
||||
],
|
||||
},
|
||||
{
|
||||
'title': '帮助与反馈',
|
||||
'icon': Icons.help,
|
||||
'emoji': '❓',
|
||||
'color': const Color(0xFF9E9E9E),
|
||||
'features': [
|
||||
'使用指南:查看使用说明',
|
||||
'常见问题:FAQ解答',
|
||||
'用户反馈:反馈问题',
|
||||
'功能建议:提交建议',
|
||||
'已知Bug:查看Bug列表',
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_scrollController.addListener(_onScroll);
|
||||
_fadeController = AnimationController(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
vsync: this,
|
||||
);
|
||||
_fadeAnimation = CurvedAnimation(
|
||||
parent: _fadeController,
|
||||
curve: Curves.easeIn,
|
||||
);
|
||||
_fadeController.forward();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController.removeListener(_onScroll);
|
||||
_scrollController.dispose();
|
||||
_fadeController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onScroll() {
|
||||
if (_scrollController.hasClients) {
|
||||
final maxScroll = _scrollController.position.maxScrollExtent;
|
||||
final currentScroll = _scrollController.position.pixels;
|
||||
final progress = maxScroll > 0 ? currentScroll / maxScroll : 0.0;
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_progress = progress;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.grey[50],
|
||||
body: Stack(
|
||||
children: [
|
||||
FadeTransition(
|
||||
opacity: _fadeAnimation,
|
||||
child: CustomScrollView(
|
||||
controller: _scrollController,
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
title: const Text(
|
||||
'软件功能',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 17,
|
||||
color: AppConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
foregroundColor: AppConstants.primaryColor,
|
||||
elevation: 0,
|
||||
centerTitle: true,
|
||||
floating: true,
|
||||
snap: true,
|
||||
pinned: false,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.help_outline),
|
||||
color: AppConstants.primaryColor,
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
const SpGuidePage(fromSettings: true),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 100),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
return _buildSectionCard(_tutorialSections[index], index);
|
||||
}, childCount: _tutorialSections.length),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_buildProgressIndicator(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSectionCard(Map<String, dynamic> section, int index) {
|
||||
return TweenAnimationBuilder<double>(
|
||||
tween: Tween(begin: 0.0, end: 1.0),
|
||||
duration: Duration(milliseconds: 300 + (index * 50)),
|
||||
curve: Curves.easeOut,
|
||||
builder: (context, value, child) {
|
||||
return Transform.translate(
|
||||
offset: Offset(0, 20 * (1 - value)),
|
||||
child: Opacity(opacity: value, child: child),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.05),
|
||||
blurRadius: 12,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: (section['color'] as Color).withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(14),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
section['emoji'],
|
||||
style: const TextStyle(fontSize: 24),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
section['title'],
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
letterSpacing: -0.3,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'第 ${index + 1} 部分',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.grey[500],
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildSectionContent(section['features'], section['color']),
|
||||
const SizedBox(height: 16),
|
||||
if (index < 4) ...[
|
||||
const Divider(height: 1, color: Color(0xFFF5F5F5)),
|
||||
const SizedBox(height: 16),
|
||||
_buildPreviewSection(section['title']),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSectionContent(List<String> features, Color color) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: features.map((feature) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 6,
|
||||
height: 6,
|
||||
margin: const EdgeInsets.only(top: 8, right: 12),
|
||||
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
feature,
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.grey[700],
|
||||
height: 1.5,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPreviewSection(String title) {
|
||||
Widget preview;
|
||||
switch (title) {
|
||||
case '首页功能':
|
||||
preview = _buildHomePreview();
|
||||
break;
|
||||
case '发现页面':
|
||||
preview = _buildDiscoverPreview();
|
||||
break;
|
||||
case '足迹页面':
|
||||
preview = _buildFootprintPreview();
|
||||
break;
|
||||
case '个人中心':
|
||||
preview = _buildProfilePreview();
|
||||
break;
|
||||
default:
|
||||
preview = const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.visibility_outlined,
|
||||
size: 16,
|
||||
color: AppConstants.primaryColor,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'界面预览',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
preview,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHomePreview() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: AppConstants.primaryColor.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.book,
|
||||
size: 18,
|
||||
color: AppConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'静夜思',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.grey[800],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'唐·李白',
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Text(
|
||||
'床前明月光,疑是地上霜。\n举头望明月,低头思故乡。',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[700],
|
||||
height: 1.6,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_buildPreviewAction(Icons.favorite_border, '点赞'),
|
||||
_buildPreviewAction(Icons.bookmark_border, '收藏'),
|
||||
_buildPreviewAction(Icons.share_outlined, '分享'),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDiscoverPreview() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.search, size: 18, color: Colors.grey[400]),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'搜索诗词...',
|
||||
style: TextStyle(fontSize: 14, color: Colors.grey[400]),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
_buildPreviewTag('唐诗'),
|
||||
const SizedBox(width: 8),
|
||||
_buildPreviewTag('宋词'),
|
||||
const SizedBox(width: 8),
|
||||
_buildPreviewTag('元曲'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildPreviewListItem('将进酒', '李白'),
|
||||
const SizedBox(height: 8),
|
||||
_buildPreviewListItem('水调歌头', '苏轼'),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFootprintPreview() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_buildPreviewStat('128', '收藏'),
|
||||
_buildPreviewStat('45', '笔记'),
|
||||
_buildPreviewStat('89', '点赞'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_buildPreviewListItem('静夜思', '已收藏'),
|
||||
const SizedBox(height: 8),
|
||||
_buildPreviewListItem('春晓', '有笔记'),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildProfilePreview() {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: AppConstants.primaryColor.withValues(alpha: 0.2),
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
),
|
||||
child: const Center(
|
||||
child: Text('👤', style: TextStyle(fontSize: 24)),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'诗词爱好者',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.grey[800],
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Lv.12 · 诗意生活',
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_buildPreviewStat('156', '浏览'),
|
||||
_buildPreviewStat('89', '点赞'),
|
||||
_buildPreviewStat('45', '答题'),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPreviewAction(IconData icon, String label) {
|
||||
return Column(
|
||||
children: [
|
||||
Icon(icon, size: 20, color: Colors.grey[600]),
|
||||
const SizedBox(height: 4),
|
||||
Text(label, style: TextStyle(fontSize: 11, color: Colors.grey[600])),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPreviewTag(String text) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: AppConstants.primaryColor.withValues(alpha: 0.3),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppConstants.primaryColor,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPreviewListItem(String title, String subtitle) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[700],
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
subtitle,
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPreviewStat(String value, String label) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppConstants.primaryColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(label, style: TextStyle(fontSize: 11, color: Colors.grey[500])),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildProgressIndicator() {
|
||||
return Positioned(
|
||||
left: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
width: 60,
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
Colors.white.withValues(alpha: 0.95),
|
||||
Colors.white.withValues(alpha: 0.85),
|
||||
Colors.white.withValues(alpha: 0.0),
|
||||
],
|
||||
stops: const [0.0, 0.7, 1.0],
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 8,
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
AnimatedPositioned(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeOut,
|
||||
top: _progress * 160,
|
||||
child: Container(
|
||||
width: 8,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: AppConstants.primaryColor,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppConstants.primaryColor.withValues(
|
||||
alpha: 0.3,
|
||||
),
|
||||
blurRadius: 8,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: AppConstants.primaryColor,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: AppConstants.primaryColor.withValues(alpha: 0.2),
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Text(
|
||||
'${(_progress * 100).toInt()}%',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: -0.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@ class _SpGuidePageState extends State<SpGuidePage>
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildShowGuideCheckbox(),
|
||||
// _buildShowGuideCheckbox(),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -621,7 +621,7 @@ class _ProfilePageState extends State<ProfilePage>
|
||||
_buildSettingsItem(
|
||||
'开发计划',
|
||||
Icons.analytics,
|
||||
() => _showSnackBar('软件开发进度'),
|
||||
() => _showSnackBar('首个上线版本暂无计划,待收集整理用户建议'),
|
||||
),
|
||||
_buildSettingsItem('去投稿', Icons.edit_note, () {
|
||||
Navigator.push(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../../../config/app_config.dart';
|
||||
import '../../../constants/app_constants.dart';
|
||||
|
||||
/// 时间: 2026-03-26
|
||||
@@ -39,7 +40,7 @@ class LearnUsPage extends StatelessWidget {
|
||||
const SizedBox(height: 16),
|
||||
_buildQQGroupCard(context),
|
||||
const SizedBox(height: 16),
|
||||
_buildDeveloperCard(),
|
||||
_buildDeveloperCard(context),
|
||||
const SizedBox(height: 16),
|
||||
_buildTeamCard(),
|
||||
const SizedBox(height: 16),
|
||||
@@ -127,7 +128,7 @@ class LearnUsPage extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
'版本 ${AppConstants.appVersion}',
|
||||
'版本 ${AppConfig.appVersion}',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.white,
|
||||
@@ -215,7 +216,7 @@ class LearnUsPage extends StatelessWidget {
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'https://*****.github.io',
|
||||
'https://poe.vogov.cn/app.html',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: AppConstants.primaryColor,
|
||||
@@ -347,7 +348,7 @@ class LearnUsPage extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDeveloperCard() {
|
||||
Widget _buildDeveloperCard(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
@@ -467,7 +468,7 @@ class LearnUsPage extends StatelessWidget {
|
||||
const Text(
|
||||
'2821981550@qq.com',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontSize: 15,
|
||||
color: Colors.blue,
|
||||
decoration: TextDecoration.underline,
|
||||
),
|
||||
@@ -478,6 +479,95 @@ class LearnUsPage extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
const Color(0xFF07C160).withValues(alpha: 0.1),
|
||||
const Color(0xFF07C160).withValues(alpha: 0.05),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: const Center(
|
||||
child: Text('💬', style: TextStyle(fontSize: 24)),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'微信公众号',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 6,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF07C160).withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.search,
|
||||
size: 16,
|
||||
color: Color(0xFF07C160),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
const Text(
|
||||
'微风暴',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF07C160),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(
|
||||
const ClipboardData(text: '微风暴'),
|
||||
);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('已复制到剪贴板'),
|
||||
duration: Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.content_copy,
|
||||
size: 16,
|
||||
color: const Color(
|
||||
0xFF07C160,
|
||||
).withValues(alpha: 0.8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -519,7 +609,6 @@ class LearnUsPage extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
_buildTeamMember('💻', '程序设计', '无书的书🤡', '尽毕生所学,取天下之诗集,只为逗她一笑'),
|
||||
_buildTeamMember('🎨', 'UI/UX/Testing', 'Ayk', '....'),
|
||||
_buildTeamMember('⚙️', '后端', '伯乐不相马', '真的吗,还是做不到吗?'),
|
||||
|
||||
@@ -22,7 +22,7 @@ class PrivacyPolicyContent extends StatelessWidget {
|
||||
_buildUpdateDate('2026.3.26'),
|
||||
const SizedBox(height: 24),
|
||||
_buildParagraph(
|
||||
'情景诗词 是由 *****工作室 (以下简称"我们")为您提供的,用于在诗词里旅行,在文化中生长的应用。本隐私声明由我们为处理您的个人信息而制定。',
|
||||
'情景诗词 是由 弥勒市朋普镇微风暴网络科技工作室 (以下简称"我们")为您提供的,用于在诗词里旅行,在文化中生长的应用。本隐私声明由我们为处理您的个人信息而制定。',
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_buildParagraph(
|
||||
@@ -47,6 +47,8 @@ class PrivacyPolicyContent extends StatelessWidget {
|
||||
const SizedBox(height: 16),
|
||||
_buildPermissionItem('存储权限', '用于保存和读取您的笔记、收藏等本地数据'),
|
||||
_buildPermissionItem('网络权限', '用于获取诗词内容和更新应用信息'),
|
||||
_buildPermissionItem('震动权限', '用于在执行操作时提供反馈提示'),
|
||||
_buildPermissionItem('分享能力', '调用系统分享功能,分享您的笔记、收藏等本地数据'),
|
||||
const SizedBox(height: 24),
|
||||
_buildSectionTitle('3. 管理您的个人信息'),
|
||||
const SizedBox(height: 16),
|
||||
@@ -64,9 +66,9 @@ class PrivacyPolicyContent extends StatelessWidget {
|
||||
const SizedBox(height: 16),
|
||||
_buildParagraph('您可通过以下方式联系我们,并行使您的相关权利,我们会尽快回复。'),
|
||||
const SizedBox(height: 12),
|
||||
_buildContactInfo('开发者', '*****工作室'),
|
||||
_buildContactInfo('地址', '云南昆明'),
|
||||
_buildContactInfo('邮箱', '********@outlook.com'),
|
||||
_buildContactInfo('开发者', '弥勒市朋普镇微风暴网络科技工作室'),
|
||||
_buildContactInfo('地址', '云南 昆明 西山区'),
|
||||
_buildContactInfo('邮箱', '2821981550@qq.com'),
|
||||
const SizedBox(height: 16),
|
||||
_buildParagraph(
|
||||
'如果您对我们的回复不满意,特别是当个人信息处理行为损害了您的合法权益时,您还可以通过向有管辖权的人民法院提起诉讼、向行业自律协会或政府相关管理机构投诉等外部途径进行解决。您也可以向我们了解可能适用的相关投诉途径的信息。',
|
||||
@@ -74,6 +76,7 @@ class PrivacyPolicyContent extends StatelessWidget {
|
||||
const SizedBox(height: 24),
|
||||
_buildEffectiveDate('2026年3月26日'),
|
||||
_buildBottomIndicator(),
|
||||
_buildParagraph(''),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -240,13 +243,13 @@ class UserAgreementContent extends StatelessWidget {
|
||||
_buildEffectiveDate('2026-03-26'),
|
||||
const SizedBox(height: 24),
|
||||
_buildParagraph(
|
||||
'欢迎使用 情景诗词(以下简称"本App")。本用户协议由个人开发者 *****工作室 制定。用户在下载、安装、注册、登录、使用本App服务前,应当仔细阅读并充分理解本协议内容。用户开始使用本App,即视为同意本协议全部条款。',
|
||||
'欢迎使用 情景诗词(以下简称"本App")。本用户协议由 弥勒市朋普镇微风暴网络科技工作室 制定。用户在下载、安装、注册、登录、使用本App服务前,应当仔细阅读并充分理解本协议内容。用户开始使用本App,即视为同意本协议全部条款。',
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
_buildSectionTitle('一、协议适用范围'),
|
||||
const SizedBox(height: 16),
|
||||
_buildParagraph(
|
||||
'本协议适用于用户与开发者 *****工作室 之间,关于用户使用 情景诗词 产品及服务所建立的权利义务关系。',
|
||||
'本协议适用于用户与开发者 弥勒市朋普镇微风暴网络科技工作室 之间,关于用户使用 情景诗词 产品及服务所建立的权利义务关系。',
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
_buildSectionTitle('二、服务内容'),
|
||||
@@ -301,11 +304,12 @@ class UserAgreementContent extends StatelessWidget {
|
||||
const SizedBox(height: 24),
|
||||
_buildSectionTitle('九、联系方式'),
|
||||
const SizedBox(height: 16),
|
||||
_buildContactInfo('开发者', '*****工作室'),
|
||||
_buildContactInfo('开发者', '弥勒市朋普镇微风暴网络科技工作室'),
|
||||
_buildContactInfo('应用名称', '情景诗词'),
|
||||
_buildContactInfo('联系邮箱', '********@outlook.com'),
|
||||
_buildContactInfo('联系邮箱', '2821981550@qq.com'),
|
||||
const SizedBox(height: 24),
|
||||
_buildBottomIndicator(),
|
||||
_buildParagraph(''),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -478,7 +482,7 @@ class _PrivacyPageState extends State<PrivacyPage>
|
||||
border: Border.all(color: Colors.grey[300]!),
|
||||
),
|
||||
child: SelectableText(
|
||||
'https://*****.github.io/privacy',
|
||||
'https://poe.vogov.cn/privacy.html',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: AppConstants.primaryColor,
|
||||
@@ -501,7 +505,7 @@ class _PrivacyPageState extends State<PrivacyPage>
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
const ClipboardData(text: 'https://*****.github.io/privacy'),
|
||||
const ClipboardData(text: 'https://poe.vogov.cn/privacy.html'),
|
||||
);
|
||||
Navigator.pop(context);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
|
||||
Reference in New Issue
Block a user