feat:更新历史记录模块
This commit is contained in:
@@ -9,7 +9,7 @@ part 'health.g.dart';
|
|||||||
@HiveType(typeId: 0)
|
@HiveType(typeId: 0)
|
||||||
class HealthRecord extends HiveObject {
|
class HealthRecord extends HiveObject {
|
||||||
@HiveField(0)
|
@HiveField(0)
|
||||||
int id;
|
String date;
|
||||||
|
|
||||||
@HiveField(1)
|
@HiveField(1)
|
||||||
String sportProject;
|
String sportProject;
|
||||||
@@ -26,11 +26,7 @@ class HealthRecord extends HiveObject {
|
|||||||
@HiveField(5)
|
@HiveField(5)
|
||||||
String sleepEndTime;
|
String sleepEndTime;
|
||||||
|
|
||||||
@HiveField(7)
|
|
||||||
String date;
|
|
||||||
|
|
||||||
HealthRecord({
|
HealthRecord({
|
||||||
required this.id,
|
|
||||||
required this.sportProject,
|
required this.sportProject,
|
||||||
required this.sportDuration,
|
required this.sportDuration,
|
||||||
required this.weight,
|
required this.weight,
|
||||||
@@ -41,7 +37,6 @@ class HealthRecord extends HiveObject {
|
|||||||
|
|
||||||
static HealthRecord getEmpty(DateTime date) {
|
static HealthRecord getEmpty(DateTime date) {
|
||||||
return HealthRecord(
|
return HealthRecord(
|
||||||
id: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
|
||||||
sportProject: '',
|
sportProject: '',
|
||||||
sportDuration: 0,
|
sportDuration: 0,
|
||||||
weight: 0,
|
weight: 0,
|
||||||
@@ -61,13 +56,12 @@ class HealthRecord extends HiveObject {
|
|||||||
String? date,
|
String? date,
|
||||||
}) {
|
}) {
|
||||||
return HealthRecord(
|
return HealthRecord(
|
||||||
id: id ?? this.id,
|
|
||||||
date: date ?? this.date,
|
date: date ?? this.date,
|
||||||
weight: weight ?? this.weight,
|
weight: weight ?? this.weight,
|
||||||
sportProject: sportProject ?? this.sportProject,
|
sportProject: sportProject ?? this.sportProject,
|
||||||
sportDuration: sportDuration ?? this.sportDuration,
|
sportDuration: sportDuration ?? this.sportDuration,
|
||||||
sleepStartTime: sleepStartTime ?? this.sleepStartTime,
|
sleepStartTime: sleepStartTime ?? this.sleepStartTime,
|
||||||
sleepEndTime: sleepEndTime ?? this.sleepEndTime
|
sleepEndTime: sleepEndTime ?? this.sleepEndTime,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,22 +17,21 @@ class HealthRecordAdapter extends TypeAdapter<HealthRecord> {
|
|||||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||||
};
|
};
|
||||||
return HealthRecord(
|
return HealthRecord(
|
||||||
id: fields[0] as int,
|
|
||||||
sportProject: fields[1] as String,
|
sportProject: fields[1] as String,
|
||||||
sportDuration: fields[2] as num,
|
sportDuration: fields[2] as num,
|
||||||
weight: fields[3] as num,
|
weight: fields[3] as num,
|
||||||
sleepStartTime: fields[4] as String,
|
sleepStartTime: fields[4] as String,
|
||||||
sleepEndTime: fields[5] as String,
|
sleepEndTime: fields[5] as String,
|
||||||
date: fields[7] as String,
|
date: fields[0] as String,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void write(BinaryWriter writer, HealthRecord obj) {
|
void write(BinaryWriter writer, HealthRecord obj) {
|
||||||
writer
|
writer
|
||||||
..writeByte(7)
|
..writeByte(6)
|
||||||
..writeByte(0)
|
..writeByte(0)
|
||||||
..write(obj.id)
|
..write(obj.date)
|
||||||
..writeByte(1)
|
..writeByte(1)
|
||||||
..write(obj.sportProject)
|
..write(obj.sportProject)
|
||||||
..writeByte(2)
|
..writeByte(2)
|
||||||
@@ -42,9 +41,7 @@ class HealthRecordAdapter extends TypeAdapter<HealthRecord> {
|
|||||||
..writeByte(4)
|
..writeByte(4)
|
||||||
..write(obj.sleepStartTime)
|
..write(obj.sleepStartTime)
|
||||||
..writeByte(5)
|
..writeByte(5)
|
||||||
..write(obj.sleepEndTime)
|
..write(obj.sleepEndTime);
|
||||||
..writeByte(7)
|
|
||||||
..write(obj.date);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -32,30 +32,10 @@ class _HistoryPageState extends State<HistoryPage> {
|
|||||||
selectedDayPredicate: (day) => isSameDay(provider.selectedDate, day),
|
selectedDayPredicate: (day) => isSameDay(provider.selectedDate, day),
|
||||||
onDaySelected: (selectedDay, focusedDay) {
|
onDaySelected: (selectedDay, focusedDay) {
|
||||||
if (!isSameDay(provider.selectedDate, selectedDay)) {
|
if (!isSameDay(provider.selectedDate, selectedDay)) {
|
||||||
setState(() {
|
provider.updateSelectDate(selectedDay);
|
||||||
provider.selectedDate = selectedDay;
|
provider.updateRecord(service.getRecordByDate(provider.selectedDate));
|
||||||
provider.focusedDate = focusedDay;
|
}
|
||||||
// provider.updateRecord(service.getRecordByDate(provider.selectedDate));
|
|
||||||
// provider.refreshSelectRecord();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
onPageChanged: (focusedDay) {
|
|
||||||
provider.focusedDate = focusedDay;
|
|
||||||
// provider.refreshRecordList();
|
|
||||||
},
|
|
||||||
// 自定义日期单元格构建器
|
|
||||||
// calendarBuilders: CalendarBuilders(
|
|
||||||
// defaultBuilder:
|
|
||||||
// (context, day, focusedDay) =>
|
|
||||||
// _buildDateItem(day, false, false, provider),
|
|
||||||
// selectedBuilder:
|
|
||||||
// (context, day, focusedDay) =>
|
|
||||||
// _buildDateItem(day, true, false, provider),
|
|
||||||
// todayBuilder:
|
|
||||||
// (context, day, focusedDay) =>
|
|
||||||
// _buildDateItem(day, false, true, provider),
|
|
||||||
// ),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import 'package:fitnote/models/health.dart';
|
import 'package:fitnote/models/health.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_common/flutter_common.dart';
|
|
||||||
|
|
||||||
class HealthProvider with ChangeNotifier {
|
class HealthProvider with ChangeNotifier {
|
||||||
late HealthRecord formItem;
|
HealthRecord formItem = HealthRecord.getEmpty(DateTime.now());
|
||||||
|
HealthRecord currentRecord = HealthRecord.getEmpty(DateTime.now());
|
||||||
DateTime selectedDate = DateTime.now();
|
DateTime selectedDate = DateTime.now();
|
||||||
DateTime focusedDate = DateTime.now();
|
|
||||||
RecordType type = RecordType.weight;
|
RecordType type = RecordType.weight;
|
||||||
bool isEditing = false;
|
bool isEditing = false;
|
||||||
|
|
||||||
@@ -18,6 +17,16 @@ class HealthProvider with ChangeNotifier {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateRecord(HealthRecord record) {
|
||||||
|
currentRecord = record;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSelectDate(DateTime date) {
|
||||||
|
selectedDate = date;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
void updateWeight(num weight) {
|
void updateWeight(num weight) {
|
||||||
formItem.weight = weight;
|
formItem.weight = weight;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|||||||
@@ -93,17 +93,18 @@ class HealthService {
|
|||||||
|
|
||||||
Future<bool> updateRecord(HealthRecord record) async {
|
Future<bool> updateRecord(HealthRecord record) async {
|
||||||
try {
|
try {
|
||||||
List<HealthRecord> records =
|
print(record.date);
|
||||||
|
final existingRecords =
|
||||||
box.values.where((item) => item.date == record.date).toList();
|
box.values.where((item) => item.date == record.date).toList();
|
||||||
|
|
||||||
if (records.isEmpty) {
|
if (existingRecords.isEmpty) {
|
||||||
await addRecord(record);
|
await addRecord(record);
|
||||||
} else {
|
} else {
|
||||||
await record.save();
|
await record.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
print(e.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:fitnote/utils/record_utils.dart';
|
|||||||
import 'package:fitnote/widget/record/common.dart';
|
import 'package:fitnote/widget/record/common.dart';
|
||||||
import 'package:fitnote/widget/record/record_form.dart';
|
import 'package:fitnote/widget/record/record_form.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_common/flutter_common.dart';
|
||||||
import 'package:flutter_common/widget/common_widget.dart';
|
import 'package:flutter_common/widget/common_widget.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:getwidget/getwidget.dart';
|
import 'package:getwidget/getwidget.dart';
|
||||||
@@ -21,16 +22,13 @@ class RecordDaily extends StatefulWidget {
|
|||||||
class _RecordDailyState extends State<RecordDaily> {
|
class _RecordDailyState extends State<RecordDaily> {
|
||||||
final HealthService service = HealthService();
|
final HealthService service = HealthService();
|
||||||
|
|
||||||
HealthRecord _record = HealthRecord.getEmpty(DateTime.now());
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
final provider = context.read<HealthProvider>();
|
final provider = context.read<HealthProvider>();
|
||||||
_record = service.getRecordByDate(provider.selectedDate);
|
provider.currentRecord = service.getRecordByDate(provider.selectedDate);
|
||||||
provider.initForm(HealthRecord.getEmpty(provider.selectedDate));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +66,8 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTodayTag() {
|
Widget _buildTodayTag() {
|
||||||
|
final provider = context.watch<HealthProvider>();
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -75,7 +75,7 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
DateFormat('MM月dd日').format(DateTime.now()),
|
DateFormat('MM月dd日').format(provider.selectedDate),
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Color(0xFF64748B),
|
color: Color(0xFF64748B),
|
||||||
@@ -86,6 +86,8 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildRecordListTile(RecordType type) {
|
Widget _buildRecordListTile(RecordType type) {
|
||||||
|
final provider = context.watch<HealthProvider>();
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
@@ -125,7 +127,7 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
_buildRecordContent(type),
|
_buildRecordContent(provider.currentRecord, type),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
trailing: GestureDetector(
|
trailing: GestureDetector(
|
||||||
@@ -138,7 +140,7 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
checkHasRecordValue(_record, type)
|
checkHasRecordValue(provider.currentRecord, type)
|
||||||
? FontAwesomeIcons.pencil
|
? FontAwesomeIcons.pencil
|
||||||
: FontAwesomeIcons.plus,
|
: FontAwesomeIcons.plus,
|
||||||
color: type.color,
|
color: type.color,
|
||||||
@@ -157,21 +159,23 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
|
|
||||||
void onTapRecord(RecordType type) {
|
void onTapRecord(RecordType type) {
|
||||||
final provider = context.read<HealthProvider>();
|
final provider = context.read<HealthProvider>();
|
||||||
provider.isEditing = checkHasRecordValue(_record, type);
|
final record = provider.currentRecord;
|
||||||
|
|
||||||
|
provider.isEditing = checkHasRecordValue(record, type);
|
||||||
provider.type = type;
|
provider.type = type;
|
||||||
|
|
||||||
if (provider.isEditing) {
|
if (provider.isEditing) {
|
||||||
switch (provider.type) {
|
switch (provider.type) {
|
||||||
case RecordType.weight:
|
case RecordType.weight:
|
||||||
provider.updateWeight(_record.weight);
|
provider.updateWeight(record.weight);
|
||||||
break;
|
break;
|
||||||
case RecordType.sport:
|
case RecordType.sport:
|
||||||
provider.updateSportProject(_record.sportProject);
|
provider.updateSportProject(record.sportProject);
|
||||||
provider.updateSportDuration(_record.sportDuration);
|
provider.updateSportDuration(record.sportDuration);
|
||||||
break;
|
break;
|
||||||
case RecordType.sleep:
|
case RecordType.sleep:
|
||||||
provider.updateSleepStartTime(_record.sleepStartTime);
|
provider.updateSleepStartTime(record.sleepStartTime);
|
||||||
provider.updateSleepEndTime(_record.sleepEndTime);
|
provider.updateSleepEndTime(record.sleepEndTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -256,19 +260,18 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
|
|
||||||
void _saveRecord() async {
|
void _saveRecord() async {
|
||||||
final provider = context.read<HealthProvider>();
|
final provider = context.read<HealthProvider>();
|
||||||
|
provider.formItem.date = formatDate(provider.selectedDate);
|
||||||
await service.updateRecord(provider.formItem);
|
await service.updateRecord(provider.formItem);
|
||||||
|
|
||||||
setState(() {
|
provider.updateRecord(service.getRecordByDate(provider.selectedDate));
|
||||||
_record = service.getRecordByDate(provider.selectedDate);
|
|
||||||
});
|
|
||||||
|
|
||||||
provider.updateLatestWeight(service.getLatestWeight());
|
provider.updateLatestWeight(service.getLatestWeight());
|
||||||
provider.updateTotalSpot(service.getTotalSport());
|
provider.updateTotalSpot(service.getTotalSport());
|
||||||
provider.updateAvgSleep(service.getAvgSleep());
|
provider.updateAvgSleep(service.getAvgSleep());
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildRecordContent(RecordType type) {
|
Widget _buildRecordContent(HealthRecord record, RecordType type) {
|
||||||
if (!checkHasRecordValue(_record, type)) {
|
if (!checkHasRecordValue(record, type)) {
|
||||||
return Text(
|
return Text(
|
||||||
"尚未记录今日数据,点击添加",
|
"尚未记录今日数据,点击添加",
|
||||||
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
style: TextStyle(fontSize: 12, color: Colors.grey[500]),
|
||||||
@@ -278,12 +281,12 @@ class _RecordDailyState extends State<RecordDaily> {
|
|||||||
late String title;
|
late String title;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case RecordType.weight:
|
case RecordType.weight:
|
||||||
title = "${_record.weight} kg";
|
title = "${record.weight} kg";
|
||||||
case RecordType.sport:
|
case RecordType.sport:
|
||||||
title = "${_record.sportProject} · ${_record.sportDuration}分钟";
|
title = "${record.sportProject} · ${record.sportDuration}分钟";
|
||||||
case RecordType.sleep:
|
case RecordType.sleep:
|
||||||
final startTime = _record.sleepStartTime;
|
final startTime = record.sleepStartTime;
|
||||||
final endTime = _record.sleepEndTime;
|
final endTime = record.sleepEndTime;
|
||||||
if (startTime.isNotEmpty && endTime.isNotEmpty) {
|
if (startTime.isNotEmpty && endTime.isNotEmpty) {
|
||||||
final duration = calSleepDuration(startTime, endTime);
|
final duration = calSleepDuration(startTime, endTime);
|
||||||
title = "入睡 $startTime · 起床 $endTime · ${duration}";
|
title = "入睡 $startTime · 起床 $endTime · ${duration}";
|
||||||
|
|||||||
Reference in New Issue
Block a user