# Flutter 授权管理(License SDK) **模块**:`xuqm_flutter_license` · **依赖**:`cryptography`、`device_info_plus`、`shared_preferences` --- ## 1. 安装 在 `pubspec.yaml` 中添加: ```yaml dependencies: xuqm_flutter_license: git: url: https://xuqinmin.com/xuqinmin12/XuqmGroup-FlutterSDK.git ref: v0.2.2 path: packages/license ``` --- ## 2. 放置 License 文件 从租户平台下载 `.xuqmlicense` 加密文件,放入 Flutter assets: ```yaml # pubspec.yaml flutter: assets: - assets/xuqm/license.xuqm ``` --- ## 3. 检查授权 ```dart import 'package:flutter/services.dart' show rootBundle; import 'package:xuqm_flutter_license/xuqm_flutter_license.dart'; Future verifyLicense() async { // 从 assets 读取加密文件 final content = await rootBundle.loadString('assets/xuqm/license.xuqm'); // 自动解密并初始化 await initializeFromFile(content); // 检查授权(有缓存时直接返回,否则网络验证) final result = await checkLicense(); switch (result) { case LicenseSuccess(reason: final r): print('授权通过: $r'); case LicenseError(message: final m): print('授权失败: $m'); } } ``` --- ## 4. 携带用户信息 ```dart final result = await checkLicense( userInfo: LicenseUserInfo( userId: 'user_001', name: '张三', email: 'zhangsan@company.com', ), ); ``` --- ## 5. API 说明 ### initialize ```dart void initialize(String appKey, {String? baseUrl, String? deviceName}) ``` 手动初始化,适用于不使用 License 文件的场景。 ### initializeFromFile ```dart Future initializeFromFile(String encryptedContent) ``` 从加密 License 文件内容自动解析 appKey 和 baseUrl 并初始化。 ### checkLicense ```dart Future checkLicense({LicenseUserInfo? userInfo}) ``` 返回 `LicenseSuccess(reason)` 或 `LicenseError(message)`(密封类,使用 `switch` 匹配)。 **缓存策略**:10 分钟有效期,有效期内不发起网络请求。 ### getStatus ```dart Future getStatus() // LicenseStatus.ok / .denied / .unknown ``` ### getDeviceId ```dart Future getDeviceId() ``` ### clear ```dart Future clear() ``` --- ## 6. 设备唯一码 | 平台 | 来源 | 说明 | |------|------|------| | Android | `androidInfo.id` | `Settings.Secure.ANDROID_ID` | | iOS | `iosInfo.identifierForVendor` | 同 Vendor 下卸载重装不变 | | 其他 | 生成 UUID 存入 SharedPreferences | fallback | --- ## 7. 数据存储 | 数据 | 存储方式 | 说明 | |------|----------|------| | deviceId | SharedPreferences | 持久化 | | token | SharedPreferences | 持久化 | | 授权状态 | SharedPreferences | 非敏感,持久化 | | statusTime | SharedPreferences | 缓存有效期判断 | --- ## 8. 离线模式 - 首次激活需要网络连接 - 激活后 10 分钟缓存内可离线使用 - 网络异常时,若历史缓存成功,继续返回 `LicenseSuccess` --- ## 9. 完整示例 ```dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:xuqm_flutter_sdk/xuqm_flutter_sdk.dart'; import 'package:xuqm_flutter_license/xuqm_license.dart' as license; void main() async { WidgetsFlutterBinding.ensureInitialized(); await XuqmSDK.initialize(XuqmInitOptions(appKey: 'your_app_key')); // 初始化 License final content = await rootBundle.loadString('assets/xuqm/license.xuqm'); await license.initializeFromFile(content); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: FutureBuilder( future: license.checkLicense( userInfo: license.LicenseUserInfo(userId: 'user_001'), ), builder: (context, snapshot) { if (!snapshot.hasData) return const CircularProgressIndicator(); final result = snapshot.data!; if (result is license.LicenseError) { return Scaffold( body: Center(child: Text('授权失败: ${result.message}')), ); } return const HomePage(); }, ), ); } } ``` --- ## 10. 常见问题 **Q: 提示 `Invalid license file format`?** 检查 License 文件是否完整,以及是否已在 `pubspec.yaml` 的 `flutter.assets` 中声明。 **Q: 不同平台可以用同一个 License 吗?** 可以,所有平台共用同一个 AppKey,设备数量统一计算。