fix: 1.优化上报逻辑,防止一样的token重复上报
2.请求头添加deviceId,为后续设备管理业务预留数据
This commit is contained in:
parent
a77cb10caf
commit
50257a7ffe
@ -28,5 +28,10 @@ FutureOr<Request> requestInterceptor(Request request) async {
|
||||
xToken = LoginData.fromJson(jsonDecode(data)).accessToken;
|
||||
}
|
||||
request.headers['Authorization'] = "Bearer ${xToken ?? ''}";
|
||||
|
||||
final String? deviceID = await Storage.getString(appDeviceID);
|
||||
if (deviceID != null && deviceID.isNotEmpty) {
|
||||
request.headers['deviceID'] = deviceID;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
@ -1,12 +1,20 @@
|
||||
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../network/api_provider.dart';
|
||||
import '../../network/api_repository.dart';
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class AppBindings extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
initDeviceId();
|
||||
}
|
||||
|
||||
}
|
||||
Future<void> initDeviceId() async {
|
||||
final String? deviceID = await Storage.getString(appDeviceID);
|
||||
final bool isNullOrBlank = GetUtils.isNullOrBlank(deviceID) ?? true;
|
||||
if (isNullOrBlank) {
|
||||
final String uuidV4 = const Uuid().v4();
|
||||
print('initDeviceId UUID:v4: $uuidV4');
|
||||
await Storage.setString(appDeviceID, uuidV4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
23
lib/tools/debounce_throttle_tool.dart
Normal file
23
lib/tools/debounce_throttle_tool.dart
Normal file
@ -0,0 +1,23 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class DebounceThrottleTool<T> {
|
||||
DebounceThrottleTool(this._debounceTime, this._callback);
|
||||
|
||||
Timer? _timer;
|
||||
final Duration _debounceTime;
|
||||
final void Function(T param) _callback;
|
||||
|
||||
void trigger(T param) {
|
||||
_timer?.cancel();
|
||||
_timer = Timer(_debounceTime, () {
|
||||
_callback(param);
|
||||
_timer = null;
|
||||
});
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
_timer?.cancel();
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:ffi';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
@ -9,6 +10,7 @@ import 'package:star_lock/flavors.dart';
|
||||
import 'package:star_lock/mine/minePersonInfo/minePersonInfoEditAccount/minePersonInfoEditAccount/mineUnbindPhoneOrEmail_entity.dart';
|
||||
import 'package:star_lock/network/api_repository.dart';
|
||||
import 'package:star_lock/tools/baseGetXController.dart';
|
||||
import 'package:star_lock/tools/debounce_throttle_tool.dart';
|
||||
import 'package:star_lock/tools/push/message_management.dart';
|
||||
import 'package:star_lock/tools/push/notification_service.dart';
|
||||
import 'package:star_lock/tools/storage.dart';
|
||||
@ -28,31 +30,32 @@ class XSJPushProvider {
|
||||
9: 'jiguang'
|
||||
};
|
||||
final JPush jpush = JPush();
|
||||
Completer<Map<String, dynamic>>? _jpushRegistrationIdCompleter;
|
||||
Completer<Map<String, dynamic>>? _vendorTokenCompleter;
|
||||
DebounceThrottleTool? _debounceThrottleTool;
|
||||
|
||||
Future<void> resetJPushService() async {
|
||||
debugPrint("resetJPushService start");
|
||||
jpush.setup(
|
||||
appKey: '',
|
||||
channel: 'flutter_channel',
|
||||
production: F.isProductionEnv,
|
||||
debug: !F.isProductionEnv,
|
||||
);
|
||||
for (final MapEntry<int, String> entry in channelTypeMapping.entries) {
|
||||
await Storage.removeData('old_${entry.value}');
|
||||
}
|
||||
debugPrint("resetJPushService end");
|
||||
}
|
||||
|
||||
// appKey: 251fc8074820d122b6de58d2--鑫泓佳AppKey
|
||||
// appKey: 7ff37d174c1a568a89e98dad--sky
|
||||
Future<void> initJPushService() async {
|
||||
debugPrint("initJPushService start");
|
||||
_jpushRegistrationIdCompleter = Completer<Map<String, dynamic>>();
|
||||
_vendorTokenCompleter = Completer<Map<String, dynamic>>();
|
||||
final String? data = await Storage.getString(saveUserLoginData);
|
||||
if (data == null || data.isEmpty) {
|
||||
AppLog.log('No user data found.');
|
||||
return;
|
||||
}
|
||||
|
||||
_debounceThrottleTool = DebounceThrottleTool(
|
||||
const Duration(milliseconds: 1500),
|
||||
(dynamic param) {
|
||||
bindPushChannels();
|
||||
},
|
||||
);
|
||||
AppLog.log('jPushKey ${F.jPushKey}');
|
||||
// final String? bundleIdentifier =
|
||||
// await NativeInteractionTool().getBundleIdentifier();
|
||||
@ -86,35 +89,20 @@ class XSJPushProvider {
|
||||
case CMD_GET_REGISTRATION_ID:
|
||||
final bool isNullOrBlank =
|
||||
GetUtils.isNullOrBlank(data['message']) ?? true;
|
||||
if (!(_jpushRegistrationIdCompleter?.isCompleted ?? true) &&
|
||||
!isNullOrBlank) {
|
||||
await Storage.setString(pushDeviceID, data['message']);
|
||||
AppLog.log('flutter get registration id : ${data['message']}');
|
||||
_jpushRegistrationIdCompleter?.complete(<String, dynamic>{
|
||||
'channel': 'jiguang',
|
||||
'channelToken': data['message']
|
||||
});
|
||||
final String? channel2TokenStr =
|
||||
await Storage.getString(vendorPushChannelInfo);
|
||||
if (Platform.isAndroid &&
|
||||
!(_vendorTokenCompleter?.isCompleted ?? true) &&
|
||||
channel2TokenStr != null) {
|
||||
_vendorTokenCompleter?.complete(jsonDecode(channel2TokenStr));
|
||||
}
|
||||
if (!isNullOrBlank) {
|
||||
AppLog.log(
|
||||
'flutter get jiguang registration id : ${data['message']}');
|
||||
await Storage.setString('jiguang', data['message']);
|
||||
_debounceThrottleTool?.trigger(data['message']);
|
||||
}
|
||||
break;
|
||||
case CMD_GET_TOKEN:
|
||||
final bool isNullOrBlank =
|
||||
GetUtils.isNullOrBlank(data['token']) ?? true;
|
||||
if (!(_vendorTokenCompleter?.isCompleted ?? true) &&
|
||||
!isNullOrBlank) {
|
||||
final Map<String, dynamic> channel2Token = <String, dynamic>{
|
||||
'channel': channelTypeMapping[data['platform']],
|
||||
'channelToken': data['token']
|
||||
};
|
||||
if (!isNullOrBlank) {
|
||||
await Storage.setString(
|
||||
vendorPushChannelInfo, jsonEncode(channel2Token));
|
||||
_vendorTokenCompleter?.complete(channel2Token);
|
||||
channelTypeMapping[data['platform']] ?? '', data['token']);
|
||||
_debounceThrottleTool?.trigger(data['token']);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -147,31 +135,54 @@ class XSJPushProvider {
|
||||
return Future.value();
|
||||
},
|
||||
);
|
||||
bindPushChannels();
|
||||
}
|
||||
|
||||
// jpush 统一推送通道设备绑定
|
||||
Future<void> bindPushChannels() async {
|
||||
try {
|
||||
if (_jpushRegistrationIdCompleter == null ||
|
||||
_vendorTokenCompleter == null) {
|
||||
debugPrint("BindPushChannels start");
|
||||
bool needReBindPushToken = false;
|
||||
final Map<String, String> newVendorsPushToken = <String, String>{};
|
||||
final Map<String, String> oldVendorsPushToken = <String, String>{};
|
||||
for (final String channel in channelTypeMapping.values) {
|
||||
debugPrint("BindPushChannels channel $channel");
|
||||
final String? newVendorToken = await Storage.getString(channel);
|
||||
debugPrint("BindPushChannels newVendorToken $newVendorToken");
|
||||
newVendorsPushToken[channel] = newVendorToken ?? '';
|
||||
final String? oldVendorToken = await Storage.getString('old_$channel');
|
||||
debugPrint("BindPushChannels oldVendorToken $oldVendorToken");
|
||||
oldVendorsPushToken['old_$channel'] = oldVendorToken ?? '';
|
||||
if (newVendorToken != oldVendorToken) {
|
||||
needReBindPushToken = true;
|
||||
}
|
||||
}
|
||||
if (!needReBindPushToken) {
|
||||
AppLog.log('vendorToken 未变动,无需重新绑定');
|
||||
return;
|
||||
}
|
||||
debugPrint("await PushChannels start");
|
||||
final List<Map<String, dynamic>> channels = await Future.wait([
|
||||
_jpushRegistrationIdCompleter!.future,
|
||||
_vendorTokenCompleter!.future
|
||||
]);
|
||||
final String? registrationId = await Storage.getString(pushDeviceID);
|
||||
debugPrint("await PushChannels end");
|
||||
|
||||
final List<Map<String, dynamic>> channels = newVendorsPushToken.entries
|
||||
.where((entry) => !(GetUtils.isNullOrBlank(entry.value) ?? true))
|
||||
.map((entry) => <String, dynamic>{
|
||||
'channel': entry.key,
|
||||
'channelToken': entry.value
|
||||
})
|
||||
.toList();
|
||||
debugPrint("BindPushChannels ${channels}");
|
||||
final String? deviceID = await Storage.getString(appDeviceID);
|
||||
final MineUnbindPhoneOrEmailEntity entity =
|
||||
await ApiRepository.to.pushBindChannels(registrationId!, channels);
|
||||
await ApiRepository.to.pushBindChannels(deviceID!, channels);
|
||||
if (entity.errorCode!.codeIsSuccessful) {
|
||||
AppLog.log('绑定成功');
|
||||
AppLog.log('vendorToken绑定成功,准备更新本地缓存');
|
||||
await Future.wait(channels.map((Map<String, dynamic> entry) =>
|
||||
Storage.setString(
|
||||
'old_${entry['channel']}', entry['channelToken'])));
|
||||
AppLog.log('vendorToken绑定成功,更新本地缓存完成');
|
||||
} else {
|
||||
AppLog.log('绑定失败');
|
||||
}
|
||||
} catch (e) {
|
||||
AppLog.log('vendorToken绑定失败,下次重启应用重新绑定');
|
||||
AppLog.log('Error binding device ID: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,8 @@ const String isAgreeCamera = 'isAgreeCamera'; //是否同意获取相机/相册
|
||||
|
||||
const String isShowUpdateVersion = 'isShowUpdateVersion'; //是否更新弹窗
|
||||
const String saveLockAlias = 'saveLockAlias'; //锁别名
|
||||
const String pushDeviceID = 'pushDeviceID'; //推送设备ID
|
||||
const String appDeviceID = 'appDeviceID'; //推送设备ID
|
||||
const String pushDeviceID = 'pushDeviceID'; //Jpush推送设备ID
|
||||
const String vendorPushChannelInfo = 'pushChannelInfo'; //推送设备ID
|
||||
const String saveIsVip = 'saveIsVip'; //是否是VIP
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user