health_v2_models.dart 8.25 KB
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:flutter/src/widgets/framework.dart';

int? _parseInt(dynamic value) {
  if (value == null) return null;
  if (value is int) return value;
  if (value is double) return value.toInt();
  if (value is String) return int.tryParse(value);
  return null;
}

double? _parseDouble(dynamic value) {
  if (value == null) return null;
  if (value is num) return value.toDouble();
  if (value is String) {
    if (value == 'NaN') return double.nan;
    if (value == 'Infinity') return double.infinity;
    if (value == '-Infinity') return double.negativeInfinity;
    return double.tryParse(value);
  }
  return null;
}

/// v2/lastest_hrv/ response
class V2LatestHrvData {
  const V2LatestHrvData(
      {this.latestHrv, this.latestDataTime, this.state, this.tip});

  final double? latestHrv;
  final int? latestDataTime;
  final int? state;
  final String? tip;

  String stateString() {
    switch (state) {
      case 1:
        return '压力过载';
      case 2:
        return '注意压力';
      case 3:
        return '状态正常';
      case 4:
        return '状态优秀';
    }
    return '等待数据';
  }

  stateColor(BuildContext context) {
    switch (state) {
      case 1:
        return context.colors.chartPink;
      case 2:
        return context.colors.chartOrange;
      case 3:
        return context.colors.chartGreen;
      case 4:
        return context.colors.chartBlue;
    }
    return context.colors.chartGreen;
  }

  factory V2LatestHrvData.fromJson(Map<String, dynamic> json) {
    return V2LatestHrvData(
      latestHrv: _parseDouble(json['latest_hrv']),
      latestDataTime: _parseInt(json['latest_data_time']),
      state: _parseInt(json['state']),
      tip: json['tip_text'],
    );
  }
}

/// v2/health_data/ response
class V2HealthData {
  const V2HealthData({
    this.hrvAvg,
    this.lastRestingHrValue,
    this.hrAvg,
    this.move,
    this.exercise,
    this.stand,
    this.steps,
    this.sleepDuration,
    this.sleepScore,
    this.sleepState,
  });

  final int? hrvAvg;
  final int? lastRestingHrValue;
  final int? hrAvg;
  final int? move;
  final int? exercise;
  final int? stand;
  final int? steps;
  final int? sleepDuration;
  final double? sleepScore;
  final int? sleepState;

  factory V2HealthData.fromJson(Map<String, dynamic> json) {
    return V2HealthData(
      hrvAvg: _parseInt(json['hrv_avg']),
      lastRestingHrValue: json['last_resting_hr_value'] == 0
          ? null
          : _parseInt(json['last_resting_hr_value']),
      hrAvg: _parseInt(json['hr_avg']),
      move: _parseInt(json['move']),
      exercise: _parseInt(json['exercise']),
      stand: _parseInt(json['stand']),
      steps: _parseInt(json['steps']),
      sleepDuration: _parseInt(json['sleep_duration']),
      sleepScore: _parseDouble(json['sleep_score']),
      sleepState: _parseInt(json['sleep_state']),
    );
  }

  Map<String, dynamic> toJson() {
    final val = <String, dynamic>{};
    if (hrvAvg != null) val['hrv_avg'] = hrvAvg;
    if (lastRestingHrValue != null) {
      val['last_resting_hr_value'] = lastRestingHrValue;
    }
    if (hrAvg != null) val['hr_avg'] = hrAvg;
    if (move != null) val['move'] = move;
    if (exercise != null) val['exercise'] = exercise;
    if (stand != null) val['stand'] = stand;
    if (steps != null) val['steps'] = steps;
    if (sleepDuration != null) val['sleep_duration'] = sleepDuration;
    if (sleepScore != null) val['sleep_score'] = sleepScore;
    if (sleepState != null) val['sleep_state'] = sleepState;
    return val;
  }

  /// 根据睡眠时长(秒)计算得分。
  int sleepDurationScore() {
    final duration = sleepDuration;
    if (duration == null || duration <= 0) return 0;
    final hours = duration / 3600.0;
    if (hours >= 7 && hours <= 9) return 100;
    if (hours > 9 && hours <= 10) return 80;
    if (hours >= 6 && hours < 7) return 80;
    if (hours >= 5 && hours < 6) return 60;
    if (hours > 10) return 50;
    return 30; // < 5h
  }

  sleepStateColor(BuildContext context) {
    switch (sleepState) {
      case 1:
        return context.colors.chartBlue;
      case 2:
        return context.colors.chartGreen;
      case 3:
        return context.colors.chartPink;
    }
    return context.colors.chartGreen;
  }

  sleepStateStr() {
    switch (sleepState) {
      case 1:
        return '睡得很棒';
      case 2:
        return '睡得不错';
      case 3:
        return '睡得差';
    }
    return '--';
  }
}

/// v2/stress_score/ response
class V2StressScore {
  const V2StressScore({
    this.state,
    this.hrvScore,
    this.hrScore,
    this.latestHr,
    this.comprehensiveScore,
  });

  final int? state;
  final int? hrvScore;
  final int? hrScore;
  final int? latestHr;
  final int? comprehensiveScore;

  factory V2StressScore.fromJson(Map<String, dynamic> json) {
    return V2StressScore(
      state: _parseInt(json['state']),
      hrvScore: _parseInt(json['hrv_score']),
      hrScore: _parseInt(json['hr_score']),
      latestHr: _parseInt(json['latest_hr']),
      comprehensiveScore: _parseInt(json['comprehensive_score']),
    );
  }

  Map<String, dynamic> toJson() {
    final val = <String, dynamic>{};
    if (state != null) val['state'] = state;
    if (hrvScore != null) val['hrv_score'] = hrvScore;
    if (hrScore != null) val['hr_score'] = hrScore;
    if (latestHr != null) val['latest_hr'] = latestHr;
    if (comprehensiveScore != null) {
      val['comprehensive_score'] = comprehensiveScore;
    }
    return val;
  }

  String stateString() {
    switch (state) {
      case 1:
        return '压力过载';
      case 2:
        return '注意压力';
      case 3:
        return '状态正常';
      case 4:
        return '状态优秀';
    }
    return '等待数据';
  }
}

/// Single item in v2/hrv_trend/ list
class V2HrvTrendItem {
  const V2HrvTrendItem({this.time, this.rawHrv, this.trendHrv, this.state});

  final int? time;
  final double? rawHrv;
  final int? trendHrv;
  final int? state;

  factory V2HrvTrendItem.fromJson(Map<String, dynamic> json) {
    return V2HrvTrendItem(
      time: _parseInt(json['time']),
      rawHrv: _parseDouble(json['raw_hrv']),
      trendHrv: _parseInt(json['trend_hrv']),
      state: _parseInt(json['state']),
    );
  }

  Map<String, dynamic> toJson() {
    final val = <String, dynamic>{};
    if (time != null) val['time'] = time;
    if (rawHrv != null) val['raw_hrv'] = rawHrv;
    if (trendHrv != null) val['trend_hrv'] = trendHrv;
    if (state != null) val['state'] = state;
    return val;
  }
}

/// v2/hrv_trend/ response
class V2HrvTrendData {
  const V2HrvTrendData({this.list});

  final List<V2HrvTrendItem>? list;

  factory V2HrvTrendData.fromJson(Map<String, dynamic> json) {
    return V2HrvTrendData(
      list: (json['list'] as List<dynamic>?)
          ?.map((e) => V2HrvTrendItem.fromJson(e as Map<String, dynamic>))
          .toList(),
    );
  }

  Map<String, dynamic> toJson() {
    final val = <String, dynamic>{};
    if (list != null) {
      val['list'] = list!.map((e) => e.toJson()).toList();
    }
    return val;
  }
}

/// Single item in v2/realtime_stress/ list
class V2RealtimeStressItem {
  const V2RealtimeStressItem({this.time, this.value, this.state});

  final int? time;
  final int? value;
  final int? state;

  factory V2RealtimeStressItem.fromJson(Map<String, dynamic> json) {
    return V2RealtimeStressItem(
      time: _parseInt(json['time']),
      value: _parseInt(json['value']),
      state: _parseInt(json['state']),
    );
  }

  Map<String, dynamic> toJson() {
    final val = <String, dynamic>{};
    if (time != null) val['time'] = time;
    if (value != null) val['value'] = value;
    if (state != null) val['state'] = state;
    return val;
  }
}

/// v2/realtime_stress/ response
class V2RealtimeStressData {
  const V2RealtimeStressData({this.list});

  final List<V2RealtimeStressItem>? list;

  factory V2RealtimeStressData.fromJson(Map<String, dynamic> json) {
    return V2RealtimeStressData(
      list: (json['list'] as List<dynamic>?)
          ?.map((e) => V2RealtimeStressItem.fromJson(e as Map<String, dynamic>))
          .toList(),
    );
  }

  Map<String, dynamic> toJson() {
    final val = <String, dynamic>{};
    if (list != null) {
      val['list'] = list!.map((e) => e.toJson()).toList();
    }
    return val;
  }
}