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

184 lines
4.8 KiB
Dart

import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:sqflite/sqflite.dart';
import '../database/database_helper.dart';
class CategoryService {
final DatabaseHelper _dbHelper = DatabaseHelper.instance;
// Web 平台使用内存存储
final Map<String, String> _webCustomCategories = {};
// 预设分类规则
static const Map<String, String> defaultCategories = {
// 工作类
'com.microsoft.Office.Word': 'work',
'com.microsoft.Office.Excel': 'work',
'com.microsoft.Office.PowerPoint': 'work',
'com.slack': 'work',
'com.notion.Notion': 'work',
'com.figma.Figma': 'work',
'com.github': 'work',
'com.microsoft.VSCode': 'work',
'com.jetbrains': 'work',
'com.google.android.apps.docs': 'work',
'com.google.android.apps.sheets': 'work',
// 学习类
'com.coursera': 'study',
'com.khanacademy': 'study',
'com.amazon.kindle': 'study',
'com.gingerlabs.Notability': 'study',
'com.goodnotes': 'study',
'com.anki': 'study',
'com.duolingo': 'study',
// 娱乐类
'com.google.YouTube': 'entertainment',
'com.netflix.Netflix': 'entertainment',
'com.spotify.music': 'entertainment',
'com.spotify.client': 'entertainment',
'com.disney': 'entertainment',
// 社交类
'net.whatsapp.WhatsApp': 'social',
'com.instagram': 'social',
'com.twitter': 'social',
'com.facebook.Facebook': 'social',
'com.tencent.mm': 'social', // 微信
'com.tencent.mobileqq': 'social', // QQ
// 工具类
'com.apple.Safari': 'tool',
'com.android.chrome': 'tool',
'com.google.chrome': 'tool',
'com.microsoft.edge': 'tool',
'com.apple.mobilemail': 'tool',
'com.google.Gmail': 'tool',
};
// 获取应用分类
Future<String> getCategory(String packageName) async {
// 1. 先查用户自定义分类
final customCategory = await _getCustomCategory(packageName);
if (customCategory != null) {
return customCategory;
}
// 2. 查系统预设分类
if (defaultCategories.containsKey(packageName)) {
return defaultCategories[packageName]!;
}
// 3. 默认分类
return 'other';
}
// 获取用户自定义分类
Future<String?> _getCustomCategory(String packageName) async {
// Web 平台使用内存存储
if (kIsWeb) {
return _webCustomCategories[packageName];
}
final db = await _dbHelper.database;
final maps = await db.query(
'app_category',
where: 'package_name = ? AND is_custom = 1',
whereArgs: [packageName],
);
if (maps.isEmpty) return null;
return maps.first['category'] as String;
}
// 设置自定义分类
Future<void> setCategory(String packageName, String category) async {
// Web 平台使用内存存储
if (kIsWeb) {
_webCustomCategories[packageName] = category;
return;
}
final db = await _dbHelper.database;
final now = DateTime.now().millisecondsSinceEpoch ~/ 1000;
await db.insert(
'app_category',
{
'package_name': packageName,
'category': category,
'is_custom': 1,
'created_at': now,
'updated_at': now,
},
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
// 删除自定义分类(恢复为系统默认)
Future<void> removeCustomCategory(String packageName) async {
// Web 平台使用内存存储
if (kIsWeb) {
_webCustomCategories.remove(packageName);
return;
}
final db = await _dbHelper.database;
await db.delete(
'app_category',
where: 'package_name = ? AND is_custom = 1',
whereArgs: [packageName],
);
}
// 获取所有自定义分类
Future<Map<String, String>> getAllCustomCategories() async {
// Web 平台使用内存存储
if (kIsWeb) {
return Map<String, String>.from(_webCustomCategories);
}
final db = await _dbHelper.database;
final maps = await db.query(
'app_category',
where: 'is_custom = 1',
);
final result = <String, String>{};
for (final map in maps) {
result[map['package_name'] as String] = map['category'] as String;
}
return result;
}
// 批量设置分类
Future<void> batchSetCategories(Map<String, String> categories) async {
// Web 平台使用内存存储
if (kIsWeb) {
_webCustomCategories.addAll(categories);
return;
}
final db = await _dbHelper.database;
final batch = db.batch();
final now = DateTime.now().millisecondsSinceEpoch ~/ 1000;
for (final entry in categories.entries) {
batch.insert(
'app_category',
{
'package_name': entry.key,
'category': entry.value,
'is_custom': 1,
'created_at': now,
'updated_at': now,
},
conflictAlgorithm: ConflictAlgorithm.replace,
);
}
await batch.commit(noResult: true);
}
}