104 lines
8.1 KiB
Markdown
104 lines
8.1 KiB
Markdown
# ReinLoop Server 功能与接口
|
||
|
||
## 通用约定
|
||
|
||
业务接口为 `POST /api`。请求与响应均为 JSON,响应包含 `success`。
|
||
|
||
标注为 Admin 的接口需要附加:
|
||
|
||
```json
|
||
{"adminToken":"<B_ADMIN_TOKEN>"}
|
||
```
|
||
|
||
`deviceId` 统一为两段格式:`<company-code>/<line-code>`。
|
||
|
||
## 服务入口
|
||
|
||
| 方法 | 路径 | 用途 |
|
||
| --- | --- | --- |
|
||
| `POST` | `/api` | 主业务 API |
|
||
| `POST` | `/upload/:token` | 根据上传凭证接收 multipart 文件 |
|
||
| `GET` | `/files/:fileID` | 下载已存储文件 |
|
||
| `GET` | `/health` | 服务存活检查 |
|
||
|
||
## 设备心跳与组织
|
||
|
||
| type | 鉴权 | 请求字段 | 功能与响应要点 |
|
||
| --- | --- | --- | --- |
|
||
| `deviceHeartbeat` | 无 | `deviceId` | 已登记设备每 10 秒上报。返回 `deviceId`、服务器记录的 `lastSeenAt`;未登记设备失败。 |
|
||
| `listOrganizations` | Admin | 无 | 返回 `companies`,每家公司包含 `productionLines`。产线包含 `id`、`companyId`、`name`、`code`、`deviceId`、`lastSeenAt`、`online`。最近 30 秒有心跳时 `online` 为 `true`。 |
|
||
| `createCompany` | Admin | `name`、`code` | 创建公司。`code` 全局唯一,只允许 2-64 位小写字母、数字、`_`、`-`。 |
|
||
| `createProductionLine` | Admin | `companyId`、`name`、`code` | 创建产线。产线编码在公司内唯一;服务端固定生成 `<company.code>/<line.code>`。 |
|
||
|
||
Panel 应每 10 秒调用 `listOrganizations` 刷新在线状态,不应自行推测设备状态。
|
||
|
||
## 许可证
|
||
|
||
| type | 鉴权 | 请求字段 | 功能与响应要点 |
|
||
| --- | --- | --- | --- |
|
||
| `createLicense` | Admin | `licenseId`、`companyId`、`productionLineId`、`customer`、`issued`、`expiry`、`features`、`license` | 创建已签名许可证。服务端以 RSA-PSS 公钥验签,校验签名载荷、组织关系和设备 ID。`issued`/`expiry` 使用 `YYYY-MM-DD HH:MM`,按 `Asia/Shanghai` 解析并存为 UTC。相同 ID 和内容幂等成功,不同内容冲突。 |
|
||
| `listLicenses` | Admin | 无 | 返回许可证摘要列表,不返回原始 `license`。 |
|
||
| `getLicense` | Admin | `licenseId` | 返回完整许可证详情,可包含原始 `license`。 |
|
||
| `revokeLicense` | Admin | `licenseId`、`reason` | 撤销许可证,保留历史、撤销时间和原因。`licenseId` 会去除首尾空白。失败时返回 `errCode`:`ADMIN_TOKEN_INVALID`、`ADMIN_TOKEN_NOT_CONFIGURED`、`LICENSE_ID_REQUIRED` 或 `LICENSE_NOT_FOUND`。兼容旧类型 `revoke_license`、`licenseRevoke`、`revoke`,以及旧字段 `license_id`、`admin_token`。每次撤销会记录不含令牌的结构化审计日志。 |
|
||
| `validateLicense` | 无 | `licenseId`、`deviceId` | 返回 `valid`、`status`、`licenseId`。状态为 `active`、`revoked`、`expired`、`not_found` 或 `device_mismatch`;不泄露客户信息和许可证原文。 |
|
||
|
||
许可证格式为 `payloadBase64|signatureBase64`。服务端只读取 `LICENSE_PUBLIC_KEY_PATH` 的公钥,绝不接收或保存 RSA 私钥。
|
||
|
||
## 文件与模型
|
||
|
||
| type | 鉴权 | 请求字段 | 功能与响应要点 |
|
||
| --- | --- | --- | --- |
|
||
| `uploadDataFile` | 视目录而定 | `fileName`、`folder` | 签发通用两步上传凭证。目录为 `*/model_config` 时必须 Admin;其他既有 ReinLoop 数据上传保持兼容。 |
|
||
| `issueModelUpload` | Admin | `deviceId`、`fileName`、可选 `modelName`、`overwrite` | `fileName` 是本地原始文件名;传入 `modelName` 时以该名称存储和识别模型,并保留 `originalFileName`。同名模型已存在时返回 `conflict: true`;仅 `overwrite: true` 可签发覆盖凭证。 |
|
||
| `listModels` | 无 | `folder` | 返回 `files` 当前模型名数组和 `fileList` 元数据数组,最多 100 条;每条同时包含 `fileName` 和 `originalFileName`。 |
|
||
| `downloadModel` | 视文件而定 | `fileID` | 模型保持兼容;非模型文件要求 Admin 并返回短期签名下载 URL。 |
|
||
| `deleteFile` | Admin | `fileID`,或 `folder` 与 `fileName` | 删除文件及元数据;同名文件不唯一时必须使用 `fileID`。 |
|
||
| `deleteModel` | Admin | 同 `deleteFile` | 模型删除的明确管理端别名。 |
|
||
|
||
上传分两步:先调用 `uploadDataFile` 或 `issueModelUpload`,再将文件作为 `multipart/form-data` 的 `file` 字段提交到响应中的 `uploadMetadata.url`。上传成功返回 HTTP `204`;响应中的 `fileID` 可用于下载和删除。
|
||
模型重命名不会修改文件格式,因此 `modelName` 与原始 `fileName` 的扩展名必须一致。未传 `modelName` 时两者相同,旧客户端行为不变。
|
||
|
||
上传到 `<deviceId>/ind_data` 的 `.csv`、`.json` 会自动进入 Panel inbox。
|
||
|
||
## 配置发布与读取
|
||
|
||
| type | 鉴权 | 请求字段 | 功能与响应要点 |
|
||
| --- | --- | --- | --- |
|
||
| `publishIdentificationConfig` | Admin | `deviceId`、`parameters` | 校验辨识参数并为 `<deviceId>/identification_config/identification_config.csv` 签发上传凭证。 |
|
||
| `getIdentificationConfig` | 无 | `deviceId` | 返回该设备辨识 CSV 的 `fileID` 和 `url`。 |
|
||
| `publishVolumeConfig` | Admin | `parameters` | 校验容积参数并签发 `volume_config.json` 上传凭证。上传完成后更新功能参数记录。 |
|
||
| `getVolumeConfigFile` | 无 | 无 | 返回已发布容积 JSON 的 `fileID`、`cloudPath`、`url`。 |
|
||
| `getFunctionConfig` | 无 | `configType: "volume"` | 返回已发布容积参数的 `parameters`、`version`、`updateTime`。 |
|
||
|
||
发布接口仅签发上传凭证;客户端完成二步上传后,读取接口才会返回新文件或参数。
|
||
|
||
## 辨识结果与 Panel 收件箱
|
||
|
||
| type | 鉴权 | 请求字段 | 功能与响应要点 |
|
||
| --- | --- | --- | --- |
|
||
| `registerIdentificationResult` | 无 | `deviceId`、`runId`、可选 `fileName` | ReinLoop 登记待审核辨识结果。 |
|
||
| `getIdentificationFeedback` | 无 | `deviceId`、`runId` | 未就绪时 `ready: false`;就绪时返回 `ready: true` 和 `result`(`0` 或 `1`)。 |
|
||
| `setIdentificationFeedback` | Admin | `deviceId`、可选 `runId`、`result` | Panel 提交辨识审核结果,`result` 必须为数字 `0` 或 `1`。 |
|
||
| `ackIdentificationFeedback` | 无 | `deviceId`、`runId` | ReinLoop 消费后清理反馈。 |
|
||
| `getPendingPanelFile` | Admin | `deviceId` | 获取指定设备下一条待处理 CSV/JSON;无数据时 `pending: false`,有数据时返回文件信息和 `url`。 |
|
||
| `ackPanelFile` | Admin | `deviceId`、`fileID` | Panel 处理完成后确认,移除 inbox 项并标记历史记录为 `processed`,不立即删除文件。 |
|
||
| `listIdentificationFiles` | Admin | `deviceId`、可选 `mediaType`、`status`、`page`、`pageSize` | 分页返回设备的辨识 CSV/JSON 暂存历史。 |
|
||
| `getIdentificationFileDownload` | Admin | `fileID` | 返回原始辨识文件的短期签名下载 URL。 |
|
||
| `deleteIdentificationFile` | Admin | `fileID` | 显式删除辨识文件、历史记录及待处理消息。 |
|
||
|
||
CSV 辨识文件须先以同名 `runId` 调用 `registerIdentificationResult`,才会出现在 `getPendingPanelFile`;初始行程 JSON 可直接获取。
|
||
已处理文件默认保留 30 天,从 `processedAt` 开始计算;待处理文件不会被 TTL 清理。
|
||
保留时长和清理周期分别由 `IDENTIFICATION_RETENTION_MS`、`IDENTIFICATION_PURGE_INTERVAL_MS` 配置。
|
||
|
||
## 容积配置请求
|
||
|
||
| type | 鉴权 | 请求字段 | 功能与响应要点 |
|
||
| --- | --- | --- | --- |
|
||
| `createVolumeConfigRequest` | 无 | `deviceId` | ReinLoop 创建一次性上传请求,返回 `requestId`、`createdAtMs`、`expiresAtMs`。同设备旧请求会被替换。 |
|
||
| `getPendingVolumeConfigRequest` | 无 | `deviceId` | 查询是否存在待上传请求,返回 `pending` 和请求时间信息。 |
|
||
| `submitVolumeConfigFile` | 无 | `deviceId`、`requestId`、`fileID`、可选 `fileName` | 将已上传到 `<deviceId>/volume_config_requests/<requestId>/` 的文件绑定至请求。 |
|
||
| `getVolumeConfigRequest` | 无 | `deviceId`、`requestId` | 轮询配置是否就绪,返回 `ready`、`expired`;就绪时包含下载 `url`。 |
|
||
| `ackVolumeConfigRequest` | 无 | `deviceId`、`requestId` | ReinLoop 下载完成后确认,清理请求及关联文件。 |
|
||
|
||
请求有效期由 `VOLUME_REQUEST_TTL_MS` 控制,默认 300000 毫秒(5 分钟)。
|