Commit 7b773e28749122b2f14a3a3f5618764989016581

Authored by 刘宏哲
1 parent 87f2e239

feat(app): bug fixed

@@ -56,9 +56,7 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { @@ -56,9 +56,7 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget {
56 Text( 56 Text(
57 HealthReportSubjectScope.titleOf( 57 HealthReportSubjectScope.titleOf(
58 context, 58 context,
59 - summary.hasData  
60 - ? context.l10n.activityHeartRateZone  
61 - : context.l10n.activityRealtimeHeartRate, 59 + context.l10n.activityHeartRateZone,
62 ), 60 ),
63 style: TextStyle( 61 style: TextStyle(
64 color: _h1, 62 color: _h1,
@@ -284,11 +282,13 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget { @@ -284,11 +282,13 @@ class ActivityBurnHeartRateZoneCard extends StatelessWidget {
284 } 282 }
285 283
286 DateTime get _startTime { 284 DateTime get _startTime {
287 - if (summary.startTime != null) return summary.startTime!;  
288 - if (summary.points.isNotEmpty) return summary.points.first.time; 285 + if (summary.startTime != null) return _dayStart(summary.startTime!);
  286 + if (summary.points.isNotEmpty) return _dayStart(summary.points.first.time);
289 return DateTime(0); 287 return DateTime(0);
290 } 288 }
291 289
  290 + DateTime _dayStart(DateTime time) => DateTime(time.year, time.month, time.day);
  291 +
292 List<ActivityBurnHeartRatePoint> _points(DateTime start, DateTime end) { 292 List<ActivityBurnHeartRatePoint> _points(DateTime start, DateTime end) {
293 return summary.points 293 return summary.points
294 .where( 294 .where(
@@ -463,27 +463,26 @@ class _HeartRateAxis { @@ -463,27 +463,26 @@ class _HeartRateAxis {
463 ActivityBurnHeartRateSummary summary, 463 ActivityBurnHeartRateSummary summary,
464 DateTime start, 464 DateTime start,
465 ) { 465 ) {
  466 + final maxMinutes = _dynamicMaxMinutes(start, DateTime.now());
466 final dayEnd = start.add(const Duration(days: 1)); 467 final dayEnd = start.add(const Duration(days: 1));
467 final points = summary.points 468 final points = summary.points
468 .where( 469 .where(
469 (point) => 470 (point) =>
470 point.bpm > 0 && 471 point.bpm > 0 &&
471 !point.time.isBefore(start) && 472 !point.time.isBefore(start) &&
472 - point.time.isBefore(dayEnd), 473 + point.time.isBefore(dayEnd) &&
  474 + point.time.difference(start).inMinutes <= maxMinutes,
473 ) 475 )
474 .toList(); 476 .toList();
475 if (points.isEmpty) { 477 if (points.isEmpty) {
476 return _HeartRateAxis( 478 return _HeartRateAxis(
477 - endTime: start.add(const Duration(hours: 18)),  
478 - maxX: 1080, 479 + endTime: start.add(Duration(minutes: maxMinutes)),
  480 + maxX: maxMinutes.toDouble(),
479 minY: 40, 481 minY: 40,
480 maxY: 200, 482 maxY: 200,
481 ); 483 );
482 } 484 }
483 485
484 - final coveredEnd = points.last.time;  
485 - final coveredMinutes = coveredEnd.difference(start).inMinutes;  
486 - final maxMinutes = _nextSixHourTick(coveredMinutes);  
487 final heartRates = points.map((point) => point.bpm); 486 final heartRates = points.map((point) => point.bpm);
488 final minY = heartRates.reduce(math.min); 487 final minY = heartRates.reduce(math.min);
489 var maxY = _roundUpToFiveOrTen(heartRates.reduce(math.max)); 488 var maxY = _roundUpToFiveOrTen(heartRates.reduce(math.max));
@@ -506,11 +505,21 @@ class _HeartRateAxis { @@ -506,11 +505,21 @@ class _HeartRateAxis {
506 return value.toStringAsFixed(1); 505 return value.toStringAsFixed(1);
507 } 506 }
508 507
  508 + static int _dynamicMaxMinutes(DateTime start, DateTime now) {
  509 + final today = DateTime(now.year, now.month, now.day);
  510 + if (start.isBefore(today)) return 1440;
  511 + if (start.isAfter(today)) return 360;
  512 +
  513 + final coveredMinutes = now.difference(start).inMinutes;
  514 + return _nextSixHourTick(coveredMinutes);
  515 + }
  516 +
509 static int _nextSixHourTick(int coveredMinutes) { 517 static int _nextSixHourTick(int coveredMinutes) {
510 const tickMinutes = 360; 518 const tickMinutes = 360;
511 final clamped = coveredMinutes.clamp(0, 1440); 519 final clamped = coveredMinutes.clamp(0, 1440);
512 if (clamped == 0) return tickMinutes; 520 if (clamped == 0) return tickMinutes;
513 - return (clamped ~/ tickMinutes + 1).clamp(1, 4) * tickMinutes; 521 + final tickIndex = (clamped / tickMinutes).ceil().clamp(1, 4).toInt();
  522 + return tickIndex * tickMinutes;
514 } 523 }
515 524
516 static double _roundUpToFiveOrTen(double value) => (value / 5).ceil() * 5.0; 525 static double _roundUpToFiveOrTen(double value) => (value / 5).ceil() * 5.0;
@@ -62,7 +62,7 @@ class FriendsController extends GetxController { @@ -62,7 +62,7 @@ class FriendsController extends GetxController {
62 Future<void> _loadFriends() async { 62 Future<void> _loadFriends() async {
63 isLoading.value = true; 63 isLoading.value = true;
64 try { 64 try {
65 - final data = await _repository.getFriendList(); 65 + final data = await _repository.getFriendList(withSelfHealthData: true);
66 friends.assignAll(data.friends); 66 friends.assignAll(data.friends);
67 selfHealthData.value = data.selfHealthData; 67 selfHealthData.value = data.selfHealthData;
68 } catch (error, stackTrace) { 68 } catch (error, stackTrace) {
@@ -11,7 +11,10 @@ import '../models/friend_stress_state.dart'; @@ -11,7 +11,10 @@ import '../models/friend_stress_state.dart';
11 abstract class FriendsRepository { 11 abstract class FriendsRepository {
12 Future<List<FriendHealthData>> getFriends({bool withHealthData = true}); 12 Future<List<FriendHealthData>> getFriends({bool withHealthData = true});
13 13
14 - Future<FriendListData> getFriendList({bool withHealthData = true}); 14 + Future<FriendListData> getFriendList({
  15 + bool withHealthData = true,
  16 + bool withSelfHealthData = false,
  17 + });
15 18
16 Future<void> updateRemark(int userId, String remark); 19 Future<void> updateRemark(int userId, String remark);
17 20
@@ -43,8 +46,14 @@ class FriendsRepositoryImpl implements FriendsRepository { @@ -43,8 +46,14 @@ class FriendsRepositoryImpl implements FriendsRepository {
43 } 46 }
44 47
45 @override 48 @override
46 - Future<FriendListData> getFriendList({bool withHealthData = true}) async {  
47 - return switch (await _friendApi.friendList(withHealthData)) { 49 + Future<FriendListData> getFriendList({
  50 + bool withHealthData = true,
  51 + bool withSelfHealthData = false,
  52 + }) async {
  53 + return switch (await _friendApi.friendList(
  54 + withHealthData,
  55 + withSelfHealthData: withSelfHealthData,
  56 + )) {
48 AppSuccess(:final data) => FriendListData( 57 AppSuccess(:final data) => FriendListData(
49 friends: data.list.map(_mapFriend).toList(), 58 friends: data.list.map(_mapFriend).toList(),
50 selfHealthData: _mapSelfHealthData(data.healthData), 59 selfHealthData: _mapSelfHealthData(data.healthData),
@@ -88,12 +88,20 @@ class FriendApi { @@ -88,12 +88,20 @@ class FriendApi {
88 ); 88 );
89 } 89 }
90 90
91 - Future<AppResult<FriendListResponse>> friendList(bool withHealthData) { 91 + Future<AppResult<FriendListResponse>> friendList(
  92 + bool withHealthData, {
  93 + bool withSelfHealthData = false,
  94 + }) {
92 return safeCall( 95 return safeCall(
93 call: () async { 96 call: () async {
  97 + final queryParameters = <String, dynamic>{
  98 + 'with_health_data': withHealthData ? 1 : 0,
  99 + 'with_self_health_data': withSelfHealthData ? 1 : 0,
  100 + };
  101 +
94 final response = await _dioClient.dio.get( 102 final response = await _dioClient.dio.get(
95 ApiPaths.friends, 103 ApiPaths.friends,
96 - queryParameters: {'with_health_data': withHealthData ? 1 : 0}, 104 + queryParameters: queryParameters,
97 ); 105 );
98 return FriendListResponse.fromJson( 106 return FriendListResponse.fromJson(
99 response.data as Map<String, dynamic>, 107 response.data as Map<String, dynamic>,