guru_sdk/guru_app/packages/guru_utils/lib/manifest/manifest.dart

215 lines
5.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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";
static const String igb = "igb";
}
class DetailsAttr {
static const permanent = 1;
static const consumable = 2;
}
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";
static const String contentId = "__contentId";
static const String barterId = "__barterId";
static const String transactionTs = "__transaction_ts";
}
class DetailsReservedField {
static const String type = "__type";
static const String sku = "__sku";
static const String amount = "__amount";
static const String name = "__name";
static const String icon = "__icon";
static const String attr = "__attr";
}
class ManifestStringConvert implements JsonConverter<Manifest, String> {
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: <String, dynamic>{})
final Map<String, dynamic> bundle;
const Details._({this.bundle = const <String, dynamic>{}});
Details.define(String type, int amount,
{String? sku, Map<String, dynamic> params = const <String, dynamic>{}})
: bundle = <String, dynamic>{
DetailsReservedField.sku: sku ?? type,
DetailsReservedField.type: type,
DetailsReservedField.amount: amount
};
factory Details.fromJson(Map<String, dynamic> json) => _$DetailsFromJson(json);
int get amount => bundle[DetailsReservedField.amount] ?? 0;
String get type => bundle[DetailsReservedField.type] ?? "unknown";
String get sku => bundle[DetailsReservedField.sku] ?? type;
String? get name => bundle[DetailsReservedField.name] ?? "unknown";
int get attr => bundle[DetailsReservedField.attr] ?? DetailsAttr.consumable;
Map<String, dynamic> 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<void> 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: <String, dynamic>{})
final Map<String, dynamic> extras;
@JsonKey(name: "details", defaultValue: <Details>[])
final List<Details> details;
String get scene => extras[ExtraReservedField.scene] ?? "";
String? get basePlanId => extras[ExtraReservedField.basePlanId];
String? get offerId => extras[ExtraReservedField.offerId];
/// 在 TransactionMethod为IAP时specific 对应的是 IAP 的 SKU
/// 如一些特定含有 ID的物品如用 IGC购买了某个道具这里面的 contentId 就是道具的 ID
String get contentId => extras[ExtraReservedField.contentId] ?? "";
// 如果你Barter进行购买这个字段会有值
String get barterId => extras[ExtraReservedField.barterId] ?? "";
int? get transactionTs => extras[ExtraReservedField.transactionTs];
Manifest.barter(this.category, String contentId, String barterId,
{Map<String, dynamic> extras = const <String, dynamic>{}, this.details = const <Details>[]})
: assert(contentId.isNotEmpty),
assert(barterId.isNotEmpty),
extras = {
...extras,
...{ExtraReservedField.contentId: contentId, ExtraReservedField.barterId: barterId}
};
Manifest.action(this.category, String scene,
{Map<String, dynamic> extras = const <String, dynamic>{}, this.details = const <Details>[]})
: assert(scene.isNotEmpty),
extras = {
...extras,
...{ExtraReservedField.scene: scene}
};
const Manifest(this.category,
{this.extras = const <String, dynamic>{}, this.details = const <Details>[]});
Manifest offer(String offerId, String basePlanId) {
return Manifest(category,
extras: {
...extras,
...{ExtraReservedField.offerId: offerId, ExtraReservedField.basePlanId: basePlanId}
},
details: details);
}
factory Manifest.fromJson(Map<String, dynamic> json) => _$ManifestFromJson(json);
static const Manifest empty = Manifest("empty");
Map<String, dynamic> 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);
}