Chapter 53
用 Electron 做一个企业语音记录工具
用 Electron 做一个企业语音记录工具
这一篇做一个能在 Windows、macOS 和 Linux 运行的桌面应用:Field Voice Log。
用户录一段现场说明,应用生成文字,再整理成问题、处理过程、风险和后续动作。企业里类似的软件会用在维修工单、保险查勘、物业巡检、客户拜访和护理记录中。

我们先用演示文本跑通桌面界面,再接麦克风和识别服务,最后制作安装包。共享密钥不会写进桌面客户端。
1. Electron 的三个部分
Electron 把网页界面和桌面系统能力放在同一个应用中,但两者不能随便混在一起。

- Main Process 管理窗口、文件和应用生命周期;
- Renderer Process 显示页面,不直接开放 Node.js;
- Preload 只暴露页面真正需要的少量能力。

录音按钮在页面里,保存临时文件和调用本地模型放在主进程里,中间通过 Preload 传递有限的数据。
2. 创建项目
确认电脑已经安装当前 LTS 版本的 Node.js,然后新建空目录,用 AI 工具打开:
请在当前目录创建 Electron Forge 项目,使用 Vite 模板。先保留默认窗口,完成后告诉我怎样启动。
依赖安装完成后运行项目。看到 Electron 默认窗口,并且终端没有红色错误,说明基础环境正常。

如果启动失败:
Electron 启动失败,错误是【粘贴错误】。请只修复启动问题,不增加业务功能。
3. 先做静态界面
请把当前窗口改成 Field Voice Log。页面包含录音按钮、录音时长、原始文字、结构化报告和保存状态,先用演示文本,不接麦克风。
这一轮只看布局。窗口缩窄以后,按钮和文字不能重叠;空白状态要告诉用户下一步做什么。

如果界面太复杂:
请简化首页,只保留录音、原始文字和结构化报告三个区域,保持现有配色。
4. 接入麦克风
录音由 Renderer 里的 getUserMedia 和 MediaRecorder 完成。不要让页面直接访问文件系统。
请给录音按钮接入麦克风。开始后显示时长和录音状态,停止后把音频交给 Preload,不要在 Renderer 开启 Node 集成。

第一次点击时,系统会询问麦克风权限。拒绝后应用应显示“没有麦克风权限”,不能一直停在加载中。
验证四种情况:
- 允许权限后可以开始和停止。
- 拒绝权限后能再次说明如何开启。
- 连续点击不会同时创建两段录音。
- 关闭窗口时会释放麦克风。
遇到问题时:
麦克风操作失败,系统是【系统】,错误是【错误】。请只修复权限或录音状态问题。
5. 先跑通假的识别结果
真实模型会增加网络、格式和模型依赖。先让主进程收到音频后返回一段固定文本:
请增加演示识别模式。主进程收到音频后返回一段固定的现场记录,让我先验证 IPC、加载状态和报告页面。

成功时,停止录音后先显示“处理中”,随后出现演示文字;快速开始第二次录音时,第一次结果不能覆盖新任务。
6. 选择识别方式
演示链路稳定后,再选本地识别或企业后端。第一版不要两条同时做。
6.1 本地 whisper.cpp
本地模式适合离线和隐私要求高的场景,但需要下载模型,也要处理不同操作系统的原生依赖。
请把演示识别替换为本地 whisper.cpp。录音先转成 16 kHz、单声道 PCM WAV,再交给模型;失败时保留原音频和错误提示。

先用小模型验证流程,再根据电脑性能选择更大的模型。模型大小、速度和硬件加速会随绑定库变化,不要把某个速度写成固定承诺。
验证时关闭网络,再录一段十秒中文:能生成文字、临时目录会清理、应用重启后没有残留录音,才算通过。
6.2 企业识别后端
企业版本应由受控后端调用云端转写服务。桌面应用只拿短期登录凭证,不保存组织共享密钥。
请把音频发送到企业后端完成转写。客户端不保存模型密钥,要有上传进度、取消、超时和重试。

不要把 API Key 放在 Renderer、localStorage、配置页或打包产物里。即使放在主进程,桌面安装包仍然能被用户读取;组织共享密钥必须留在服务器。
7. 生成结构化报告
转写稳定后,再把文字整理成业务字段:
请把转写结果整理成问题、处理过程、使用物料、风险和后续动作。保留原始文字,任何字段都允许人工修改。
模型整理结果不能直接覆盖真实工单。保存前让用户确认,并记录谁修改了哪些字段。
设置页只保存语言、识别方式和下载目录等非敏感选项。

8. 调试时看三个地方
- Renderer 错误:打开窗口开发者工具;
- Main Process 错误:看启动 Electron 的终端;
- IPC 问题:给每次录音生成请求编号,两边日志都记录编号。
日志可以记录状态、耗时和错误码,不能记录完整音频、报告正文、Token 和联系方式。
录音请求编号【编号】一直处理中。Renderer 日志是【内容】,主进程日志是【内容】。请只找出没有返回的原因。
9. 完整验收
- 允许和拒绝麦克风权限各测试一次。
- 连续录两段,确认结果不会串任务。
- 本地模式下断网测试,或企业模式下测试取消与超时。
- 修改结构化字段,确认原始文字没有被覆盖。
- 重启应用,确认非敏感设置还在。
- 检查日志中没有音频、密钥和完整业务正文。
一项失败时:
验收第【几】步失败,现象是【描述】。请只修复这一项,不改已经通过的功能。
10. 打包
先确认 Forge 配置里存在当前系统需要的 Maker,再执行:
npm run makeForge 只会生成已经配置、并且当前操作系统支持的格式。一次命令不会自动在任意电脑上同时生成所有平台安装包。

拿生成物到一台没有 Node.js、没有项目源码的干净电脑测试:
- 能否安装和启动;
- 麦克风权限是否正常;
- 模型或后端不可用时是否有提示;
- 卸载后是否留下敏感临时文件。
macOS 面向外部用户分发时需要签名和公证;Windows 正式分发也建议代码签名。能生成安装文件,不等于已经可以公开发布。
11. 最后检查
- Renderer 没有开启 Node 集成;
- Preload 只暴露有限方法;
- 麦克风拒绝、录音中、处理中、成功和失败状态齐全;
- 音频经过真实转码,而不是只改扩展名;
- 共享密钥不在客户端;
- 用户能修改并确认结构化结果;
- 安装包在干净电脑上通过测试。
