Files
wushu/lib/services/get/home_controller.dart
Developer cba04235c8 release
2026-04-03 03:26:06 +08:00

606 lines
19 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
};
update(); // 立即通知UI更新显示骨架屏
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. 立即更新所有数据
poetryData.value = newPoetryData;
keywordList.value = PoetryDataUtils.extractKeywords(newPoetryData);
starDisplay.value = PoetryDataUtils.getStarDisplay(newPoetryData);
isLiked.value = false;
errorMessage.value = '';
update(); // 通知UI更新
// 2. 短暂延迟后,一次性关闭所有加载状态
await Future.delayed(const Duration(milliseconds: 100));
// 一次性关闭所有加载状态
sectionLoadingStates.value = {
'title': false,
'content': false,
'name': false,
'keywords': false,
'introduction': false,
};
update();
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();
}
}
}