XuqmGroup-Web/docs-site/docs/flutter/license.md

198 行
4.3 KiB
Markdown

# 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/xuqmGroup/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<void> 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 说明
### initializeFromFile
```dart
Future<void> initializeFromFile(String encryptedContent)
```
从加密 License 文件内容自动解析 appKey 和 baseUrl 并初始化。
### checkLicense
```dart
Future<LicenseResult> checkLicense({LicenseUserInfo? userInfo})
```
返回 `LicenseSuccess(reason)``LicenseError(message)`(密封类,使用 `switch` 匹配)。
**缓存策略**10 分钟有效期,有效期内不发起网络请求。
### getStatus
```dart
Future<LicenseStatus> getStatus() // LicenseStatus.ok / .denied / .unknown
```
### getDeviceId
```dart
Future<String?> getDeviceId()
```
### clear
```dart
Future<void> 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,设备数量统一计算。