Commit 853b626c2c152cd453caf1d5619459247acb016b

Authored by 权海
1 parent 5e42fc23

feat(ui):能量消耗在原始值就统一向上取整

@@ -207,11 +207,11 @@ final class HealthKitQueryReader { @@ -207,11 +207,11 @@ final class HealthKitQueryReader {
207 207
208 return NativeActivityTarget( 208 return NativeActivityTarget(
209 healthValueTimestamp: timestamp, 209 healthValueTimestamp: timestamp,
210 - move: Int(summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie())), 210 + move: Int(summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()).rounded(.up)),
211 stand: Int(summary.appleStandHoursGoal.doubleValue(for: .count())), 211 stand: Int(summary.appleStandHoursGoal.doubleValue(for: .count())),
212 activityMoveMode: Self.activityMoveModeValue(from: summary), 212 activityMoveMode: Self.activityMoveModeValue(from: summary),
213 - activeEnergyBurned: summary.activeEnergyBurned.doubleValue(for: .kilocalorie()),  
214 - activeEnergyBurnedGoal: summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()), 213 + activeEnergyBurned: summary.activeEnergyBurned.doubleValue(for: .kilocalorie()).rounded(.up),
  214 + activeEnergyBurnedGoal: summary.activeEnergyBurnedGoal.doubleValue(for: .kilocalorie()).rounded(.up),
215 appleMoveTime: Self.appleMoveTimeValue(from: summary), 215 appleMoveTime: Self.appleMoveTimeValue(from: summary),
216 appleMoveTimeGoal: Self.appleMoveTimeGoalValue(from: summary), 216 appleMoveTimeGoal: Self.appleMoveTimeGoalValue(from: summary),
217 appleExerciseTime: summary.appleExerciseTime.doubleValue(for: .second()), 217 appleExerciseTime: summary.appleExerciseTime.doubleValue(for: .second()),
@@ -266,8 +266,10 @@ class LocalHealthDataConvert { @@ -266,8 +266,10 @@ class LocalHealthDataConvert {
266 totalSteps: 0, 266 totalSteps: 0,
267 totalStand: _sum(daily.map((e) => e.standHours).toList()), 267 totalStand: _sum(daily.map((e) => e.standHours).toList()),
268 totalExercise: _sum(daily.map((e) => e.exerciseSeconds).toList()), 268 totalExercise: _sum(daily.map((e) => e.exerciseSeconds).toList()),
269 - avgMove: _averageOrNull(daily.map((e) => e.move).toList()),  
270 - qoqAvgMove: _averageOrNull(previousDaily.map((e) => e.move).toList()), 269 + avgMove: _ceilOrNull(_averageOrNull(daily.map((e) => e.move).toList())),
  270 + qoqAvgMove: _ceilOrNull(
  271 + _averageOrNull(previousDaily.map((e) => e.move).toList()),
  272 + ),
271 activityTargetInfo: _activityTargetInfo(latestWithGoal), 273 activityTargetInfo: _activityTargetInfo(latestWithGoal),
272 moveTrendList: [ 274 moveTrendList: [
273 for (final item in daily) 275 for (final item in daily)
@@ -412,7 +414,7 @@ class LocalHealthDataConvert { @@ -412,7 +414,7 @@ class LocalHealthDataConvert {
412 ); 414 );
413 return V2ActivityTarget( 415 return V2ActivityTarget(
414 userId: userId, 416 userId: userId,
415 - move: latestWithGoal?.activeEnergyBurnedGoal?.ceil(), 417 + move: _ceilOrNull(latestWithGoal?.activeEnergyBurnedGoal),
416 step: 0, 418 step: 0,
417 stand: latestWithGoal?.standHoursGoal?.round(), 419 stand: latestWithGoal?.standHoursGoal?.round(),
418 exercise: latestWithGoal?.exerciseTimeGoal == null 420 exercise: latestWithGoal?.exerciseTimeGoal == null
@@ -584,10 +586,10 @@ class LocalHealthDataConvert { @@ -584,10 +586,10 @@ class LocalHealthDataConvert {
584 final latest = dayActivity.isEmpty ? null : dayActivity.last; 586 final latest = dayActivity.isEmpty ? null : dayActivity.last;
585 return _ActivityDaySummary( 587 return _ActivityDaySummary(
586 day: day, 588 day: day,
587 - move: (latest?.activeEnergyBurned ?? 0).ceil(), 589 + move: _ceilOrZero(latest?.activeEnergyBurned),
588 standHours: latest?.appleStandHours ?? 0, 590 standHours: latest?.appleStandHours ?? 0,
589 exerciseSeconds: latest?.appleExerciseTime ?? 0, 591 exerciseSeconds: latest?.appleExerciseTime ?? 0,
590 - moveGoal: latest?.activeEnergyBurnedGoal, 592 + moveGoal: _ceilOrNull(latest?.activeEnergyBurnedGoal),
591 standGoal: latest?.standHoursGoal, 593 standGoal: latest?.standHoursGoal,
592 exerciseGoalSeconds: latest?.exerciseTimeGoal, 594 exerciseGoalSeconds: latest?.exerciseTimeGoal,
593 ); 595 );
@@ -693,7 +695,7 @@ class LocalHealthDataConvert { @@ -693,7 +695,7 @@ class LocalHealthDataConvert {
693 ) { 695 ) {
694 if (summary == null || !summary.hasGoal) return null; 696 if (summary == null || !summary.hasGoal) return null;
695 return ActivityTargetInfo( 697 return ActivityTargetInfo(
696 - move: summary.moveGoal, 698 + move: _ceilOrNull(summary.moveGoal),
697 step: 0, 699 step: 0,
698 stand: summary.standGoal, 700 stand: summary.standGoal,
699 exercise: summary.exerciseGoalSeconds, 701 exercise: summary.exerciseGoalSeconds,
@@ -1002,6 +1004,10 @@ class LocalHealthDataConvert { @@ -1002,6 +1004,10 @@ class LocalHealthDataConvert {
1002 } 1004 }
1003 1005
1004 static bool _isPositive(num? value) => value != null && value > 0; 1006 static bool _isPositive(num? value) => value != null && value > 0;
  1007 +
  1008 + static int _ceilOrZero(num? value) => (value ?? 0).ceil();
  1009 +
  1010 + static int? _ceilOrNull(num? value) => value?.ceil();
1005 } 1011 }
1006 1012
1007 class _ActivityDaySummary { 1013 class _ActivityDaySummary {
@@ -342,7 +342,7 @@ class LocalHealthDataSource implements HealthDataSource { @@ -342,7 +342,7 @@ class LocalHealthDataSource implements HealthDataSource {
342 for (final item in reversed) { 342 for (final item in reversed) {
343 if (activeEnergyBurnedGoal == null && 343 if (activeEnergyBurnedGoal == null &&
344 _isPositive(item.activeEnergyBurnedGoal)) { 344 _isPositive(item.activeEnergyBurnedGoal)) {
345 - activeEnergyBurnedGoal = item.activeEnergyBurnedGoal; 345 + activeEnergyBurnedGoal = item.activeEnergyBurnedGoal?.ceilToDouble();
346 resolvedEndTime = 346 resolvedEndTime =
347 resolvedEndTime < item.endTime ? item.endTime : resolvedEndTime; 347 resolvedEndTime < item.endTime ? item.endTime : resolvedEndTime;
348 } 348 }
@@ -457,9 +457,7 @@ void main() { @@ -457,9 +457,7 @@ void main() {
457 }); 457 });
458 458
459 group('LocalHealthDataConvert activity unit conversion', () { 459 group('LocalHealthDataConvert activity unit conversion', () {
460 - test(  
461 - 'passes through exercise seconds and stand hours from raw activity data',  
462 - () { 460 + test('uses ceiled kcal move values and raw exercise/stand units', () {
463 final day = DateTime(2026, 7, 16); 461 final day = DateTime(2026, 7, 16);
464 final endTime = LocalHealthDataConvert.unixSeconds( 462 final endTime = LocalHealthDataConvert.unixSeconds(
465 day.add(const Duration(hours: 12)), 463 day.add(const Duration(hours: 12)),
@@ -468,8 +466,8 @@ void main() { @@ -468,8 +466,8 @@ void main() {
468 HealthKitRawActivityDataPoint( 466 HealthKitRawActivityDataPoint(
469 endTime: endTime, 467 endTime: endTime,
470 activityMoveMode: 0, 468 activityMoveMode: 0,
471 - activeEnergyBurned: 300,  
472 - activeEnergyBurnedGoal: 500, 469 + activeEnergyBurned: 300.1,
  470 + activeEnergyBurnedGoal: 500.1,
473 appleMoveTime: 8000, 471 appleMoveTime: 8000,
474 appleMoveTimeGoal: 10000, 472 appleMoveTimeGoal: 10000,
475 appleExerciseTime: 1800, 473 appleExerciseTime: 1800,
@@ -499,13 +497,19 @@ void main() { @@ -499,13 +497,19 @@ void main() {
499 sleepIntervals: const [], 497 sleepIntervals: const [],
500 ); 498 );
501 499
  500 + expect(healthData.move, 301);
502 expect(healthData.exercise, 1800); 501 expect(healthData.exercise, 1800);
503 expect(healthData.stand, 6); 502 expect(healthData.stand, 6);
  503 + expect(target.move, 501);
504 expect(target.exercise, 3600); 504 expect(target.exercise, 3600);
505 expect(target.stand, 12); 505 expect(target.stand, 12);
  506 + expect(statistics.totalMove, 301);
  507 + expect(statistics.avgMove, 301);
  508 + expect(statistics.moveTrendList?.single.value, 301);
  509 + expect(statistics.overallList?.single.value?.move, 301);
506 expect(statistics.totalExercise, 1800); 510 expect(statistics.totalExercise, 1800);
507 expect(statistics.totalStand, 6); 511 expect(statistics.totalStand, 6);
508 - expect(statistics.activityTargetInfo?.move, 500); 512 + expect(statistics.activityTargetInfo?.move, 501);
509 expect(statistics.activityTargetInfo?.exercise, 3600); 513 expect(statistics.activityTargetInfo?.exercise, 3600);
510 expect(statistics.activityTargetInfo?.stand, 12); 514 expect(statistics.activityTargetInfo?.stand, 12);
511 }); 515 });
@@ -526,7 +530,7 @@ void main() { @@ -526,7 +530,7 @@ void main() {
526 endTime: LocalHealthDataConvert.unixSeconds( 530 endTime: LocalHealthDataConvert.unixSeconds(
527 secondDay.add(const Duration(hours: 12)), 531 secondDay.add(const Duration(hours: 12)),
528 ), 532 ),
529 - activeEnergyBurnedGoal: 600, 533 + activeEnergyBurnedGoal: 600.1,
530 exerciseTimeGoal: 0, 534 exerciseTimeGoal: 0,
531 standHoursGoal: null, 535 standHoursGoal: null,
532 ), 536 ),
@@ -540,7 +544,7 @@ void main() { @@ -540,7 +544,7 @@ void main() {
540 sleepIntervals: const [], 544 sleepIntervals: const [],
541 ); 545 );
542 546
543 - expect(statistics.activityTargetInfo?.move, 600); 547 + expect(statistics.activityTargetInfo?.move, 601);
544 expect(statistics.activityTargetInfo?.exercise, 3600); 548 expect(statistics.activityTargetInfo?.exercise, 3600);
545 expect(statistics.activityTargetInfo?.stand, 12); 549 expect(statistics.activityTargetInfo?.stand, 12);
546 }); 550 });