# 变更记录 ## 2026-07-24 ### 许可证签发与管理集成 - 集成许可证签发、登记、查询、下载与撤销管理流程。 - 许可证签发使用 RSA-PSS 签名;私钥仅由操作者本地选择使用,不上传至服务端。 ### 公司与产线管理 - 支持新增公司与产线,并生成由公司编码和产线编码组成的设备 ID。 - 支持在控制台选择公司和产线,作为模型、配置和数据操作的目标范围。 ### Server:部署 PostgreSQL 数据库 - 新增 PostgreSQL 存储实现和数据库迁移脚本。 - 支持通过 `DATABASE_URL` 启用 PostgreSQL,持久化公司、产线、许可证、文件元数据、配置和任务状态。 ### 模型管理 - 支持按产线上传模型文件,并保存模型原始文件名与当前模型名。 - 支持列出和删除指定产线的模型文件及对应元数据。 涉及文件: - `ControlPanel/electron-ui/index.html` - `ControlPanel/electron-ui/renderer.js` - `ControlPanel/electron-main.js` - `ControlPanel/electron-preload.js` - `ControlPanel/license-manager.js` - `server/src/app.js` - `server/src/postgres-store.js` - `server/migrations/001_normalized_schema.sql` ## 2026-07-27 ### ControlPanel:模型操作二次确认 - 模型上传遇到同名文件时,要求操作者确认覆盖,并输入完整文件名后才允许执行覆盖。 - 删除模型前要求操作者确认,并输入完整文件名后才允许永久删除,防止误操作。 ### ControlPanel:JSON 配置云端暂存与下载 - JSON 配置发布由“仅从本地文件读取”调整为可直接在界面输入和编辑。 - 支持将容积测量和系统辨识配置暂存到云端,并支持读取、下载当前云端配置后继续编辑。 ### 稳态压力图绘制优化 - 调整行程 JSON 的稳态压力图片绘制逻辑,使曲线和数据点展示更清晰。 - 在图中标注稳态压力节点,便于核对各行程位置对应的稳定压力结果。 涉及文件: - `ControlPanel/electron-ui/index.html` - `ControlPanel/electron-ui/renderer.js` - `ControlPanel/electron-main.js` - `ControlPanel/electron-preload.js` - `ControlPanel/b-admin.js` - `ControlPanel/plot-json.js` - `server/src/app.js` ## 2026-07-28 ### ControlPanel:完善辨识数据管理 - 新增辨识数据文件列表,支持按当前选择的公司和产线查看已上传的辨识 CSV 与行程 JSON 数据。 - 支持辨识数据文件的预览、下载和永久删除;删除操作会要求二次确认,避免误删。 - 支持模型同名覆盖前的二次确认:操作者必须输入完整文件名后才可覆盖已有模型,降低误覆盖风险。 ### ControlPanel:新增图片放大预览 - 为辨识 CSV 图和行程 JSON 图增加图片放大显示功能。 - 放大预览支持适应窗口、原始比例、放大、缩小和关闭操作,便于检查曲线细节。 涉及文件: - `ControlPanel/electron-ui/index.html` - `ControlPanel/electron-ui/renderer.js` - `ControlPanel/electron-ui/styles.css` - `ControlPanel/electron-main.js` - `ControlPanel/electron-preload.js` - `server/src/app.js` ## 2026-07-30 ### ReinLoop:修复底部连接状态显示 - `ConnectionManager` 的连接状态回调统一发送 `● 已连接`、`● 未连接` 文本。 - 主窗口在设备连接成功、连接失败和主动断开时,直接同步更新右下角状态栏;不再仅依赖连接管理器回调,避免界面持续显示“未连接”。 涉及文件: - `ReinLoop/core/connection_manager.py` - `ReinLoop/ui/main_window.py` ### ControlPanel:增强许可证撤销可靠性 - `callServer()` 现在会在 HTTP 非成功响应时优先解析并展示服务端返回的 `errMsg`,并对非 JSON 响应和无效响应体给出明确报错。 - 新增已验证连接凭证的回退逻辑;许可证列表、详情、撤销和下载操作在界面未携带完整凭证时,会使用当前会话保存的 API 地址和管理令牌,降低撤销因空 Token 或空 API 地址失败的概率。 涉及文件: - `ControlPanel/server-client.js` - `ControlPanel/electron-main.js` ### ControlPanel:新增控制数据管理与下载 - 新增“控制数据”管理页面,按当前选择的公司和产线加载控制数据文件列表。 - 支持查看控制数据文件的元信息与 JSON 内容预览;二进制 `.pkl` 分片文件提示下载后使用 ReinLoop/Python 分析。 - 支持将选中的控制数据文件保存到本地,并支持永久删除对应的服务端文件及元数据。 - 控制数据接口按设备 ID 隔离,并通过 Admin Token 鉴权,避免跨产线访问或操作非控制数据文件。 涉及文件: - `ControlPanel/electron-ui/index.html` - `ControlPanel/electron-ui/renderer.js` - `ControlPanel/electron-main.js` - `ControlPanel/electron-preload.js` - `server/src/app.js` ### Server:完善许可证撤销并完成部署 - `revokeLicense` 现在会去除 `licenseId` 首尾空白,并返回稳定错误码:`ADMIN_TOKEN_INVALID`、`ADMIN_TOKEN_NOT_CONFIGURED`、`LICENSE_ID_REQUIRED`、`LICENSE_NOT_FOUND`。 - 增加撤销审计日志,记录时间、可选请求 ID、许可证 ID、执行结果和错误码,不记录管理令牌。 - 兼容旧撤销请求类型 `revoke_license`、`licenseRevoke`、`revoke` 及字段 `license_id`、`admin_token`。 - 已完成 `npm run check`、完整服务端测试(19 项通过)、运行中服务验证,并重启 `reinloop-server.service` 部署。 涉及文件: - `server/src/app.js` - `server/test/server.test.js` - `server/features.md` ### 文档:合并项目说明 - 将 ReinLoop 客户端、ControlPanel 和 Server 的三份说明合并为根目录 `README.md`。 - 删除已合并的 `B端实现说明.md` 和 `README1.md`;接口定义继续统一维护在 `server/features.md`。 ### 验证 - 已完成修改文件的 Python、JavaScript 语法检查,未发现语法错误。 ## 2026-08-03 ### Server:下载接口改造为一次性临时 URL 并绑定来源 IP - 文件下载流程由“业务接口返回可复用直链”改为“业务接口签发一次性临时 URL + 下载后立即失效”。 - 新增下载入口 `GET /downloads/:ticket`,票据校验包含有效期、一次性消费和请求来源 IP 一致性。 - 旧入口 `GET /files/:fileID` 已停用并固定返回 `403`,避免 fileID 直链被转发复用。 - `downloadModel` 统一要求 `adminToken`,下载能力与管理权限保持一致。 - 返回下载 URL 的业务接口已统一改为临时票据地址:`downloadModel`、`getPendingPanelFile`、`getIdentificationFileDownload`、`getControlFileDownload`、`getIdentificationConfig`、`getVolumeConfigFile`、`getVolumeConfigRequest`。 涉及文件: - `server/src/app.js` - `server/test/server.test.js` - `ControlPanel/server-client.js` - `server/features.md` ### 验证 - 已完成 `server` 全量测试(21 项)通过。 - 已完成 ControlPanel 无 GUI 内核联调测试通过(`model-handlers` 与 `license-manager` 相关用例)。 - 已重启 `reinloop-server.service` 并验证:同一临时下载 URL 首次下载成功,二次访问返回 `403`。 ### Server + ReinLoop:设备分路由与最小权限访问 - 新增 `POST /device` 设备侧路由,ReinLoop 通过 `deviceAuth`(`licenseId` + `deviceId`)换取短期 `deviceToken` 后访问设备接口。 - 设备侧接口采用白名单权限,不再使用 `adminToken`,并强制按 `deviceId` 隔离目录和模型访问范围。 - ReinLoop 客户端核心模块已切换为 `/device` 访问链路:设备心跳、模型列表与下载、辨识配置下载、容积请求、辨识反馈、控制与辨识结果上传申请。 - ReinLoop 离线宽限默认调整为 `100` 小时(`REINLOOP_LICENSE_OFFLINE_HOURS` 默认值)。 ### ReinLoop + Panel:离线持续运行与组织清理增强 - ReinLoop 调整为“仅启动时执行许可证校验”,不再自动启动后台巡检线程,满足离线持续运行需求。 - Server 新增许可证删除接口 `deleteLicense`(仅允许删除已撤销许可证)。 - Server 新增组织删除接口 `deleteProductionLine`、`deleteCompany`,并增加前置约束与关联数据清理。 - Panel 新增操作入口: - 已撤销许可证支持“删除”; - 组织管理页支持删除当前公司与当前产线。 涉及文件: - `ReinLoop/license_utils.py` - `ReinLoop/core/__init__.py` - `server/src/app.js` - `server/features.md` - `ControlPanel/electron-main.js` - `ControlPanel/electron-preload.js` - `ControlPanel/electron-ui/index.html` - `ControlPanel/electron-ui/renderer.js` 涉及文件: - `server/src/app.js` - `server/features.md` - `ReinLoop/api.py` - `ReinLoop/license_utils.py` - `ReinLoop/core/model_manager.py` - `ReinLoop/core/identification_config.py` - `ReinLoop/core/volume_config.py` - `ReinLoop/core/identification_feedback.py` - `ReinLoop/core/device_heartbeat.py` - `ReinLoop/core/data_collector.py` - `ReinLoop/core/identification.py` ### ReinLoop:许可证文件改为通配检索 - 许可证启动校验与信息读取不再固定使用 `license.lic`,改为在程序目录检索匹配 `*license.lic` 的文件。 - 当存在多个匹配文件时,按“最近修改时间优先”选择目标文件,降低人工改名或多版本并存时的启动失败概率。 - 同步更新提示文案:明确要求许可证文件名需匹配 `*license.lic`。 - 新增协议测试覆盖:默认通配匹配与多文件择优选择。 涉及文件: - `ReinLoop/license_utils.py` - `ReinLoop/tests/test_license_protocol.py` ### ControlPanel:删除确认提示文案修正 - 删除产线、删除公司、删除许可证的二次确认弹窗改为按业务字段显示错误提示,不再统一显示“文件名不匹配”。 - 现分别提示 `deviceId`、公司编码、许可证 ID 的必填和匹配错误,减少误解与误操作。 ### Server + ControlPanel:删除逻辑防死数据增强 - `deleteProductionLine` 重构为统一的产线清理流程:删除产线时会同时清理关联文件元数据、通知、辨识反馈、容积配置请求/结果、许可证记录,并增加磁盘目录兜底删除,减少孤儿目录残留。 - `deleteCompany` 改为级联删除:在不存在有效许可证时,自动删除该公司下全部产线及其关联数据,再删除公司本体;若仍有有效许可证则阻止删除并返回 `ACTIVE_LICENSES_PRESENT`。 - Panel 删除提示文案升级:明确告知“删除公司/产线会删除关联模型、辨识数据、容积配置、通知与许可证记录”。 - 删除许可证确认弹窗补充“当前许可证 ID”显示,且确认比较支持忽略大小写,降低输入误判。 涉及文件: - `server/src/app.js` - `server/test/server.test.js` - `ControlPanel/electron-ui/renderer.js` 涉及文件: - `ControlPanel/electron-ui/renderer.js`