feat: 实现日历提醒完整功能(操作执行、通知服务重构、归档)
- 新增 ReminderActionExecutor 处理取消/稍后提醒操作 - 新增 ReminderOutboxStore 本地存储待处理操作 - 重构 LocalNotificationService 支持聚合提醒和交互操作 - 新增 event_color_resolver 工具类统一颜色解析 - 新增 CalendarService.archiveEvent 归档方法 - 增强 ModelTracking 支持缓存命中、推理token和成本追踪 - 添加 qwen3.5-35b-a3b 模型配置 - 更新 AndroidManifest 全屏intent权限 - 补充相关单元测试和文档
This commit is contained in:
@@ -9,6 +9,7 @@ import '../../data/models/schedule_item_model.dart';
|
||||
import '../../data/services/calendar_service.dart';
|
||||
import '../calendar_state_manager.dart';
|
||||
import '../calendar_time_utils.dart';
|
||||
import '../utils/event_color_resolver.dart';
|
||||
import '../dayweek/day_event_layout_engine.dart';
|
||||
import '../dayweek/day_timeline_metrics.dart';
|
||||
import '../dayweek/day_view_scale.dart';
|
||||
@@ -614,7 +615,10 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
|
||||
required DayEventLayout layout,
|
||||
required double boardHeight,
|
||||
}) {
|
||||
final eventColor = _parseColor(layout.event.metadata?.color);
|
||||
final eventColor = resolveEventColor(
|
||||
status: layout.event.status,
|
||||
colorHex: layout.event.metadata?.color,
|
||||
);
|
||||
final isCompact = layout.visualHeight < 20;
|
||||
final tapHeight = layout.visualHeight < _minEventTapHeight
|
||||
? _minEventTapHeight
|
||||
@@ -687,17 +691,6 @@ class _CalendarDayWeekScreenState extends State<CalendarDayWeekScreen>
|
||||
);
|
||||
}
|
||||
|
||||
Color _parseColor(String? hex) {
|
||||
if (hex == null || hex.isEmpty) {
|
||||
return AppColors.blue600;
|
||||
}
|
||||
try {
|
||||
return Color(int.parse(hex.replaceFirst('#', '0xFF')));
|
||||
} catch (_) {
|
||||
return AppColors.blue600;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildBottomDock() {
|
||||
return BottomDock(
|
||||
activeTab: DockTab.calendar,
|
||||
|
||||
@@ -10,6 +10,7 @@ import '../../../../shared/widgets/detail_header_action_menu.dart';
|
||||
import '../../../../shared/widgets/destructive_action_sheet.dart';
|
||||
import '../../data/services/calendar_service.dart';
|
||||
import '../../data/models/schedule_item_model.dart';
|
||||
import '../utils/event_color_resolver.dart';
|
||||
import '../widgets/create_event_sheet.dart';
|
||||
import '../widgets/calendar_share_dialog.dart';
|
||||
|
||||
@@ -223,7 +224,7 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
|
||||
_formatReminderText(event.metadata?.reminderMinutes),
|
||||
),
|
||||
const SizedBox(height: 14),
|
||||
_buildColorField(event.metadata?.color),
|
||||
_buildColorField(event),
|
||||
const SizedBox(height: 14),
|
||||
if (event.metadata?.location != null) ...[
|
||||
_buildDetailField('地点', event.metadata!.location!),
|
||||
@@ -275,7 +276,10 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
|
||||
width: 4,
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
color: _parseColor(event.metadata?.color),
|
||||
color: resolveEventColor(
|
||||
status: event.status,
|
||||
colorHex: event.metadata?.color,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
),
|
||||
@@ -343,8 +347,11 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildColorField(String? colorHex) {
|
||||
final color = _parseColor(colorHex);
|
||||
Widget _buildColorField(ScheduleItemModel event) {
|
||||
final color = resolveEventColor(
|
||||
status: event.status,
|
||||
colorHex: event.metadata?.color,
|
||||
);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -400,15 +407,6 @@ class _CalendarEventDetailScreenState extends State<CalendarEventDetailScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Color _parseColor(String? hex) {
|
||||
if (hex == null || hex.isEmpty) return AppColors.blue600;
|
||||
try {
|
||||
return Color(int.parse(hex.replaceFirst('#', '0xFF')));
|
||||
} catch (_) {
|
||||
return AppColors.blue600;
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildInputContainer() {
|
||||
return Container(
|
||||
height: 80,
|
||||
|
||||
@@ -7,6 +7,7 @@ import '../../../../core/theme/design_tokens.dart';
|
||||
import '../../../../shared/widgets/app_pressable.dart';
|
||||
import '../calendar_state_manager.dart';
|
||||
import '../calendar_time_utils.dart';
|
||||
import '../utils/event_color_resolver.dart';
|
||||
import '../widgets/bottom_dock.dart';
|
||||
import '../widgets/create_event_sheet.dart';
|
||||
import '../../data/models/schedule_item_model.dart';
|
||||
@@ -360,7 +361,10 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
...displayEvents.map((event) {
|
||||
final color = _parseColor(event.metadata?.color);
|
||||
final color = resolveEventColor(
|
||||
status: event.status,
|
||||
colorHex: event.metadata?.color,
|
||||
);
|
||||
return AppPressable(
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
onTap: () {
|
||||
@@ -415,15 +419,6 @@ class _CalendarMonthScreenState extends State<CalendarMonthScreen>
|
||||
);
|
||||
}
|
||||
|
||||
Color _parseColor(String? hex) {
|
||||
if (hex == null || hex.isEmpty) return AppColors.blue600;
|
||||
try {
|
||||
return Color(int.parse(hex.replaceFirst('#', '0xFF')));
|
||||
} catch (_) {
|
||||
return AppColors.blue600;
|
||||
}
|
||||
}
|
||||
|
||||
void _showMonthPicker() {
|
||||
var selectedYear = _currentMonth.year;
|
||||
var selectedMonth = _currentMonth.month;
|
||||
|
||||
Reference in New Issue
Block a user