85 lines
2.9 KiB
Dart
85 lines
2.9 KiB
Dart
import 'dart:convert';
|
||
import 'dart:math';
|
||
|
||
import 'package:android_id/android_id.dart';
|
||
import 'package:client_proxy_framework/client_proxy_framework.dart';
|
||
import 'package:crypto/crypto.dart' show md5;
|
||
import 'package:device_info_plus/device_info_plus.dart';
|
||
import 'package:flutter/foundation.dart';
|
||
import 'package:shared_preferences/shared_preferences.dart';
|
||
|
||
import '../user/user_state.dart';
|
||
|
||
const _prefsKeyFallbackDeviceId = 'persisted_device_id';
|
||
|
||
Future<String> _persistedFallbackDeviceId() async {
|
||
final prefs = await SharedPreferences.getInstance();
|
||
var id = prefs.getString(_prefsKeyFallbackDeviceId);
|
||
if (id != null && id.isNotEmpty) return id;
|
||
final random = Random.secure();
|
||
final bytes = List<int>.generate(16, (_) => random.nextInt(256));
|
||
id = base64UrlEncode(bytes).replaceAll('=', '');
|
||
await prefs.setString(_prefsKeyFallbackDeviceId, id);
|
||
return id;
|
||
}
|
||
|
||
class AppAuthCallbacks implements AuthServiceCallbacks {
|
||
/// 与 app_client 一致:Android 用 Settings.Secure.ANDROID_ID(android_id 包,非 Build.ID);
|
||
/// iOS 用 identifierForVendor;失败或其它平台用 SharedPreferences 持久化随机 id。
|
||
@override
|
||
Future<String> getDeviceId() async {
|
||
switch (defaultTargetPlatform) {
|
||
case TargetPlatform.android:
|
||
final androidId = await const AndroidId().getId();
|
||
if (androidId != null && androidId.isNotEmpty) {
|
||
return androidId;
|
||
}
|
||
return _persistedFallbackDeviceId();
|
||
case TargetPlatform.iOS:
|
||
final ios = await DeviceInfoPlugin().iosInfo;
|
||
final idfv = ios.identifierForVendor;
|
||
if (idfv != null && idfv.isNotEmpty) return idfv;
|
||
return _persistedFallbackDeviceId();
|
||
default:
|
||
return _persistedFallbackDeviceId();
|
||
}
|
||
}
|
||
|
||
@override
|
||
String computeSign(String deviceId) {
|
||
return md5.convert(utf8.encode(deviceId)).toString().toUpperCase();
|
||
}
|
||
|
||
@override
|
||
void onLoginSuccess(FastLoginResponse data) {
|
||
if (data.userId != null) UserState.setUserId(data.userId!);
|
||
if (data.credits != null) UserState.setCredits(data.credits!);
|
||
if (data.avatar != null) UserState.setAvatar(data.avatar!);
|
||
if (data.userName != null) UserState.setUserName(data.userName!);
|
||
}
|
||
|
||
@override
|
||
void onCommonInfoLoaded(CommonInfoResponse data) {
|
||
if (data.credits != null) UserState.setCredits(data.credits!);
|
||
if (data.avatar != null) UserState.setAvatar(data.avatar!);
|
||
if (data.userName != null) UserState.setUserName(data.userName!);
|
||
}
|
||
|
||
@override
|
||
void onLoginFailed(String msg) {
|
||
debugPrint('[AuthService] Login failed: $msg');
|
||
}
|
||
}
|
||
|
||
/// 应用侧登录封装;Adjust 归因桥已由框架 [FrameworkAuthService.init] 默认注册。
|
||
class AuthService {
|
||
static final _authCallbacks = AppAuthCallbacks();
|
||
|
||
static Future<void> init() async {
|
||
FrameworkAuthService.init(_authCallbacks);
|
||
await FrameworkAuthService.start();
|
||
}
|
||
|
||
static Future<void> get loginComplete => FrameworkAuthService.loginComplete;
|
||
}
|