diff --git a/lib/src/model/resp.dart b/lib/src/model/resp.dart new file mode 100644 index 0000000..b315a98 --- /dev/null +++ b/lib/src/model/resp.dart @@ -0,0 +1,88 @@ +import 'dart:convert'; + +import 'package:json_annotation/json_annotation.dart'; + +part 'resp.g.dart'; + +abstract class BaseResp { + const BaseResp({ + required this.ret, + this.msg, + }); + + /// 网络请求成功发送至服务器,并且服务器返回数据格式正确 + /// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致 + static const int RET_SUCCESS = 0; + + /// 网络异常,或服务器返回的数据格式不正确导致无法解析 + static const int RET_FAILED = 1; + + static const int RET_COMMON = -1; + + static const int RET_USERCANCEL = -2; + + @JsonKey( + defaultValue: RET_SUCCESS, + ) + final int ret; + final String? msg; + + bool get isSuccessful => ret == RET_SUCCESS; + + bool get isCancelled => ret == RET_USERCANCEL; + + Map toJson(); + + @override + String toString() => const JsonEncoder.withIndent(' ').convert(toJson()); +} + +@JsonSerializable( + explicitToJson: true, + fieldRename: FieldRename.snake, +) +class LoginResp extends BaseResp { + const LoginResp({ + required int ret, + String? msg, + this.openid, + this.accessToken, + this.expiresIn, + this.createAt, + }) : super(ret: ret, msg: msg); + + factory LoginResp.fromJson(Map json) => + _$LoginRespFromJson(json); + + final String? openid; + final String? accessToken; + final int? expiresIn; + final int? createAt; + + bool? get isExpired => isSuccessful + ? DateTime.now().millisecondsSinceEpoch - createAt! >= expiresIn! * 1000 + : null; + + @override + Map toJson() => _$LoginRespToJson(this); +} + +@JsonSerializable( + explicitToJson: true, + fieldRename: FieldRename.snake, +) +class ShareMsgResp extends BaseResp { + const ShareMsgResp({ + required int ret, + String? msg, + }) : super( + ret: ret, + msg: msg, + ); + + factory ShareMsgResp.fromJson(Map json) => + _$ShareMsgRespFromJson(json); + + @override + Map toJson() => _$ShareMsgRespToJson(this); +} diff --git a/lib/src/model/tencent_login_resp.g.dart b/lib/src/model/resp.g.dart similarity index 60% rename from lib/src/model/tencent_login_resp.g.dart rename to lib/src/model/resp.g.dart index c2ec9a9..9958336 100644 --- a/lib/src/model/tencent_login_resp.g.dart +++ b/lib/src/model/resp.g.dart @@ -1,13 +1,13 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'tencent_login_resp.dart'; +part of 'resp.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -TencentLoginResp _$TencentLoginRespFromJson(Map json) { - return TencentLoginResp( +LoginResp _$LoginRespFromJson(Map json) { + return LoginResp( ret: json['ret'] as int? ?? 0, msg: json['msg'] as String?, openid: json['openid'] as String?, @@ -17,8 +17,7 @@ TencentLoginResp _$TencentLoginRespFromJson(Map json) { ); } -Map _$TencentLoginRespToJson(TencentLoginResp instance) => - { +Map _$LoginRespToJson(LoginResp instance) => { 'ret': instance.ret, 'msg': instance.msg, 'openid': instance.openid, @@ -26,3 +25,16 @@ Map _$TencentLoginRespToJson(TencentLoginResp instance) => 'expires_in': instance.expiresIn, 'create_at': instance.createAt, }; + +ShareMsgResp _$ShareMsgRespFromJson(Map json) { + return ShareMsgResp( + ret: json['ret'] as int? ?? 0, + msg: json['msg'] as String?, + ); +} + +Map _$ShareMsgRespToJson(ShareMsgResp instance) => + { + 'ret': instance.ret, + 'msg': instance.msg, + }; diff --git a/lib/src/model/tencent_login_resp.dart b/lib/src/model/tencent_login_resp.dart deleted file mode 100644 index 61631c5..0000000 --- a/lib/src/model/tencent_login_resp.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:tencent_kit/src/model/tencent_sdk_resp.dart'; - -part 'tencent_login_resp.g.dart'; - -@JsonSerializable( - explicitToJson: true, - fieldRename: FieldRename.snake, -) -class TencentLoginResp extends TencentSdkResp { - const TencentLoginResp({ - required int ret, - String? msg, - this.openid, - this.accessToken, - this.expiresIn, - this.createAt, - }) : super(ret: ret, msg: msg); - - factory TencentLoginResp.fromJson(Map json) => - _$TencentLoginRespFromJson(json); - - final String? openid; - final String? accessToken; - final int? expiresIn; - final int? createAt; - - bool? get isExpired => isSuccessful - ? DateTime.now().millisecondsSinceEpoch - createAt! >= expiresIn! * 1000 - : null; - - @override - Map toJson() => _$TencentLoginRespToJson(this); -} diff --git a/lib/src/model/tencent_sdk_resp.dart b/lib/src/model/tencent_sdk_resp.dart deleted file mode 100644 index 8c33f91..0000000 --- a/lib/src/model/tencent_sdk_resp.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'tencent_sdk_resp.g.dart'; - -@JsonSerializable( - explicitToJson: true, - fieldRename: FieldRename.snake, -) -class TencentSdkResp { - const TencentSdkResp({ - required this.ret, - this.msg, - }); - - factory TencentSdkResp.fromJson(Map json) => - _$TencentSdkRespFromJson(json); - - /// 网络请求成功发送至服务器,并且服务器返回数据格式正确 - /// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致 - static const int RET_SUCCESS = 0; - - /// 网络异常,或服务器返回的数据格式不正确导致无法解析 - static const int RET_FAILED = 1; - - static const int RET_COMMON = -1; - - static const int RET_USERCANCEL = -2; - - @JsonKey( - defaultValue: RET_SUCCESS, - ) - final int ret; - final String? msg; - - bool get isSuccessful => ret == RET_SUCCESS; - - bool get isCancelled => ret == RET_USERCANCEL; - - Map toJson() => _$TencentSdkRespToJson(this); -} diff --git a/lib/src/model/tencent_sdk_resp.g.dart b/lib/src/model/tencent_sdk_resp.g.dart deleted file mode 100644 index 8ed8f1b..0000000 --- a/lib/src/model/tencent_sdk_resp.g.dart +++ /dev/null @@ -1,20 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'tencent_sdk_resp.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -TencentSdkResp _$TencentSdkRespFromJson(Map json) { - return TencentSdkResp( - ret: json['ret'] as int? ?? 0, - msg: json['msg'] as String?, - ); -} - -Map _$TencentSdkRespToJson(TencentSdkResp instance) => - { - 'ret': instance.ret, - 'msg': instance.msg, - }; diff --git a/lib/src/tencent.dart b/lib/src/tencent.dart index 0d63615..bb38c55 100644 --- a/lib/src/tencent.dart +++ b/lib/src/tencent.dart @@ -1,8 +1,7 @@ import 'dart:async'; import 'package:flutter/services.dart'; -import 'package:tencent_kit/src/model/tencent_login_resp.dart'; -import 'package:tencent_kit/src/model/tencent_sdk_resp.dart'; +import 'package:tencent_kit/src/model/resp.dart'; import 'package:tencent_kit/src/tencent_constant.dart'; /// @@ -48,20 +47,17 @@ class Tencent { const MethodChannel('v7lin.github.io/tencent_kit') ..setMethodCallHandler(_handleMethod); - final StreamController _loginRespStreamController = - StreamController.broadcast(); - - final StreamController _shareRespStreamController = - StreamController.broadcast(); + final StreamController _respStreamController = + StreamController.broadcast(); Future _handleMethod(MethodCall call) async { switch (call.method) { case _METHOD_ONLOGINRESP: - _loginRespStreamController.add(TencentLoginResp.fromJson( + _respStreamController.add(LoginResp.fromJson( (call.arguments as Map).cast())); break; case _METHOD_ONSHARERESP: - _shareRespStreamController.add(TencentSdkResp.fromJson( + _respStreamController.add(ShareMsgResp.fromJson( (call.arguments as Map).cast())); break; } @@ -82,14 +78,9 @@ class Tencent { ); } - /// 登录 - Stream loginResp() { - return _loginRespStreamController.stream; - } - - /// 分享 - Stream shareResp() { - return _shareRespStreamController.stream; + /// + Stream respStream() { + return _respStreamController.stream; } /// 检查QQ是否已安装 diff --git a/lib/tencent_kit.dart b/lib/tencent_kit.dart index c920068..3476280 100644 --- a/lib/tencent_kit.dart +++ b/lib/tencent_kit.dart @@ -1,6 +1,5 @@ library tencent_kit; -export 'src/model/tencent_login_resp.dart'; -export 'src/model/tencent_sdk_resp.dart'; +export 'src/model/resp.dart'; export 'src/tencent.dart'; export 'src/tencent_constant.dart'; diff --git a/test/tencent_kit_test.dart b/test/tencent_kit_test.dart index 3f85764..b8698ba 100644 --- a/test/tencent_kit_test.dart +++ b/test/tencent_kit_test.dart @@ -64,25 +64,31 @@ void main() { }); test('login', () async { - final StreamSubscription sub = - Tencent.instance.loginResp().listen((TencentLoginResp resp) { - expect(resp.ret, TencentSdkResp.RET_USERCANCEL); + final StreamSubscription subs = + Tencent.instance.respStream().listen((BaseResp resp) { + expect(resp.runtimeType, LoginResp); + expect(resp.ret, BaseResp.RET_USERCANCEL); }); await Tencent.instance.login( - scope: [TencentScope.GET_SIMPLE_USERINFO], + scope: [ + TencentScope.GET_SIMPLE_USERINFO, + ], ); - await sub.cancel(); + await Future.delayed(const Duration(seconds: 1)); + await subs.cancel(); }); test('share', () async { - final StreamSubscription sub = - Tencent.instance.shareResp().listen((TencentSdkResp resp) { - expect(resp.ret, TencentSdkResp.RET_SUCCESS); + final StreamSubscription subs = + Tencent.instance.respStream().listen((BaseResp resp) { + expect(resp.runtimeType, ShareMsgResp); + expect(resp.ret, BaseResp.RET_SUCCESS); }); await Tencent.instance.shareMood( scene: TencentScene.SCENE_QZONE, summary: 'share text', ); - await sub.cancel(); + await Future.delayed(const Duration(seconds: 1)); + await subs.cancel(); }); }