Skip to content

Repository files navigation

RM Extension — 扩展 RM 无限可能

浏览器里的 RoboMaster 助手,持续扩展 RM 的使用体验与无限可能。

RM Extension Logo

源代码 · 演示视频 · 软件说明书 · Microsoft Edge Add-ons · Chrome Web Store

▶ 点击封面观看项目演示视频

RM Extension 项目演示视频封面

成果摘要

RM Extension 是一个面向 RoboMaster 社区的可持续扩展型浏览器助手。它以浏览器扩展为统一载体,连接 RoboMaster 官网、论坛以及 RMer 日常使用的协作平台,逐步解决资料发布、赛事观看和社区使用中的重复操作与体验问题。

项目当前落地了两项能力:一是将飞书文档或整个知识库迁移到 RoboMaster 论坛,二是通过 RMLive 增强官网直播体验。飞书迁移是目前功能最完整、技术积累最集中的模块,也是当前技术实现最完整的能力;它不代表 RM Extension 的最终功能边界,后续能力将继续围绕真实的 RoboMaster 社区需求扩展。

截至 2026-08-23,项目已有以下公开成果:

指标 结果 数据来源
论坛站内引用 114 次 软件说明书
Bilibili 演示 4,792 播放、470 点赞、235 投币、260 收藏 视频页面
Edge 扩展 283 名用户 商店页面
Chrome 扩展 114 名用户 商店页面

公开成果截图

RM Extension 软件说明书在 RoboMaster 论坛获得 114 次引用

Microsoft Edge Add-ons · 283 名用户Chrome Web Store · 114 名用户
RM Extension Microsoft Edge Add-ons 页面显示 283 名用户RM Extension Chrome Web Store 页面显示 114 名用户
当前飞书迁移能力的三个技术亮点是:
  1. 结构级转换:将飞书 Block 和富文本样式映射到论坛编辑器使用的 HTML,而非依赖反复复制粘贴。
  2. 完整资源迁移:自动下载图片、视频和附件,上传至论坛使用的 OSS,并可在更新文章时复用已有对象。
  3. 目录级迁移:读取飞书知识库树,根据插入、覆盖、空节点或跳过策略重建论坛 Wiki 层级和顺序。

项目愿景与背景

项目名称中的 Extension 有双重含义:它首先是一款 Browser Extension(浏览器扩展),以浏览器为载体接入 RoboMaster 官网、论坛和外部服务;同时也代表 Extension of Possibilities(可能性的扩展),希望不断拓展 RMer 使用工具、共享知识和参与赛事的方式。这正是“扩展 RM 无限可能”的由来。

“扩展 RM 无限可能”不仅是项目名称,也是 RM Extension 的长期目标。RoboMaster 用户需要在官网、论坛、协作文档、赛事直播和其他工具之间频繁切换,其中仍有许多可以由浏览器扩展连接、自动化或重新设计的环节。RM Extension 采用模块化入口和按站点加载的 Content Script,使新能力可以逐步加入同一扩展,而不必把项目限定成单一用途的转换工具。

RoboMaster 战队常用飞书沉淀机械、嵌入式、算法和运营资料,但论坛开源通常需要再次整理。队员已经习惯在在线文档中多人协作,转到论坛编辑时却难以继续同步编辑;外部图片通常还要先下载、再重新上传。一个赛季专栏可能包含 30~50 篇文档,逐篇复制、校对和重建目录会形成大量重复劳动。

手工搬运不仅要复制正文,还要重新处理标题、列表、表格、公式、图片、附件和目录。内容规模越大、格式越复杂,搬运成本和人工疏漏风险就越高。

飞书迁移模块面向已经完成内容创作、希望发布到 RoboMaster 论坛的成员,目标是减少机械操作,同时尽可能保留原始结构。它不是通用飞书备份器,也不会把飞书在线表格、多维表格或画板转换成可编辑的论坛对象。这些限制只描述当前模块,并不限制 RM Extension 未来增加其他 RoboMaster 场景能力。

方案 格式保留 图片/附件 知识库目录 目标平台适配
手工复制粘贴 需要逐项检查 手工重传 手工重建 人工调整
通用文档导出 取决于导出格式 通常导出到本地 通常变为文件目录 仍需再次导入
RM Extension 按 Block 转换 自动迁移并支持复用 自动映射和重建 直接生成论坛编辑器数据

需求约束与方案论证

赛季规划、技术报告和开源专栏往往由多名队员在在线文档中共同编辑,最终再发布到论坛。因此,本项目需要同时满足四项约束:降低非开发者的使用门槛,尽量保留文档结构,避免把战队未公开资料中转到第三方服务器,并为后续 RoboMaster 场景保留扩展空间。

实现形态 优势 主要代价 结论
命令行工具 轻量,易于复用现有转换库 需要安装运行时、配置参数并理解命令,难以面向全队推广 适合开发者,不适合作为默认产品形态
Web 站点 界面友好,易于集中更新 后端需要承担转换和运维;文档内容可能经过项目方服务器 与战队资料的隐私边界不匹配
桌面应用 可在本地执行并提供完整 UI 需要分发、安装和维护多平台客户端,与论坛页面交互仍需额外授权 能实现,但产品和维护成本更高
浏览器扩展 安装后可以在用户浏览器内直接交互,可访问目标页面上下文,同一代码库可构建多浏览器版本 受扩展权限、后台生命周期和浏览器 API 约束 采用

RM Extension 使用浏览器扩展作为执行边界:凭证保存在 Extension Storage,文档读取、结构转换和媒体搬运由用户浏览器直接调用飞书、RoboMaster 论坛和 OSS 接口,项目不设中转业务服务器。这一选择不仅解决当前的文档迁移,也允许通过 Popup、Background 或按站点加载的 Content Script 继续增加 RMLive 等相互独立的能力。

当前能力

下列能力代表当前版本,而不是项目的最终功能清单。新的功能可以通过 Popup 入口、Background 任务或面向特定 RoboMaster 页面加载的 Content Script 接入。

飞书文档导入

  • 将飞书 Docx 或 Wiki 页面导入为论坛文章、FAQ 或 Wiki 页面。
  • 支持发布内容、保持草稿状态以及更新已有内容。
  • 转换富文本、标题、多级列表、代码、引用、待办、表格、图片、文件、视频和行内公式。
  • 可复用文章中已经上传的媒体对象,减少重复下载和上传。
  • 可将 @用户 的 Open ID 转换为可读用户名,并可强制为表格生成表头。

飞书知识库迁移

  • 递归读取飞书知识库目录,并与目标论坛 Wiki 树进行匹配。
  • 对每个节点选择覆盖、插入、新建空节点或不处理。
  • 根据父节点和前序兄弟关系重建页面层级与顺序。
  • 展示总任务、当前文档和媒体 I/O 进度。
  • 支持主动取消,并区分成功、失败与已取消状态。

RMLive 直播体验增强

RMLive 是与文档迁移并列、相互独立的当前能力。启用后,扩展会在 RoboMaster 官网直播页加载增强直播界面,并把页面请求所需的论坛身份信息通过限定来源的 postMessage 传给 RMLive。它体现了 RM Extension 除内容迁移之外,还能够通过页面集成改善官网使用体验。下文以成熟度更高的飞书迁移模块介绍核心技术实现,不代表产品只服务于文档转换。

格式兼容性

支持程度 飞书内容 转换结果
完整转换 Page、普通文本、1–9 级标题、项目符号、有序列表、代码、引用、待办、Callout、分割线、文件、图片、表格、分栏、Iframe、View 转换为论坛编辑器 HTML;图片和文件同时迁移
尽力转换 群聊卡片、流程图、部分嵌入内容 保留可提取的标题、链接或说明
明确降级 多维表格、电子表格、思维笔记、任务、OKR、画板、Jira、同步块、子页面列表、AI 模板等 在正文中写入“不支持”提示,不静默丢弃

效果展示

演示视频

《不必按烂 CV 键,RM Extension 助你一键搬运飞书文档到论坛》展示了从飞书内容到 RoboMaster 论坛的实际操作过程。

文档转换效果对比

下图左侧为飞书原始文档,右侧为转换后的 RoboMaster 论坛 Wiki 页面,可对比正文结构、富文本样式、链接、代码、颜色、用户与文档提及、日期提醒、公式以及目录层级。

飞书原始文档与 RoboMaster 论坛转换结果对比

快速开始

使用条件

  • Edge、Chrome 或 Firefox 桌面浏览器。
  • 一个可发布并获得管理员批准的飞书企业自建应用。
  • 机器人对源文档或知识库具有读取权限。
  • 当前浏览器已登录 RoboMaster 论坛,并对目标文章、FAQ 或 Wiki 具有编辑权限。

安装

Edge 用户可从 Microsoft Edge Add-ons 安装,Chrome 用户可从 Chrome Web Store 安装。Firefox 或需要调试的用户可按“开发与构建”章节从源码构建。

配置飞书应用

  1. 飞书开放平台创建企业自建应用并添加机器人能力。
  2. 为应用开通文档、云盘、知识库和群聊只读权限;以飞书开放平台当前展示的权限名称为准。
  3. 创建版本、申请发布并等待企业管理员批准。
  4. 将机器人加入能够访问目标文档的群,并为该群授予对应文档或知识库权限。
  5. 打开扩展的“选项”页,填入 App ID 和 App Secret,点击“测试连接”。

App Secret 会写入浏览器扩展的本地存储。不要在公共电脑配置,不要把包含凭证的浏览器配置目录或调试日志公开。

导入单篇文档

  1. 在浏览器打开有权编辑的论坛文章、FAQ、Wiki 页面或已保存的草稿。
  2. 打开扩展,选择“飞书文档转 RM 论坛文章”。
  3. 粘贴飞书 Docx 或 Wiki 页面链接并等待解析。
  4. 选择是否保持草稿、复用资源、转换用户名称和强制表头。
  5. 开始执行,完成后检查标题、正文、图片、附件和页面状态。

导入整个知识库

  1. 打开目标论坛 Wiki 中任意页面。
  2. 在扩展中选择“飞书知识库转论坛专栏”,粘贴飞书知识库页面链接。
  3. 在目录中选择待迁移页面;同名节点默认覆盖,不存在的节点默认插入。
  4. 确认设置后执行,并在关闭 Popup 后重新打开扩展查看当前任务。

常见问题

现象 检查项
飞书连接失败 App ID/Secret、应用是否发布、机器人权限、企业管理员审批
无法解析飞书链接 使用 /docx//wiki/ 页面链接,并确认机器人能够读取
无法识别论坛目标 确保域名为 bbs.robomaster.com,目标页面可编辑;新草稿需先保存以取得 draftId
图片或附件失败 检查网络、飞书资源权限、论坛登录状态和 OSS 临时凭证获取
页面出现“不支持” 对照格式兼容表;原始 Block 未被静默删除,而是降级为提示文字

开发与构建

开发环境与构建命令

以下命令于 2026-08-23 在 macOS ARM64、Node.js 20.20.2、pnpm 10.33.0 下验证。项目使用 TypeScript 5.9、WXT 0.20、React 19;建议从 Node.js 20 LTS 开始复现。

git clone https://github.com/scutrobotlab/rm-extension.git
cd rm-extension
pnpm install --frozen-lockfile
pnpm compile
pnpm build

常用命令:

命令 用途
pnpm dev 启动 Chromium 开发模式
pnpm dev:firefox 启动 Firefox 开发模式
pnpm compile TypeScript 静态检查,不输出文件
pnpm build / pnpm build:firefox 构建 Chromium / Firefox 扩展
pnpm zip / pnpm zip:firefox 生成商店提交压缩包
pnpm api:lark / pnpm api:robomaster 根据 OpenAPI 描述重新生成客户端;需要另行安装 OpenAPI Generator

开发调试可使用以下环境变量覆盖本地存储中的飞书凭证;不要提交真实值:

WXT_LARK_APP_ID=
WXT_LARK_APP_SECRET=
WXT_LARK_ACCESS_TOKEN=

WXT 默认把构建结果写入 .output/。Chromium 可在扩展管理页开启开发者模式并加载对应的 unpacked 目录;Firefox 可通过 about:debugging 临时加载构建产物。

项目结构

rm-extension/
├── entrypoints/
│   ├── background/         # 长任务、飞书转换编排和论坛写入
│   ├── popup/              # 功能入口、表单、目录选择和进度 UI
│   ├── options/            # 飞书 App ID / App Secret 配置
│   ├── robomaster.content/ # RMLive 官网内容脚本
│   └── message.ts          # Popup 与 Background 的消息契约
├── components/             # 跨页面 React 组件
├── utils/
│   ├── lark/               # 飞书认证、Block 转换、下载和状态模型
│   ├── robomaster/         # 论坛 URL、Wiki 树、OSS 和论坛接口
│   └── common/             # MD5 等通用能力
├── public/                 # 扩展可公开访问的注入资源
├── assets/                 # 图标与 README 资源
└── wxt.config.ts           # WXT 与扩展 Manifest 配置

utils/lark/openapiutils/robomaster/openapi 是由接口描述生成的客户端;业务修改应优先发生在生成目录之外,接口更新时再统一重新生成。

系统架构与数据流

软件架构

flowchart LR
    U[用户] --> P[Popup React UI]
    U --> O[Options 配置页]
    O --> S[(Extension Storage)]
    P <-->|消息与进度| B[Background]
    B --> L[飞书开放平台]
    B --> R[RoboMaster 论坛 API]
    B --> A[阿里云 OSS]
    C[Content Script] --> W[RoboMaster 官网直播页]
    C --> I[RMLive iframe]
    W --> C
Loading

Popup 只负责收集参数和展示状态;耗时转换在 Background 中执行,避免用户界面组件卸载后任务立即中断。Options 保存飞书凭证,Content Script 仅负责 RMLive 这一独立功能。

文档迁移数据流

flowchart LR
    A[飞书链接] --> B[读取文档<br/>解析 Block]
    B --> C[建立结构<br/>转换 HTML]
    C --> D[处理媒体]
    D --> E[组装文章数据]
    E --> F[写入文章<br/>FAQ / Wiki]
Loading

媒体处理分支:

flowchart LR
    A{包含媒体?} -->|否| E[继续组装文章]
    A -->|是| B[下载飞书资源]
    B --> C{MD5 匹配<br/>已有对象?}
    C -->|是| E
    C -->|否| D[获取 STS<br/>上传 OSS]
    D --> E
Loading

知识库目录迁移

flowchart TD
    A[读取飞书 Wiki 树] --> B[读取论坛 Wiki 树]
    B --> C[按标题匹配节点]
    C --> D{用户策略}
    D -->|覆盖| E[更新已有页面]
    D -->|插入| F[转换并创建页面]
    D -->|空节点| G[创建目录占位页面]
    D -->|跳过| H[不处理]
    E --> I[更新节点映射]
    F --> I
    G --> I
    I --> J[按 parentId / prevId 重建顺序]
Loading

核心原理与理论支持

Block 到 HTML

飞书返回的是带 block_idchildrenblock_type 的 Block 列表。DocxConverter 首先建立 block_id → Block 映射,再从 Page Block 递归遍历。每种 Block 交给对应转换方法,文本元素则继续映射粗体、斜体、删除线、下划线、链接、颜色、对齐方式和缩进。从数据模型看,这是一个“扁平节点集合 → 有根文档树 → 目标 HTML 树”的模型变换过程;Map 使子节点按 ID 查找保持常数期望时间,整体遍历与 Block 数量近似线性增长。

相比先转 Markdown 再导入,直接从 Block 语义映射论坛 HTML 可避免在中间表示中过早丢失表格合并、提及、颜色和媒体元数据。按 Block 类型分派又使结构遍历与具体渲染规则分离,新类型可通过独立转换函数加入。无法转换的类型会生成清晰提示,这是采用“显式降级”而非静默丢弃,防止发布者误判迁移完整性。

媒体迁移与复用

转换器通过飞书临时下载地址读取媒体,并用流式读取反馈下载进度。上传前计算 MD5,从论坛取得短期 OSS 凭证后执行分片上传,最终生成论坛编辑器需要的图片、附件或视频 HTML 以及 fileItems 元数据。这条管线将“内容转换”与“二进制对象迁移”分开:HTML 负责引用关系,headImgfileItems 保留论坛发布接口需要的结构化元数据。

更新已有文章时,转换器会用飞书资源 Token 在旧的 headImgfileItems 中查找对象;用户启用复用后可跳过重复传输。该策略类似内容寻址与幂等更新:先识别已存在对象,再决定是否执行有副作用的上传。它减少网络 I/O,也避免同一文章反复更新产生过多对象;MD5 用于传输与完整性校验,不承担密码学安全功能。

Wiki 树映射

论坛节点位置由 parentIdprevId 共同决定。buildWikiNodeMap 深度优先遍历论坛树,为每个 postsId 记录父节点和前序兄弟;批量任务再根据飞书目录和用户策略创建或覆盖页面。从数据结构上看,飞书与论坛都是有序树,但对顺序的表达不同:前者以子节点列表表达次序,后者以父节点和前驱节点表达插入位置。迁移的本质是在保持父子关系与兄弟顺序的前提下,完成两种树表示之间的同构映射。

创建节点会改变论坛树,因此任务在必要时重新读取并更新映射,避免使用已失效的位置索引。插入过程逆序处理同级节点,是由目标接口的 prevId 约束导出的顺序策略,使新节点的插入不会破坏尚未处理的兄弟位置,最终得到与飞书一致的可见顺序。

长任务状态

Popup 通过 webext-bridge 发出转换、取消和状态查询消息。Background 维护 Ready → Converting → Success / Failed / Canceled 状态,在文档转换和每次 I/O 前检查取消标志,并把总进度、子进度和文件进度推送给 Popup。这里采用消息驱动和显式有限状态模型:Popup 是可随时关闭的短生命周期视图,Background 才是任务状态的唯一事实来源。界面重新打开后通过查询消息恢复展示,避免把长任务绑定到 React 组件生命周期。

该取消机制是协作式取消:它在安全点检查标志并阻止后续步骤,无需强行中断正在执行的 API 调用。代价是它不能撤销已经写入论坛或上传 OSS 的数据,因此该流程提供的是“停止继续执行”而非跨系统事务回滚。知识库任务取消后,应检查已完成节点。

设计模式与可扩展性

设计思想 代码落点 实际收益
转换器 DocxConverter 把飞书 Block、媒体状态和最终论坛 HTML 聚合在明确边界内
策略式分派 ConvertBlockToHTML 根据 BlockType 选择转换方法 新增 Block 时可增加独立转换函数,不必改写整条迁移流程
适配器 飞书 Block/媒体模型 → 论坛 HTML、headImgfileItems 隔离两个平台的数据模型差异
消息驱动 Popup 消息契约与 Background 处理器 UI 生命周期与长任务解耦,并统一进度及取消入口
显式状态机 LarkConvertState UI 对初始化、就绪、转换、成功、失败和取消状态进行穷举展示
生成式 API 边界 两套 OpenAPI 客户端 业务代码不手写大量请求/响应类型,接口变更可集中再生成

增加飞书 Block 支持时,应扩展 BlockType 映射并实现单一转换方法。若未来增加新的发布平台,建议保留飞书读取层,把论坛专用 HTML 和媒体上传抽象为目标适配器,而不是继续扩张单个转换器。

代码规范

  • 业务代码使用 TypeScript,消息请求、转换任务、论坛目标和状态都有显式类型。
  • React 组件使用 PascalCase,函数和变量使用 camelCase;既有跨模块公共函数中仍有部分 PascalCase 命名,后续将逐步统一。
  • 关键转换、目录遍历、媒体上传和取消检查包含目的性注释;生成代码不作为人工注释质量样本。
  • pnpm compile 是当前静态质量门禁。
  • utils/**/openapi 为生成代码,不直接进行零散手工修改。

创新性与社区价值

从产品形态看,RM Extension 把浏览器作为连接 RoboMaster 生态的能力入口:无需要求用户迁移到新的桌面客户端,便可针对官网、论坛和外部协作服务逐步增加功能。飞书迁移与 RMLive 分别验证了“跨平台工作流自动化”和“官网体验增强”两条不同方向,也证明项目结构可以承载更多相互独立的 RM 场景。

以当前最完整的飞书模块为例,RM Extension 的价值不只是“少按几次 Ctrl+C/Ctrl+V”,而是把战队内部知识发布所需的结构转换、资源搬运和目录维护组合成可重复流程。它针对 RoboMaster 论坛编辑器的数据结构处理表格、公式、附件和视频,并能以论坛 Wiki 节点关系重建飞书知识库。

对其他队伍而言,它降低了将内部资料整理为公共开源内容的边际成本:作者可以继续在熟悉的飞书环境协作,再把完成稿迁移到论坛。转换器的 Block 分派、对象复用和目录映射也为“协作文档 → 社区发布平台”类工具提供了可复用实现参考。

114 次论坛引用表明 RM Extension 已在社区内容中形成广泛关联,体现了项目的实际应用价值与传播影响力。

已知限制与 Roadmap

已知限制

  • 多维表格、电子表格、思维笔记、画板、任务、OKR 等复杂 Block 尚未转换为可编辑内容。
  • 用户必须自行创建和授权飞书企业应用,初次配置成本高于只依赖 Cookie 的工具。
  • 大型知识库受飞书接口频率、网络质量、OSS 上传和浏览器 Background 生命周期影响。
  • 取消是协作式取消,不能回滚已完成的论坛写入和对象上传。
  • App Secret 当前保存在扩展本地存储中,安全性取决于浏览器配置和设备环境。

Roadmap

  • 将 RM Search 无缝集成到 RoboMaster 论坛,减少资料检索时的页面切换。
  • 建设常驻浏览器的 RM 工具箱,逐步汇集官网、论坛、赛事与战队协作场景中的高频能力。
  • 优化大型知识库迁移,支持请求限流、节点失败重试、断点恢复和任务记录。
  • 支持电子表格、画板和思维笔记等高优先级飞书 Block。
  • 增加转换前预览及更新前差异检查。

开源协议、贡献与致谢

本项目采用 Apache License 2.0 开源。该许可证允许在保留版权、许可证声明并标明修改的前提下使用、修改和分发项目代码,同时包含明确的专利授权条款。项目名称、标识及第三方依赖不因该许可证自动获得额外授权。

欢迎通过 GitHub Issues 报告问题。请附浏览器与扩展版本、源文档 Block 类型、可复现步骤、预期结果和脱敏后的错误信息;不要提交 App Secret、Access Token、论坛 Cookie 或包含个人资料的文档。

感谢 RoboMaster 社区,以及所有参与反馈和内容开源的 RMer。

华南理工大学机器人未来创新实验室 华南虎战队
软件开发组 & 宣传运营组 出品

项目成员:

  • 产品经理 & 软件开发:常霆钰
  • Logo 设计:杜雨潼
  • 视频制作 & 视频配音:常霆钰
  • 视频封面:杨卓石

特别感谢以下队伍对项目的支持:

  • 合肥工业大学(宣城校区)WDR 战队
  • 东莞理工学院 ACE 战队
  • 东北大学 T-DT 战队
  • 湖南大学跃鹿战队

特别感谢以下个人对项目的帮助:

  • 东莞理工学院 黄煜翔
  • 合肥工业大学 郑雅文
  • 华中科技大学 周晗

About

浏览器里的 RoboMaster 助手,持续扩展 RM 的使用体验与无限可能。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages