import 'dart:convert'; import 'dart:io'; import 'package:json_annotation/json_annotation.dart'; /// Created by Haoyi on 2021/7/1 part "manifest.g.dart"; class DetailsReservedType { static const String igc = "igc"; } class ExtraReservedField { static const String scene = "__scene"; static const String offerId = "__offer_id"; static const String basePlanId = "__base_plan_id"; static const String sales = "__sales"; static const String rate = "__rate"; } class DetailsReservedField { static const String type = "__type"; static const String amount = "__amount"; static const String name = "__name"; static const String icon = "__icon"; } class ManifestStringConvert implements JsonConverter { const ManifestStringConvert(); @override Manifest fromJson(String json) { if (json.isEmpty) { return Manifest.empty; } final map = jsonDecode(json); return Manifest.fromJson(map); } @override String toJson(Manifest manifest) { return jsonEncode(manifest); } } const ManifestStringConvert manifestStringConvert = ManifestStringConvert(); @JsonSerializable(constructor: "_") class Details { @JsonKey(name: "bundle", defaultValue: {}) final Map bundle; const Details._({this.bundle = const {}}); Details.define(String type, int amount, {Map params = const {}}) : bundle = { DetailsReservedField.type: type, DetailsReservedField.amount: amount }; factory Details.fromJson(Map json) => _$DetailsFromJson(json); int get amount => bundle[DetailsReservedField.amount] ?? 0; String get type => bundle[DetailsReservedField.type] ?? "unknown"; Map toJson() => _$DetailsToJson(this); void merge(Details details) { bundle.addAll(details.bundle); } bool containsKey(String name) { return bundle.containsKey(name); } void setInt(String key, int value) { bundle[key] = value.toString(); } void setDouble(String key, double value) { bundle[key] = value.toString(); } void setString(String key, String value) { bundle[key] = value; } void setBool(String key, bool value) { bundle[key] = value; } int? getInt(String key) { final value = bundle[key]; if (value == null) { return null; } return int.parse(value); } double? getDouble(String key) { final value = bundle[key]; if (value == null) { return null; } return double.parse(value); } String? getString(String key) { return bundle[key]; } bool? getBool(String key) { final value = bundle[key]; if (value == null) { return null; } return value == true; } Future forEach(void Function(String key, String value) f) async { for (var entry in bundle.entries) { f.call(entry.key, entry.value); } } } @JsonSerializable(explicitToJson: true) class Manifest { @JsonKey(name: "category", defaultValue: "") final String category; @JsonKey(name: "extras", defaultValue: {}) final Map extras; @JsonKey(name: "details", defaultValue:
[]) final List
details; String get scene => extras[ExtraReservedField.scene] ?? ""; String? get basePlanId => extras[ExtraReservedField.basePlanId]; String? get offerId => extras[ExtraReservedField.offerId]; const Manifest(this.category, {this.extras = const {}, this.details = const
[]}); Manifest offer(String offerId, String basePlanId) { return Manifest(category, extras: { ...extras, ...{ExtraReservedField.offerId: offerId, ExtraReservedField.basePlanId: basePlanId} }, details: details); } factory Manifest.fromJson(Map json) => _$ManifestFromJson(json); static const Manifest empty = Manifest("empty"); Map toJson() => _$ManifestToJson(this); } extension DefaultManifestExtension on Manifest { int get igcAmount => details .map((details) => details.type == DetailsReservedType.igc ? details.amount : 0) .reduce((value, element) => element + value); }