8.5 KiB
8.5 KiB
OTA 管理界面 — 实施方案
Context
系统设置模块目前缺少固件/版本管理入口。运维人员需要在一个统一界面里:
- 查看所有机器的当前固件版本
- 上传新的固件包(.bin/.zip)
- 对单台或批量选中机器下发升级
- 每台机器记住上一次的版本号,支持按机器批量回退
后端 OTA 接口尚未实现。本方案先以 Mock 数据把页面与交互跑通,API 函数集中在 src/api/ota.ts,后续后端接口就绪时只需把 mock 实现替换为真实 request 调用即可,页面无需改动。
关键参考文件
- routes.tsx — 路由 + 懒加载注册位置(L35-L42 导入区,L160-L177 systemSetting.children)
- SystemSetting.tsx — 系统设置页 Outlet 容器
- AllDeviceManagement.tsx — 表格 + 搜索 + 操作列模板
- DeviceManagement.tsx — Tabs 子页面模板
- device.ts — API 封装范例(
request、getAllDevice、importBindDevices上传 FormData 范例) - request.ts — axios 实例 + token/FormData 拦截器
- Layout.tsx — 侧边栏菜单构建(
buildMenuTree、renderMenuItems),动态菜单来自getMenuList - DeviceOverviewPage.tsx#L811-L814 — 设备已有
firmwareVersion字段 - zh/index.ts — 中文 i18n(
systemSetting节 L2433、router节 L3562) - en/index.ts — 英文 i18n
实施步骤
1. 新建 Mock API 层 src/api/ota.ts
定义以下函数,内部用 setTimeout 模拟网络延迟,数据保存在模块级内存变量中(页面刷新即重置)。
// 数据结构
interface MachineVersion {
id: number; // 机器ID
code: string; // 编号
name: string; // 名称
type: string; // 类型 ROBOT/DRONE/CAMERA/...
online: 'ONLINE' | 'OFFLINE';
currentVersion: string; // 当前固件版本
previousVersion: string | null; // 上一版本(首次升级前为 null)
lastUpgradeTime: string | null;
status: 'IDLE' | 'UPGRADING' | 'FAILED' | 'SUCCESS';
}
interface FirmwarePackage {
id: number;
version: string; // 版本号,如 v1.2.3
fileName: string;
fileSize: number; // bytes
description?: string;
uploadTime: string;
}
导出函数:
getMachineVersionList()→ 返回 8~10 条 Mock 机器数据getFirmwarePackageList()→ 返回已上传的固件包列表(初始内置 2 条历史版本)uploadFirmwarePackage({ file, version, description })→ 把新固件加入列表并返回upgradeMachines({ machineIds, targetVersion })→ 更新对应机器:previousVersion = currentVersion,currentVersion = targetVersion,status流转,lastUpgradeTime = nowrollbackMachines({ machineIds })→ 对每台机器:若previousVersion存在则交换 current/previous;否则报错
2. 新建页面 src/components/SystemSetting/OTAManagement.tsx
单页三段式布局(参考 AllDeviceManagement.tsx 的表格范式):
A. 顶部 — 固件包上传卡(Card)
Upload组件(antd)accept=".bin,.zip"beforeUpload返回false阻止自动上传Input版本号(必填,校验v\d+\.\d+\.\d+格式)Input.TextArea描述- 「上传」按钮 → 调用
uploadFirmwarePackage,成功后刷新固件列表
B. 中部 — 已上传固件包列表(Table)
- 列:版本号 / 文件名 / 文件大小(格式化为 KB/MB)/ 描述 / 上传时间 / 操作(删除)
rowKey="id",分页 pageSize=10
C. 底部 — 机器版本表(Table + rowSelection)
- 列:机器编号 / 名称 / 类型 / 在线状态 / 当前版本 / 上一版本 / 最近升级时间 / 升级状态 / 操作(单台升级 / 单台回退)
rowSelection={{ type: 'checkbox' }}支持多选- 表格上方工具栏:「批量升级」「批量回退」「刷新」按钮
- 「批量升级」弹出
Modal.select让用户选择目标固件版本(从固件包列表) - 「批量回退」对每台选中机器调用
rollbackMachines,对previousVersion为空的机器用message.warning跳过 - 操作期间
loading状态,操作完成后message.success并刷新表格
整页使用 useTranslation + App.useApp().modal/message 保持与 AllDeviceManagement.tsx 一致的交互风格。
3. 注册路由 src/router/routes.tsx
- L35-L42 区添加:
const OTAManagementPage = lazy(() => import('../components/SystemSetting/OTAManagement')); systemSetting.children数组追加:{ path: 'ota', element: withSuspense(OTAManagementPage) },
4. 侧边栏入口 — src/components/Layout.tsx 加静态 fallback
getMenu() 拉到后端菜单后,遍历 menuList 找 path === '/systemSetting' 的节点,在其 children 末尾追加一项(若不存在):
{
key: '/systemSetting/ota',
label: t('router.otaManagement'),
icon: null, // 子项无图标,与现有子菜单保持一致
}
这样后端菜单数据未配置 OTA 时,前端也能立即在侧边栏看到入口;后端配置好之后该项会被原生菜单项覆盖或共存(key 相同不会重复渲染)。可通过 t('router.otaManagement') 做开关:前端 fallback 项的 label 与后端配置时使用同一个 i18n key。
5. i18n 文案
src/locales/zh/index.ts
router 节新增:
otaManagement: 'OTA 管理',
systemSetting 节新增:
ota: {
title: 'OTA 固件管理',
uploadCard: '上传固件包',
versionPlaceholder: '例如 v1.2.3',
description: '描述',
uploadBtn: '上传',
firmwareList: '已上传固件包',
machineVersionList: '机器版本列表',
currentVersion: '当前版本',
previousVersion: '上一版本',
lastUpgradeTime: '最近升级时间',
upgradeStatus: '升级状态',
batchUpgrade: '批量升级',
batchRollback: '批量回退',
selectTargetVersion: '选择目标固件版本',
confirmUpgrade: '确认对选中的 {count} 台机器升级到 {version}?',
confirmRollback: '确认对选中的 {count} 台机器回退到上一版本?',
noPreviousVersion: '机器 {name} 没有上一版本,无法回退',
uploadSuccess: '固件包上传成功',
upgradeSuccess: '升级指令已下发',
rollbackSuccess: '回退指令已下发',
deleteConfirm: '确认删除固件包 {version}?',
statusIdle: '空闲',
statusUpgrading: '升级中',
statusFailed: '失败',
statusSuccess: '成功',
},
src/locales/en/index.ts 同步补全英文翻译。
验证步骤
npm run dev启动开发服务器- 登录后从侧边栏「系统设置 → OTA 管理」进入,或直接访问
/systemSetting/ota - 验证流程:
- 顶部上传一个
.zip测试文件 + 填版本号v1.0.0→ 中部固件列表出现新条目 - 底部机器表勾选 2-3 台机器 → 点「批量升级」→ 弹窗选
v1.0.0→ 确认 → 选中机器currentVersion变为v1.0.0、previousVersion记录原版本、lastUpgradeTime刷新 - 再次勾选同样机器 → 点「批量回退」→ 确认 →
currentVersion与previousVersion互换 - 单台机器「操作」列的「升级」/「回退」按钮单独验证
- 取消勾选时「批量升级/回退」按钮置灰
- 切换语言到 English,所有文案正常
- 顶部上传一个
- 浏览器 Network 面板无需真实请求(Mock 在前端完成);控制台无报错
npm run build通过,无 TS 报错
范围边界
- 仅做前端 + Mock 数据,不修改后端代码
- 不改
getMenuList接口契约,仅前端 Layout 加 fallback - 不引入新依赖,全部使用项目已有的 antd 组件
- Mock 数据保存在模块内存,刷新即重置;后续接后端时仅替换
src/api/ota.ts内部实现