first commit
This commit is contained in:
154
lib/database/app_usage_dao.dart
Normal file
154
lib/database/app_usage_dao.dart
Normal file
@@ -0,0 +1,154 @@
|
||||
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],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user