24123eb93c
- 新增套餐目录 license_plans.dart(标准/高级 × 月付/年付,与官网 checkout 一致) - license 模型/仓库新增 PurchaseOrder/PurchaseStatusInfo 与下单、查单接口 - 系统设置授权面板:管理员显示「在线购买 / 续费」按钮,弹窗选套餐→ 外部浏览器打开支付宝收银台→3s 轮询到账→自动刷新授权并展示新到期日 - 用户手册(docs.md + user-manual.html)同步补充在线购买入口说明 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
84 lines
2.8 KiB
Dart
84 lines
2.8 KiB
Dart
import 'package:dio/dio.dart';
|
|
import '../core/api/api_client.dart';
|
|
import '../core/device/device_id.dart';
|
|
import '../core/exceptions.dart';
|
|
import '../models/license.dart';
|
|
|
|
class LicenseRepository {
|
|
final ApiClient _client;
|
|
const LicenseRepository(this._client);
|
|
|
|
Future<LicenseInfo?> getInfo() async {
|
|
try {
|
|
final resp = await _client.get('/license/info');
|
|
final data = resp.data['data'];
|
|
if (data == null) return null;
|
|
return LicenseInfo.fromJson(data as Map<String, dynamic>);
|
|
} on DioException catch (e) {
|
|
throw AppException(
|
|
e.response?.data?['error'] as String? ?? '获取授权信息失败',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Activate a license key for this device.
|
|
Future<void> activate(String licenseKey, {String? deviceName}) async {
|
|
final deviceId = await DeviceId.get();
|
|
try {
|
|
await _client.post('/license/activate', data: {
|
|
'license_key': licenseKey,
|
|
'device_id': deviceId,
|
|
'device_name': deviceName ?? DeviceId.platformName,
|
|
'platform': DeviceId.platformName,
|
|
});
|
|
} on DioException catch (e) {
|
|
throw AppException(
|
|
e.response?.data?['error'] as String? ?? '激活失败',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 在线购买/续费下单(仅管理员),返回 pay 收银台跳转信息。
|
|
Future<PurchaseOrder> createPurchase(String bizCode) async {
|
|
try {
|
|
final resp =
|
|
await _client.post('/license/purchase', data: {'biz_code': bizCode});
|
|
return PurchaseOrder.fromJson(resp.data['data'] as Map<String, dynamic>);
|
|
} on DioException catch (e) {
|
|
throw AppException(
|
|
e.response?.data?['error'] as String? ?? '下单失败,请稍后重试',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 查询购买单状态(到账轮询)。到账(paid)后返回续期后的授权到期时间。
|
|
Future<PurchaseStatusInfo> purchaseStatus(String outTradeNo) async {
|
|
try {
|
|
final resp = await _client.get('/license/purchase/$outTradeNo');
|
|
return PurchaseStatusInfo.fromJson(
|
|
resp.data['data'] as Map<String, dynamic>);
|
|
} on DioException catch (e) {
|
|
throw AppException(
|
|
e.response?.data?['error'] as String? ?? '查询订单状态失败',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Deactivate (unbind) this device from its license.
|
|
Future<void> deactivate() async {
|
|
final deviceId = await DeviceId.get();
|
|
try {
|
|
await _client.post('/license/deactivate', data: {'device_id': deviceId});
|
|
} on DioException catch (e) {
|
|
throw AppException(
|
|
e.response?.data?['error'] as String? ?? '解绑失败',
|
|
statusCode: e.response?.statusCode,
|
|
);
|
|
}
|
|
}
|
|
}
|