feat: 增强日历功能并集成 AgentScope 代理服务

This commit is contained in:
qzl
2026-03-11 17:16:11 +08:00
parent e20e7d2a02
commit 85b314cf64
53 changed files with 3642 additions and 297 deletions
@@ -0,0 +1,115 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest.dart' as tz_data;
import 'package:timezone/timezone.dart' as tz;
import '../../features/calendar/data/models/schedule_item_model.dart';
class LocalNotificationService {
final FlutterLocalNotificationsPlugin _plugin;
bool _initialized = false;
LocalNotificationService({FlutterLocalNotificationsPlugin? plugin})
: _plugin = plugin ?? FlutterLocalNotificationsPlugin();
Future<void> initialize() async {
if (_initialized) {
return;
}
tz_data.initializeTimeZones();
const android = AndroidInitializationSettings('@mipmap/ic_launcher');
const ios = DarwinInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
);
const settings = InitializationSettings(android: android, iOS: ios);
await _plugin.initialize(settings);
await _plugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin
>()
?.requestNotificationsPermission();
await _plugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin
>()
?.requestPermissions(alert: true, badge: true, sound: true);
_initialized = true;
}
Future<void> upsertEventReminder(ScheduleItemModel event) async {
await initialize();
final reminderMinutes = event.metadata?.reminderMinutes;
if (reminderMinutes == null) {
await cancelEventReminder(event.id);
return;
}
final fireAt = event.startAt.subtract(Duration(minutes: reminderMinutes));
if (!fireAt.isAfter(DateTime.now())) {
await cancelEventReminder(event.id);
return;
}
final notificationId = _notificationIdForEvent(event.id);
final scheduledAt = tz.TZDateTime.from(fireAt, tz.local);
final details = NotificationDetails(
android: AndroidNotificationDetails(
'calendar_reminder_channel',
'日历提醒',
channelDescription: '日历事件提醒通知',
importance: Importance.max,
priority: Priority.high,
enableVibration: true,
),
iOS: const DarwinNotificationDetails(
presentAlert: true,
presentSound: true,
presentBadge: true,
),
);
await _plugin.zonedSchedule(
notificationId,
event.title,
_buildReminderBody(event, reminderMinutes),
scheduledAt,
details,
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
);
}
Future<void> cancelEventReminder(String eventId) async {
await initialize();
await _plugin.cancel(_notificationIdForEvent(eventId));
}
Future<void> rebuildUpcomingReminders(
Iterable<ScheduleItemModel> events,
) async {
await initialize();
for (final event in events) {
await upsertEventReminder(event);
}
}
int _notificationIdForEvent(String eventId) {
return eventId.hashCode & 0x7fffffff;
}
String _buildReminderBody(ScheduleItemModel event, int reminderMinutes) {
if (reminderMinutes == 0) {
return '日程现在开始:${event.title}';
}
return '日程即将开始(提前$reminderMinutes分钟):${event.title}';
}
}