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

155 lines
4.8 KiB
Dart

import 'package:flutter/foundation.dart' show kIsWeb;
import '../models/app_usage.dart';
import 'database_helper.dart';
class AppUsageDao {
final DatabaseHelper _dbHelper = DatabaseHelper.instance;
// Web 平台检查
bool get _isWeb => kIsWeb;
// 插入应用使用记录
Future<int> insertAppUsage(AppUsage usage) async {
final db = await _dbHelper.database;
return await db.insert('app_usage', usage.toMap());
}
// 批量插入
Future<void> batchInsertAppUsages(List<AppUsage> usages) async {
final db = await _dbHelper.database;
final batch = db.batch();
for (final usage in usages) {
batch.insert('app_usage', usage.toMap());
}
await batch.commit(noResult: true);
}
// 获取指定时间范围的应用使用记录
Future<List<AppUsage>> getAppUsages({
required DateTime startTime,
required DateTime endTime,
}) async {
if (_isWeb) return [];
final db = await _dbHelper.database;
final startTimestamp = startTime.millisecondsSinceEpoch ~/ 1000;
final endTimestamp = endTime.millisecondsSinceEpoch ~/ 1000;
final maps = await db.query(
'app_usage',
where: 'start_time >= ? AND end_time <= ?',
whereArgs: [startTimestamp, endTimestamp],
orderBy: 'start_time DESC',
);
return maps.map((map) {
return AppUsage(
id: map['id'] as int?,
packageName: map['package_name'] as String,
appName: map['app_name'] as String,
startTime: DateTime.fromMillisecondsSinceEpoch((map['start_time'] as int) * 1000),
endTime: DateTime.fromMillisecondsSinceEpoch((map['end_time'] as int) * 1000),
duration: map['duration'] as int,
category: map['category'] as String,
projectId: map['project_id'] as int?,
deviceUnlockCount: map['device_unlock_count'] as int,
createdAt: DateTime.fromMillisecondsSinceEpoch((map['created_at'] as int) * 1000),
updatedAt: DateTime.fromMillisecondsSinceEpoch((map['updated_at'] as int) * 1000),
);
}).toList();
}
// 获取今日应用使用记录
Future<List<AppUsage>> getTodayAppUsages() async {
final now = DateTime.now();
final startOfDay = DateTime(now.year, now.month, now.day);
final endOfDay = startOfDay.add(const Duration(days: 1));
return await getAppUsages(startTime: startOfDay, endTime: endOfDay);
}
// 获取 Top N 应用
Future<List<AppUsage>> getTopApps({
required DateTime startTime,
required DateTime endTime,
int limit = 10,
}) async {
if (_isWeb) return [];
final db = await _dbHelper.database;
final startTimestamp = startTime.millisecondsSinceEpoch ~/ 1000;
final endTimestamp = endTime.millisecondsSinceEpoch ~/ 1000;
final maps = await db.rawQuery('''
SELECT
package_name,
app_name,
category,
SUM(duration) as total_duration,
MIN(start_time) as first_start_time,
MAX(end_time) as last_end_time,
MIN(created_at) as created_at,
MAX(updated_at) as updated_at
FROM app_usage
WHERE start_time >= ? AND end_time <= ?
GROUP BY package_name, app_name, category
ORDER BY total_duration DESC
LIMIT ?
''', [startTimestamp, endTimestamp, limit]);
return maps.map((map) {
final firstStart = DateTime.fromMillisecondsSinceEpoch((map['first_start_time'] as int) * 1000);
final lastEnd = DateTime.fromMillisecondsSinceEpoch((map['last_end_time'] as int) * 1000);
return AppUsage(
packageName: map['package_name'] as String,
appName: map['app_name'] as String,
startTime: firstStart,
endTime: lastEnd,
duration: map['total_duration'] as int,
category: map['category'] as String,
createdAt: DateTime.fromMillisecondsSinceEpoch((map['created_at'] as int) * 1000),
updatedAt: DateTime.fromMillisecondsSinceEpoch((map['updated_at'] as int) * 1000),
);
}).toList();
}
// 更新应用分类
Future<void> updateAppUsageCategory(int id, String category) async {
final db = await _dbHelper.database;
await db.update(
'app_usage',
{
'category': category,
'updated_at': DateTime.now().millisecondsSinceEpoch ~/ 1000,
},
where: 'id = ?',
whereArgs: [id],
);
}
// 删除应用使用记录
Future<void> deleteAppUsage(int id) async {
if (_isWeb) return;
final db = await _dbHelper.database;
await db.delete(
'app_usage',
where: 'id = ?',
whereArgs: [id],
);
}
// 删除指定日期之前的数据(用于数据清理)
Future<void> deleteBeforeDate(DateTime date) async {
if (_isWeb) return;
final db = await _dbHelper.database;
final timestamp = date.millisecondsSinceEpoch ~/ 1000;
await db.delete(
'app_usage',
where: 'start_time < ?',
whereArgs: [timestamp],
);
}
}