import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/api/api_client.dart'; import '../core/auth/auth_state.dart'; class LicenseInfo { final String type; // trial / monthly / annual / lifetime final bool isActive; final DateTime? expiresAt; final DateTime? activatedAt; const LicenseInfo({ required this.type, required this.isActive, this.expiresAt, this.activatedAt, }); factory LicenseInfo.fromJson(Map json) { return LicenseInfo( type: json['type'] as String? ?? 'trial', isActive: json['is_active'] as bool? ?? false, expiresAt: json['expires_at'] != null ? DateTime.tryParse(json['expires_at'] as String) : null, activatedAt: json['activated_at'] != null ? DateTime.tryParse(json['activated_at'] as String) : null, ); } String get typeLabel { switch (type) { case 'monthly': return '月度授权'; case 'annual': return '年度授权'; case 'lifetime': return '永久授权'; default: return '试用版'; } } /// 是否已过期 bool get isExpired => expiresAt != null && DateTime.now().isAfter(expiresAt!); /// 距到期剩余天数(null = 永久) int? get daysRemaining { if (expiresAt == null) return null; final diff = expiresAt!.difference(DateTime.now()).inDays; return diff < 0 ? 0 : diff; } } final licenseProvider = AsyncNotifierProvider(LicenseNotifier.new); class LicenseNotifier extends AsyncNotifier { @override Future build() async { ref.watch(authStateProvider.select((s) => s.user?.shopId)); return _fetch(); } Future _fetch() async { try { final client = ref.read(apiClientProvider); final resp = await client.get('/license/info'); final data = resp.data['data']; if (data == null) return null; return LicenseInfo.fromJson(data as Map); } catch (_) { return null; } } Future reload() async { state = const AsyncValue.loading(); state = AsyncValue.data(await _fetch()); } }