141 lines
3.8 KiB
Dart
141 lines
3.8 KiB
Dart
import 'package:fitnote/models/health.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
bool checkHasRecordValue(HealthRecord record, RecordType type) {
|
|
switch (type) {
|
|
case RecordType.weight:
|
|
return record.weight != 0;
|
|
case RecordType.sport:
|
|
return record.sportDuration != 0;
|
|
case RecordType.sleep:
|
|
return record.sleepStartTime != '' || record.sleepEndTime != '';
|
|
}
|
|
}
|
|
|
|
bool checkNeedRecordTip(HealthRecord record, RecordType type) {
|
|
switch (type) {
|
|
case RecordType.weight:
|
|
return record.weight != 0;
|
|
case RecordType.sport:
|
|
return record.sportDuration != 0;
|
|
case RecordType.sleep:
|
|
return record.sleepStartTime != '' && record.sleepEndTime != '';
|
|
}
|
|
}
|
|
|
|
// 将字符串时间转换为 TimeOfDay
|
|
TimeOfDay? parseTime(String timeString) {
|
|
if (timeString.isEmpty) {
|
|
return null;
|
|
}
|
|
try {
|
|
final parts = timeString.split(':');
|
|
return TimeOfDay(hour: int.parse(parts[0]), minute: int.parse(parts[1]));
|
|
} catch (e) {
|
|
return TimeOfDay.now();
|
|
}
|
|
}
|
|
|
|
DateTime? timeOfDayToDateTime(TimeOfDay? timeOfDay) {
|
|
if (timeOfDay == null) {
|
|
return null;
|
|
}
|
|
|
|
final now = DateTime.now();
|
|
return DateTime(
|
|
now.year,
|
|
now.month,
|
|
now.day,
|
|
timeOfDay.hour,
|
|
timeOfDay.minute,
|
|
);
|
|
}
|
|
|
|
// 将 TimeOfDay 格式化为字符串 (HH:mm)
|
|
String formatTime(DateTime time) {
|
|
return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
|
|
}
|
|
|
|
int calSleepMinDuration(String startTime, String endTime) {
|
|
final start = parseTime(startTime);
|
|
final end = parseTime(endTime);
|
|
|
|
int startMinutes = start!.hour * 60 + start.minute;
|
|
int endMinutes = end!.hour * 60 + end.minute;
|
|
|
|
// 处理跨天情况(如果结束时间小于开始时间,认为是第二天)
|
|
if (endMinutes < startMinutes) {
|
|
endMinutes += 24 * 60;
|
|
}
|
|
|
|
return endMinutes - startMinutes;
|
|
}
|
|
|
|
// 计算睡眠时长
|
|
String calSleepDuration(String startTime, String endTime) {
|
|
try {
|
|
int durationMinutes = calSleepMinDuration(startTime, endTime);
|
|
int hours = durationMinutes ~/ 60;
|
|
int minutes = durationMinutes % 60;
|
|
|
|
return '${hours}小时${minutes}分钟';
|
|
} catch (e) {
|
|
return '计算错误';
|
|
}
|
|
}
|
|
|
|
double roundNum(num value) {
|
|
return double.parse(value.toStringAsFixed(2));
|
|
}
|
|
|
|
double calWeightProgress(num currentWeight, num targetWeight, num startWeight) {
|
|
if (currentWeight == 0) return 0.0;
|
|
if (startWeight <= targetWeight) return 0.0;
|
|
if (currentWeight <= targetWeight) return 1.0;
|
|
|
|
num totalToLose = startWeight - targetWeight;
|
|
num alreadyLost = startWeight - currentWeight;
|
|
|
|
return formatProgress((alreadyLost / totalToLose).clamp(0.0, 1.0));
|
|
}
|
|
|
|
double formatProgress(double value) {
|
|
final result = roundNum(value);
|
|
|
|
if (result >= 1) {
|
|
return 1;
|
|
} else {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
String formatContent(HealthRecord record, RecordType type) {
|
|
late String title;
|
|
switch (type) {
|
|
case RecordType.weight:
|
|
title = "${record.weight.toStringAsFixed(1)} ${type.unit}";
|
|
case RecordType.sport:
|
|
title = "${record.sportProject} · ${record.sportDuration} ${type.unit}";
|
|
case RecordType.sleep:
|
|
final startTime = record.sleepStartTime;
|
|
final endTime = record.sleepEndTime;
|
|
if (startTime.isNotEmpty && endTime.isNotEmpty) {
|
|
final duration = calSleepDuration(startTime, endTime);
|
|
title = "入睡 $startTime · 起床 $endTime \n${duration}";
|
|
} else if (startTime.isNotEmpty) {
|
|
title = "入睡 $startTime";
|
|
} else if (endTime.isNotEmpty) {
|
|
title = "起床 $endTime";
|
|
}
|
|
}
|
|
|
|
return title;
|
|
}
|
|
|
|
String getTimeFromSelectDate(Map<String, int> selected) {
|
|
final String hour = selected['hour'].toString().padLeft(2, '0');
|
|
final String minute = selected['minute'].toString().padLeft(2, '0');
|
|
|
|
return '${hour}:${minute}';
|
|
}
|