enterprise-saa-s-dashboard-.../API_LICENSE.md

341 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 授权文件管理 API 文档
## 概述
本系统提供基于设备型号和配置文件的授权文件生成功能。手机APP可以通过设备SN号从平台获取对应的授权文件JSON格式
## 核心功能
1. **授权项管理** - 定义设备可用的功能模块
2. **配置文件管理** - 设备的技术参数配置
3. **授权文件生成** - 根据授权项+配置自动生成JSON授权文件
4. **授权文件下载** - 手机APP通过设备SN获取授权文件
## API 接口
### 1. 获取授权列表
**接口**: `GET /api/licenses`
**响应示例**:
```json
[
{
"id": 1,
"model": "GD-30",
"modules": "一维自电/电阻率/激电测试模块, 二维自电/电阻率/激电测试模块",
"expiry": "2027-04-30",
"status": "生效",
"config_id": 5,
"device_sn": "",
"license_file": "{...}",
"created_at": "2026-04-30 16:00:00",
"updated_at": "2026-04-30 16:00:00"
}
]
```
### 2. 创建授权
**接口**: `POST /api/licenses`
**请求体**:
```json
{
"model": "GD-30",
"modules": "一维自电/电阻率/激电测试模块, 二维自电/电阻率/激电测试模块, 三维自电/电阻率/激电测试模块",
"expiry": "2027-04-30",
"status": "生效",
"config_id": 5,
"device_sn": ""
}
```
**参数说明**:
- `model`: 设备型号(必填)
- `modules`: 授权模块列表,多个模块用", "分隔(必填)
- `expiry`: 到期时间(可选)
- `status`: 状态,"生效"或"已停用"(可选,默认"生效"
- `config_id`: 配置文件ID可选不传则自动使用最新配置
- `device_sn`: 设备SN可选用于设备级授权不填则为型号级授权
**响应示例**:
```json
{
"id": 1,
"licenseFile": {
"version": "1.0",
"generatedAt": "2026-04-30T16:00:00.000Z",
"deviceModel": "GD-30",
"deviceSN": "",
"validUntil": "2027-04-30",
"status": "active",
"authModules": [...],
"config": {...},
"signature": {...}
}
}
```
### 3. 更新授权
**接口**: `PUT /api/licenses`
**请求体**:
```json
{
"id": 1,
"model": "GD-30",
"modules": "一维自电/电阻率/激电测试模块, 二维自电/电阻率/激电测试模块",
"expiry": "2027-04-30",
"status": "生效",
"config_id": 5,
"device_sn": ""
}
```
**响应示例**:
```json
{
"ok": true
}
```
### 4. 手机APP获取授权文件 ⭐
**接口**: `GET /api/licenses/download?sn={device_sn}`
**说明**: 这是手机APP调用的核心接口根据设备SN号返回对应的授权文件JSON。
**查询参数**:
- `sn`: 设备序列号(必填)
**响应示例**:
```json
{
"version": "1.0",
"generatedAt": "2026-04-30T16:00:00.000Z",
"deviceModel": "GD-30 Supreme",
"deviceSN": "GD30-20260430-001",
"validUntil": "2027-04-30",
"status": "active",
"authModules": [
{
"id": "1D",
"name": "一维自电/电阻率/激电测试模块",
"category": "一维",
"enabled": true
},
{
"id": "2D",
"name": "二维自电/电阻率/激电测试模块",
"category": "二维",
"enabled": true
},
{
"id": "3D",
"name": "三维自电/电阻率/激电测试模块",
"category": "三维",
"enabled": true
}
],
"config": {
"name": "CFG-GD30-v2.1",
"version": "v2.1",
"emissionParams": {
"maxVoltage": "1000V",
"maxCurrent": "10A",
"waveform": "0+0-",
"pulseWidth": "0.25s/0.5s/1s/2s/4s/8s/16s/32s/64s"
},
"acquisitionParams": {
"channels": 12,
"sampleRate": "50Hz、60Hz/50Hz、60Hz、100Hz、1000Hz",
"voltageRange": "±2.5V、±80V/±80V、±600V",
"fullWaveform": true
},
"networkParams": {
"wifiSSIDPrefix": "GD30_"
}
},
"signature": {
"algorithm": "SHA256",
"value": "a1b2c3d4e5f6...",
"publicKey": "platform-public-key-placeholder"
}
}
```
**错误响应**:
```json
// 设备不存在
{
"error": "设备不存在"
}
// 无有效授权
{
"error": "该设备暂无有效授权",
"deviceSN": "GD30-20260430-001",
"deviceModel": "GD-30 Supreme"
}
```
**查找逻辑**:
1. 优先查找绑定到具体设备SN的授权device_sn字段匹配
2. 如果没有设备级授权则查找型号级别的授权model字段匹配
3. 只返回状态为"生效"且未过期的授权
4. 每次下载都会记录下载日志
### 5. 预览授权文件
**接口**: `GET /api/licenses/{id}/preview`
**说明**: 在管理后台预览授权文件的JSON内容。
**路径参数**:
- `id`: 授权ID
**响应**: 与下载接口相同的JSON格式
## 授权文件JSON结构说明
```typescript
interface LicenseFile {
version: string; // 版本号,如 "1.0"
generatedAt: string; // 生成时间ISO格式
deviceModel: string; // 设备型号
deviceSN: string; // 设备序列号
validUntil: string; // 有效期
status: string; // 状态:"active" 或 "inactive"
authModules: Array<{ // 授权模块列表
id: string; // 模块ID
name: string; // 模块名称
category: string; // 分类
enabled: boolean; // 是否启用
}>;
config: { // 配置参数
name: string; // 配置名称
version: string; // 配置版本
emissionParams: { // 发射参数
maxVoltage: string; // 最大发射电压
maxCurrent: string; // 最大发射电流
waveform: string; // 发射波形
pulseWidth: string; // 脉宽范围
};
acquisitionParams: { // 采集参数
channels: number; // 通道数
sampleRate: string; // 采样率
voltageRange: string; // 电压量程
fullWaveform: boolean; // 是否支持全波形
};
networkParams: { // 网络参数
wifiSSIDPrefix: string; // WiFi SSID前缀
};
};
signature: { // 数字签名
algorithm: string; // 签名算法
value: string; // 签名值
publicKey: string; // 公钥(用于验证)
};
}
```
## 数据库表结构
### licenses 表(已扩展)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| model | TEXT | 设备型号 |
| modules | TEXT | 授权模块(逗号分隔) |
| expiry | TEXT | 到期时间 |
| status | TEXT | 状态:"生效"或"已停用" |
| config_id | INTEGER | 关联的配置文件ID |
| device_sn | TEXT | 设备SN可选用于设备级授权 |
| license_file | TEXT | 生成的JSON授权文件 |
| created_at | TEXT | 创建时间 |
| updated_at | TEXT | 更新时间 |
### license_download_logs 表(新增)
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键 |
| license_id | INTEGER | 关联的授权ID |
| device_sn | TEXT | 下载的设备SN |
| download_time | TEXT | 下载时间 |
| ip_address | TEXT | 客户端IP |
| app_version | TEXT | APP版本信息 |
## 使用流程
### 管理员操作流程
1. **创建配置文件** - 在"配置文件管理"页面为设备型号创建配置
2. **创建授权** - 在"授权管理"页面选择设备型号、授权项和配置
3. **系统自动生成** - 保存时自动生成JSON授权文件并存储
### 手机APP使用流程
1. APP启动时调用 `GET /api/licenses/download?sn={device_sn}`
2. 平台返回JSON格式的授权文件
3. APP解析授权文件启用对应功能模块
4. APP可以验证签名确保文件完整性
## 安全特性
1. **数字签名** - 每个授权文件都包含SHA256签名
2. **下载日志** - 记录每次授权的下载行为
3. **有效期控制** - 只返回未过期的有效授权
4. **双重匹配** - 支持设备级和型号级授权
## 测试示例
### 使用curl测试下载接口
```bash
# 获取设备SN为 GD30-20260430-001 的授权文件
curl "http://localhost:3000/api/licenses/download?sn=GD30-20260430-001"
```
### JavaScript调用示例
```javascript
async function getLicense(deviceSN) {
const response = await fetch(`/api/licenses/download?sn=${deviceSN}`);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || '获取授权失败');
}
const license = await response.json();
// 验证签名
const isValid = verifySignature(license);
if (!isValid) {
throw new Error('授权文件签名验证失败');
}
return license;
}
function verifySignature(license) {
const { signature, ...dataWithoutSig } = license;
const jsonString = JSON.stringify(dataWithoutSig, null, 2);
const calculatedHash = sha256(jsonString);
return calculatedHash === signature.value;
}
```
## 注意事项
1. 授权文件一旦生成,建议不要频繁修改,以保持稳定性
2. 设备级授权优先级高于型号级授权
3. 签名验证应在APP端实现确保文件未被篡改
4. 定期清理过期的下载日志以优化性能