Files
AutoTime-Tracker/lib/database/daily_stats_dao.dart
2025-11-13 15:45:28 +08:00

166 lines
4.7 KiB
Dart

import 'package:flutter/foundation.dart' show kIsWeb;
import '../models/daily_stats.dart';
import 'database_helper.dart';
class DailyStatsDao {
final DatabaseHelper _dbHelper = DatabaseHelper.instance;
// Web 平台检查
bool get _isWeb => kIsWeb;
// 插入或更新每日统计
Future<void> upsertDailyStats(DailyStats stats) async {
final db = await _dbHelper.database;
final dateStr = _formatDate(stats.date);
final map = stats.toMap();
final existing = await db.query(
'daily_stats',
where: 'date = ?',
whereArgs: [dateStr],
);
if (existing.isEmpty) {
await db.insert('daily_stats', map);
} else {
await db.update(
'daily_stats',
map,
where: 'date = ?',
whereArgs: [dateStr],
);
}
}
// 获取指定日期的统计
Future<DailyStats?> getDailyStats(DateTime date) async {
final db = await _dbHelper.database;
final dateStr = _formatDate(date);
final maps = await db.query(
'daily_stats',
where: 'date = ?',
whereArgs: [dateStr],
);
if (maps.isEmpty) return null;
return _mapToDailyStats(maps.first);
}
// 获取今日统计
Future<DailyStats?> getTodayStats() async {
return await getDailyStats(DateTime.now());
}
// 获取指定日期范围的统计
Future<List<DailyStats>> getStatsRange({
required DateTime startDate,
required DateTime endDate,
}) async {
if (_isWeb) return [];
final db = await _dbHelper.database;
final startStr = _formatDate(startDate);
final endStr = _formatDate(endDate);
final maps = await db.query(
'daily_stats',
where: 'date >= ? AND date <= ?',
whereArgs: [startStr, endStr],
orderBy: 'date ASC',
);
return maps.map((map) => _mapToDailyStats(map)).toList();
}
// 获取本周统计
Future<List<DailyStats>> getWeekStats() async {
final now = DateTime.now();
final startOfWeek = now.subtract(Duration(days: now.weekday - 1));
final endOfWeek = startOfWeek.add(const Duration(days: 6));
return await getStatsRange(startDate: startOfWeek, endDate: endOfWeek);
}
// 获取本月统计
Future<List<DailyStats>> getMonthStats() async {
final now = DateTime.now();
final startOfMonth = DateTime(now.year, now.month, 1);
final endOfMonth = DateTime(now.year, now.month + 1, 0);
return await getStatsRange(startDate: startOfMonth, endDate: endOfMonth);
}
// 删除指定日期之前的数据
Future<void> deleteBeforeDate(DateTime date) async {
if (_isWeb) return;
final db = await _dbHelper.database;
final dateStr = _formatDate(date);
await db.delete(
'daily_stats',
where: 'date < ?',
whereArgs: [dateStr],
);
}
// 删除指定 ID 的统计
Future<void> deleteDailyStats(int id) async {
if (_isWeb) return;
final db = await _dbHelper.database;
await db.delete(
'daily_stats',
where: 'id = ?',
whereArgs: [id],
);
}
String _formatDate(DateTime date) {
return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
}
DailyStats _mapToDailyStats(Map<String, dynamic> map) {
return DailyStats(
id: map['id'] as int?,
date: DateTime.parse(map['date'] as String),
totalTime: map['total_time'] as int,
workTime: map['work_time'] as int? ?? 0,
studyTime: map['study_time'] as int? ?? 0,
entertainmentTime: map['entertainment_time'] as int? ?? 0,
socialTime: map['social_time'] as int? ?? 0,
toolTime: map['tool_time'] as int? ?? 0,
efficiencyScore: map['efficiency_score'] as int?,
focusScore: map['focus_score'] as int?,
appSwitchCount: map['app_switch_count'] as int? ?? 0,
createdAt: DateTime.fromMillisecondsSinceEpoch((map['created_at'] as int) * 1000),
updatedAt: DateTime.fromMillisecondsSinceEpoch((map['updated_at'] as int) * 1000),
);
}
}
// 扩展 DailyStats 模型,添加 toMap 方法
extension DailyStatsExtension on DailyStats {
Map<String, dynamic> toMap() {
return {
'id': id,
'date': _formatDate(date),
'total_time': totalTime,
'work_time': workTime,
'study_time': studyTime,
'entertainment_time': entertainmentTime,
'social_time': socialTime,
'tool_time': toolTime,
'efficiency_score': efficiencyScore,
'focus_score': focusScore,
'app_switch_count': appSwitchCount,
'created_at': createdAt.millisecondsSinceEpoch ~/ 1000,
'updated_at': updatedAt.millisecondsSinceEpoch ~/ 1000,
};
}
String _formatDate(DateTime date) {
return '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}';
}
}