Files
wangjia ba53a0d478
ci-pangolin / Lint — shellcheck (push) Has been cancelled
ci-pangolin / OpenAPI Sync Check (push) Has been cancelled
ci-pangolin / Redline Scan — 脱敏 (UI 文案) (push) Has been cancelled
ci-pangolin / Flutter — analyze + test (push) Has been cancelled
feat(client): P1 真实数据接入地基(#6 6A)
- api_config.dart:API 基址单源(消除各处重复 _kApiUrl)
- api_client.dart:统一鉴权 HTTP 客户端,401→AuthNotifier.refresh→重试一次,
  错误统一 AuthApiException;+ 单测覆盖 401 刷新重试
- 模型 me/device/plan/usage_point(对齐后端 snake_case 契约)
- account_api.dart:/v1/me、/v1/plans、/v1/me/devices(列表+删)、/v1/usage、
  /v1/redeem、/v1/ads/unlock 封装
- auth_provider:注入 AuthApi + refresh();account_providers 装配 ApiClient/AccountApi
- 顺带修复 onboarding 提交遗留的测试 stub(_NullTokenStore 缺 isOnboarded/markOnboarded)

flutter analyze 0 error;114 tests passed。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 23:32:57 +08:00

26 lines
738 B
Dart

// usage_point.dart — 单日用量(GET /v1/usage?days=N 的一条)。
class UsagePoint {
const UsagePoint({
required this.date,
this.bytesUp = 0,
this.bytesDown = 0,
this.minutesUsed = 0,
});
/// YYYY-MM-DD(UTC)。
final String date;
final int bytesUp;
final int bytesDown;
final int minutesUsed;
int get bytesTotal => bytesUp + bytesDown;
double get gbTotal => bytesTotal / (1024 * 1024 * 1024);
factory UsagePoint.fromJson(Map<String, dynamic> m) => UsagePoint(
date: m['date'] as String? ?? '',
bytesUp: (m['bytes_up'] as num?)?.toInt() ?? 0,
bytesDown: (m['bytes_down'] as num?)?.toInt() ?? 0,
minutesUsed: (m['minutes_used'] as num?)?.toInt() ?? 0,
);
}