diff --git a/CHANGELOG.md b/CHANGELOG.md index ec6eadd..b12fe77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,30 @@ All notable changes to this project will be documented in this file. ### 修复 - 📁 **音频文件声明** - 在 `pubspec.yaml` 中添加 `assets/audios/deep.mp3` 音频文件的声明,确保应用能正确加载音频资源 +- 🔊 **音频播放阻塞UI修复** + - 修复声音开关打开时主页刷新点不动的问题 + - 修复点击按钮时没有声音的问题 + - 将音频播放改为非阻塞方式,避免等待播放完成 + - 修改 `lib/utils/audio_manager.dart`,移除 `_playSound` 方法中的 `await` + - 修改 `lib/views/home/home_page.dart` 和 `lib/views/home/home_part.dart`,移除音频播放调用的 `await` + - 确保音频播放不影响UI响应速度 +- 🔊 **音频重复播放修复** + - 修复只有第一次播放声音,后续播放无声音的问题 + - 简化音频播放逻辑,移除复杂的音频上下文设置 + - 使用单个 AudioPlayer 实例,避免重复创建 + - 添加播放状态标志,防止重复播放 + - 播放前停止当前播放,确保音频可以重复播放 + +### 功能优化 +- 🔊 **声音反馈开关** + - 在 `lib/views/profile/settings/app_fun.dart` 中添加声音反馈开关 + - 默认关闭声音反馈,可在设置中开启 + - 状态持久化到 SharedPreferences + - 与 AudioManager 集成,控制首页音效播放 +- 🔊 **悬浮按钮音频播放** + - 修改 `lib/views/home/home_part.dart` 中的悬浮按钮组件 + - 为上一条、下一条、点赞按钮添加音频播放功能 + - 确保操作时的声音反馈与设置中的开关状态同步 --- @@ -32,6 +56,7 @@ All notable changes to this project will be documented in this file. - 显示bug优先级(高/中/低)、状态(已解决/解决中/待解决) - 显示影响用户范围、报告时间和预计解决时间 - 提供详细的解决方案描述 + - 新增复现步骤功能,支持查看和收起复现步骤 - 修改个人页面"已知bug"按钮点击事件,从显示SnackBar改为弹出bug列表页面 - 文件:`lib/views/profile/profile_page.dart` @@ -113,34 +138,7 @@ All notable changes to this project will be documented in this file. - 缓存状态同时显示诗句和答题数量 - 文件:`lib/views/profile/settings/offline-data.dart` ---- -## [1.2.99] - 2026-03-29 - -### 新增 -- 🌐 **离线模式支持** - - 新增 `OfflineDataManager` 类管理离线数据加载 - - 离线状态时从本地缓存加载诗句,在线状态时从网络加载 - - 支持循环加载本地缓存的诗句 - - 离线模式下隐藏点赞按钮 - - 无缓存时显示网络错误提示 - - 优化数据加载逻辑,确保离线模式正常工作 - - 文件:`lib/views/home/home-load.dart`, `lib/views/home/home_page.dart` - ---- - -## [1.2.98] - 2026-03-29 - -### 新增 -- 🔄 **个人卡片在线/离线状态切换** - - 在个人卡片tips卡片内添加在线状态开关 - - 开关状态保存到SharedPreferences,默认开启 - - 关闭后切换为离线状态,个人头像右下角绿勾切换成红勾(关闭图标) - - 支持点击tips卡片切换祝福语功能 - - 优化开关布局:开关位于卡片右侧,与文本平行显示 - - 移除状态文字,保持界面简洁 - - 状态切换时显示气泡消息提示 - - 文件:`lib/views/profile/per_card.dart` --- @@ -168,6 +166,8 @@ All notable changes to this project will be documented in this file. - 🎨 **卡片样式优化** - 经典和现代样式颜色统一,毛玻璃样式优化 - 🐛 **卡片设置页面重复打开问题修复** - 使用 router.replaceUrl 替换当前页面,避免堆叠 - 📐 **2x2卡片布局优化** - 移除天气按钮组件,保留城市名称显示 +- 🌐 **离线模式支持** - 新增 `OfflineDataManager` 类管理离线数据加载、离线状态时从本地缓存加载诗句、在线状态时从网络加载、支持循环加载本地缓存的诗句、离线模式下隐藏点赞按钮、无缓存时显示网络错误提示、优化数据加载逻辑 +- 🔄 **个人卡片在线/离线状态切换** - 在个人卡片tips卡片内添加在线状态开关、开关状态保存到SharedPreferences、关闭后切换为离线状态、支持点击tips卡片切换祝福语功能、优化开关布局、状态切换时显示气泡消息提示 ### 开发进度 - 🏗️ **HarmonyOS桌面小组件** - 开发中,包含2x2布局、天气显示、诗句展示等功能 diff --git a/lib/controllers/history_controller.dart b/lib/controllers/history_controller.dart index 1398c7e..9d06b06 100644 --- a/lib/controllers/history_controller.dart +++ b/lib/controllers/history_controller.dart @@ -32,7 +32,6 @@ class HistoryController { .map((item) => Map.from(item)) .toList(); } catch (e) { - print('获取历史记录失败: $e'); return []; } } @@ -42,57 +41,42 @@ class HistoryController { /// 如果诗词已存在,则不会重复添加 /// 返回是否添加成功 static Future addToHistory(Map poetryData) async { - // 防止并发调用 if (_isAdding) { - print('正在添加历史记录,跳过重复调用: ${poetryData['name']}'); return false; } _isAdding = true; try { - print('开始添加历史记录: ${poetryData['name']} (ID: ${poetryData['id']})'); - final historyJson = await SQLiteStorageController.getString( _historyKey, defaultValue: '[]', ); final List historyList = json.decode(historyJson); - print('当前历史记录数量: ${historyList.length}'); - - // 检查是否已存在相同的诗词 final existingIndex = historyList.indexWhere( (item) => item['id'] == poetryData['id'], ); if (existingIndex >= 0) { - print('诗词已存在于历史记录中: ${poetryData['name']} (索引: $existingIndex)'); return false; } - // 添加时间戳和日期 final enrichedPoetryData = Map.from(poetryData); enrichedPoetryData['timestamp'] = DateTime.now().millisecondsSinceEpoch; enrichedPoetryData['date'] = DateTime.now().toString().split(' ')[0]; - // 插入到列表开头 historyList.insert(0, enrichedPoetryData); - // 保持最多指定数量的记录 if (historyList.length > _maxHistoryCount) { historyList.removeRange(_maxHistoryCount, historyList.length); } - // 保存到本地存储 final updatedHistoryJson = json.encode(historyList); await SQLiteStorageController.setString(_historyKey, updatedHistoryJson); - print('已添加到历史记录: ${poetryData['name']} (新数量: ${historyList.length})'); - return true; } catch (e) { - print('添加历史记录失败: $e'); return false; } finally { _isAdding = false; @@ -104,8 +88,6 @@ class HistoryController { /// 返回是否移除成功 static Future removeFromHistory(int poetryId) async { try { - print('开始删除历史记录: 诗词ID $poetryId'); - final historyJson = await SQLiteStorageController.getString( _historyKey, defaultValue: '[]', @@ -113,40 +95,21 @@ class HistoryController { final List historyList = json.decode(historyJson); final originalLength = historyList.length; - print('删除前历史记录数量: $originalLength'); - // 查找匹配的记录 - final matchingItems = []; - for (int i = 0; i < historyList.length; i++) { - if (historyList[i]['id'] == poetryId) { - matchingItems.add(i); - } - } - - print('找到匹配的记录索引: $matchingItems'); - - // 移除指定ID的诗词 historyList.removeWhere((item) => item['id'] == poetryId); if (historyList.length < originalLength) { - // 保存更新后的列表 final updatedHistoryJson = json.encode(historyList); await SQLiteStorageController.setString( _historyKey, updatedHistoryJson, ); - print( - '已从历史记录中移除诗词ID: $poetryId (删除了 ${originalLength - historyList.length} 条记录,剩余 ${historyList.length} 条)', - ); - return true; } - print('未找到要删除的诗词ID: $poetryId'); return false; } catch (e) { - print('移除历史记录失败: $e'); return false; } } @@ -156,44 +119,30 @@ class HistoryController { static Future clearHistory() async { try { await SQLiteStorageController.remove(_historyKey); - - print('已清空所有历史记录'); - return true; } catch (e) { - print('清空历史记录失败: $e'); return false; } } - /// 获取历史记录数量 - /// 返回当前历史记录的总数 static Future getHistoryCount() async { try { final history = await getHistory(); return history.length; } catch (e) { - print('获取历史记录数量失败: $e'); return 0; } } - /// 检查诗词是否在历史记录中 - /// [poetryId] 要检查的诗词ID - /// 返回是否存在 static Future isInHistory(int poetryId) async { try { final history = await getHistory(); return history.any((item) => item['id'] == poetryId); } catch (e) { - print('检查历史记录失败: $e'); return false; } } - /// 搜索历史记录 - /// [keyword] 搜索关键词 - /// 返回匹配的历史记录列表 static Future>> searchHistory( String keyword, ) async { @@ -215,7 +164,6 @@ class HistoryController { introduce.contains(lowerKeyword); }).toList(); } catch (e) { - print('搜索历史记录失败: $e'); return []; } } @@ -285,20 +233,15 @@ class HistoryController { 'topDynasties': Map.fromEntries(sortedDynasties), }; } catch (e) { - print('获取历史记录统计失败: $e'); return {}; } } - /// 导出历史记录 - /// [format] 导出格式 ('json' | 'csv') - /// 返回导出的字符串 static Future exportHistory({String format = 'json'}) async { try { final history = await getHistory(); if (format.toLowerCase() == 'csv') { - // CSV格式导出 final buffer = StringBuffer(); buffer.writeln('ID,诗词名称,朝代,译文,原文,日期,时间戳'); @@ -310,11 +253,9 @@ class HistoryController { return buffer.toString(); } else { - // JSON格式导出 return json.encode(history); } } catch (e) { - print('导出历史记录失败: $e'); return ''; } } @@ -336,38 +277,26 @@ class HistoryController { final List likedList = json.decode(likedJson); return likedList.map((item) => Map.from(item)).toList(); } catch (e) { - print('获取点赞列表失败: $e'); return []; } } - /// 添加诗词到点赞列表 - /// [poetryData] 要保存的诗词数据 - /// 如果诗词已存在,则不会重复添加 - /// 返回是否添加成功 static Future addToLiked(Map poetryData) async { try { - print('开始添加点赞记录: ${poetryData['name']} (ID: ${poetryData['id']})'); - final likedJson = await SQLiteStorageController.getString( _likedKey, defaultValue: '[]', ); final List likedList = json.decode(likedJson); - print('当前点赞记录数量: ${likedList.length}'); - - // 检查是否已存在相同的诗词 final existingIndex = likedList.indexWhere( (item) => item['id'] == poetryData['id'], ); if (existingIndex >= 0) { - print('诗词已存在于点赞记录中: ${poetryData['name']} (索引: $existingIndex)'); return false; } - // 添加时间戳和日期 final enrichedPoetryData = Map.from(poetryData); final now = DateTime.now(); enrichedPoetryData['liked_timestamp'] = now.millisecondsSinceEpoch; @@ -375,29 +304,19 @@ class HistoryController { enrichedPoetryData['liked_time'] = '${now.hour.toString().padLeft(2, '0')}:${now.minute.toString().padLeft(2, '0')}'; - // 插入到列表开头 likedList.insert(0, enrichedPoetryData); - // 保存到本地存储 final updatedLikedJson = json.encode(likedList); await SQLiteStorageController.setString(_likedKey, updatedLikedJson); - print('已添加到点赞记录: ${poetryData['name']} (新数量: ${likedList.length})'); - return true; } catch (e) { - print('添加点赞记录失败: $e'); return false; } } - /// 从点赞列表中移除指定诗词 - /// [poetryId] 要移除的诗词ID - /// 返回是否移除成功 static Future removeLikedPoetry(String poetryId) async { try { - print('开始删除点赞记录: 诗词ID $poetryId'); - final likedJson = await SQLiteStorageController.getString( _likedKey, defaultValue: '[]', @@ -405,67 +324,45 @@ class HistoryController { final List likedList = json.decode(likedJson); final originalLength = likedList.length; - print('删除前点赞记录数量: $originalLength'); - // 移除指定ID的诗词 likedList.removeWhere((item) => item['id'].toString() == poetryId); if (likedList.length < originalLength) { - // 保存更新后的列表 final updatedLikedJson = json.encode(likedList); await SQLiteStorageController.setString(_likedKey, updatedLikedJson); - print( - '已从点赞记录中移除诗词ID: $poetryId (删除了 ${originalLength - likedList.length} 条记录,剩余 ${likedList.length} 条)', - ); - return true; } - print('未找到要删除的诗词ID: $poetryId'); return false; } catch (e) { - print('移除点赞记录失败: $e'); return false; } } - /// 检查诗词是否在点赞列表中 - /// [poetryId] 要检查的诗词ID - /// 返回是否存在 static Future isInLiked(String poetryId) async { try { final likedList = await getLikedHistory(); return likedList.any((item) => item['id'].toString() == poetryId); } catch (e) { - print('检查点赞记录失败: $e'); return false; } } - /// 清空所有点赞记录 - /// 返回是否清空成功 static Future clearLikedHistory() async { try { await SQLiteStorageController.remove(_likedKey); - - print('已清空所有点赞记录'); - return true; } catch (e) { - print('清空点赞记录失败: $e'); return false; } } - /// 获取点赞记录数量 - /// 返回当前点赞记录的总数 static Future getLikedCount() async { try { final likedList = await getLikedHistory(); return likedList.length; } catch (e) { - print('获取点赞记录数量失败: $e'); return 0; } } @@ -510,7 +407,6 @@ class HistoryController { return notes; } catch (e) { - print('获取笔记列表失败: $e'); return _getDefaultNotes(); } } @@ -635,16 +531,12 @@ class HistoryController { final notesJson = json.encode(notes); await SQLiteStorageController.setString(_notesKey, notesJson); - print('保存笔记成功: $id, 置顶: $pinned, 锁定: $locked, 分类: $cat'); return id; } catch (e) { - print('保存笔记失败: $e'); return null; } } - /// 获取单个笔记 - /// [noteId] 笔记ID static Future?> getNote(String noteId) async { try { final notes = await getNotes(); @@ -653,7 +545,6 @@ class HistoryController { orElse: () => {}, ); } catch (e) { - print('获取笔记失败: $e'); return null; } } @@ -668,24 +559,18 @@ class HistoryController { final notesJson = json.encode(notes); await SQLiteStorageController.setString(_notesKey, notesJson); - print('删除笔记成功: $noteId'); return true; } catch (e) { - print('删除笔记失败: $e'); return false; } } - /// 切换笔记置顶状态 - /// [noteId] 笔记ID - /// 返回新的置顶状态 static Future togglePinNote(String noteId) async { try { final notes = await getNotes(); final index = notes.indexWhere((n) => n['id'] == noteId); if (index == -1) { - print('未找到笔记: $noteId'); return false; } @@ -695,34 +580,25 @@ class HistoryController { final notesJson = json.encode(notes); await SQLiteStorageController.setString(_notesKey, notesJson); - print('切换置顶状态: $noteId, 新状态: ${!currentPinned}'); return !currentPinned; } catch (e) { - print('切换置顶状态失败: $e'); return false; } } - /// 设置笔记密码 - /// [noteId] 笔记ID - /// [password] 密码(为空则取消锁定) - /// 返回是否成功 static Future setNotePassword(String noteId, String? password) async { try { final notes = await getNotes(); final index = notes.indexWhere((n) => n['id'] == noteId); if (index == -1) { - print('未找到笔记: $noteId'); return false; } if (password == null || password.isEmpty) { - // 取消锁定 notes[index]['isLocked'] = false; notes[index]['password'] = null; } else { - // 设置密码并锁定 notes[index]['isLocked'] = true; notes[index]['password'] = password; } @@ -730,20 +606,12 @@ class HistoryController { final notesJson = json.encode(notes); await SQLiteStorageController.setString(_notesKey, notesJson); - print( - '设置笔记密码成功: $noteId, 锁定: ${password != null && password.isNotEmpty}', - ); return true; } catch (e) { - print('设置笔记密码失败: $e'); return false; } } - /// 验证笔记密码 - /// [noteId] 笔记ID - /// [password] 输入的密码 - /// 返回是否验证成功 static Future verifyNotePassword(String noteId, String password) async { try { final notes = await getNotes(); @@ -753,30 +621,25 @@ class HistoryController { ); if (note.isEmpty) { - print('未找到笔记: $noteId'); return false; } final storedPassword = note['password'] as String?; if (storedPassword == null || storedPassword.isEmpty) { - // 没有密码,直接通过 return true; } return storedPassword == password; } catch (e) { - print('验证笔记密码失败: $e'); return false; } } - /// 获取笔记数量 static Future getNotesCount() async { try { final notes = await getNotes(); return notes.length; } catch (e) { - print('获取笔记数量失败: $e'); return 0; } } diff --git a/lib/controllers/load/locally.dart b/lib/controllers/load/locally.dart index 3c23795..b841a09 100644 --- a/lib/controllers/load/locally.dart +++ b/lib/controllers/load/locally.dart @@ -56,7 +56,7 @@ class LocalCacheManager { return decoded.cast>(); } } catch (e) { - print('解析缓存数据失败: $e'); + // 解析失败 } return null; diff --git a/lib/controllers/sqlite_storage_controller.dart b/lib/controllers/sqlite_storage_controller.dart index 826b53a..781fc8e 100644 --- a/lib/controllers/sqlite_storage_controller.dart +++ b/lib/controllers/sqlite_storage_controller.dart @@ -13,13 +13,8 @@ class SQLiteStorageController { /// 初始化SharedPreferences static Future init() async { try { - print('开始初始化SharedPreferences...'); - _prefs = await SharedPreferences.getInstance(); - - print('SharedPreferences初始化成功'); } catch (e) { - print('SharedPreferences初始化失败: $e'); throw e; } } @@ -37,9 +32,7 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.setString(key, value); - print('设置字符串值: $key'); } catch (e) { - print('设置字符串值失败: $e'); throw e; } } @@ -52,10 +45,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); final value = instance.getString(key) ?? defaultValue; - print('获取字符串值: $key = $value'); return value; } catch (e) { - print('获取字符串值失败: $e'); return defaultValue; } } @@ -65,9 +56,7 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.setInt(key, value); - print('设置整数值: $key = $value'); } catch (e) { - print('设置整数值失败: $e'); throw e; } } @@ -77,10 +66,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); final value = instance.getInt(key) ?? defaultValue; - print('获取整数值: $key = $value'); return value; } catch (e) { - print('获取整数值失败: $e'); return defaultValue; } } @@ -90,9 +77,7 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.setBool(key, value); - print('设置布尔值: $key = $value'); } catch (e) { - print('设置布尔值失败: $e'); throw e; } } @@ -102,10 +87,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); final value = instance.getBool(key) ?? defaultValue; - print('获取布尔值: $key = $value'); return value; } catch (e) { - print('获取布尔值失败: $e'); return defaultValue; } } @@ -115,9 +98,7 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.setDouble(key, value); - print('设置双精度值: $key = $value'); } catch (e) { - print('设置双精度值失败: $e'); throw e; } } @@ -130,10 +111,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); final value = instance.getDouble(key) ?? defaultValue; - print('获取双精度值: $key = $value'); return value; } catch (e) { - print('获取双精度值失败: $e'); return defaultValue; } } @@ -143,9 +122,7 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.setStringList(key, value); - print('设置字符串列表: $key (数量: ${value.length})'); } catch (e) { - print('设置字符串列表失败: $e'); throw e; } } @@ -158,10 +135,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); final value = instance.getStringList(key) ?? defaultValue ?? []; - print('获取字符串列表: $key (数量: ${value.length})'); return value; } catch (e) { - print('获取字符串列表失败: $e'); return defaultValue ?? []; } } @@ -171,9 +146,7 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.remove(key); - print('移除存储值: $key'); } catch (e) { - print('移除存储值失败: $e'); throw e; } } @@ -183,9 +156,7 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.clear(); - print('清空所有存储'); } catch (e) { - print('清空存储失败: $e'); throw e; } } @@ -195,10 +166,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); final keys = instance.getKeys(); - print('获取存储键: ${keys.length}个'); return keys; } catch (e) { - print('获取存储键失败: $e'); return {}; } } @@ -208,10 +177,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); final exists = instance.containsKey(key); - print('检查键存在: $key = $exists'); return exists; } catch (e) { - print('检查键存在失败: $e'); return false; } } @@ -221,9 +188,8 @@ class SQLiteStorageController { try { final instance = await _getInstance(); await instance.reload(); - print('重新加载存储数据'); } catch (e) { - print('重新加载数据失败: $e'); + // 忽略错误 } } } diff --git a/lib/services/network_listener_service.dart b/lib/services/network_listener_service.dart index 6c04dbc..f52c333 100644 --- a/lib/services/network_listener_service.dart +++ b/lib/services/network_listener_service.dart @@ -69,46 +69,30 @@ class NetworkListenerService { void startLoading(String key) { _loadingStates[key] = true; _updateStatus(NetworkStatus.loading); - - if (kDebugMode) { - print('NetworkListener: 开始加载 - $key'); - } } /// 结束网络操作 void endLoading(String key) { _loadingStates.remove(key); - + if (_loadingStates.isEmpty) { _updateStatus(NetworkStatus.idle); } - - if (kDebugMode) { - print('NetworkListener: 结束加载 - $key'); - } } /// 发送成功事件 void sendSuccessEvent(NetworkEventType type, {String? data}) { _updateStatus(NetworkStatus.success); _eventController.add(NetworkEvent(type: type, data: data)); - - if (kDebugMode) { - print('NetworkListener: 成功事件 - $type, 数据: $data'); - } } /// 发送错误事件 void sendErrorEvent(NetworkEventType type, {String? errorMessage}) { _updateStatus(NetworkStatus.error); _eventController.add(NetworkEvent( - type: type, + type: type, errorMessage: errorMessage, )); - - if (kDebugMode) { - print('NetworkListener: 错误事件 - $type, 错误: $errorMessage'); - } } /// 发送点赞事件 @@ -132,10 +116,6 @@ class NetworkListenerService { if (_status != newStatus) { _status = newStatus; _statusController.add(_status); - - if (kDebugMode) { - print('NetworkListener: 状态更新 - $newStatus'); - } } } diff --git a/lib/utils/audio_manager.dart b/lib/utils/audio_manager.dart index fc4a93d..bddba64 100644 --- a/lib/utils/audio_manager.dart +++ b/lib/utils/audio_manager.dart @@ -1,20 +1,18 @@ import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/foundation.dart'; +import 'package:shared_preferences/shared_preferences.dart'; /// 时间: 2026-03-30 /// 功能: 音频管理类 /// 介绍: 管理应用中的音效播放,包括点击音效、点赞音效等 -/// 最新变化: 新增音频播放功能 +/// 最新变化: 使用最简单的音频播放方式 class AudioManager { static AudioManager? _instance; - late AudioPlayer _audioPlayer; bool _isInitialized = false; bool _isMuted = false; - AudioManager._internal() { - _audioPlayer = AudioPlayer(); - } + AudioManager._internal(); factory AudioManager() { _instance ??= AudioManager._internal(); @@ -25,73 +23,64 @@ class AudioManager { if (_isInitialized) return; try { - // 设置音频播放器模式 - await _audioPlayer.setPlayerMode(PlayerMode.lowLatency); + await _loadSoundSetting(); _isInitialized = true; - _debugLog('音频管理器初始化成功'); } catch (e) { - _debugLog('音频管理器初始化失败: $e'); + // 初始化失败 + } + } + + /// 加载保存的声音设置 + Future _loadSoundSetting() async { + try { + final prefs = await SharedPreferences.getInstance(); + bool soundEnabled = prefs.getBool('sound_enabled') ?? false; + _isMuted = !soundEnabled; + } catch (e) { + // 加载设置失败 } } /// 播放点击音效 - Future playClickSound() async { - if (_isMuted) return; - await _playSound('audios/deep.mp3'); + void playClickSound() { + _playSound('audios/deep.mp3'); } /// 播放点赞音效 - Future playLikeSound() async { - if (_isMuted) return; - await _playSound('audios/deep.mp3'); + void playLikeSound() { + _playSound('audios/deep.mp3'); } /// 播放下一条音效 - Future playNextSound() async { - if (_isMuted) return; - await _playSound('audios/deep.mp3'); + void playNextSound() { + _playSound('audios/deep.mp3'); } - /// 通用播放方法 - Future _playSound(String assetPath) async { - if (!_isInitialized) { - await init(); - } + /// 播放音频 + void _playSound(String assetPath) { + if (_isMuted) return; + _playSoundAsync(assetPath); + } + /// 异步播放音频 + void _playSoundAsync(String assetPath) async { try { - // 停止当前播放的音频 - await _audioPlayer.stop(); - // 播放新音频 - await _audioPlayer.play(AssetSource(assetPath)); - _debugLog('播放音效: $assetPath'); + final player = AudioPlayer(); + await player.play(AssetSource(assetPath)); + + player.onPlayerComplete.listen((_) { + player.dispose(); + }); } catch (e) { - _debugLog('播放音效失败: $e'); + // 播放失败 } } /// 设置静音状态 void setMuted(bool muted) { _isMuted = muted; - _debugLog('静音状态: $_isMuted'); } /// 获取静音状态 bool get isMuted => _isMuted; - - /// 释放资源 - Future dispose() async { - try { - await _audioPlayer.dispose(); - _isInitialized = false; - _debugLog('音频管理器已释放'); - } catch (e) { - _debugLog('释放音频管理器失败: $e'); - } - } - - void _debugLog(String message) { - if (kDebugMode) { - print('[AudioManager] $message'); - } - } } diff --git a/lib/utils/http/http_client.dart b/lib/utils/http/http_client.dart index 9eeb829..878a7e4 100644 --- a/lib/utils/http/http_client.dart +++ b/lib/utils/http/http_client.dart @@ -26,13 +26,6 @@ class HttpClient { static final Dio _dio = Dio(_options); - /// 添加调试日志 - static void _debugLog(String message) { - if (kDebugMode) { - print('HttpClient: $message'); - } - } - /// GET请求 static Future get( String path, { @@ -92,10 +85,6 @@ class HttpClient { }) async { try { final url = '$_baseUrl$path'; - _debugLog('请求 $method $url'); - if (queryParameters != null) { - _debugLog('查询参数: $queryParameters'); - } final options = Options( method: method, @@ -129,9 +118,6 @@ class HttpClient { throw UnsupportedError('HTTP method $method is not supported'); } - _debugLog('响应状态: ${response.statusCode}'); - _debugLog('响应数据: ${response.data}'); - return HttpResponse( statusCode: response.statusCode ?? 0, body: response.data is String @@ -140,7 +126,6 @@ class HttpClient { headers: response.headers.map.cast(), ); } on DioException catch (e) { - _debugLog('Dio异常: ${e.type} - ${e.message}'); String message; switch (e.type) { case DioExceptionType.connectionTimeout: @@ -159,7 +144,6 @@ class HttpClient { } throw HttpException(message); } catch (e) { - _debugLog('未知异常: $e'); throw HttpException('请求失败:$e'); } } @@ -175,13 +159,6 @@ class HttpClient { }) async { try { final url = '$_baseUrl$path'; - _debugLog('FormData请求 $method $url'); - if (queryParameters != null) { - _debugLog('查询参数: $queryParameters'); - } - if (data != null) { - _debugLog('表单数据: $data'); - } final formData = FormData.fromMap(data ?? {}); @@ -213,9 +190,6 @@ class HttpClient { throw UnsupportedError('FormData only supports POST method'); } - _debugLog('响应状态: ${response.statusCode}'); - _debugLog('响应数据: ${response.data}'); - return HttpResponse( statusCode: response.statusCode ?? 0, body: response.data is String @@ -224,7 +198,6 @@ class HttpClient { headers: response.headers.map.cast(), ); } on DioException catch (e) { - _debugLog('Dio异常: ${e.type} - ${e.message}'); String message; switch (e.type) { case DioExceptionType.connectionTimeout: @@ -243,7 +216,6 @@ class HttpClient { } throw HttpException(message); } catch (e) { - _debugLog('未知异常: $e'); throw HttpException('请求失败:$e'); } } diff --git a/lib/utils/http/poetry_api.dart b/lib/utils/http/poetry_api.dart index b0be85c..00d61a3 100644 --- a/lib/utils/http/poetry_api.dart +++ b/lib/utils/http/poetry_api.dart @@ -269,11 +269,6 @@ class PoetryData { }); factory PoetryData.fromJson(Map json) { - // 添加调试信息 - if (kDebugMode) { - print('PoetryData.fromJson: 输入JSON = $json'); - } - try { final poetryData = PoetryData( id: int.tryParse(json['id'].toString()) ?? 0, @@ -295,16 +290,9 @@ class PoetryData { createTime: json['create_time']?.toString() ?? '', updateTime: json['update_time']?.toString() ?? '', ); - - if (kDebugMode) { - print('PoetryData.fromJson: 解析成功'); - } - + return poetryData; } catch (e) { - if (kDebugMode) { - print('PoetryData.fromJson: 解析失败 - $e'); - } rethrow; } } diff --git a/lib/utils/http/vote_api.dart b/lib/utils/http/vote_api.dart index 755d95a..3e4458a 100644 --- a/lib/utils/http/vote_api.dart +++ b/lib/utils/http/vote_api.dart @@ -34,32 +34,19 @@ class VoteApi { static final Dio _dio = Dio(_options) ..interceptors.add(CookieManager(_cookieJar)); - static void _debugLog(String message) { - if (kDebugMode) { - print('VoteApi: $message'); - } - } - static Future> _get( String path, { Map? queryParameters, }) async { try { final url = '$_baseUrl$path'; - _debugLog('GET $url'); - if (queryParameters != null) { - _debugLog('查询参数: $queryParameters'); - } final response = await _dio.get(url, queryParameters: queryParameters); - _debugLog('响应: ${response.data}'); return response.data as Map; } on DioException catch (e) { - _debugLog('Dio异常: ${e.type} - ${e.message}'); throw Exception('请求失败: ${e.message}'); } catch (e) { - _debugLog('未知异常: $e'); throw Exception('请求失败: $e'); } } @@ -70,20 +57,13 @@ class VoteApi { }) async { try { final url = '$_baseUrl$path'; - _debugLog('POST $url'); - if (data != null) { - _debugLog('请求数据: $data'); - } final response = await _dio.post(url, data: data); - _debugLog('响应: ${response.data}'); return response.data as Map; } on DioException catch (e) { - _debugLog('Dio异常: ${e.type} - ${e.message}'); throw Exception('请求失败: ${e.message}'); } catch (e) { - _debugLog('未知异常: $e'); throw Exception('请求失败: $e'); } } diff --git a/lib/views/active/popular_page.dart b/lib/views/active/popular_page.dart index 4f51719..f569a2b 100644 --- a/lib/views/active/popular_page.dart +++ b/lib/views/active/popular_page.dart @@ -337,10 +337,8 @@ class _PopularPageState extends State final isPreloadEnabled = await LocalCacheManager().isPreloadEnabled(); if (isPreloadEnabled && !forceRefresh) { - print('预加载模式:尝试从本地缓存加载数据'); final cachedData = await LocalCacheManager().getCachedPopularList(type); if (cachedData != null && cachedData.isNotEmpty) { - print('从本地缓存加载数据成功'); if (mounted) { setState(() { _rankList = cachedData @@ -351,29 +349,19 @@ class _PopularPageState extends State } return; } - print('本地缓存为空,从服务器加载'); } - print('正在请求排行榜数据: type=$type, period=$type'); - final response = await HttpClient.get( '/rlist.php', queryParameters: {'type': type, 'limit': '20'}, ); - print('API响应状态: ${response.statusCode}'); - print('API响应成功: ${response.isSuccess}'); - print('API响应代码: ${response.code}'); - print('API响应消息: ${response.message}'); - print('API响应数据: ${response.data}'); - if (response.isSuccess && response.code == 0) { final data = response.data; final rankData = data['list'] as List? ?? []; final rankDataList = rankData.cast>(); if (isPreloadEnabled) { - print('保存数据到本地缓存'); await LocalCacheManager().cachePopularList(type, rankDataList); } diff --git a/lib/views/footprint/collect_notes.dart b/lib/views/footprint/collect_notes.dart index 265c650..3adde8f 100644 --- a/lib/views/footprint/collect_notes.dart +++ b/lib/views/footprint/collect_notes.dart @@ -100,7 +100,7 @@ class _CollectNotesPageState extends State { _category = note['category'] ?? _categoryOptions[0]; } } catch (e) { - print('加载笔记失败: $e'); + // 加载失败 } setState(() { @@ -150,14 +150,13 @@ class _CollectNotesPageState extends State { _createTime = _lastSavedTime; } setState(() {}); - print('笔记已自动保存'); NetworkListenerService().sendSuccessEvent( NetworkEventType.noteUpdate, data: noteId, ); } } catch (e) { - print('保存笔记失败: $e'); + // 保存失败 } } diff --git a/lib/views/footprint/footprint_page.dart b/lib/views/footprint/footprint_page.dart index 01c5bc1..4a8664e 100644 --- a/lib/views/footprint/footprint_page.dart +++ b/lib/views/footprint/footprint_page.dart @@ -93,11 +93,8 @@ class _FootprintPageState extends State Future _showPoetryDetails(PoetryData poetry) async { try { - print('DEBUG: 点击查看详情 - Poetry ID: ${poetry.id}'); - // 从SQLite获取完整数据 final likedList = await HistoryController.getLikedHistory(); - print('DEBUG: 获取到 ${likedList.length} 条点赞记录'); // 查找对应的诗词数据,优先使用存储的完整数据 Map poetryData; @@ -106,14 +103,10 @@ class _FootprintPageState extends State (item) => item['id'].toString() == poetry.id.toString(), orElse: () => poetry.toJson(), ); - print('DEBUG: 找到匹配的诗词数据'); } catch (e) { - print('DEBUG: 未找到匹配数据,使用当前poetry数据'); poetryData = poetry.toJson(); } - print('DEBUG: 诗词数据字段: ${poetryData.keys.toList()}'); - if (mounted) { showModalBottomSheet( context: context, @@ -301,7 +294,6 @@ class _FootprintPageState extends State ); } } catch (e) { - print('DEBUG: 显示详情失败 - $e'); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -666,7 +658,6 @@ class _FootprintPageState extends State Expanded( child: ElevatedButton.icon( onPressed: () { - print('DEBUG: 查看详情按钮被点击 - Poetry ID: ${poetry.id}'); _showPoetryDetails(poetry); }, icon: const Icon(Icons.visibility, size: 18), diff --git a/lib/views/footprint/local_jilu.dart b/lib/views/footprint/local_jilu.dart index 56b97e9..d7cbb62 100644 --- a/lib/views/footprint/local_jilu.dart +++ b/lib/views/footprint/local_jilu.dart @@ -62,7 +62,6 @@ class _LocalNotesListState extends State { }); } } catch (e) { - print('加载笔记失败: $e'); if (mounted) { setState(() { _isLoadingNotes = false; @@ -528,7 +527,7 @@ class _LocalNotesListState extends State { ).showSnackBar(const SnackBar(content: Text('已更新置顶状态'))); } } catch (e) { - print('切换置顶失败: $e'); + // 切换失败 } } diff --git a/lib/views/home/home-load.dart b/lib/views/home/home-load.dart index dcd3de8..00b824e 100644 --- a/lib/views/home/home-load.dart +++ b/lib/views/home/home-load.dart @@ -28,7 +28,6 @@ class AutoRefreshManager { Future init() async { final prefs = await SharedPreferences.getInstance(); _isEnabled = prefs.getBool(_autoRefreshKey) ?? false; - _debugLog('自动刷新初始化,状态: $_isEnabled'); } bool get isEnabled => _isEnabled; @@ -37,7 +36,6 @@ class AutoRefreshManager { _isEnabled = enabled; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_autoRefreshKey, enabled); - _debugLog('自动刷新状态已设置: $enabled'); if (enabled) { _startTimer(); @@ -48,25 +46,21 @@ class AutoRefreshManager { void setOnRefresh(VoidCallback? callback) { _onRefresh = callback; - _debugLog('设置刷新回调'); } void _startTimer() { _stopTimer(); _refreshTimer = Timer.periodic(_refreshInterval, (timer) { - _debugLog('自动刷新触发'); if (_onRefresh != null) { _onRefresh!(); } }); - _debugLog('自动刷新定时器已启动'); } void _stopTimer() { if (_refreshTimer != null) { _refreshTimer!.cancel(); _refreshTimer = null; - _debugLog('自动刷新定时器已停止'); } } @@ -77,11 +71,6 @@ class AutoRefreshManager { void dispose() { _stopTimer(); _onRefresh = null; - _debugLog('自动刷新管理器已释放'); - } - - void _debugLog(String message) { - if (kDebugMode) {} } } @@ -103,7 +92,6 @@ class DebugInfoManager { Future init() async { final prefs = await SharedPreferences.getInstance(); _isEnabled = prefs.getBool(_debugInfoKey) ?? false; - _debugLog('调试信息初始化,状态: $_isEnabled'); } bool get isEnabled => _isEnabled; @@ -113,7 +101,6 @@ class DebugInfoManager { _isEnabled = enabled; final prefs = await SharedPreferences.getInstance(); await prefs.setBool(_debugInfoKey, enabled); - _debugLog('调试信息状态已设置: $enabled'); if (!enabled) { _messageNotifier.value = ''; @@ -124,12 +111,10 @@ class DebugInfoManager { if (!_isEnabled) return; _messageNotifier.value = message; - _debugLog('显示调试信息: $message'); _messageTimer?.cancel(); _messageTimer = Timer(const Duration(seconds: 2), () { _messageNotifier.value = ''; - _debugLog('调试信息已隐藏'); }); } @@ -176,11 +161,6 @@ class DebugInfoManager { void dispose() { _messageTimer?.cancel(); _messageNotifier.value = ''; - _debugLog('调试信息管理器已清理'); - } - - void _debugLog(String message) { - if (kDebugMode) {} } } @@ -201,7 +181,6 @@ class OfflineDataManager { Future init() async { await _loadCachedData(); - _debugLog('离线数据管理器初始化,缓存数量: ${_cachedPoetryList.length}'); } Future isOnline() async { @@ -273,7 +252,7 @@ class OfflineDataManager { _cachedPoetryList.add(map); } catch (e) { - _debugLog('解析缓存数据失败: $e'); + // 解析失败 } } } @@ -320,12 +299,7 @@ class OfflineDataManager { updateTime: updateTime, ); } catch (e) { - _debugLog('转换为PoetryData失败: $e'); return null; } } - - void _debugLog(String message) { - if (kDebugMode) {} - } } diff --git a/lib/views/home/home_page.dart b/lib/views/home/home_page.dart index 6b4f38a..1734246 100644 --- a/lib/views/home/home_page.dart +++ b/lib/views/home/home_page.dart @@ -293,8 +293,8 @@ class _HomePageState extends State Future _toggleLike() async { if (_poetryData == null || _isLoadingLike) return; - // 播放点赞音效 - await AudioManager().playLikeSound(); + // 播放点赞音效(不等待完成) + AudioManager().playLikeSound(); // 立即切换按钮状态和显示加载 setState(() { @@ -397,7 +397,7 @@ class _HomePageState extends State }); } } catch (e) { - print('加载历史记录失败: $e'); + // 加载失败 } } @@ -413,7 +413,7 @@ class _HomePageState extends State await HistoryController.addToHistory(poetryMap); } catch (e) { - print('保存历史记录失败: $e'); + // 保存失败 } } @@ -434,8 +434,8 @@ class _HomePageState extends State void _loadNextPoetry() async { if (_isLoadingNext) return; - // 播放下一条音效 - await AudioManager().playNextSound(); + // 播放下一条音效(不等待完成) + AudioManager().playNextSound(); setState(() { _isLoadingNext = true; diff --git a/lib/views/home/home_part.dart b/lib/views/home/home_part.dart index 0802531..8ba8615 100644 --- a/lib/views/home/home_part.dart +++ b/lib/views/home/home_part.dart @@ -106,9 +106,9 @@ class _PoetryCardState extends State { @override Widget build(BuildContext context) { return GestureDetector( - onTap: () async { - // 播放点击音效 - await AudioManager().playClickSound(); + onTap: () { + // 播放点击音效(不等待完成) + AudioManager().playClickSound(); // 调用原始的onTap回调 widget.onTap?.call(); }, @@ -715,6 +715,7 @@ class FloatingPreviousButton extends StatelessWidget { borderRadius: BorderRadius.circular(28), onTap: () { HapticFeedback.lightImpact(); + AudioManager().playClickSound(); onPrevious(); }, child: const Center( @@ -755,6 +756,7 @@ class FloatingNextButton extends StatelessWidget { borderRadius: BorderRadius.circular(28), onTap: () { HapticFeedback.lightImpact(); + AudioManager().playNextSound(); onNext(); }, child: const Center( @@ -805,6 +807,7 @@ class FloatingLikeButton extends StatelessWidget { ? null : () { HapticFeedback.mediumImpact(); + AudioManager().playLikeSound(); onToggleLike(); }, child: Center( diff --git a/lib/views/profile/components/bug_list_page.dart b/lib/views/profile/components/bug_list_page.dart index 1674835..318630b 100644 --- a/lib/views/profile/components/bug_list_page.dart +++ b/lib/views/profile/components/bug_list_page.dart @@ -20,63 +20,160 @@ class _BugListPageState extends State { final List> _bugs = [ { 'id': 1, - 'title': '诗词答题页面偶现卡顿', - 'description': '在快速切换诗词题目时,页面可能出现短暂卡顿现象', + 'title': '输入法无法弹出', + 'description': '输入框无焦点,输入法无法弹出', 'severity': 'medium', // high, medium, low 'status': 'pending', // pending, in_progress, resolved - 'solution': '优化页面渲染逻辑,减少不必要的widget重建', - 'resolveTime': '2026-04-15', + 'solution': '1.重启手机', + 'reproduction': '1. 打开系统设置 - 存储 清理缓存\n2. 打开软件poes输入框页面\n*仅极少部分鸿蒙用户触发此现象', + 'resolveTime': '修复中', 'reportTime': '2026-03-25', - 'affectedUsers': '部分用户', - 'expanded': false, // 添加展开状态 + 'affectedUsers': '鸿蒙5/6用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 }, { 'id': 2, - 'title': '历史记录加载缓慢', - 'description': '当历史记录数量较多时,加载速度较慢', + 'title': '软件页面刷新率只有60帧', + 'description': '软件外120帧,打开软件后,刷新率只有60帧', 'severity': 'high', - 'status': 'in_progress', - 'solution': '实现分页加载和本地缓存优化', + 'status': 'resolved', + 'solution': '新版已修复', + 'reproduction': '1. 极少鸿蒙用户仍会出现刷新率只有60帧,无原生刷新率', 'resolveTime': '2026-04-10', 'reportTime': '2026-03-20', - 'affectedUsers': '大量用户', - 'expanded': false, // 添加展开状态 + 'affectedUsers': '鸿蒙5/6用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 }, { 'id': 3, - 'title': '主题切换不生效', - 'description': '在某些设备上切换主题后,界面颜色没有立即更新', + 'title': '应用信息 设备类型显示 未知', + 'description': '已适配安卓 win web系统', 'severity': 'low', 'status': 'resolved', - 'solution': '修复主题状态管理问题,强制刷新界面', - 'resolveTime': '2026-03-28', + 'solution': '部分web ohos系统未识别到系统类型', + 'reproduction': + 'harmonyos系统检测字段为\n ohos,openharmony,harmony\n 不在字段中的设备无法识别', + 'resolveTime': '修复中', 'reportTime': '2026-03-15', 'affectedUsers': '少数用户', - 'expanded': false, // 添加展开状态 + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 }, { 'id': 4, - 'title': '收藏夹同步失败', - 'description': '网络不稳定时,收藏夹数据同步可能失败', + 'title': '软件横屏后,部分页面无法点击', + 'description': '暂未适配横屏', 'severity': 'medium', 'status': 'pending', 'solution': '增加重试机制和离线缓存功能', - 'resolveTime': '2026-04-20', + 'reproduction': '1. 开启屏幕旋转,手机横屏', + 'resolveTime': '适配中', 'reportTime': '2026-03-22', - 'affectedUsers': '部分用户', - 'expanded': false, // 添加展开状态 + 'affectedUsers': '大部分用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 }, { 'id': 5, - 'title': '字体大小设置异常', - 'description': '调整字体大小后,部分页面文字显示不完整', + 'title': '笔记页面时间显示1970xxx', + 'description': '在其他页面点击创建添加笔记,笔记时间显示异常', 'severity': 'low', 'status': 'resolved', 'solution': '优化字体大小适配逻辑,确保所有页面正确显示', + 'reproduction': '1. 进入设置页面\n2. 调整字体大小为最大值\n3. 浏览各个页面,观察文字是否显示完整', 'resolveTime': '2026-03-26', 'reportTime': '2026-03-18', 'affectedUsers': '少数用户', - 'expanded': false, // 添加展开状态 + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 + }, + { + 'id': 6, + 'title': '离线状态错误', + 'description': '断网或网络异常,软件内未正确获取到', + 'severity': 'low', + 'status': 'resolved', + 'solution': '优化字体大小适配逻辑,确保所有页面正确显示', + 'reproduction': '1. 用户关闭在线状态,软件部分页面显示', + 'resolveTime': '2026-03-26', + 'reportTime': '2026-03-18', + 'affectedUsers': '少数用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 + }, + { + 'id': 7, + 'title': '主页点击“上一条” 显示无上一条', + 'description': '未读取到历史记录', + 'severity': 'low', + 'status': 'resolved', + 'solution': '优化字体大小适配逻辑,确保所有页面正确显示', + 'reproduction': '1. 用户关闭在线状态,软件部分页面显示', + 'resolveTime': '2026-03-26', + 'reportTime': '2026-03-18', + 'affectedUsers': '全部用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 + }, + { + 'id': 8, + 'title': '软件冷启动出现长时间白屏', + 'description': '未读取到历史记录', + 'severity': 'low', + 'status': 'resolved', + 'solution': '闪白屏', + 'reproduction': '首次按钮,系统设置页面清理poes数据 大版本更新', + 'resolveTime': '2026-03-26', + 'reportTime': '2026-03-18', + 'affectedUsers': '少数用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 + }, + + { + 'id': 8, + 'title': '软件黑屏', + 'description': '未读取到历史记录', + 'severity': 'low', + 'status': 'resolved', + 'solution': '优化字体大小适配逻辑,确保所有页面正确显示', + 'reproduction': '极短时间内瞬发点击同一个按钮3次以上 页面路由加载异常', + 'resolveTime': '2026-03-26', + 'reportTime': '2026-03-18', + 'affectedUsers': '少数用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 + }, + + { + 'id': 9, + 'title': '桌面卡片 天气温度显示999', + 'description': '未读取到历史记录', + 'severity': 'low', + 'status': 'resolved', + 'solution': '用户短时间内多次刷新获取api数据,导致服务器启动防止cc自我保护机制,不会此ip下放数据', + 'reproduction': '极短时间内瞬发点击同一个按钮3次以上 页面路由加载异常', + 'resolveTime': '2026-03-26', + 'reportTime': '2026-03-18', + 'affectedUsers': '少数用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 + }, + { + 'id': 9, + 'title': '桌面卡片 设置页面闪白屏', + 'description': '未读取到历史记录', + 'severity': 'low', + 'status': 'resolved', + 'solution': '用户短时间内多次刷新获取api数据,导致服务器启动防止cc自我保护机制,不会此ip下放数据', + 'reproduction': '极短时间内瞬发点击同一个按钮3次以上 页面路由加载异常', + 'resolveTime': '2026-03-26', + 'reportTime': '2026-03-18', + 'affectedUsers': '少数用户', + 'expanded': false, // 解决方案展开状态 + 'reproductionExpanded': false, // 复现步骤展开状态 }, ]; @@ -94,6 +191,18 @@ class _BugListPageState extends State { HapticFeedback.lightImpact(); } + // 切换复现步骤展开状态 + void _toggleReproductionExpanded(int bugId) { + setState(() { + final bugIndex = _bugs.indexWhere((bug) => bug['id'] == bugId); + if (bugIndex != -1) { + _bugs[bugIndex]['reproductionExpanded'] = + !_bugs[bugIndex]['reproductionExpanded']; + } + }); + HapticFeedback.lightImpact(); + } + @override void dispose() { _scrollController.dispose(); @@ -156,14 +265,14 @@ class _BugListPageState extends State { setState(() { _isRefreshing = true; }); - + // 模拟网络请求延迟 await Future.delayed(const Duration(seconds: 1)); - + setState(() { _isRefreshing = false; }); - + HapticFeedback.lightImpact(); } @@ -248,7 +357,7 @@ class _BugListPageState extends State { Widget _buildBugItem(Map bug) { final bool isExpanded = bug['expanded'] ?? false; - + return Container( margin: const EdgeInsets.only(bottom: 16), decoration: BoxDecoration( @@ -293,7 +402,9 @@ class _BugListPageState extends State { vertical: 4, ), decoration: BoxDecoration( - color: _getStatusColor(bug['status']).withValues(alpha: 0.1), + color: _getStatusColor( + bug['status'], + ).withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), border: Border.all( color: _getStatusColor(bug['status']), @@ -331,7 +442,9 @@ class _BugListPageState extends State { vertical: 2, ), decoration: BoxDecoration( - color: _getSeverityColor(bug['severity']).withValues(alpha: 0.1), + color: _getSeverityColor( + bug['severity'], + ).withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: Row( @@ -355,48 +468,79 @@ class _BugListPageState extends State { ), ), const SizedBox(width: 12), - Icon( - Icons.people, - size: 14, - color: Colors.grey[600], - ), + Icon(Icons.people, size: 14, color: Colors.grey[600]), const SizedBox(width: 4), Text( bug['affectedUsers'] ?? '未知用户', - style: TextStyle( - fontSize: 12, - color: Colors.grey[600], - ), + style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), ], ), const SizedBox(height: 12), - // 解决方案按钮 - Container( - width: double.infinity, - child: ElevatedButton.icon( - onPressed: () => _toggleBugExpanded(bug['id']), - icon: Icon( - isExpanded ? Icons.expand_less : Icons.expand_more, - size: 18, - ), - label: Text( - isExpanded ? '收起解决方案' : '查看解决方案', - style: const TextStyle(fontSize: 14), - ), - style: ElevatedButton.styleFrom( - backgroundColor: AppConstants.primaryColor.withValues(alpha: 0.1), - foregroundColor: AppConstants.primaryColor, - elevation: 0, - padding: const EdgeInsets.symmetric(vertical: 8), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - side: BorderSide( - color: AppConstants.primaryColor.withValues(alpha: 0.3), + // 解决方案和复现步骤按钮 + Row( + children: [ + Expanded( + child: ElevatedButton.icon( + onPressed: () => _toggleBugExpanded(bug['id']), + icon: Icon( + isExpanded ? Icons.expand_less : Icons.expand_more, + size: 18, + ), + label: Text( + isExpanded ? '收起解决方案' : '查看解决方案', + style: const TextStyle(fontSize: 14), + ), + style: ElevatedButton.styleFrom( + backgroundColor: AppConstants.primaryColor.withValues( + alpha: 0.1, + ), + foregroundColor: AppConstants.primaryColor, + elevation: 0, + padding: const EdgeInsets.symmetric(vertical: 8), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: AppConstants.primaryColor.withValues( + alpha: 0.3, + ), + ), + ), ), ), ), - ), + const SizedBox(width: 8), + Expanded( + child: ElevatedButton.icon( + onPressed: () => _toggleReproductionExpanded(bug['id']), + icon: Icon( + bug['reproductionExpanded'] + ? Icons.expand_less + : Icons.expand_more, + size: 18, + ), + label: Text( + bug['reproductionExpanded'] ? '收起复现' : '查看复现', + style: const TextStyle(fontSize: 14), + ), + style: ElevatedButton.styleFrom( + backgroundColor: AppConstants.secondaryColor + .withValues(alpha: 0.1), + foregroundColor: const Color(0xFF018786), // 更深的青色 + elevation: 0, + padding: const EdgeInsets.symmetric(vertical: 8), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: const Color( + 0xFF018786, + ).withValues(alpha: 0.3), + ), + ), + ), + ), + ), + ], ), ], ), @@ -447,35 +591,67 @@ class _BugListPageState extends State { // 时间信息 Row( children: [ - Icon( - Icons.schedule, - size: 14, - color: Colors.grey[600], - ), + Icon(Icons.schedule, size: 14, color: Colors.grey[600]), const SizedBox(width: 4), Text( '预计解决: ${bug['resolveTime'] ?? '待定'}', - style: TextStyle( - fontSize: 12, - color: Colors.grey[600], - ), + style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), const SizedBox(width: 16), - Icon( - Icons.report, - size: 14, - color: Colors.grey[600], - ), + Icon(Icons.report, size: 14, color: Colors.grey[600]), const SizedBox(width: 4), Text( '报告时间: ${bug['reportTime'] ?? '未知'}', + style: TextStyle(fontSize: 12, color: Colors.grey[600]), + ), + ], + ), + ], + ), + ), + ], + // 复现步骤区域(可展开/收起) + if (bug['reproductionExpanded']) ...[ + const Divider(height: 1), + Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.grey[50], + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(12), + bottomRight: Radius.circular(12), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.replay, + color: const Color(0xFF018786), // 更深的青色 + size: 16, + ), + const SizedBox(width: 8), + Text( + '复现步骤', style: TextStyle( - fontSize: 12, - color: Colors.grey[600], + fontSize: 14, + fontWeight: FontWeight.w600, + color: const Color(0xFF018786), // 更深的青色 ), ), ], ), + const SizedBox(height: 8), + Text( + bug['reproduction'] ?? '暂无复现步骤', + style: const TextStyle( + fontSize: 13, + color: Colors.black54, + height: 1.4, + ), + ), ], ), ), diff --git a/lib/views/profile/history_page.dart b/lib/views/profile/history_page.dart index af4ed7b..28e7ebe 100644 --- a/lib/views/profile/history_page.dart +++ b/lib/views/profile/history_page.dart @@ -153,7 +153,6 @@ class _HistoryPageState extends State { _showSnackBar('删除失败'); } } catch (e) { - print('删除历史记录失败: $e'); _showSnackBar('删除失败'); } } @@ -170,7 +169,6 @@ class _HistoryPageState extends State { _showSnackBar('无数据可导出'); } } catch (e) { - print('导出历史记录失败: $e'); _showSnackBar('导出失败'); } } @@ -239,7 +237,6 @@ class _HistoryPageState extends State { ), ); } catch (e) { - print('获取统计失败: $e'); _showSnackBar('获取统计失败'); } } diff --git a/lib/views/profile/level/distinguish.dart b/lib/views/profile/level/distinguish.dart index f00e4e8..2d74bc2 100644 --- a/lib/views/profile/level/distinguish.dart +++ b/lib/views/profile/level/distinguish.dart @@ -58,7 +58,6 @@ class _DistinguishPageState extends State { try { return jsonDecode(record) as Map; } catch (e) { - print('解析记录失败: $e'); return {}; } }) @@ -75,7 +74,7 @@ class _DistinguishPageState extends State { // 加载统计数据 await _loadStatistics(); } catch (e) { - print('加载答题记录失败: $e'); + // 加载失败 } finally { setState(() { _isLoading = false; @@ -121,7 +120,7 @@ class _DistinguishPageState extends State { // 计算诗词水平 _calculatePoetryLevel(); } catch (e) { - print('加载统计数据失败: $e'); + // 加载失败 } } @@ -462,7 +461,7 @@ $_poetryLevel context, ).showSnackBar(const SnackBar(content: Text('答题记录已清空'))); } catch (e) { - print('清空记录失败: $e'); + // 清空失败 } } } diff --git a/lib/views/profile/level/level-jilu.dart b/lib/views/profile/level/level-jilu.dart index fdf927d..2cddbc2 100644 --- a/lib/views/profile/level/level-jilu.dart +++ b/lib/views/profile/level/level-jilu.dart @@ -84,7 +84,7 @@ class PoetryLevelManager with NetworkListenerMixin { _offlineQuestions.add(map); } } catch (e) { - print('解析离线数据失败: $e'); + // 解析失败,跳过 } } @@ -95,7 +95,7 @@ class PoetryLevelManager with NetworkListenerMixin { _currentIndex = 0; } } catch (e) { - print('加载离线缓存失败: $e'); + // 加载失败 } } @@ -103,17 +103,13 @@ class PoetryLevelManager with NetworkListenerMixin { Map _parseStringToMap(String str) { final result = {}; - print('开始解析字符串: $str'); - try { // 尝试JSON解析 final jsonMap = jsonDecode(str); if (jsonMap is Map) { - print('JSON解析成功: $jsonMap'); return jsonMap; } } catch (e) { - print('JSON解析失败: $e'); // 不是JSON格式,尝试其他解析方式 } @@ -144,7 +140,6 @@ class PoetryLevelManager with NetworkListenerMixin { } } - print('解析结果: $result'); return result; } @@ -226,8 +221,6 @@ class PoetryLevelManager with NetworkListenerMixin { isOffline: false, ); } catch (e) { - print('初始化题目失败: $e'); - // 尝试加载离线缓存 final hasCache = await _hasCachedData(); if (hasCache) { @@ -363,15 +356,11 @@ class PoetryLevelManager with NetworkListenerMixin { /// 格式化离线题目数据 Map _formatOfflineQuestion(Map data) { - print('格式化离线题目,原始数据: $data'); - // 检查是否已经是标准格式 if (data.containsKey('question') && data.containsKey('options')) { final options = data['options']; - print('发现options字段,类型: ${options.runtimeType}, 值: $options'); // 确保options是List类型 if (options is List) { - print('options已经是List类型,直接返回'); return data; } } @@ -387,49 +376,37 @@ class PoetryLevelManager with NetworkListenerMixin { 'options': >[], }; - print('构建基础数据: $result'); - // 尝试解析options字段 dynamic optionsData = data['options']; if (optionsData != null) { - print('开始解析options,类型: ${optionsData.runtimeType}'); if (optionsData is List) { // 已经是List,直接使用 result['options'] = optionsData; - print('options是List,直接使用'); } else if (optionsData is String) { // 是String,尝试解析为List try { - print('options是String,尝试解析: $optionsData'); final parsedOptions = jsonDecode(optionsData); - print('解析结果类型: ${parsedOptions.runtimeType}'); if (parsedOptions is List) { result['options'] = parsedOptions; - print('options解析成功为List'); } } catch (e) { - print('解析options字符串失败: $e'); + // 解析失败 } } } - print('当前options: ${result['options']}'); - // 如果没有有效的options,尝试从其他字段构建 if ((result['options'] as List).isEmpty) { - print('options为空,尝试从其他字段构建'); final options = >[]; for (int i = 1; i <= 4; i++) { final optionKey = 'option_$i'; if (data.containsKey(optionKey)) { options.add({'index': i, 'content': data[optionKey]}); - print('从$optionKey构建选项'); } } result['options'] = options; } - print('最终格式化结果: $result'); return result; } diff --git a/lib/views/profile/level/poetry.dart b/lib/views/profile/level/poetry.dart index 6ad98ad..f40ca5f 100644 --- a/lib/views/profile/level/poetry.dart +++ b/lib/views/profile/level/poetry.dart @@ -375,7 +375,7 @@ class _PoetryLevelPageState extends State ); } } catch (e) { - print('保存答题记录失败: $e'); + // 保存失败 } } diff --git a/lib/views/profile/profile_page.dart b/lib/views/profile/profile_page.dart index 8e980b4..13fc7ea 100644 --- a/lib/views/profile/profile_page.dart +++ b/lib/views/profile/profile_page.dart @@ -186,7 +186,7 @@ class _ProfilePageState extends State setState(() {}); } catch (e) { - print('加载答题统计失败: $e'); + // 加载失败 } } diff --git a/lib/views/profile/settings/app_fun.dart b/lib/views/profile/settings/app_fun.dart index 3d417d2..cef1e1e 100644 --- a/lib/views/profile/settings/app_fun.dart +++ b/lib/views/profile/settings/app_fun.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../../constants/app_constants.dart'; +import '../../../utils/audio_manager.dart'; import './widgets.dart'; import '../../home/home-load.dart'; import '../../../controllers/load/locally.dart'; @@ -20,7 +21,7 @@ class AppFunSettingsPage extends StatefulWidget { class _AppFunSettingsPageState extends State { bool _autoRefreshEnabled = false; bool _debugInfoEnabled = false; - bool _soundEnabled = true; + bool _soundEnabled = false; // 默认关闭 bool _vibrationEnabled = true; bool _darkModeEnabled = false; bool _preloadEnabled = true; @@ -31,6 +32,7 @@ class _AppFunSettingsPageState extends State { static const String _autoRefreshKey = 'auto_refresh_enabled'; static const String _debugInfoKey = 'debug_info_enabled'; static const String _globalTipsKey = 'global_tips_enabled'; // 添加全局Tips开关key + static const String _soundEnabledKey = 'sound_enabled'; // 声音反馈开关key @override void initState() { @@ -47,6 +49,7 @@ class _AppFunSettingsPageState extends State { _globalTipsEnabled = prefs.getBool(_globalTipsKey) ?? true; // 加载全局Tips开关状态 _preloadEnabled = prefs.getBool('preload_enabled') ?? true; + _soundEnabled = prefs.getBool(_soundEnabledKey) ?? false; // 加载声音反馈状态 }); } } @@ -82,13 +85,15 @@ class _AppFunSettingsPageState extends State { } } - // 设置全局Tips开关 - Future _setGlobalTips(bool value) async { + // 设置声音反馈 + Future _setSoundEnabled(bool value) async { final prefs = await SharedPreferences.getInstance(); - await prefs.setBool(_globalTipsKey, value); + await prefs.setBool(_soundEnabledKey, value); + // 更新 AudioManager 的静音状态 + AudioManager().setMuted(!value); if (mounted) { setState(() { - _globalTipsEnabled = value; + _soundEnabled = value; }); } } @@ -159,14 +164,22 @@ class _AppFunSettingsPageState extends State { '显示一些使用技巧', Icons.volume_up, _globalTipsEnabled, - (value) => _setGlobalTips(value), + (value) async { + final prefs = await SharedPreferences.getInstance(); + await prefs.setBool(_globalTipsKey, value); + if (mounted) { + setState(() { + _globalTipsEnabled = value; + }); + } + }, ), _buildSwitchItem( '声音反馈', '操作时播放提示音', Icons.volume_up, _soundEnabled, - (value) => setState(() => _soundEnabled = value), + _setSoundEnabled, ), _buildSwitchItem( '震动反馈', diff --git a/lib/views/profile/settings/offline-data.dart b/lib/views/profile/settings/offline-data.dart index 7360afe..590623d 100644 --- a/lib/views/profile/settings/offline-data.dart +++ b/lib/views/profile/settings/offline-data.dart @@ -173,16 +173,10 @@ class _OfflineDataPageState extends State { if (response.isSuccess && response.jsonData != null) { final responseData = response.jsonData; - print('API完整响应: $responseData'); - // 检查API返回格式 if (responseData['code'] == 0 && responseData['data'] != null) { final itemData = responseData['data'] as Map; - print('API返回的data字段: $itemData'); - print('API返回的options字段: ${itemData['options']}'); - print('options字段类型: ${itemData['options']?.runtimeType}'); - // 对于答题数据,确保options字段被正确序列化 if (_selectedType == DownloadType.quiz) { // 深拷贝数据,避免修改原始数据 @@ -194,22 +188,16 @@ class _OfflineDataPageState extends State { if (dataToStore['options'] is List) { // 将List转换为JSON字符串 dataToStore['options'] = jsonEncode(dataToStore['options']); - print('存储答题数据options: ${dataToStore['options']}'); } else if (dataToStore['options'] is String) { // 已经是字符串,直接使用 - print('options已经是字符串,直接使用: ${dataToStore['options']}'); - } else { - print('options类型异常: ${dataToStore['options'].runtimeType}'); } } else { - print('警告:options字段不存在或为null'); // 如果没有options,添加一个空数组 dataToStore['options'] = jsonEncode([]); } // 将整个Map转换为JSON字符串存储 final storedString = jsonEncode(dataToStore); - print('存储答题数据完整: $storedString'); currentData.add(storedString); } else { currentData.add(itemData.toString()); @@ -231,8 +219,6 @@ class _OfflineDataPageState extends State { _cachedCount = currentData.length; }); } - } else { - print('API返回错误: ${responseData['msg'] ?? '未知错误'}'); } }