int _parseCode(dynamic value) { if (value is int) return value; if (value is String) return int.tryParse(value) ?? -1; if (value is num) return value.toInt(); return -1; } /// 统一 API 响应包装 /// 后端格式:{ "code": 0, "data": {...}, "message": "ok" } class ApiResponse { final int code; final T? data; final String message; const ApiResponse({ required this.code, this.data, required this.message, }); bool get isSuccess => code == 0; factory ApiResponse.fromJson( Map json, T Function(Object? json)? fromJsonT, ) { return ApiResponse( code: _parseCode(json['code']), data: json['data'] != null && fromJsonT != null ? fromJsonT(json['data']) : json['data'] as T?, message: json['message'] as String? ?? json['msg'] as String? ?? '', ); } } /// API 异常 class ApiException implements Exception { final int code; final String message; const ApiException({required this.code, required this.message}); @override String toString() => 'ApiException($code): $message'; }