first commit

This commit is contained in:
ytc1012
2025-11-13 15:45:28 +08:00
commit 6b321890c0
54 changed files with 8412 additions and 0 deletions

70
lib/models/app_usage.dart Normal file
View File

@@ -0,0 +1,70 @@
class AppUsage {
final int? id;
final String packageName;
final String appName;
final DateTime startTime;
final DateTime endTime;
final int duration; // 秒
final String category;
final int? projectId;
final int deviceUnlockCount;
final DateTime createdAt;
final DateTime updatedAt;
AppUsage({
this.id,
required this.packageName,
required this.appName,
required this.startTime,
required this.endTime,
required this.duration,
required this.category,
this.projectId,
this.deviceUnlockCount = 0,
required this.createdAt,
required this.updatedAt,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'package_name': packageName,
'app_name': appName,
'start_time': startTime.millisecondsSinceEpoch ~/ 1000,
'end_time': endTime.millisecondsSinceEpoch ~/ 1000,
'duration': duration,
'category': category,
'project_id': projectId,
'device_unlock_count': deviceUnlockCount,
'created_at': createdAt.millisecondsSinceEpoch ~/ 1000,
'updated_at': updatedAt.millisecondsSinceEpoch ~/ 1000,
};
}
factory AppUsage.fromMap(Map<String, dynamic> map) {
return AppUsage(
id: map['id'],
packageName: map['package_name'],
appName: map['app_name'],
startTime: DateTime.fromMillisecondsSinceEpoch(map['start_time'] * 1000),
endTime: DateTime.fromMillisecondsSinceEpoch(map['end_time'] * 1000),
duration: map['duration'],
category: map['category'],
projectId: map['project_id'],
deviceUnlockCount: map['device_unlock_count'] ?? 0,
createdAt: DateTime.fromMillisecondsSinceEpoch(map['created_at'] * 1000),
updatedAt: DateTime.fromMillisecondsSinceEpoch(map['updated_at'] * 1000),
);
}
// 格式化时长
String get formattedDuration {
final hours = duration ~/ 3600;
final minutes = (duration % 3600) ~/ 60;
if (hours > 0) {
return '${hours}h ${minutes}m';
}
return '${minutes}m';
}
}

View File

@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
class DailyStats {
final int? id;
final DateTime date;
final int totalTime; // 秒
final int workTime;
final int studyTime;
final int entertainmentTime;
final int socialTime;
final int toolTime;
final int? efficiencyScore;
final int? focusScore;
final int appSwitchCount;
final DateTime createdAt;
final DateTime updatedAt;
DailyStats({
this.id,
required this.date,
required this.totalTime,
this.workTime = 0,
this.studyTime = 0,
this.entertainmentTime = 0,
this.socialTime = 0,
this.toolTime = 0,
this.efficiencyScore,
this.focusScore,
this.appSwitchCount = 0,
required this.createdAt,
required this.updatedAt,
});
Map<String, int> get categoryTime => {
'work': workTime,
'study': studyTime,
'entertainment': entertainmentTime,
'social': socialTime,
'tool': toolTime,
};
// 格式化总时长
String get formattedTotalTime {
final hours = totalTime ~/ 3600;
final minutes = (totalTime % 3600) ~/ 60;
if (hours > 0) {
return '${hours}h ${minutes}m';
}
return '${minutes}m';
}
// 获取效率评分颜色
Color get efficiencyColor {
final score = efficiencyScore ?? 0;
if (score >= 80) {
return const Color(0xFF10B981); // Green
} else if (score >= 50) {
return const Color(0xFFF59E0B); // Orange
} else {
return const Color(0xFFEF4444); // Red
}
}
}

54
lib/models/time_goal.dart Normal file
View File

@@ -0,0 +1,54 @@
class TimeGoal {
final int? id;
final String goalType; // 'daily_total' 或 'daily_category'
final String? category; // 如果是分类目标,指定分类
final int targetTime; // 目标时长(秒)
final bool isActive;
final DateTime createdAt;
final DateTime updatedAt;
TimeGoal({
this.id,
required this.goalType,
this.category,
required this.targetTime,
this.isActive = true,
required this.createdAt,
required this.updatedAt,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'goal_type': goalType,
'category': category,
'target_time': targetTime,
'is_active': isActive ? 1 : 0,
'created_at': createdAt.millisecondsSinceEpoch ~/ 1000,
'updated_at': updatedAt.millisecondsSinceEpoch ~/ 1000,
};
}
factory TimeGoal.fromMap(Map<String, dynamic> map) {
return TimeGoal(
id: map['id'] as int?,
goalType: map['goal_type'] as String,
category: map['category'] as String?,
targetTime: map['target_time'] as int,
isActive: (map['is_active'] as int) == 1,
createdAt: DateTime.fromMillisecondsSinceEpoch((map['created_at'] as int) * 1000),
updatedAt: DateTime.fromMillisecondsSinceEpoch((map['updated_at'] as int) * 1000),
);
}
// 格式化目标时长
String get formattedTargetTime {
final hours = targetTime ~/ 3600;
final minutes = (targetTime % 3600) ~/ 60;
if (hours > 0) {
return '${hours}小时${minutes}分钟';
}
return '${minutes}分钟';
}
}