638 lines
20 KiB
Dart
638 lines
20 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:get/get.dart';
|
||
import '../../../controllers/history_controller.dart';
|
||
import '../../../utils/http/poetry_api.dart';
|
||
import '../../../services/network_listener_service.dart';
|
||
import '../../../utils/audio_manager.dart';
|
||
import '../../../constants/app_constants.dart';
|
||
import '../../views/home/set/home_components.dart';
|
||
import '../../views/home/set/home-load.dart';
|
||
import '../../../views/profile/guide/tongji.dart';
|
||
|
||
class HomeController extends GetxController with NetworkListenerMixin {
|
||
var poetryData = Rxn<PoetryData>();
|
||
var keywordList = <String>[].obs;
|
||
var loading = false.obs;
|
||
var isLiked = false.obs;
|
||
var isLoadingLike = false.obs;
|
||
var errorMessage = ''.obs;
|
||
var starDisplay = ''.obs;
|
||
var historyList = <Map<String, dynamic>>[].obs;
|
||
var currentHistoryIndex = (-1).obs;
|
||
|
||
// 动态加载状态
|
||
var isLoadingNext = false.obs;
|
||
var sectionLoadingStates = {
|
||
'title': false,
|
||
'content': false,
|
||
'name': false,
|
||
'keywords': false,
|
||
'introduction': false,
|
||
}.obs;
|
||
|
||
@override
|
||
void onInit() {
|
||
super.onInit();
|
||
// 异步初始化所有服务,然后加载诗词
|
||
_initializeAndLoadPoetry();
|
||
}
|
||
|
||
Future<void> _initializeAndLoadPoetry() async {
|
||
try {
|
||
// 并行初始化所有服务
|
||
await Future.wait([
|
||
_initAudioManager(),
|
||
_initSecondaryButtonsManager(),
|
||
_initAutoRefresh(),
|
||
_initDebugInfo(),
|
||
_initOfflineDataManager(),
|
||
]);
|
||
// 所有初始化完成后,加载诗词
|
||
await loadPoetry();
|
||
} catch (e) {
|
||
// 初始化失败时,仍然尝试加载诗词
|
||
await loadPoetry();
|
||
}
|
||
}
|
||
|
||
Future<void> _initSecondaryButtonsManager() async {
|
||
await SecondaryButtonsManager().init();
|
||
}
|
||
|
||
Future<void> _initAudioManager() async {
|
||
await AudioManager().init();
|
||
}
|
||
|
||
Future<void> _initOfflineDataManager() async {
|
||
final offlineDataManager = OfflineDataManager();
|
||
await offlineDataManager.init();
|
||
}
|
||
|
||
Future<void> _initAutoRefresh() async {
|
||
final autoRefreshManager = AutoRefreshManager();
|
||
await autoRefreshManager.init();
|
||
autoRefreshManager.setOnRefresh(() {
|
||
loadNextPoetry();
|
||
});
|
||
if (autoRefreshManager.isEnabled) {
|
||
autoRefreshManager.setEnabled(true);
|
||
}
|
||
}
|
||
|
||
Future<void> _initDebugInfo() async {
|
||
final debugInfoManager = DebugInfoManager();
|
||
await debugInfoManager.init();
|
||
}
|
||
|
||
@override
|
||
void onClose() {
|
||
// 只停止定时器,不释放单例资源
|
||
AutoRefreshManager().stopTimer();
|
||
super.onClose();
|
||
}
|
||
|
||
Future<void> loadPoetry() async {
|
||
if (loading.value) return;
|
||
|
||
loading.value = true;
|
||
PoetryStateManager.triggerHapticFeedback();
|
||
|
||
try {
|
||
final offlineDataManager = OfflineDataManager();
|
||
final isOnline = await offlineDataManager.isOnline();
|
||
final hasCachedData = await offlineDataManager.hasCachedData();
|
||
|
||
if (isOnline) {
|
||
// 在线状态:从网络加载
|
||
final response = await PoetryApi.getRandomPoetry();
|
||
|
||
if (response.data != null) {
|
||
// 记录浏览统计
|
||
try {
|
||
await StatisticsManager().recordView();
|
||
await StatisticsManager().recordFirstUse();
|
||
await StatisticsManager().recordTotalView();
|
||
} catch (e) {
|
||
// 忽略错误
|
||
}
|
||
|
||
poetryData.value = response.data;
|
||
keywordList.value = PoetryDataUtils.extractKeywords(response.data);
|
||
starDisplay.value = PoetryDataUtils.getStarDisplay(response.data);
|
||
isLiked.value = false;
|
||
loading.value = false;
|
||
errorMessage.value = '';
|
||
|
||
checkIfLiked();
|
||
await saveToHistory(response.data!);
|
||
DebugInfoManager().showRefreshSuccess();
|
||
update(); // 通知UI更新
|
||
} else {
|
||
// 数据为空时,显示默认内容
|
||
poetryData.value = createDefaultPoetryData();
|
||
keywordList.value = [];
|
||
starDisplay.value = '⭐⭐⭐⭐⭐';
|
||
isLiked.value = false;
|
||
loading.value = false;
|
||
errorMessage.value = '';
|
||
|
||
DebugInfoManager().showRefreshFailed();
|
||
update(); // 通知UI更新
|
||
}
|
||
} else {
|
||
// 离线状态:从本地缓存加载
|
||
if (hasCachedData) {
|
||
final poetryData = await offlineDataManager.getNextPoetry();
|
||
|
||
if (poetryData != null) {
|
||
// 记录浏览统计
|
||
try {
|
||
await StatisticsManager().recordView();
|
||
await StatisticsManager().recordFirstUse();
|
||
await StatisticsManager().recordTotalView();
|
||
} catch (e) {
|
||
// 忽略错误
|
||
}
|
||
|
||
this.poetryData.value = poetryData;
|
||
keywordList.value = PoetryDataUtils.extractKeywords(poetryData);
|
||
starDisplay.value = PoetryDataUtils.getStarDisplay(poetryData);
|
||
isLiked.value = false;
|
||
loading.value = false;
|
||
errorMessage.value = '';
|
||
|
||
checkIfLiked();
|
||
DebugInfoManager().showRefreshSuccess();
|
||
update(); // 通知UI更新
|
||
} else {
|
||
// 缓存为空时,显示错误信息
|
||
loading.value = false;
|
||
errorMessage.value = '离线模式下无缓存数据,请先在线下载';
|
||
DebugInfoManager().showRefreshFailed();
|
||
update(); // 通知UI更新
|
||
}
|
||
} else {
|
||
// 离线且无缓存时,显示错误信息
|
||
loading.value = false;
|
||
errorMessage.value = '离线模式下无缓存数据,请先在线下载';
|
||
DebugInfoManager().showRefreshFailed();
|
||
update(); // 通知UI更新
|
||
}
|
||
}
|
||
} catch (e) {
|
||
loading.value = false;
|
||
errorMessage.value = '加载失败,请检查网络连接';
|
||
DebugInfoManager().showRefreshFailed();
|
||
update(); // 通知UI更新
|
||
}
|
||
}
|
||
|
||
// 创建默认诗词数据,确保页面始终有内容显示
|
||
PoetryData createDefaultPoetryData() {
|
||
final now = DateTime.now();
|
||
final dateStr = now.toString().substring(0, 10);
|
||
final monthStr = dateStr.substring(0, 7);
|
||
final timeStr = now.toString().substring(11, 19);
|
||
|
||
return PoetryData(
|
||
id: 1,
|
||
name: '静夜思',
|
||
alias: '李白',
|
||
keywords: '思乡,月亮,静夜',
|
||
introduce: '床前明月光,疑是地上霜。举头望明月,低头思故乡。',
|
||
drtime: '唐·李白《静夜思》',
|
||
like: 0,
|
||
url: '李白-静夜思',
|
||
tui: 1,
|
||
star: 5,
|
||
hitsTotal: 10000,
|
||
hitsMonth: 1000,
|
||
hitsDay: 100,
|
||
date: dateStr,
|
||
datem: monthStr,
|
||
time: timeStr,
|
||
createTime: timeStr,
|
||
updateTime: timeStr,
|
||
);
|
||
}
|
||
|
||
Future<void> loadPoetryById(int poetryId) async {
|
||
if (loading.value) return;
|
||
|
||
loading.value = true;
|
||
|
||
try {
|
||
final response = await PoetryApi.getPoetryById(poetryId);
|
||
|
||
if (response.data != null) {
|
||
// 记录浏览统计
|
||
try {
|
||
await StatisticsManager().recordView();
|
||
await StatisticsManager().recordFirstUse();
|
||
await StatisticsManager().recordTotalView();
|
||
} catch (e) {
|
||
// 忽略错误
|
||
}
|
||
|
||
poetryData.value = response.data;
|
||
keywordList.value = PoetryDataUtils.extractKeywords(response.data);
|
||
starDisplay.value = PoetryDataUtils.getStarDisplay(response.data);
|
||
loading.value = false;
|
||
errorMessage.value = '';
|
||
update(); // 通知UI更新
|
||
|
||
checkIfLiked();
|
||
updateCurrentHistoryIndex();
|
||
} else {
|
||
// 数据为空时,显示默认内容
|
||
poetryData.value = createDefaultPoetryData();
|
||
keywordList.value = [];
|
||
starDisplay.value = '⭐⭐⭐⭐⭐';
|
||
isLiked.value = false;
|
||
loading.value = false;
|
||
errorMessage.value = '';
|
||
update(); // 通知UI更新
|
||
}
|
||
} catch (e) {
|
||
poetryData.value = createDefaultPoetryData();
|
||
keywordList.value = [];
|
||
starDisplay.value = '⭐⭐⭐⭐⭐';
|
||
isLiked.value = false;
|
||
loading.value = false;
|
||
errorMessage.value = '';
|
||
update(); // 通知UI更新
|
||
}
|
||
}
|
||
|
||
Future<void> toggleLike() async {
|
||
if (poetryData.value == null || isLoadingLike.value) return;
|
||
|
||
// 播放点赞音效(不等待完成)
|
||
AudioManager().playLikeSound();
|
||
|
||
// 立即切换按钮状态和显示加载
|
||
isLoadingLike.value = true;
|
||
|
||
// 发送网络加载开始事件
|
||
startNetworkLoading('toggle_like');
|
||
|
||
try {
|
||
final response = await PoetryApi.toggleLike(poetryData.value!.id);
|
||
|
||
// 根据API响应消息直接判断状态
|
||
isLiked.value = response.message.contains('点赞成功');
|
||
|
||
// 更新诗词数据
|
||
if (response.data != null) {
|
||
poetryData.value = PoetryData(
|
||
id: poetryData.value!.id,
|
||
name: poetryData.value!.name,
|
||
alias: poetryData.value!.alias,
|
||
keywords: poetryData.value!.keywords,
|
||
introduce: poetryData.value!.introduce,
|
||
drtime: poetryData.value!.drtime,
|
||
like: response.data!.like,
|
||
url: poetryData.value!.url,
|
||
tui: poetryData.value!.tui,
|
||
star: poetryData.value!.star,
|
||
hitsTotal: poetryData.value!.hitsTotal,
|
||
hitsMonth: poetryData.value!.hitsMonth,
|
||
hitsDay: poetryData.value!.hitsDay,
|
||
date: poetryData.value!.date,
|
||
datem: poetryData.value!.datem,
|
||
time: poetryData.value!.time,
|
||
createTime: poetryData.value!.createTime,
|
||
updateTime: poetryData.value!.updateTime,
|
||
);
|
||
update(); // 通知UI更新
|
||
}
|
||
|
||
// 通知UI更新点赞状态
|
||
update();
|
||
|
||
// 管理点赞存储
|
||
if (isLiked.value) {
|
||
// 添加到点赞列表
|
||
await HistoryController.addToLiked(poetryData.value!.toJson());
|
||
// 记录今日点赞
|
||
await StatisticsManager().recordTodayLike();
|
||
// 记录累计点赞
|
||
await StatisticsManager().recordTotalLike();
|
||
} else {
|
||
// 从点赞列表移除
|
||
await HistoryController.removeLikedPoetry(
|
||
poetryData.value!.id.toString(),
|
||
);
|
||
}
|
||
|
||
// 发送点赞事件通知其他页面
|
||
sendLikeEvent(poetryData.value!.id.toString(), isLiked.value);
|
||
|
||
if (isLiked.value) {
|
||
DebugInfoManager().showLiked();
|
||
} else {
|
||
DebugInfoManager().showUnliked();
|
||
}
|
||
} catch (e) {
|
||
Get.snackbar(
|
||
'提示',
|
||
'操作失败,请重试',
|
||
snackPosition: SnackPosition.TOP,
|
||
backgroundColor: AppConstants.errorColor.withValues(alpha: 0.8),
|
||
colorText: Colors.white,
|
||
duration: const Duration(seconds: 2),
|
||
margin: const EdgeInsets.all(16),
|
||
borderRadius: 20,
|
||
animationDuration: const Duration(milliseconds: 300),
|
||
);
|
||
} finally {
|
||
isLoadingLike.value = false;
|
||
update(); // 通知UI更新加载状态
|
||
// 发送网络加载结束事件
|
||
endNetworkLoading('toggle_like');
|
||
}
|
||
}
|
||
|
||
Future<void> loadHistory() async {
|
||
try {
|
||
final historyJson = await HistoryController.getHistory();
|
||
historyList.value = historyJson;
|
||
// 重新计算当前诗词在历史记录中的索引
|
||
if (poetryData.value != null && historyList.isNotEmpty) {
|
||
currentHistoryIndex.value = historyList.indexWhere(
|
||
(item) => item['id'] == poetryData.value!.id,
|
||
);
|
||
} else {
|
||
currentHistoryIndex.value = -1;
|
||
}
|
||
} catch (e) {
|
||
// 加载失败
|
||
}
|
||
}
|
||
|
||
Future<void> saveToHistory(PoetryData poetryData) async {
|
||
try {
|
||
final poetryMap = {
|
||
'id': poetryData.id,
|
||
'name': poetryData.name, // 诗句名称/标题
|
||
'alias': poetryData.alias, // 诗句朝代/作者
|
||
'introduce': poetryData.introduce, // 诗句译文/解释
|
||
'drtime': poetryData.drtime, // 诗句原文/内容
|
||
};
|
||
|
||
await HistoryController.addToHistory(poetryMap);
|
||
} catch (e) {
|
||
// 保存失败
|
||
}
|
||
}
|
||
|
||
void updateCurrentHistoryIndex() {
|
||
if (poetryData.value?.id != null) {
|
||
final index = historyList.indexWhere(
|
||
(item) => item['id'] == poetryData.value!.id,
|
||
);
|
||
currentHistoryIndex.value = index >= 0 ? index : -1;
|
||
}
|
||
}
|
||
|
||
Future<void> checkIfLiked() async {
|
||
// 这里可以实现检查收藏状态的逻辑
|
||
// 暂时使用简单的模拟逻辑
|
||
}
|
||
|
||
Future<void> loadNextPoetry() async {
|
||
if (isLoadingNext.value) return;
|
||
|
||
// 播放下一条音效(不等待完成)
|
||
AudioManager().playNextSound();
|
||
|
||
isLoadingNext.value = true;
|
||
// 设置所有区域为加载状态
|
||
sectionLoadingStates.value = {
|
||
'title': true,
|
||
'content': true,
|
||
'name': true,
|
||
'keywords': true,
|
||
'introduction': true,
|
||
};
|
||
|
||
try {
|
||
final offlineDataManager = OfflineDataManager();
|
||
final isOnline = await offlineDataManager.isOnline();
|
||
final hasCachedData = await offlineDataManager.hasCachedData();
|
||
|
||
PoetryData? newPoetryData;
|
||
|
||
if (isOnline) {
|
||
// 在线状态:从网络加载
|
||
// 确保历史记录已加载
|
||
if (historyList.isEmpty) {
|
||
await loadHistory();
|
||
}
|
||
|
||
if (currentHistoryIndex.value < 0 ||
|
||
currentHistoryIndex.value >= historyList.length - 1) {
|
||
// 如果没有下一条了,加载新的诗词
|
||
final response = await PoetryApi.getRandomPoetry();
|
||
newPoetryData = response.data;
|
||
|
||
if (newPoetryData != null) {
|
||
await saveToHistory(newPoetryData);
|
||
}
|
||
} else {
|
||
// 如果有下一条,加载下一条
|
||
final nextPoetry = historyList[currentHistoryIndex.value + 1];
|
||
final response = await PoetryApi.getPoetryById(nextPoetry['id']);
|
||
newPoetryData = response.data;
|
||
}
|
||
} else {
|
||
// 离线状态:从本地缓存加载
|
||
if (hasCachedData) {
|
||
newPoetryData = await offlineDataManager.getNextPoetry();
|
||
} else {
|
||
// 离线且无缓存时,显示错误信息
|
||
Get.snackbar(
|
||
'提示',
|
||
'离线模式下无缓存数据,请先在线下载',
|
||
snackPosition: SnackPosition.TOP,
|
||
backgroundColor: AppConstants.errorColor.withValues(alpha: 0.8),
|
||
colorText: Colors.white,
|
||
duration: const Duration(seconds: 2),
|
||
margin: const EdgeInsets.all(16),
|
||
borderRadius: 20,
|
||
animationDuration: const Duration(milliseconds: 300),
|
||
);
|
||
// 重置所有加载状态
|
||
var states = <String, bool>{};
|
||
sectionLoadingStates.forEach((key, value) {
|
||
states[key] = false;
|
||
});
|
||
sectionLoadingStates.assignAll(states);
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (newPoetryData != null) {
|
||
// 模拟分步加载
|
||
await simulateSectionLoading(newPoetryData);
|
||
DebugInfoManager().showNextSuccess();
|
||
}
|
||
} catch (e) {
|
||
DebugInfoManager().showNextFailed();
|
||
// 重置所有加载状态
|
||
var states = <String, bool>{};
|
||
sectionLoadingStates.forEach((key, value) {
|
||
states[key] = false;
|
||
});
|
||
sectionLoadingStates.assignAll(states);
|
||
} finally {
|
||
isLoadingNext.value = false;
|
||
}
|
||
}
|
||
|
||
// 模拟分步加载过程
|
||
Future<void> simulateSectionLoading(PoetryData newPoetryData) async {
|
||
// 记录浏览统计
|
||
try {
|
||
await StatisticsManager().recordView();
|
||
await StatisticsManager().recordFirstUse();
|
||
await StatisticsManager().recordTotalView();
|
||
} catch (e) {
|
||
// 忽略错误
|
||
}
|
||
|
||
// 1. 加载标题区域
|
||
var states = <String, bool>{};
|
||
sectionLoadingStates.forEach((key, value) {
|
||
states[key] = value;
|
||
});
|
||
states['title'] = false;
|
||
sectionLoadingStates.assignAll(states);
|
||
poetryData.value = newPoetryData;
|
||
update(); // 通知UI更新
|
||
await Future.delayed(const Duration(milliseconds: 200));
|
||
|
||
// 2. 加载诗句区域
|
||
states = <String, bool>{};
|
||
sectionLoadingStates.forEach((key, value) {
|
||
states[key] = value;
|
||
});
|
||
states['name'] = false;
|
||
sectionLoadingStates.assignAll(states);
|
||
update(); // 通知UI更新
|
||
await Future.delayed(const Duration(milliseconds: 200));
|
||
|
||
// 3. 加载原文区域
|
||
states = <String, bool>{};
|
||
sectionLoadingStates.forEach((key, value) {
|
||
states[key] = value;
|
||
});
|
||
states['content'] = false;
|
||
sectionLoadingStates.assignAll(states);
|
||
update(); // 通知UI更新
|
||
await Future.delayed(const Duration(milliseconds: 200));
|
||
|
||
// 4. 加载关键词区域
|
||
states = <String, bool>{};
|
||
sectionLoadingStates.forEach((key, value) {
|
||
states[key] = value;
|
||
});
|
||
states['keywords'] = false;
|
||
sectionLoadingStates.assignAll(states);
|
||
keywordList.value = PoetryDataUtils.extractKeywords(newPoetryData);
|
||
update(); // 通知UI更新
|
||
await Future.delayed(const Duration(milliseconds: 200));
|
||
|
||
// 5. 加载译文区域
|
||
states = <String, bool>{};
|
||
sectionLoadingStates.forEach((key, value) {
|
||
states[key] = value;
|
||
});
|
||
states['introduction'] = false;
|
||
sectionLoadingStates.assignAll(states);
|
||
starDisplay.value = PoetryDataUtils.getStarDisplay(newPoetryData);
|
||
isLiked.value = false;
|
||
errorMessage.value = '';
|
||
update(); // 通知UI更新
|
||
|
||
checkIfLiked();
|
||
updateCurrentHistoryIndex();
|
||
}
|
||
|
||
Future<void> loadPreviousPoetry() async {
|
||
try {
|
||
final offlineDataManager = OfflineDataManager();
|
||
final isOnline = await offlineDataManager.isOnline();
|
||
final hasCachedData = await offlineDataManager.hasCachedData();
|
||
|
||
if (isOnline) {
|
||
// 在线状态:从历史记录加载
|
||
// 确保历史记录已加载
|
||
if (historyList.isEmpty) {
|
||
await loadHistory();
|
||
}
|
||
|
||
if (currentHistoryIndex.value <= 0) {
|
||
// 如果当前索引无效或已经是第一条,则重新加载历史记录
|
||
await loadHistory();
|
||
|
||
// 如果历史记录为空,显示提示
|
||
if (historyList.isEmpty) {
|
||
DebugInfoManager().showPreviousFailed();
|
||
return;
|
||
}
|
||
|
||
// 如果当前索引无效,设置为最新的一条
|
||
if (currentHistoryIndex.value < 0) {
|
||
currentHistoryIndex.value = 0;
|
||
}
|
||
}
|
||
|
||
// 检查是否有上一条
|
||
if (currentHistoryIndex.value > 0) {
|
||
final previousPoetry = historyList[currentHistoryIndex.value - 1];
|
||
await loadPoetryById(previousPoetry['id']);
|
||
} else {
|
||
// 如果没有上一条了,显示提示
|
||
DebugInfoManager().showPreviousFailed();
|
||
}
|
||
} else {
|
||
// 离线状态:从本地缓存加载
|
||
if (hasCachedData) {
|
||
final poetryData = await offlineDataManager.getPreviousPoetry();
|
||
|
||
if (poetryData != null) {
|
||
this.poetryData.value = poetryData;
|
||
keywordList.value = PoetryDataUtils.extractKeywords(poetryData);
|
||
starDisplay.value = PoetryDataUtils.getStarDisplay(poetryData);
|
||
isLiked.value = false;
|
||
errorMessage.value = '';
|
||
update(); // 通知UI更新
|
||
|
||
checkIfLiked();
|
||
DebugInfoManager().showPreviousSuccess();
|
||
} else {
|
||
// 缓存为空时,显示错误信息
|
||
DebugInfoManager().showPreviousFailed();
|
||
}
|
||
} else {
|
||
// 离线且无缓存时,显示错误信息
|
||
DebugInfoManager().showPreviousFailed();
|
||
}
|
||
}
|
||
} catch (e) {
|
||
DebugInfoManager().showPreviousFailed();
|
||
}
|
||
}
|
||
|
||
Future<void> refreshPoetry() async {
|
||
if (poetryData.value?.id != null) {
|
||
// 如果有当前诗词ID,则重新加载当前诗词
|
||
await loadPoetryById(poetryData.value!.id);
|
||
} else {
|
||
// 如果没有当前诗词ID,则加载新的诗词
|
||
await loadPoetry();
|
||
}
|
||
}
|
||
}
|