trend_period_controller.dart 2.87 KB
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';

import 'trend_types.dart';

/// TrendPeriodController — 抽象基类
///
/// 封装 HRV / 活动 / 睡眠 三个 Controller 共用的:
///   - 第2层:周 / 月 / 年 period 切换
///   - 第3层:日期范围偏移(每个 period 各自记忆 offset)
///   - isLoading 状态
///   - dateRangeLabel 计算
///
/// 子类只需实现 [loadData()],专注自己的数据逻辑。
abstract class TrendPeriodController extends GetxController {
  // ── 第2层:时间维度 ──────────────────────────────────
  final currentPeriod = TrendPeriod.week.obs;

  // ── 第3层:日期偏移(每个 period 独立记忆)──────────
  // key = TrendPeriod,value = offset(0=当前,-1=上一个…)
  final _offsetByPeriod = <TrendPeriod, int>{};
  final dateOffset = 0.obs;

  // ── 加载状态 ─────────────────────────────────────────
  final isLoading = false.obs;

  // ────────────────────────────────────────────────────
  // 公开 API
  // ────────────────────────────────────────────────────

  void changePeriod(TrendPeriod period) {
    if (currentPeriod.value == period) return;
    // 保存当前 period 的 offset,再切换
    _offsetByPeriod[currentPeriod.value] = dateOffset.value;
    currentPeriod.value = period;
    // 恢复新 period 上次记忆 of offset(默认 0)
    dateOffset.value = _offsetByPeriod[period] ?? 0;
    loadData();
  }

  void goToPrevious() {
    final key = currentPeriod.value;
    _offsetByPeriod[key] = (_offsetByPeriod[key] ?? 0) - 1;
    dateOffset.value = _offsetByPeriod[key]!;
    loadData();
  }

  void goToNext() {
    if (!canGoNext) return;
    final key = currentPeriod.value;
    _offsetByPeriod[key] = (_offsetByPeriod[key] ?? 0) + 1;
    dateOffset.value = _offsetByPeriod[key]!;
    loadData();
  }

  bool get canGoNext => dateOffset.value < 0;

  /// 当前 period + offset 对应的日期显示文字
  String get dateRangeLabel =>
      buildDateRangeLabel(currentPeriod.value, dateOffset.value);

  // ────────────────────────────────────────────────────
  // 子类必须实现:各自的数据加载逻辑
  // ────────────────────────────────────────────────────

  @protected
  void loadData();

  @override
  void onInit() {
    super.onInit();
    loadData();
  }
}