# 韫珠IM 这是一个使用 Electron 和 React 构建的仿微信 PC 客户端桌面应用。 ## 📋 项目概述 **项目名称**: 韫珠IM **项目类型**: 基于 Electron 的桌面即时通讯客户端 **技术栈**: Electron + React + TypeScript + Vite ### 核心功能 1. **即时通讯**: 支持文本、图片、视频、文件等多种消息类型 2. **联系人管理**: 联系人列表、详情查看、搜索功能 3. **应用中心**: 内置浏览器窗口,支持多标签页浏览 4. **消息通知**: 系统托盘、任务栏徽章、窗口标题提示 5. **媒体预览**: 独立的图片/视频预览窗口 6. **消息搜索**: 全局搜索和聊天内搜索功能 7. **日志系统**: 完整的本地日志记录功能 8. **自动更新**: 启动与定时检测、后台下载、进度显示、更新说明(releaseNotes)、下载完成后强制重启更新 --- ## 📁 项目结构 ``` local_client/ ├── src/ │ ├── main/ # 主进程代码 │ │ └── index.ts # 窗口管理、IPC通信、系统托盘等 │ ├── preload/ # 预加载脚本 │ │ └── index.ts # 安全地暴露 Electron API 给渲染进程 │ └── renderer/ # 渲染进程(React应用) │ ├── index.html # HTML入口 │ └── src/ │ ├── App.tsx # 主应用组件 │ ├── components/ # React组件 │ │ ├── Login.tsx # 登录组件 │ │ ├── ContactList.tsx # 联系人列表 │ │ ├── ChatWindow/ # 聊天窗口组件 │ │ ├── Navigation.tsx # 导航栏 │ │ └── Modals/ # 模态框组件 │ ├── hooks/ # 自定义Hooks │ │ ├── useAuth.ts # 认证Hook │ │ ├── useContacts.ts # 联系人Hook │ │ ├── useMessages.ts # 消息Hook │ │ └── useWebSocket.ts # WebSocket Hook │ ├── services/ # API和WebSocket服务 │ │ ├── api.ts # REST API调用 │ │ └── websocket.ts # WebSocket连接管理 │ ├── pages/ # 页面组件 │ │ └── ChatPage.tsx # 聊天页面 │ ├── types/ # TypeScript类型定义 │ │ └── index.ts │ └── utils/ # 工具函数 │ ├── logger.ts # 日志工具 │ ├── timeUtils.ts # 时间工具 │ ├── messageUtils.ts # 消息工具 │ └── avatarUtils.tsx # 头像工具 ├── resources/ # 资源文件(logo等) ├── logs/ # 日志文件 ├── out/ # 构建输出目录 ├── package.json # 项目配置 ├── electron.vite.config.ts # Electron-Vite配置 └── tsconfig.json # TypeScript配置 ``` --- ## 🚀 开发指南 ### 环境要求 - Node.js (建议 18+) - npm 或 yarn ### 安装依赖 ```bash npm install ``` ### 开发模式 ```bash npm run dev ``` 这将: - 启动 Electron 开发服务器 - 渲染进程运行在 `http://127.0.0.1:3000` - 支持热重载(HMR) - API 代理:`/api` → `https://api.hnyunzhu.com` ### 开发配置说明 **electron.vite.config.ts**: - 主进程和预加载脚本使用 `externalizeDepsPlugin` - 渲染进程使用 React 插件 - 开发服务器端口:3000 - API 代理配置:`/api` 代理到 `https://api.hnyunzhu.com` **主要开发文件**: - `src/main/index.ts`: 主进程逻辑(窗口、IPC、系统托盘) - `src/renderer/src/App.tsx`: 主应用组件 - `src/renderer/src/services/api.ts`: REST API 调用 - `src/renderer/src/services/websocket.ts`: WebSocket 连接管理 ### 预览构建结果 ```bash npm run preview ``` --- ## 📦 打包指南 ### 构建项目 首先需要构建项目(编译 TypeScript,打包资源): ```bash npm run build ``` 该命令会: - 编译 TypeScript 代码 - 打包主进程代码到 `out/main/` - 打包预加载脚本到 `out/preload/` - 打包渲染进程到 `out/renderer/` ### 生成可执行文件 项目使用 `electron-builder` 进行打包。 #### 仅打包(不生成安装程序) ```bash npm run pack ``` #### 构建并打包(推荐) ```bash npm run dist ``` 这将执行 `build` 和 `pack` 两个步骤,生成完整的安装包。 ### 打包输出 打包完成后,安装包将输出到 `dist/` 目录: - **Windows**: `韫珠IM Setup x.x.x.exe` (NSIS 安装程序) - **macOS**: `韫珠IM-x.x.x.dmg` (DMG 镜像) - **Linux**: `韫珠IM-x.x.x.AppImage` (AppImage 格式) ### 打包配置 打包配置位于 `package.json` 的 `build` 字段: - **appId**: `com.hnyunzhu.im` - **productName**: `韫珠IM` - **输出目录**: `dist/` - **应用图标**: Windows 使用 `resources/icon.ico`,macOS/Linux 使用 `resources/logo.png` - **afterPack**: `scripts/afterPack.js`(通过 rcedit 将图标嵌入 Windows exe) - **Windows**: 生成 NSIS 安装程序,支持自定义安装路径 - **macOS**: 生成 DMG 镜像,支持 x64 和 arm64 架构 - **Linux**: 生成 AppImage 格式 ### 平台特定打包 如果需要为特定平台打包,可以使用环境变量: ```bash # Windows npm run dist -- --win # macOS npm run dist -- --mac # Linux npm run dist -- --linux ``` --- ## 🔄 自动更新 应用使用 `electron-updater` 配合自建更新服务器实现自动更新,仅在生产环境生效(开发模式不检测更新)。 ### 更新策略 - **启动时**:应用启动后自动检测一次更新;若有新版本则自动在后台下载。 - **运行中**:每隔 **5 小时** 自动检测一次更新,有更新则自动下载。 - **手动检测**:在「设置」中可点击「检查更新」随时触发一次检测。 - **下载完成后**:弹出强制更新弹窗,仅提供「立即重启并更新」,必须重启以完成安装;下载过程中在界面顶部显示下载进度条。 ### 配置说明 更新地址在 `package.json` 的 `build.publish` 中配置: ```json "publish": { "provider": "generic", "url": "https://api.hnyunzhu.com:9004/app-updates/1773848909/windows/update/" } ``` 客户端会请求该 URL 下的 `latest.yml` 判断是否有新版本。 ### 发布新版本流程 1. **修改版本号**:在 `package.json` 中将 `version` 改为新版本号(如 `1.0.5`)。 2. **打包**:执行 `npm run dist`,在 `dist/` 目录得到: - `韫珠IM Setup x.x.x.exe`(安装包) - `latest.yml`(更新元数据,electron-updater 据此检测与下载) 3. **(可选)填写更新说明**:编辑 `dist/latest.yml`,在末尾增加 `releaseNotes` 字段,应用会在「有更新」和「下载完成」时展示该内容: ```yaml releaseNotes: | 1. 修复若干问题 2. 新增 xxx 功能 3. 优化性能 ``` 单行可写为:`releaseNotes: "1. 修复若干问题;2. 新增 xxx 功能"` 4. **上传**:将 `dist/latest.yml` 和 `dist/韫珠IM Setup x.x.x.exe`(及同名的 `.exe.blockmap`,若有)上传到上述 `publish.url` 对应目录,保证可通过 `https://api.hnyunzhu.com:9004/app-updates/1773848909/windows/update/latest.yml` 和同目录下的 exe 被访问。 ### 服务端要求 - 需支持 HTTPS(当前为端口 9004)。 - 安装包响应建议带 **Content-Length** 头,否则下载进度可能无法正确显示百分比。 - 无需 CORS(更新请求在主进程内发起)。 ### 用户端表现 - **发现新版本**:顶部出现绿色条「正在下载更新…」及进度条与百分比;可继续使用应用(后台下载)。 - **设置中**:「检查更新」按钮可手动检测;若处于下载中,会显示进度条与更新说明(若 `latest.yml` 中有 `releaseNotes`)。 - **下载完成**:弹出「新版本已下载,请重启以完成更新」弹窗,可展示本次版本的更新说明,仅可点击「立即重启并更新」完成安装。 ### 相关依赖与代码 - **依赖**:`electron-updater`(见 `package.json` 的 `dependencies`)。 - **主进程**:`src/main/index.ts` 中注册 `autoUpdater` 事件、`check-for-updates` IPC、5 小时定时检测及 `quit-and-install`。 - **渲染进程**:`src/renderer/src/App.tsx` 中监听更新事件、展示下载进度与强制更新弹窗;`src/renderer/src/components/Modals/SettingsModal.tsx` 中「检查更新」按钮与状态展示。 --- ## 🏗️ 技术架构 ### 进程架构 1. **主进程** (`src/main/index.ts`) - 窗口管理(主窗口、浏览器窗口、预览窗口) - 系统托盘和通知 - IPC 通信处理 - 文件系统操作 - 日志管理 2. **渲染进程** (`src/renderer/`) - React 应用 - UI 渲染和用户交互 - 业务逻辑处理 3. **预加载脚本** (`src/preload/index.ts`) - 安全桥接主进程和渲染进程 - 暴露 Electron API 给渲染进程 ### 通信方式 - **IPC (Inter-Process Communication)**: 主进程与渲染进程通信 - **WebSocket**: 实时消息推送 - **REST API**: HTTP 请求(通过 Vite 代理) ### 关键依赖 - `electron`: ^28.0.0 - Electron 框架 - `electron-vite`: ^2.0.0 - Electron + Vite 构建工具 - `react`: ^18.2.0 - React UI 框架 - `typescript`: ^5.0.2 - TypeScript 语言 - `vite`: ^5.0.0 - 构建工具 - `crypto-js`: ^4.2.0 - 加密库(用于签名认证) - `electron-builder`: ^26.8.1 - 打包工具 --- ## 🔑 关键代码说明 ### 应用中心实现原理 在 `src/main/index.ts` 中: ```typescript mainWindow.webContents.setWindowOpenHandler((details) => { // 拦截所有 http/https 链接 if (details.url.startsWith('http')) { createInternalBrowserWindow(details.url) return { action: 'deny' } // 阻止默认行为 } return { action: 'allow' } }) ``` 在 `src/renderer/src/App.tsx` 中: 链接必须带有 `target="_blank"` 属性才能触发上述拦截。 ```tsx ... ``` ### 窗口管理 项目支持多种窗口类型: - **主窗口**: 聊天主界面 - **浏览器窗口**: 应用中心,支持多标签页(使用 BrowserView) - **预览窗口**: 图片/视频预览窗口 ### WebSocket 连接 WebSocket 服务位于 `src/renderer/src/services/websocket.ts`,支持: - 自动重连机制 - 心跳保活(ping/pong) - 消息推送处理 --- ## ⚠️ 注意事项 1. **API 配置**: - 开发环境通过 Vite 代理访问 API - 生产环境需要直接连接 `https://api.hnyunzhu.com` 2. **日志文件**: - 存储在 `logs/` 目录 - 按日期命名(如 `2026-02-26.log`) 3. **资源文件**: - `app_icon.png` 用于应用图标(已配置) - `resources/logo.png` 用于其他资源 - **图标要求**: 图标文件必须至少为 256x256 像素,当前使用的 `app_icon.png` 已满足要求 4. **窗口管理**: - 支持主窗口、浏览器窗口、预览窗口等多种窗口类型 - 使用 BrowserView 实现多标签页功能 5. **安全设置**: - 使用 `contextIsolation` 和 `sandbox` 模式确保安全性 - 通过预加载脚本安全地暴露 API 6. **打包注意事项**: - 首次打包会下载对应平台的 Electron 二进制文件,可能需要一些时间 - 确保有足够的磁盘空间(至少 500MB) - Windows 打包需要安装 NSIS(electron-builder 会自动处理) - **图标问题**: 如果遇到 `image must be at least 256x256` 错误,说明图标尺寸不够,需要准备至少 256x256 像素的图标文件,或暂时移除图标配置 - **代码签名问题**: Windows 打包时如果遇到符号链接权限错误,这是因为 electron-builder 尝试下载代码签名工具(`winCodeSign`),其压缩包中包含 macOS 符号链接文件,在非管理员模式下解压会失败。当前配置已通过 `forceCodeSigning: false`、`signAndEditExecutable: false` 和环境变量禁用代码签名。 - **备选方案**: 如果 NSIS 安装程序打包失败,可以: 1. 使用 `npm run dist:portable` 生成便携版(不需要签名) 2. 直接使用 `dist/win-unpacked/韫珠IM.exe` 运行应用 3. 以管理员权限运行 PowerShell 后再打包(解决符号链接权限问题) 7. **Windows exe 图标嵌入机制**: - `signAndEditExecutable: false` 会导致 electron-builder 跳过图标嵌入步骤,exe 文件和任务栏将无法显示自定义图标 - 项目通过 `afterPack` 钩子 (`scripts/afterPack.js`) 使用 `rcedit` 手动将 `resources/icon.ico` 嵌入到 exe 中,绕过了 `winCodeSign` 的下载问题 - **不要删除** `scripts/afterPack.js` 文件和 `rcedit` 依赖,否则打包后 exe 和任务栏将没有图标 - 更换图标时,替换 `resources/icon.ico` 即可。ico 文件建议包含多尺寸(16x16、32x32、48x48、256x256),Windows 在不同场景使用不同尺寸: - 16x16:任务栏、窗口标题栏 - 32x32:桌面快捷方式(小图标) - 48x48:资源管理器 - 256x256:资源管理器大图标视图 - 托盘图标由 `src/main/index.ts` 中的 `Tray` 在运行时从文件加载,不依赖 exe 嵌入 - 安装程序图标由 NSIS 单独处理,不受 `signAndEditExecutable` 影响 --- ## 📝 开发脚本说明 - `npm run dev`: 启动开发服务器 - `npm run build`: 构建项目(编译 TypeScript,打包资源) - `npm run preview`: 预览构建结果 - `npm run pack`: 仅打包(不重新构建) - `npm run dist`: 构建并打包 NSIS 安装程序(推荐用于生产环境) - `npm run dist:portable`: 构建并打包便携版(单 exe,无需安装) --- ## 📄 许可证 MIT