主要变更: 1. 重构多处Provider初始化逻辑,使用Future.microtask避免build阶段修改state 2. 重命名"灵感"模块为"工作流","天气诗词"改为"情景诗词" 3. 新增插件系统页面与路由,添加speech_to_text_windows插件支持 4. 优化玻璃容器性能,添加性能节流与模糊值适配 5. 新增离线横幅、阅读体验控制器、手势控制器等组件 6. 完善头像审核状态展示与缓存管理 7. 修复键盘弹出与页面路由问题 8. 更新依赖与项目配置,优化widget默认数据
149 lines
4.5 KiB
Dart
149 lines
4.5 KiB
Dart
/// ============================================================
|
||
/// 闲言APP — 后台任务回调
|
||
/// 创建时间: 2026-05-25
|
||
/// 更新时间: 2026-05-25
|
||
/// 作用: Workmanager顶层静态回调函数,后台拉取每日一句→推送小组件→触发通知
|
||
/// 上次更新: 初始创建
|
||
/// ============================================================
|
||
|
||
import 'package:dio/dio.dart';
|
||
import 'package:workmanager/workmanager.dart';
|
||
|
||
import '../data/home_widget_service.dart';
|
||
import '../notification/local_notification_service.dart';
|
||
import '../../utils/logger.dart';
|
||
|
||
// ============================================================
|
||
// Workmanager 回调入口(必须是顶层函数)
|
||
// ============================================================
|
||
|
||
@pragma('vm:entry-point')
|
||
void callbackDispatcher() {
|
||
Workmanager().executeTask((task, inputData) async {
|
||
Log.i('BackgroundCallback: 执行后台任务 — $task');
|
||
|
||
try {
|
||
switch (task) {
|
||
case BackgroundTasks.dailySentencePush:
|
||
await _handleDailySentencePush();
|
||
case BackgroundTasks.widgetDataSync:
|
||
await _handleWidgetDataSync(inputData);
|
||
default:
|
||
Log.w('BackgroundCallback: 未知任务 — $task');
|
||
}
|
||
} catch (e, st) {
|
||
Log.e('BackgroundCallback: 任务执行失败 — $task', e, st);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
});
|
||
}
|
||
|
||
// ============================================================
|
||
// 每日一句推送 — 拉取API → 推送到HomeWidget → 触发通知
|
||
// ============================================================
|
||
|
||
Future<void> _handleDailySentencePush() async {
|
||
final sentence = await _fetchDailySentence();
|
||
if (sentence == null) {
|
||
Log.w('BackgroundCallback: 每日一句获取失败,跳过推送');
|
||
return;
|
||
}
|
||
|
||
final content = sentence['content'] as String? ?? '';
|
||
final author = sentence['author'] as String? ?? '';
|
||
|
||
if (content.isEmpty) {
|
||
Log.w('BackgroundCallback: 每日一句内容为空,跳过推送');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
await HomeWidgetService.instance.updateDailySentence(content, author);
|
||
Log.i('BackgroundCallback: 每日一句已推送到小组件');
|
||
} catch (e) {
|
||
Log.e('BackgroundCallback: 推送到小组件失败', e);
|
||
}
|
||
|
||
try {
|
||
await LocalNotificationService.showDailySentence(
|
||
sentence: content,
|
||
author: author,
|
||
);
|
||
Log.i('BackgroundCallback: 每日一句通知已触发');
|
||
} catch (e) {
|
||
Log.e('BackgroundCallback: 触发通知失败', e);
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 小组件数据同步
|
||
// ============================================================
|
||
|
||
Future<void> _handleWidgetDataSync(Map<String, dynamic>? inputData) async {
|
||
if (inputData == null) {
|
||
Log.w('BackgroundCallback: widgetDataSync 无输入数据');
|
||
return;
|
||
}
|
||
|
||
final sentence = inputData['daily_sentence'] as String?;
|
||
final author = inputData['daily_author'] as String?;
|
||
|
||
if (sentence != null && sentence.isNotEmpty) {
|
||
try {
|
||
await HomeWidgetService.instance.updateDailySentence(sentence, author ?? '');
|
||
Log.i('BackgroundCallback: 小组件数据同步完成');
|
||
} catch (e) {
|
||
Log.e('BackgroundCallback: 小组件数据同步失败', e);
|
||
}
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 拉取今日诗词API
|
||
// ============================================================
|
||
|
||
Future<Map<String, dynamic>?> _fetchDailySentence() async {
|
||
try {
|
||
final dio = Dio(
|
||
BaseOptions(
|
||
connectTimeout: const Duration(seconds: 10),
|
||
receiveTimeout: const Duration(seconds: 10),
|
||
),
|
||
);
|
||
|
||
final resp = await dio.get<Map<String, dynamic>>(
|
||
'https://v2.jinrishici.com/sentence',
|
||
);
|
||
|
||
if (resp.statusCode == 200 && resp.data != null) {
|
||
final data = resp.data!['data'] as Map<String, dynamic>?;
|
||
if (data != null) {
|
||
final content = data['content'] as String? ?? '';
|
||
final origin = data['origin'] as Map<String, dynamic>?;
|
||
final author = origin?['author'] as String? ?? '';
|
||
|
||
return {
|
||
'content': content,
|
||
'author': author,
|
||
};
|
||
}
|
||
}
|
||
} catch (e) {
|
||
Log.e('BackgroundCallback: 拉取每日一句失败', e);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
// ============================================================
|
||
// 任务名常量
|
||
// ============================================================
|
||
|
||
class BackgroundTasks {
|
||
BackgroundTasks._();
|
||
|
||
static const String dailySentencePush = 'dailySentencePush';
|
||
static const String widgetDataSync = 'widgetDataSync';
|
||
}
|