feat:增加睡眠记录

This commit is contained in:
2025-12-02 14:09:56 +08:00
parent 2cc69b4019
commit 8a71ea542e
14 changed files with 402 additions and 129 deletions

View File

@@ -1,11 +1,13 @@
import 'package:fitnote/models/health.dart';
import 'package:fitnote/provider/health_provider.dart';
import 'package:fitnote/service/health_service.dart';
import 'package:fitnote/utils/record_utils.dart';
import 'package:fitnote/widget/record/common.dart';
import 'package:fitnote/widget/record/record_form.dart';
import 'package:flutter/material.dart';
import 'package:flutter_common/widget/common_widget.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:getwidget/getwidget.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
@@ -19,24 +21,18 @@ class RecordDaily extends StatefulWidget {
class _RecordDailyState extends State<RecordDaily> {
final HealthService service = HealthService();
late HealthRecord _record;
HealthRecord _record = HealthRecord.getEmpty('');
@override
void initState() {
super.initState();
_record = service.getAllRecordByDate('2025-12-01');
}
final recordForm = HealthRecord(
id: 1,
sportProject: '羽毛球',
sportDuration: 20,
sleepStartTime: '23:00',
sleepEndTime: '24:00',
sleepDuration: 60,
weight: 70,
date: '2025-11-28',
);
WidgetsBinding.instance.addPostFrameCallback((_) {
final provider = context.read<HealthProvider>();
_record = service.getAllRecordByDate(provider.date);
provider.initForm(HealthRecord.getEmpty(provider.date));
});
}
@override
Widget build(BuildContext context) {
@@ -142,7 +138,7 @@ class _RecordDailyState extends State<RecordDaily> {
borderRadius: BorderRadius.circular(20),
),
child: Icon(
_checkHasRecordValue(type)
checkHasRecordValue(_record, type)
? FontAwesomeIcons.pencil
: FontAwesomeIcons.plus,
color: type.color,
@@ -159,29 +155,112 @@ class _RecordDailyState extends State<RecordDaily> {
);
}
bool _checkHasRecordValue(RecordType type) {
switch (type) {
case RecordType.weight:
return _record.weight != 0;
case RecordType.sport:
return _record.sportProject != '';
case RecordType.sleep:
return _record.sleepStartTime != '';
}
}
void onTapRecord(RecordType type) {
final provider = context.read<HealthProvider>();
provider.initForm(HealthRecord.getDefault());
provider.isEditing = checkHasRecordValue(_record, type);
provider.type = type;
if (provider.isEditing) {
_initRecord(provider);
} else {
_defaultRecord(provider);
}
showDialog(
context: context,
builder: (context) => Dialog(child: RecordForm(type: type)),
builder:
(context) => Dialog(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [RecordForm(type: type), _buildDialogButton()],
),
),
),
);
}
Widget _buildDialogButton() {
final colors = Theme.of(context).colorScheme;
return Row(
children: [
Expanded(
child: GFButton(
onPressed: () {
Navigator.of(context).pop();
_resetRecord();
},
color: colors.secondary,
text: "取消",
),
),
const SizedBox(width: 12),
Expanded(
child: GFButton(
onPressed: () {
Navigator.of(context).pop();
_saveRecord();
},
color: colors.primary,
text: "确定",
),
),
],
);
}
void _initRecord(HealthProvider provider) {
switch (provider.type) {
case RecordType.weight:
provider.updateWeight(_record.weight);
break;
case RecordType.sport:
provider.updateSportProject(_record.sportProject);
provider.updateSportDuration(_record.sportDuration);
break;
case RecordType.sleep:
provider.updateSleepStartTime(_record.sleepStartTime);
provider.updateSleepEndTime(_record.sleepEndTime);
break;
}
}
void _resetRecord() {
final provider = context.read<HealthProvider>();
if (!provider.isEditing) {
_defaultRecord(provider);
}
}
void _defaultRecord(HealthProvider provider) {
switch (provider.type) {
case RecordType.weight:
provider.updateWeight(70);
break;
case RecordType.sport:
provider.updateSportProject('跑步');
provider.updateSportDuration(30);
break;
case RecordType.sleep:
provider.updateSleepStartTime('');
provider.updateSleepEndTime('');
break;
}
}
void _saveRecord() async {
final provider = context.read<HealthProvider>();
await service.updateRecord(provider.formItem);
setState(() {
_record = service.getAllRecordByDate(provider.date);
});
}
Widget _buildRecordContent(RecordType type) {
if (!_checkHasRecordValue(type)) {
if (!checkHasRecordValue(_record, type)) {
return Text(
"尚未记录今日数据,点击添加",
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
@@ -195,8 +274,16 @@ class _RecordDailyState extends State<RecordDaily> {
case RecordType.sport:
title = "${_record.sportProject} · ${_record.sportDuration}分钟";
case RecordType.sleep:
title =
"入睡 ${_record.sleepStartTime} · 起床 ${_record.sleepEndTime} · ${_record.sleepDuration}分钟";
final startTime = _record.sleepStartTime;
final endTime = _record.sleepEndTime;
if (startTime.isNotEmpty && endTime.isNotEmpty) {
final duration = calculateDuration(startTime, endTime);
title = "入睡 $startTime · 起床 $endTime · ${duration}";
} else if (startTime.isNotEmpty) {
title = "入睡 $startTime";
} else if (endTime.isNotEmpty) {
title = "起床 $endTime";
}
}
return Text(