diff --git a/client/lib/models/device_usage.dart b/client/lib/models/device_usage.dart new file mode 100644 index 0000000..90ec88f --- /dev/null +++ b/client/lib/models/device_usage.dart @@ -0,0 +1,33 @@ +// device_usage.dart — 单设备窗口用量(GET /v1/usage/devices?days=N 的一条)。 +// 统计页「下分设备」明细的数据载体,与账户聚合的 UsagePoint 对应。 +class DeviceUsage { + const DeviceUsage({ + required this.uuid, + required this.name, + required this.platform, + this.bytesUp = 0, + this.bytesDown = 0, + this.minutesUsed = 0, + }); + + final String uuid; + final String name; + + /// ios | android | windows | macos。 + final String platform; + final int bytesUp; + final int bytesDown; + final int minutesUsed; + + int get bytesTotal => bytesUp + bytesDown; + double get gbTotal => bytesTotal / (1024 * 1024 * 1024); + + factory DeviceUsage.fromJson(Map m) => DeviceUsage( + uuid: m['uuid'] as String? ?? '', + name: m['name'] as String? ?? '', + platform: m['platform'] 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, + ); +} diff --git a/client/test/unit/device_usage_test.dart b/client/test/unit/device_usage_test.dart new file mode 100644 index 0000000..b96672e --- /dev/null +++ b/client/test/unit/device_usage_test.dart @@ -0,0 +1,33 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:pangolin_vpn/models/device_usage.dart'; + +void main() { + group('DeviceUsage.fromJson', () { + test('parses a full row and derives totals', () { + final d = DeviceUsage.fromJson(const { + 'uuid': 'dev-a', + 'name': 'My iPhone', + 'platform': 'ios', + 'bytes_up': 1500, + 'bytes_down': 2500, + 'minutes_used': 8, + }); + expect(d.uuid, 'dev-a'); + expect(d.name, 'My iPhone'); + expect(d.platform, 'ios'); + expect(d.bytesUp, 1500); + expect(d.bytesDown, 2500); + expect(d.minutesUsed, 8); + expect(d.bytesTotal, 4000); + expect(d.gbTotal, 4000 / (1024 * 1024 * 1024)); + }); + + test('tolerates missing/absent fields with zero defaults', () { + final d = DeviceUsage.fromJson(const {'uuid': 'dev-b', 'name': '', 'platform': ''}); + expect(d.bytesUp, 0); + expect(d.bytesDown, 0); + expect(d.minutesUsed, 0); + expect(d.bytesTotal, 0); + }); + }); +}