309 lines
6.9 KiB
Markdown
309 lines
6.9 KiB
Markdown
# 授权文件功能 - 快速开始
|
||
|
||
## 🚀 5分钟快速上手
|
||
|
||
### 第一步:启动项目
|
||
|
||
```bash
|
||
npm run dev
|
||
```
|
||
|
||
访问 http://localhost:3000
|
||
|
||
### 第二步:准备测试数据
|
||
|
||
确保已有以下数据(如没有请先创建):
|
||
|
||
1. **设备型号** - 例如 "GD-30 Supreme"
|
||
2. **配置文件** - 为该型号创建至少一个配置
|
||
3. **设备** - 创建一个测试设备,SN如 "GD30-TEST-001"
|
||
|
||
### 第三步:创建授权
|
||
|
||
#### 方式A:通过管理界面
|
||
|
||
1. 访问 http://localhost:3000/licenses
|
||
2. 点击"选择授权项"
|
||
3. 选择:
|
||
- 设备型号:GD-30 Supreme
|
||
- 授权模块:勾选需要的模块
|
||
- 到期时间:选择日期
|
||
4. 点击"保存"
|
||
|
||
✅ 系统自动生成JSON授权文件!
|
||
|
||
#### 方式B:通过API
|
||
|
||
```bash
|
||
curl -X POST http://localhost:3000/api/licenses \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"model": "GD-30",
|
||
"modules": "一维自电/电阻率/激电测试模块, 二维自电/电阻率/激电测试模块",
|
||
"expiry": "2027-04-30",
|
||
"status": "生效"
|
||
}'
|
||
```
|
||
|
||
### 第四步:预览授权文件
|
||
|
||
1. 在授权列表中找到刚创建的记录
|
||
2. 点击"预览"按钮
|
||
3. 查看生成的JSON内容
|
||
|
||
你会看到类似这样的结构:
|
||
```json
|
||
{
|
||
"version": "1.0",
|
||
"deviceModel": "GD-30",
|
||
"authModules": [...],
|
||
"config": {...},
|
||
"signature": {...}
|
||
}
|
||
```
|
||
|
||
### 第五步:测试手机APP接口 ⭐
|
||
|
||
这是最关键的一步!
|
||
|
||
```bash
|
||
# 替换为你的设备SN
|
||
curl "http://localhost:3000/api/licenses/download?sn=GD30-TEST-001"
|
||
```
|
||
|
||
**成功响应示例:**
|
||
```json
|
||
{
|
||
"version": "1.0",
|
||
"generatedAt": "2026-04-30T16:00:00.000Z",
|
||
"deviceModel": "GD-30 Supreme",
|
||
"deviceSN": "GD30-TEST-001",
|
||
"validUntil": "2027-04-30",
|
||
"status": "active",
|
||
"authModules": [
|
||
{
|
||
"id": "1D",
|
||
"name": "一维自电/电阻率/激电测试模块",
|
||
"category": "一维",
|
||
"enabled": true
|
||
}
|
||
],
|
||
"config": {
|
||
"name": "...",
|
||
"emissionParams": {...},
|
||
"acquisitionParams": {...}
|
||
},
|
||
"signature": {
|
||
"algorithm": "SHA256",
|
||
"value": "abc123...",
|
||
"publicKey": "platform-public-key-placeholder"
|
||
}
|
||
}
|
||
```
|
||
|
||
## 📱 手机APP集成示例
|
||
|
||
### JavaScript/TypeScript
|
||
|
||
```typescript
|
||
interface LicenseFile {
|
||
version: string;
|
||
deviceModel: string;
|
||
deviceSN: string;
|
||
validUntil: string;
|
||
status: string;
|
||
authModules: Array<{
|
||
id: string;
|
||
name: string;
|
||
enabled: boolean;
|
||
}>;
|
||
config: any;
|
||
signature: {
|
||
algorithm: string;
|
||
value: string;
|
||
};
|
||
}
|
||
|
||
async function getDeviceLicense(deviceSN: string): Promise<LicenseFile> {
|
||
const response = await fetch(
|
||
`http://your-server.com/api/licenses/download?sn=${deviceSN}`
|
||
);
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`获取授权失败: ${response.statusText}`);
|
||
}
|
||
|
||
const license = await response.json();
|
||
|
||
// 验证签名(生产环境必须)
|
||
if (!verifySignature(license)) {
|
||
throw new Error('授权文件签名验证失败');
|
||
}
|
||
|
||
return license;
|
||
}
|
||
|
||
function verifySignature(license: LicenseFile): boolean {
|
||
// 实现签名验证逻辑
|
||
// ...
|
||
return true;
|
||
}
|
||
|
||
// 使用示例
|
||
const license = await getDeviceLicense('GD30-TEST-001');
|
||
console.log('授权模块:', license.authModules);
|
||
console.log('配置参数:', license.config);
|
||
```
|
||
|
||
### React Native
|
||
|
||
```javascript
|
||
import React, { useEffect, useState } from 'react';
|
||
|
||
function App() {
|
||
const [license, setLicense] = useState(null);
|
||
const deviceSN = 'GD30-TEST-001';
|
||
|
||
useEffect(() => {
|
||
fetchLicense();
|
||
}, []);
|
||
|
||
async function fetchLicense() {
|
||
try {
|
||
const response = await fetch(
|
||
`http://your-server.com/api/licenses/download?sn=${deviceSN}`
|
||
);
|
||
const data = await response.json();
|
||
setLicense(data);
|
||
|
||
// 启用授权的功能模块
|
||
enableFeatures(data.authModules);
|
||
} catch (error) {
|
||
console.error('获取授权失败:', error);
|
||
}
|
||
}
|
||
|
||
function enableFeatures(modules) {
|
||
modules.forEach(module => {
|
||
if (module.enabled) {
|
||
console.log(`启用模块: ${module.name}`);
|
||
// 启用对应功能
|
||
}
|
||
});
|
||
}
|
||
|
||
return (
|
||
<View>
|
||
<Text>设备SN: {deviceSN}</Text>
|
||
<Text>授权状态: {license?.status}</Text>
|
||
<Text>有效期至: {license?.validUntil}</Text>
|
||
</View>
|
||
);
|
||
}
|
||
```
|
||
|
||
### Flutter (Dart)
|
||
|
||
```dart
|
||
import 'dart:convert';
|
||
import 'package:http/http.dart' as http;
|
||
|
||
class LicenseService {
|
||
static Future<Map<String, dynamic>> getLicense(String deviceSN) async {
|
||
final response = await http.get(
|
||
Uri.parse('http://your-server.com/api/licenses/download?sn=$deviceSN'),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
return jsonDecode(response.body);
|
||
} else {
|
||
throw Exception('获取授权失败: ${response.statusCode}');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 使用
|
||
final license = await LicenseService.getLicense('GD30-TEST-001');
|
||
print('授权模块: ${license['authModules']}');
|
||
```
|
||
|
||
## 🔍 常见问题排查
|
||
|
||
### 问题1:返回"设备不存在"
|
||
|
||
**原因**: 设备SN在数据库中不存在
|
||
|
||
**解决**:
|
||
```bash
|
||
# 先创建设备
|
||
curl -X POST http://localhost:3000/api/devices \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"sn": "GD30-TEST-001",
|
||
"model": "GD-30 Supreme",
|
||
"type": "电法仪",
|
||
"status": "装配中",
|
||
"production_date": "2026-04-30"
|
||
}'
|
||
```
|
||
|
||
### 问题2:返回"该设备暂无有效授权"
|
||
|
||
**原因**: 该设备型号没有有效的授权记录
|
||
|
||
**解决**:
|
||
1. 检查是否已为该型号创建授权
|
||
2. 确认授权状态是"生效"
|
||
3. 确认授权未过期(expiry >= 当前日期)
|
||
|
||
### 问题3:config字段为空
|
||
|
||
**原因**: 没有关联的配置文件
|
||
|
||
**解决**:
|
||
1. 在"配置文件管理"页面创建配置
|
||
2. 确保配置状态是"生效"
|
||
3. 重新创建授权或更新授权
|
||
|
||
## 📊 查看下载日志
|
||
|
||
```bash
|
||
# 使用SQLite命令行
|
||
sqlite3 data/app.db "SELECT * FROM license_download_logs ORDER BY id DESC LIMIT 5;"
|
||
|
||
# 或使用DB Browser for SQLite打开 data/app.db
|
||
# 查看 license_download_logs 表
|
||
```
|
||
|
||
## ✅ 验证清单
|
||
|
||
完成以下步骤确认功能正常:
|
||
|
||
- [ ] 可以创建授权记录
|
||
- [ ] 授权列表中显示"预览"和"下载"按钮
|
||
- [ ] 点击"预览"可以看到JSON内容
|
||
- [ ] 点击"下载"可以保存JSON文件
|
||
- [ ] 调用 `/api/licenses/download?sn=xxx` 返回授权JSON
|
||
- [ ] JSON包含authModules、config、signature字段
|
||
- [ ] 下载日志记录到数据库
|
||
|
||
## 🎯 下一步
|
||
|
||
1. **阅读完整文档**: 查看 `API_LICENSE.md` 了解所有API细节
|
||
2. **运行测试**: 按照 `TEST_LICENSE.md` 进行完整测试
|
||
3. **集成到APP**: 使用上面的代码示例集成到你的手机APP
|
||
4. **安全加固**: 实现真实的RSA签名替换SHA256占位符
|
||
|
||
## 💡 提示
|
||
|
||
- 开发时可以使用浏览器直接访问下载接口查看结果
|
||
- 生产环境务必实现真正的数字签名验证
|
||
- 建议定期备份授权数据和下载日志
|
||
- 监控下载接口的响应时间和错误率
|
||
|
||
---
|
||
|
||
**需要帮助?**
|
||
- 查看 `API_LICENSE.md` - 完整的API文档
|
||
- 查看 `TEST_LICENSE.md` - 详细的测试指南
|
||
- 查看 `IMPLEMENTATION_SUMMARY.md` - 实现总结 |