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 _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.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 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 init() async { FrameworkAuthService.init(_authCallbacks); await FrameworkAuthService.start(); } static Future get loginComplete => FrameworkAuthService.loginComplete; }