Files
ReinLoopTest/ControlPanel/features.md
T
2026-07-30 11:12:31 +08:00

534 lines
11 KiB
Markdown
Raw 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.
# ReinLoop ControlPanel 功能总览
## 1. 产品定位
ControlPanel 是 ReinLoop 的 B 端管理工作台,用于管理公司与产线、签发许可证、管理模型、发布参数配置,并接收和审核 ReinLoop 上传的辨识数据。
桌面端基于 Electron,业务请求统一发送到 ReinLoop Server。渲染页面不直接访问文件系统、私钥或管理凭据,敏感操作通过 Electron 主进程完成。
## 2. 连接与鉴权
应用启动后首先显示连接页面,只包含:
- Server API URL
- Admin Token
- “连接并校验”按钮
点击连接后,主进程调用需要管理权限的 `listOrganizations` 接口,同时验证:
- Server 地址是否可访问
- API 路径是否正确
- Admin Token 是否有效
只有校验成功才显示后续业务工作台。连接失败时业务区域保持隐藏,并显示 Server 返回的错误信息。
连接信息仅保存在当前应用进程中:
- Token 不写入浏览器存储。
- Token 不写入本地配置文件。
- Token 只由 Electron 主进程附加到 Server 请求。
- 本次应用会话不提供更改连接入口;需要切换 Server 或 Token 时重新启动应用。
支持通过环境变量提供默认值:
```text
REINLOOP_API_URL
B_ADMIN_TOKEN
REINLOOP_DEVICE_ID
POLL_INTERVAL_MS
DOWNLOAD_DIR
```
## 3. 公司与产线选择
连接成功后,工作台顶部显示公司和产线两个选择菜单。
设备业务标识由 Server 生成,格式固定为:
```text
<company_code>/<production_line_code>
```
例如:
```text
sample-co/line-1
```
配置、模型、辨识数据、审核反馈和容积请求都使用同一个 `deviceId`,避免不同公司或产线的数据混用。
### 在线状态
公司菜单显示在线产线汇总,例如:
```text
示例公司 (sample-co) · 在线 2/3
```
产线菜单显示具体状态:
```text
● 在线 · 一号产线 (line-1)
○ 离线 · 二号产线 (line-2)
◇ 状态未知 · 三号产线 (line-3)
```
Panel 每 10 秒调用一次 `listOrganizations` 静默刷新状态。
Server 已实现设备心跳:
- ReinLoop 调用 `deviceHeartbeat` 更新产线的 `lastSeenAt`
- Server 以最近 30 秒是否收到心跳计算 `online`
- `listOrganizations` 返回每条产线的 `online``lastSeenAt`
- 旧数据缺少状态字段时,Panel 显示“状态未知”,不会误报在线或离线。
## 4. 组织管理
“组织管理”页面支持:
- 添加公司
- 为指定公司添加产线
- 刷新公司与产线列表
公司编码和产线编码只允许:
- 小写英文字母
- 数字
- 下划线
- 连字符
编码长度为 2 到 64 位,并且必须以字母或数字开头。
公司编码由 Server 保证全局唯一;产线编码在同一公司内唯一。
相关 Server 接口:
```text
listOrganizations
createCompany
createProductionLine
```
## 5. 许可证签发与管理
“许可证”页面根据当前选择的公司和产线签发许可证。
签发字段包括:
- 公司
- 产线
- 组合设备 ID
- 签发时间
- 到期时间
- 功能范围
- 唯一许可证 ID
许可证载荷示例:
```json
{
"license_id": "UUID",
"customer": "示例公司",
"company_id": "company_UUID",
"production_line_id": "line_UUID",
"device_id": "sample-co/line-1",
"issued": "2026-07-25 12:00",
"expiry": "2027-07-25 12:00",
"features": "*"
}
```
### 签名格式
Panel 使用 RSA-PSS SHA-256 签名,与 ReinLoop 的 Python 验签逻辑兼容。
许可证文件格式:
```text
base64(JSON)|base64(signature)
```
签发核心会拒绝:
- 空公司或产线标识
- 非法组合设备 ID
- 无效日期格式
- 到期时间不晚于签发时间
- 空功能字段
### 私钥安全
- 每次签发由操作者选择外部 PEM 私钥。
- 私钥只在 Electron 主进程内读取。
- 私钥不会进入渲染页面。
- 私钥不会上传 Server。
- 私钥路径和内容不会由 Panel 持久化。
- 私钥不会打进安装包。
### 本地与 Server 一致性
签发流程为:
1. 选择私钥。
2. 选择本地许可证保存位置。
3. 生成并写入本地许可证。
4. 将签发结果登记到 Server。
5. Server 登记失败时删除本次本地文件,避免出现半完成状态。
许可证管理支持:
- 刷新许可证列表
- 查看许可证详情
- 撤销有效许可证
- 填写撤销原因
- 区分有效和已撤销状态
相关 Server 接口:
```text
createLicense
listLicenses
getLicense
revokeLicense
```
## 6. 模型管理
“模型管理”页面按当前产线操作:
```text
<deviceId>/model_config
```
支持:
- 刷新模型列表
- 查看文件名、上传时间和大小
- 从本地选择并上传模型
- 同名模型覆盖前要求确认并输入完整文件名
- 下载模型到本地 `downloads` 目录
-`fileID` 精确删除模型;删除前要求两次确认并输入完整文件名
上传使用 Server 的两步协议:
1. 调用 `uploadDataFile` 获取上传地址与凭证。
2. 使用 multipart 表单上传文件内容。
相关 Server 接口:
```text
listModels
uploadDataFile
downloadModel
deleteFile
```
## 7. 参数配置发布
“配置发布”页面支持两类参数:
- 容积测量配置
- 系统辨识配置
用户可以:
- 直接编辑 JSON
- 从本地导入 JSON
- 从 Server 读取当前配置
- 发布新配置
### 容积测量参数
严格包含 8 个字段:
```json
{
"q_in_val": 91,
"dt": 0.1,
"p_max": 200,
"fit_low": 50,
"fit_high": 200,
"T_delta": 30,
"xa_full": 1000,
"num_runs": 6
}
```
Panel 在发布前检查:
- 配置必须是 JSON 对象
- 字段不能缺失
- 不能包含多余字段
- 数值必须有限
- `num_runs` 必须是整数
容积配置只会响应 ReinLoop 当前有效的一次性请求;没有待处理请求时 Server 拒绝提交。
### 系统辨识参数
严格包含 9 个字段:
```json
{
"q_in_val": 91,
"dt": 0.1,
"n_order": 8,
"t_c": 2.5,
"levels": [10, 20, 30, 40, 50, 60, 70, 80],
"dead_area": 0,
"xa_full": 1000,
"V_val": 1,
"repeat": 2
}
```
Panel 将其序列化为 `parameter,value` 两列 CSV,并发布到当前产线:
```text
<deviceId>/identification_config/identification_config.csv
```
## 8. 辨识数据接收与绘图
Panel 按当前产线轮询 Server 收件箱,不扫描 Server 文件目录。
默认轮询间隔为 1 秒,可通过 `POLL_INTERVAL_MS` 修改,最小允许值为 500 毫秒。
支持两类数据:
### 辨识 CSV
收到 CSV 后:
1. 下载到本地。
2. 生成阀门开度与压力组合时序图。
3. 在工作台中显示图片。
4. 等待人工提交“通过”或“未通过”。
### 行程稳定压力 JSON
收到 JSON 后:
1. 下载到本地。
2. 将行程与稳定压力绘制为固定 0-1000 行程范围的数值折线图,并显示各点坐标。
3. 在工作台中显示图片。
4. 绘图成功后确认已处理;文件保留在 Server 暂存区,可继续查看和下载。
绘图结果支持在系统文件管理器中定位,也支持在应用内放大、缩小、适应窗口和原始比例查看。
## 9. 辨识数据暂存
“辨识数据”页面按当前产线列出 Server 暂存的 CSV 和行程 JSON,支持:
- 查看并生成对应图像预览
- 将原始 CSV 或 JSON 保存到用户选择的位置
- 管理员二次确认后删除暂存数据
- 查看待处理和已处理状态
文件下载请求携带 Admin Token;Server 可使用该令牌校验下载访问,或返回短期授权下载 URL。
## 10. 辨识人工审核
绘图页面提供:
- “通过”按钮
- “未通过”按钮
### 通过
提交数字 `1`
```json
{
"type": "setIdentificationFeedback",
"deviceId": "sample-co/line-1",
"runId": "辨识 CSV 文件名",
"result": 1
}
```
ReinLoop 获取结果后结束当前辨识流程。
### 未通过
提交数字 `0` 前,Panel 强制要求:
1. 选择一份新的系统辨识参数 JSON。
2. 成功发布新的辨识 CSV 配置。
3. 再提交未通过结果。
ReinLoop 获取数字 `0` 后重新下载配置并执行下一轮辨识。
### 消息可靠性
CSV 不会在绘图后立即从 Server 删除。
只有以下操作都成功后才确认消息:
1. 人工审核结论提交成功。
2. Server 接受 `0/1` 反馈。
3. Panel 调用 `ackPanelFile` 成功。
如果应用在审核前退出,CSV 仍保留在 Server,重新启动并选择同一产线后可以再次获取。
Panel 同一时间只处理一个待审核 CSV,避免多个审核结果串线。
## 10. Electron 安全边界
BrowserWindow 使用:
```text
contextIsolation: true
nodeIntegration: false
sandbox: true
```
渲染页面只能通过 preload 暴露的有限 IPC 调用主进程。
以下能力仅存在于主进程:
- Server Token 请求
- 私钥读取和许可证签名
- 本地文件选择与保存
- 模型上传与下载
- 绘图文件读取
- 在文件管理器中定位文件
页面配置了 Content Security Policy,只允许加载应用自身脚本、样式和 data URL 图片。
## 11. 命令行兼容工具
除 Electron GUI 外,仍保留原有命令行能力:
```text
b-admin.js
poll-panel-inbox.js
```
支持:
- 发布容积配置
- 发布系统辨识配置
- 读取配置
- 轮询待处理数据
- 命令行人工审核
Electron GUI 是主要管理入口,命令行工具用于调试和兼容既有流程。
## 12. 运行与打包
安装依赖:
```bash
cd ControlPanel
npm install
```
启动 Electron
```bash
npm run gui
```
运行语法检查:
```bash
npm run check
```
运行测试:
```bash
npm test
```
构建 Windows 安装版和便携版:
```bash
npm run pack:win
```
输出目录:
```text
Build/
```
构建内容包含:
- Electron 主进程和 preload
- 页面文件
- Server 客户端
- 配置管理模块
- 许可证签发模块
- CSV/JSON 绘图模块
- `canvas` 原生依赖
`canvas` 会从 ASAR 中解包,以便 Windows 原生模块正常加载。
## 13. 当前验证状态
已验证:
- 所有 Panel JavaScript 文件通过 `node --check`
- 许可证 RSA-PSS 签名可由对应公钥验证。
- 非法身份、设备 ID 和时间范围会被拒绝。
- 许可证签发单元测试通过。
- 连接门禁首屏只显示 Server URL、Token 和校验按钮。
- 未通过连接校验时业务区域保持隐藏。
- 页面文件没有编辑器诊断错误。
当前 Linux 工作区中的完整绘图测试受原生 `canvas` 环境限制:已有 `canvas.node` 不是当前 Linux 可加载格式,源码重建又缺少系统 `pangocairo` 开发库。该限制不影响 JavaScript 语法和许可证测试,但 Windows 发布前仍需在目标构建环境执行完整绘图和打包验证。
## 14. 主要 Server 接口依赖
连接与组织:
```text
listOrganizations
createCompany
createProductionLine
```
许可证:
```text
createLicense
listLicenses
getLicense
revokeLicense
```
模型与文件:
```text
uploadDataFile
listModels
downloadModel
deleteFile
```
配置:
```text
getPendingVolumeConfigRequest
submitVolumeConfigFile
publishIdentificationConfig
getIdentificationConfig
getFunctionConfig
```
辨识与收件箱:
```text
getPendingPanelFile
ackPanelFile
setIdentificationFeedback
```
设备在线状态由 ReinLoop 调用:
```text
deviceHeartbeat
```