LRAgent 桌面客户端

LRAgent 桌面客户端

LRAgent 桌面客户端基于 Electron v28 构建,在网页版基础上扩展了丰富的本地系统能力。

与网页版的区别

功能网页版桌面端
系统托盘常驻-
全局快捷键唤起-✅ Ctrl+Shift+L
拖拽文件导入-
离线数据缓存-
本地文件系统读写-
原生文件对话框-
导出为PDF-
Windows原生通知-
自动检查更新-
系统信息查看-
剪贴板图片读写-
窗口最小化到托盘-
NSIS安装包分发-

快速启动

开发模式

cd C:\bossagents
npm run electron:dev

此命令会自动:

  1. 检测 Vite 开发服务器是否在 5173 端口运行
  2. 如未运行则自动启动 Vite
  3. 清除 ELECTRON_RUN_AS_NODE 环境变量(关键步骤)
  4. 启动 Electron 桌面窗口

生产模式(安装包)

npm run electron:build

生成的安装包位于 release/LRAgent-Setup-{version}-win-x64.exe

仅预览(不打包)

npm run electron:preview

快捷键

| 快捷键 | 功能 |

|--------|------|

| Ctrl+Shift+L | 显示/隐藏主窗口 |

| Ctrl+Shift+N | 快速创建 Part |

| Ctrl+Shift+I | 数据质量检查 |

| Ctrl+O | 导入文件 |

| Ctrl+S | 导出文件 |

| Ctrl+F | 查找 Part |

| F11 | 全屏切换 |

系统托盘

最小化窗口后,LRAgent 会缩小到系统托盘区域:

  • 单击托盘图标:显示右键菜单
  • 双击托盘图标:恢复主窗口
  • 托盘菜单包含:显示窗口、快速创建Part、数据质量检查、离线模式切换、关于、退出

离线模式

桌面端支持离线数据缓存:

  • 前端通过 window.lragent.offlineCacheSave(key, data) 保存数据
  • 通过 window.lragent.offlineCacheLoad(key) 读取缓存
  • 通过 window.lragent.offlineCacheList() 列出所有缓存条目
  • 缓存存储在 %APPDATA%/lragent/offline-cache/ 目录
  • 菜单「工具 → 清除缓存」可一键清空

前端 API

桌面端通过 window.lragent 对象暴露以下 API(仅在桌面端可用):

文件系统

// 判断是否在桌面端
if (window.lragent?.isDesktop) {
  // 读取文本文件
  const result = await window.lragent.readFile('/path/to/file.json')
  
  // 写入文件
  await window.lragent.writeFile('/path/to/output.json', JSON.stringify(data))
  
  // 读取二进制文件(返回 base64)
  const binary = await window.lragent.readBinaryFile('/path/to/image.png')
  
  // 检查文件是否存在
  const exists = await window.lragent.fileExists('/path/to/file')
  
  // 获取文件信息
  const stat = await window.lragent.fileStat('/path/to/file')
  
  // 列出目录内容
  const dir = await window.lragent.listDir('/path/to/dir')
  
  // 创建目录
  await window.lragent.mkdir('/path/to/new/dir')
  
  // 删除文件
  await window.lragent.deleteFile('/path/to/file')
  
  // 原生文件选择对话框
  const { filePaths } = await window.lragent.selectOpenFile({
    filters: [{ name: 'Excel', extensions: ['xlsx', 'xls'] }]
  })
  
  // 保存文件对话框
  const { filePath } = await window.lragent.selectSaveFile({
    filters: [{ name: 'JSON', extensions: ['json'] }]
  })
  
  // 选择目录
  const { filePath: dirPath } = await window.lragent.selectDirectory()
}

剪贴板

const text = await window.lragent.readClipboardText()
await window.lragent.writeClipboardText('复制内容')
const imageDataURL = await window.lragent.readClipboardImage() // 返回 data:image/png;base64,... 或 null

系统信息

const info = await window.lragent.getSystemInfo()
// 返回: { platform, arch, cpuModel, cpuCores, totalMemGB, freeMemGB, uptime, hostname, electronVer, chromeVer, nodeVer }

通知

await window.lragent.sendNotification('LRAgent', 'Part 创建成功')

窗口控制

await window.lragent.windowMinimize()
await window.lragent.windowMaximize()  // 切换最大化
await window.lragent.windowClose()
await window.lragent.windowSetTitle('LRAgent - Part 详情')

离线缓存

await window.lragent.offlineCacheSave('parts-list', partsData)
const cached = await window.lragent.offlineCacheLoad('parts-list')
const allKeys = await window.lragent.offlineCacheList()

事件监听

// 文件拖拽到窗口
window.lragent.onFilesDropped((filePaths) => {
  console.log('拖入文件:', filePaths)
})

// 菜单导入文件
window.lragent.onFilesImported((filePaths) => {
  console.log('导入文件:', filePaths)
})

// 菜单导入目录
window.lragent.onDirectoryImported((dirPath) => {
  console.log('导入目录:', dirPath)
})

// 快捷操作(托盘菜单/全局快捷键触发)
window.lragent.onQuickAction((action) => {
  // action: 'create-part' | 'inspect-quality' | 'change-impact' | 'search' | 'local-db'
  if (action === 'create-part') openCreatePartDialog()
  if (action === 'inspect-quality') runQualityInspection()
})

// 离线模式切换
window.lragent.onOfflineMode((enabled) => {
  console.log('离线模式:', enabled ? '开启' : '关闭')
})

// 缓存已清除
window.lragent.onCacheCleared(() => {
  console.log('缓存已清除')
})

// 导出完成
window.lragent.onExportComplete((info) => {
  console.log('导出完成:', info.type, info.path)
})

其他

const version = await window.lragent.getAppVersion()       // '0.1.0'
const dataPath = await window.lragent.getAppPath('userData') // 用户数据目录
const locale = await window.lragent.getAppLocale()          // 'zh-CN'
await window.lragent.openExternal('https://eastaiai.com')   // 打开外部链接
await window.lragent.openPath('C:\\Users\\...')             // 用系统程序打开
await window.lragent.showItemInFolder('C:\\file.txt')       // 在资源管理器中显示
await window.lragent.checkForUpdates()                      // 检查GitHub更新

目录结构

C:\bossagents\
├── electron/              # Electron 启动脚本
│   ├── run.js             # 启动器(自动管理Vite + ELECTRON_RUN_AS_NODE)
│   ├── main.js            # 主进程(备用,与electron-app/main.js同步)
│   └── preload.js         # 预加载脚本(备用)
├── electron-app/          # 独立Electron应用目录
│   ├── package.json       # 独立package.json(避免node_modules干扰)
│   ├── main.js            # 主进程(窗口、托盘、快捷键、IPC)
│   ├── preload.js         # 安全桥接层(contextBridge API)
│   └── installer.nsh      # NSIS自定义安装脚本
├── electron-builder.yml   # 打包配置
├── dist/                  # Vite构建产物(打包时包含)
└── release/               # 安装包输出目录
    └── LRAgent-Setup-0.1.0-win-x64.exe

打包配置

electron-builder.yml 支持:

  • Windows: NSIS 安装包(支持自定义安装路径、中文界面、桌面快捷方式)
  • macOS: DMG 镜像(x64 + arm64)
  • Linux: AppImage + deb
  • 自动更新: GitHub Release 发布后自动检测

故障排查

1. ELECTRON_RUN_AS_NODE 导致启动失败

症状: TypeError: Cannot read properties of undefined (reading 'handle')

原因: npm/pnpm 在执行脚本时设置 ELECTRON_RUN_AS_NODE=1,导致 Electron 以普通 Node.js 模式运行。

解决: electron/run.js 已自动处理此问题。如手动启动需确保:

$env:ELECTRON_RUN_AS_NODE=''
& "node_modules\electron\dist\electron.exe" "electron-app" --dev

2. Vite 未启动导致白屏

症状: 窗口打开但显示 ERR_CONNECTION_REFUSED

解决: 先启动 Vite 再启动 Electron,或使用 npm run electron:dev(自动管理)

3. Electron v43 不兼容

原因: Electron v43 要求 ESM 导入(import from 'electron/main'),与 CJS 项目不兼容。

解决: 当前使用 Electron v28 LTS(CJS 兼容),package.json 已锁定版本。

4. 安装包缺少图标

现状: 使用 Electron 默认图标。如需自定义,将 icon.ico 放入 electron-app/ 目录,并在 electron-builder.yml 中配置 win.icon

5. better-sqlite3 原生模块重建失败

原因: electron-builder 默认会 rebuild 原生模块,需要 Python + Visual Studio Build Tools。

解决: 打包时加 --config.npmRebuild=false 跳过重建:

npx electron-builder --win --x64 --config.npmRebuild=false

版本历史

  • v0.1.0 (2026-08-16)
  • 初始桌面客户端
  • 系统托盘 + 全局快捷键
  • 拖拽文件导入
  • 离线数据缓存
  • 本地文件系统 API
  • NSIS 安装包
  • 自动更新检测
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁