第 10 章:综合项目:RPA 桌面助手
本章将综合运用前面所有章节的知识,从零构建一个模仿影刀 RPA 的桌面自动化助手。 项目包含可视化流程编辑器、操作录制与回放、数据管理等核心功能,是一个完整的生产级 Electron 应用。
10.1 项目需求分析
影刀 RPA 是一款流行的桌面自动化工具,核心功能包括:可视化流程编排、鼠标键盘录制、 自动化任务执行、数据表格管理等。我们将实现一个简化但功能完整的版本。
功能清单
| 模块 | 功能 | 技术点 |
|---|---|---|
| 流程编辑器 | 拖拽式节点编排 | Vue3 + 自定义拖拽 |
| 操作录制 | 记录鼠标/键盘操作 | @nut-tree/nut.js |
| 任务回放 | 执行录制的操作序列 | IPC + 工作线程 |
| 数据管理 | 变量、数据表格 | Pinia + SQLite |
| 截图识别 | 屏幕截图 + OCR | desktopCapturer + Tesseract |
| 任务调度 | 定时执行、循环执行 | Node.js 定时器 |
10.2 架构设计
好的架构是项目成功的一半。我们采用分层设计,将核心自动化逻辑放在主进程,UI 层放在渲染进程。
┌─────────────────────────────────────────────────────────┐
│ RPA Desktop Assistant │
├─────────────────────────────────────────────────────────┤
│ 渲染进程 (Renderer) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 流程编辑器 │ │ 任务列表 │ │ 数据表格 │ │
│ │ (Vue3) │ │ (Vue3) │ │ (Vue3) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
│ └─────────────────┼─────────────────┘ │
│ │ │
│ ┌────────────────────────┴────────────────────────┐ │
│ │ IPC (contextBridge) │ │
│ └────────────────────────┬────────────────────────┘ │
├───────────────────────────┼─────────────────────────────┤
│ 主进程 (Main) │ │
│ ┌────────────────────────┴────────────────────────┐ │
│ │ 自动化引擎 (Automation Engine) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 录制器 │ │ 执行器 │ │ 调度器 │ │ │
│ │ │ Recorder │ │ Executor │ │ Scheduler│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 数据层 (Data Layer) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ electron-│ │ SQLite │ │ 文件系统 │ │ │
│ │ │ store │ │ │ │ │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
10.3 项目初始化
使用 electron-vite 创建项目,并安装必要的依赖。
# 创建项目
npm create electron-vite@latest rpa-assistant --template vue-ts
# 进入项目目录
cd rpa-assistant
# 安装核心依赖
npm install @nut-tree/nut-js tesseract.js electron-store pinia vue-router element-plus
# 安装开发依赖
npm install -D @types/node electron-builder electron-updater
# 安装 Sentry(可选)
npm install @sentry/electron
10.4 核心模块实现
自动化引擎(主进程)
// main/automation/engine.js
const { mouse, keyboard, screen, clipboard } = require('@nut-tree/nut-js');
const { ipcMain } = require('electron');
class AutomationEngine {
constructor() {
this.isRecording = false;
this.isPlaying = false;
this.actions = [];
this.setupIPC();
}
setupIPC() {
// 开始录制
ipcMain.handle('automation:start-record', () => {
this.startRecording();
return { success: true };
});
// 停止录制
ipcMain.handle('automation:stop-record', () => {
const actions = this.stopRecording();
return { success: true, actions };
});
// 执行流程
ipcMain.handle('automation:execute', async (event, actions) => {
try {
await this.executeActions(actions, (progress) => {
event.sender.send('automation:progress', progress);
});
return { success: true };
} catch (error) {
return { success: false, error: error.message };
}
});
}
startRecording() {
this.isRecording = true;
this.actions = [];
// 监听鼠标移动
mouse.config.mouseSpeed = 500;
// 记录初始状态
this.recordAction({
type: 'start',
timestamp: Date.now()
});
}
stopRecording() {
this.isRecording = false;
return this.actions;
}
recordAction(action) {
if (this.isRecording) {
this.actions.push(action);
}
}
// 执行操作序列
async executeActions(actions, onProgress) {
this.isPlaying = true;
const total = actions.length;
for (let i = 0; i < actions.length; i++) {
if (!this.isPlaying) break;
const action = actions[i];
await this.executeAction(action);
onProgress?.({
current: i + 1,
total,
percent: Math.round(((i + 1) / total) * 100)
});
}
this.isPlaying = false;
}
async executeAction(action) {
switch (action.type) {
case 'mouse-move':
await mouse.move({ x: action.x, y: action.y });
break;
case 'mouse-click':
await mouse.click();
break;
case 'mouse-double-click':
await mouse.doubleClick();
break;
case 'mouse-right-click':
await mouse.rightClick();
break;
case 'key-press':
await keyboard.type(action.key);
break;
case 'key-combination':
await keyboard.type(action.keys);
break;
case 'wait':
await new Promise(resolve => setTimeout(resolve, action.duration));
break;
case 'clipboard-set':
await clipboard.copy(action.text);
break;
case 'screenshot':
const screenshot = await screen.capture();
// 保存截图...
break;
}
}
stopExecution() {
this.isPlaying = false;
}
}
module.exports = { AutomationEngine };
可视化流程编辑器(Vue3)
{{ node.name }}
位置: ({{ node.data.x }}, {{ node.data.y }})
输入: {{ node.data.text }}
等待: {{ node.data.duration }}ms
节点属性
10.5 Preload 脚本配置
为项目配置完整的 Preload 脚本,暴露所有需要的 API。
// preload/index.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronAPI', {
// ===== 自动化 API =====
automation: {
startRecord: () => ipcRenderer.invoke('automation:start-record'),
stopRecord: () => ipcRenderer.invoke('automation:stop-record'),
execute: (actions) => ipcRenderer.invoke('automation:execute', actions),
onProgress: (callback) => ipcRenderer.on('automation:progress', callback),
offProgress: (callback) => ipcRenderer.removeListener('automation:progress', callback)
},
// ===== 文件 API =====
file: {
open: (options) => ipcRenderer.invoke('dialog:openFile', options),
save: (options, content) => ipcRenderer.invoke('dialog:saveFile', options, content),
read: (path) => ipcRenderer.invoke('file:read', path)
},
// ===== 屏幕 API =====
screen: {
capture: () => ipcRenderer.invoke('screen:capture'),
getSize: () => ipcRenderer.invoke('screen:getSize')
},
// ===== 系统 API =====
system: {
getVersion: () => ipcRenderer.invoke('app:getVersion'),
getPlatform: () => process.platform
},
// ===== 更新 API =====
update: {
check: () => ipcRenderer.invoke('update:check'),
install: () => ipcRenderer.invoke('update:install'),
onAvailable: (callback) => ipcRenderer.on('update-available', callback),
onProgress: (callback) => ipcRenderer.on('update-progress', callback)
}
});
10.6 打包与发布
完成开发后,使用 electron-builder 打包应用并发布。
# electron-builder.yml
appId: com.yourcompany.rpa-assistant
productName: "RPA Desktop Assistant"
directories:
output: release
buildResources: build
files:
- "out/**/*"
- "node_modules/**/*"
- "package.json"
asarUnpack:
- "node_modules/@nut-tree/**/*"
- "node_modules/tesseract.js/**/*"
win:
target:
- nsis
icon: build/icon.ico
mac:
target:
- dmg
icon: build/icon.icns
category: public.app-category.productivity
publish:
provider: github
owner: your-username
repo: rpa-assistant
10.7 项目总结
通过这个综合项目,我们实践了 Electron 桌面应用开发的完整流程:
-
环境搭建
使用 electron-vite 快速搭建 Vue3 + Electron 工程化项目
-
核心功能
实现了录制、回放、可视化编辑等 RPA 核心功能
-
系统交互
使用 @nut-tree/nut-js 实现鼠标键盘控制,使用 desktopCapturer 实现截图
-
数据管理
使用 Pinia 管理应用状态,使用 electron-store 持久化配置
-
打包发布
使用 electron-builder 打包为 Windows 和 macOS 安装包
你已经完成了 Electron 桌面应用开发的系统学习!从前端开发者到桌面应用工程师, 你现在具备了构建跨平台桌面应用的完整能力。继续深入某个方向(如更复杂的自动化、 AI 集成、企业级功能),或者开始你的下一个项目吧!