# 授权文件功能测试指南 ## 前置准备 1. 确保已启动开发服务器:`npm run dev` 2. 确保数据库中已有以下数据: - 至少一个设备型号(如 GD-30 Supreme) - 至少一个配置文件 - 至少一个设备(用于测试下载接口) ## 测试步骤 ### 1. 创建授权记录 **方式一:通过管理界面** 1. 访问 `http://localhost:3000/licenses` 2. 点击"选择授权项"按钮 3. 选择设备型号、授权模块和到期时间 4. 点击保存,系统会自动生成授权文件JSON **方式二:通过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": "生效", "config_id": 1 }' ``` ### 2. 预览授权文件 1. 在授权管理页面找到刚创建的授权记录 2. 点击"预览"按钮 3. 查看生成的JSON格式授权文件 4. 可以点击下载JSON按钮保存到本地 ### 3. 下载授权文件 1. 在授权管理页面点击"下载"按钮 2. 文件将以 `license_GD-30_1.json` 格式下载 ### 4. 测试手机APP下载接口 ⭐ **首先需要创建一个测试设备:** ```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" }' ``` **然后测试下载接口:** ```bash # 方式一:使用curl curl "http://localhost:3000/api/licenses/download?sn=GD30-TEST-001" # 方式二:使用浏览器直接访问 # 打开浏览器访问:http://localhost:3000/api/licenses/download?sn=GD30-TEST-001 # 方式三:使用JavaScript fetch('http://localhost:3000/api/licenses/download?sn=GD30-TEST-001') .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err)) ``` **预期响应:** ```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": "...", "version": "...", "emissionParams": {...}, "acquisitionParams": {...}, "networkParams": {...} }, "signature": { "algorithm": "SHA256", "value": "...", "publicKey": "platform-public-key-placeholder" } } ``` ### 5. 测试错误情况 **测试设备不存在:** ```bash curl "http://localhost:3000/api/licenses/download?sn=NONEXIST-001" # 应返回:{"error": "设备不存在"} ``` **测试无授权的设备:** ```bash # 先创建一个没有授权的设备 curl -X POST http://localhost:3000/api/devices \ -H "Content-Type: application/json" \ -d '{ "sn": "GD30-NO-LICENSE-001", "model": "GD-30 Supreme", "type": "电法仪", "status": "装配中", "production_date": "2026-04-30" }' # 然后尝试获取授权 curl "http://localhost:3000/api/licenses/download?sn=GD30-NO-LICENSE-001" # 应返回:{"error": "该设备暂无有效授权", ...} ``` ### 6. 验证签名 可以使用以下Node.js脚本验证授权文件签名: ```javascript const crypto = require('crypto'); function verifyLicense(licenseJson) { const license = typeof licenseJson === 'string' ? JSON.parse(licenseJson) : licenseJson; const { signature, ...dataWithoutSig } = license; const jsonString = JSON.stringify(dataWithoutSig, null, 2); const calculatedHash = crypto.createHash('sha256').update(jsonString).digest('hex'); return calculatedHash === signature.value; } // 测试 fetch('http://localhost:3000/api/licenses/download?sn=GD30-TEST-001') .then(res => res.json()) .then(license => { const isValid = verifyLicense(license); console.log('签名验证结果:', isValid ? '✅ 通过' : '❌ 失败'); }); ``` ### 7. 查看下载日志 ```bash # 可以直接查询数据库查看下载记录 sqlite3 data/app.db "SELECT * FROM license_download_logs ORDER BY id DESC LIMIT 10;" ``` 或在SQLite浏览器中打开 `data/app.db` 查看 `license_download_logs` 表。 ## 常见问题 ### Q1: 下载接口返回404? - 检查设备SN是否正确 - 确认该设备型号有有效的授权记录 - 检查授权状态是否为"生效"且未过期 ### Q2: 授权文件中config为空? - 确保已为该设备型号创建了配置文件 - 配置文件状态需要是"生效" ### Q3: 如何区分设备级授权和型号级授权? - 设备级授权:`device_sn` 字段有值 - 型号级授权:`device_sn` 字段为空 - 下载时优先匹配设备级授权 ### Q4: 授权文件何时重新生成? - 创建新授权时自动生成 - 更新授权信息时自动重新生成 - 首次下载时如果license_file为空会生成并保存 ## 性能优化建议 1. **缓存策略**:授权文件生成后保存在数据库中,避免重复生成 2. **索引优化**:为licenses表的device_sn、model、status字段添加索引 3. **日志清理**:定期清理过期的下载日志 4. **CDN加速**:生产环境可以考虑将授权文件缓存到CDN ## 下一步开发建议 1. **前端增强**: - 在设备详情页显示授权状态 - 添加授权文件批量导出功能 - 显示授权下载统计 2. **安全增强**: - 实现真实的RSA签名(目前使用SHA256占位) - 添加授权文件加密 - 实现授权文件版本控制 3. **功能扩展**: - 支持授权模板批量应用 - 添加授权到期提醒 - 实现授权历史记录 4. **监控告警**: - 监控授权下载次数 - 异常下载行为检测 - 授权即将到期预警