# 项目概览 - 本项目使用 Vite + React 19 + TypeScript + Electron 重构现有 Python Qt 桌面应用,打造跨平台(Windows/macOS)的多窗口桌面程序。 - 核心界面为单页应用(SPA),同时支持通过 Electron 打开独立窗口以承载子功能。 # 核心需求 - 完整还原原有 Qt 应用的业务逻辑与视觉体验,并对交互进行现代化改造。 - 必须支持 多窗口(主窗口 + 可动态创建的辅助窗口),窗口间需通过事件/消息进行低耦合通信。 - 适配 Windows 与 macOS,处理好快捷键、托盘、菜单、窗口边框等平台差异。 - 采用 离线优先 架构,保障本地数据处理性能,合理使用本地存储(如 electron-store 或 SQLite)。 - 所有对系统底层能力的调用必须通过 Electron 主进程,严禁在渲染进程直接使用 Node.js API(除非通过 preload 安全暴露)。 # 技术架构 ## 整体分层 - 主进程(Main Process):Electron 主进程,管理窗口生命周期、系统菜单、托盘、IPC 事件调度、本地文件/数据库操作。 - 预加载脚本(Preload):桥接渲染进程与主进程,使用 contextBridge 安全暴露有限 API。 - 渲染进程(Renderer):基于 React 19 的 SPA(主窗口)与独立窗口的 React 入口,负责 UI 展示与用户交互。 - 共享层(Shared):进程间共享的 TypeScript 类型、常量、工具函数、事件名称枚举。 ## 前端架构原则 - 组件化:以函数组件 + Hooks 为唯一组件形式,UI 拆分为展示组件与容器组件。 - 单向数据流:全局状态使用 Context + Provider 模式(AppContext / ThemeContext / SettingsContext), 遵循 Provider → Context → Comsumer 单向流动。组件内部状态使用 useState/useReducer,不污染全局 Context。 - 事件驱动(EDA): 1. 主进程与渲染进程通信基于 Electron IPC(ipcMain/ipcRenderer),定义明确的事件通道与载荷类型。 2. 渲染进程内跨组件通信优先使用 Context;需要解耦的场景使用自定义事件总线(src/utils/event-bus.ts), 所有 emit 调用自动记录到日志文件用于审计追踪。 3. 自定义错误体系(RequestError / RefreshError)通过事件总线解耦:请求拦截器抛出自定义错误 → 全局捕获 → emit 事件 → UI 层响应。 4. 窗口间通信统一通过主进程转发(或使用 MessagePort 等 Electron 支持的机制),保持窗口独立性。 - 路由与导航:主窗口为 单页应用,使用 React Router v7+ 管理页面切换,支持嵌套路由。 - 辅助窗口(设置、预览、导入导出等)为独立 BrowserWindow,加载独立的 HTML 入口(可根据路由参数或 windowId 决定内部路由),不与主窗口共享 DOM。 # 目录结构 ```md ├── electron/ # Electron 主进程 │ ├── main.ts # 入口:窗口创建 / IPC 注册 / 生命周期 │ ├── preload.ts # 预加载脚本(contextBridge) │ └── main/ │ ├── updater.ts # 自定义更新(API 版本检查 + OSS 下载 + NSIS 安装) │ ├── logger.ts # 主进程日志核心(JSON Lines 写入 / 轮转 / 清理) │ ├── log-ipc.ts # 渲染进程日志 IPC 通道接收 │ ├── net-request.ts # Electron net.request 的 axios 风格封装 │ ├── menu/index.ts # 系统菜单 │ └── utils/ # 平台判断 / 图标路径 ├── src/ # 渲染进程(React 19 SPA) │ ├── main.tsx # React 挂载点 + 全局错误捕获 │ ├── App.tsx # 根组件(路由 + 登录弹窗) │ ├── components/ # 通用 UI 组件 + Provider │ │ ├── AppProvider.tsx # 全局状态(platform / edition / login) │ │ ├── ThemeProvider.tsx # 主题状态(light / dark) │ │ ├── SettingsProvider.tsx # 设置状态(存储路径等) │ │ ├── Layout.tsx # 页面壳(NavBar + Outlet) │ │ └── navbar/ # 导航栏 + 公告抽屉 │ ├── contexts/ # Context 定义(app / settings / theme) │ ├── hooks/ # 自定义 Hooks(useUpdater / useTheme) │ ├── pages/ # 页面组件 │ │ ├── home/ # 首页仪表盘 │ │ ├── login/ # 登录 / 注册页 │ │ └── settings/ # 设置面板(主题 / 存储 / 更新) │ ├── router/index.tsx # HashRouter 路由配置 │ ├── services/ # HTTP 请求封装 │ │ ├── request.ts # Axios 封装 + 拦截器 + Token 刷新 │ │ ├── types.ts # 自定义错误类型(RequestError / RefreshError) │ │ ├── auth-token.ts # refresh_token 管理 │ │ └── modules/ # API 模块(auth / announcement) │ ├── theme/ # 主题系统 │ │ ├── tokens.ts # 设计令牌 │ │ └── globals.css # Tailwind + 全局样式 │ └── utils/ # 纯函数工具 │ ├── event-bus.ts # 事件总线(on / off / emit + 日志钩子) │ ├── logger.ts # 渲染进程日志器(IPC 转发 / DEV 控制台) │ ├── ipc.ts # 安全 IPC 守卫(safeIpcOn / send / invoke) │ ├── platform.ts # 平台判定 │ └── device.ts # 设备 ID 生成 ├── shared/ # 主进程 & 渲染进程共享 │ ├── types/ # 类型定义(API / IPC / update / logging) │ ├── constants/ # 常量(IPC 通道 / version / app) │ └── utils/ # 共享工具 │ ├── index.ts # debounce / throttle / compareVersions │ └── sanitize.ts # 日志脱敏工具(ID / 邮箱 / 手机 / 名称) ├── scripts/ # 构建脚本 │ ├── build.mjs # 构建总管 │ ├── clean.mjs # 清理产物 │ ├── upload-oss.mjs # OSS 上传 │ ├── publish-release.mjs # 发布到 API │ └── generate-update-info.mjs # 生成更新元信息 ├── package.json # 含 electron-builder 打包配置 ├── vite.config.ts ├── tsconfig.json └── tailwind.config.ts ``` # 多窗口与平台判定 - windowManager.ts 负责统一创建 BrowserWindow,根据环境变量/参数加载不同入口(如 src/main/index.html 或 src/sub/settings/index.html)。 - src/utils/platform.ts 提供 isMacOS、isWindows 等函数(基于 navigator.userAgent 或 preload 暴露的 process.platform)。在主进程的 electron/main/utils/platform.ts 中直接使用 Node.js API。 - 打包配置 (package.json build 字段) 须针对平台设置不同的图标、签名策略、安装包格式。 # 代码风格 ## TypeScript - 所有语句必须以分号 ; 结尾,缺失分号将被视为错误。 - 启用 strict 模式,禁止隐式 any,优先使用 interface 定义对象类型,复杂类型可适度使用 type。 - 文件名使用小写短横线连接(kebab-case),如 use-window-state.ts;组件文件名与组件名保持一致(PascalCase),如 ThemeAdapter.tsx。 - 导入顺序:第三方库 → 项目内共享模块 → 相对路径模块,中间用空行分隔。 ## React - 只允许函数组件与 Hooks,禁止使用类组件。 - 每个组件必须有明确的 Props 类型,使用 React.FC 或直接标注函数参数类型(推荐直接标注)。 - 事件处理函数命名以 handle 开头(如 handleClick),自定义 Hook 以 use 开头。 - 避免直接操作 DOM,除非封装在自定义 Hook 中(如焦点管理)。 - 使用 React.memo、useMemo、useCallback 优化性能,但不要过早优化。 ## 状态管理 - 使用 React Context + Provider 模式管理全局状态,按领域拆分:AppContext(平台/登录)、ThemeContext(主题)、 SettingsContext(设置项)。避免引入 Redux 等重量级方案。 - Provider 组件在 main.tsx 中按层级嵌套挂载: AppProvider → ThemeProvider → SettingsProvider → AntdApp → App - 各模块通过自定义 Hook 消费(useAppContext / useTheme / useSettings),Hook 内部做 null 检查。 ## 日志系统 - 双端日志:主进程直接写文件(electron/main/logger.ts),渲染进程通过 IPC send 上报(src/utils/logger.ts)。 两端暴露一致的 API:`logger.debug / info / warn / error(category, message, error?, context?)`。 - 文件存储:JSON Lines 格式(每行一个 JSON),路径 `{userData}/logs/app-YYYY-MM-DD.log`, 每日轮转 + 7 天自动清理。 - 事件总线联动:event-bus.ts 暴露 `setEventLogListener` 钩子,logger 注册后所有 emit 自动记录 DEBUG 日志。 - 错误日志:request.ts 拦截器根据错误类型自动分级记录(AUTH_EXPIRED → debug,5xx → error,其余 → warn)。 - 脱敏:shared/utils/sanitize.ts 在日志写入前自动处理 ID(哈希)、邮箱/手机/名称/Token 等字段。 # 样式与主题 - 优先使用 Tailwind 工具类 完成布局与常规样式,自定义设计令牌应映射为 Tailwind 扩展(在 tailwind.config.ts 中配置 theme.extend)。 - Ant Design 组件样式通过 ConfigProvider 的 theme 属性覆盖,确保与 Tailwind 主题令牌同步。在 src/theme/adapters/ 中创建 antd-theme.ts,导出主题配置对象,引用 tokens.ts 中的设计变量。 - 禁止在组件中硬编码颜色、字号等设计令牌,一律使用主题变量或 Tailwind 类名。 - 全局样式文件 globals.css 只引入 Tailwind 指令和必要的重置样式,不堆积组件样式。 # 事件与 IPC - 所有 IPC 通道名称定义在 shared/constants/ipc-channels.ts 中,分为三类: MAIN_TO_RENDERER / RENDERER_TO_MAIN / BIDIRECTIONAL。 - 渲染进程通过 src/utils/ipc.ts 中的安全守卫访问 IPC(hasIpc 检查 → safeIpcOn / send / invoke), 非 Electron 环境下静默跳过,保证浏览器预览不崩溃。 - 主进程事件处理函数需做好错误捕获与日志记录,渲染进程调用 IPC 时使用 try-catch 并处理超时。 - 窗口间通信走主进程转发:发送窗口 safeIpcSend,主进程接收后定位目标窗口并 webContents.send。 # 开发与构建命令 - 开发模式:npm run dev 或 yarn dev(同时启动 Vite 与 Electron,支持热重载)。 - 构建:npm run build 编译渲染进程 → 打包 Electron 应用。 - 代码检查:npm run lint(ESLint + Prettier,规则已配置为强制分号、单引号等)。 - 类型检查:npm run typecheck(tsc --noEmit)。 # 与其他 AI 协作的补充说明 - 所有生成的代码片段必须放在完整的文件上下文中,并注明所属文件路径。 - 若涉及跨平台逻辑,必须同时给出 Windows 与 macOS 的兼容实现或判断分支。 - 新增窗口时,需同步说明窗口入口、预加载脚本、主进程创建逻辑及 IPC 通道注册。 - 修改主题令牌时,需同步更新 tokens.ts、tailwind.config.ts 及 antd-theme.ts,确保三处一致。