1
0
Files
nex/openspec/specs/desktop-app/spec.md
lanyuanxiaoyao 64dc66afa6 fix: Windows 桌面应用打包问题修复
- 删除通用 desktop target,重命名 platform targets 为简短形式 (desktop-mac/win/linux)
- 构建产物文件名统一为 nex-{os}-{arch}[.exe] 格式
- Windows 托盘图标使用 .ico 格式(运行时按平台选择)
- Windows 原生对话框使用 user32.MessageBoxW 替代 msg * 命令
- 更新 README.md 和 package-macos.sh 中的引用
- 添加单元测试覆盖 MessageBoxW 封装和图标选择逻辑
- 同步更新 desktop-app spec 规范文档
2026-04-22 23:20:39 +08:00

156 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 桌面应用
## Purpose
TBD - 提供跨平台桌面应用支持,将后端服务与前端静态资源打包为单一可执行文件
## Requirements
### Requirement: 桌面应用启动
系统 SHALL 支持作为桌面应用启动,将后端服务与前端静态资源打包为单一可执行文件。
#### Scenario: 双击启动
- **WHEN** 用户双击桌面应用可执行文件
- **THEN** 系统使用 `gofrs/flock` 尝试获取排他文件锁
- **AND** 锁文件路径为系统临时目录下的 `nex-gateway.lock`
- **AND** 系统启动后端服务
- **AND** 系统托盘图标出现
- **AND** 浏览器自动打开 `http://localhost:9826` 显示管理界面
#### Scenario: 单实例检查
- **WHEN** 用户尝试启动第二个实例
- **THEN** 系统检测到已有实例持有文件锁
- **AND** 显示错误提示"已有 Nex 实例运行"
- **AND** 新实例退出
#### Scenario: 退出释放锁
- **WHEN** 用户点击托盘菜单"退出"
- **THEN** 系统释放文件锁
- **AND** 应用进程退出
### Requirement: 系统托盘
系统 SHALL 提供跨平台系统托盘功能,支持托盘图标和菜单。图标格式 SHALL 根据平台自动选择。
#### Scenario: 托盘图标显示
- **WHEN** 桌面应用启动成功
- **THEN** 系统根据平台加载正确的图标格式
- **AND** 在 Windows 上加载 ICO 格式图标(`assets/icon.ico`
- **AND** 在 macOS 和 Linux 上加载 PNG 格式图标(`assets/icon.png`
- **AND** 托盘图标 tooltip 显示"AI Gateway"
#### Scenario: 托盘菜单显示
- **WHEN** 用户点击托盘图标(左键或右键)
- **THEN** 显示托盘菜单
- **AND** 菜单包含"打开管理界面"选项
- **AND** 菜单包含"状态: 运行中"选项(禁用状态)
- **AND** 菜单包含"端口: 9826"选项(禁用状态)
- **AND** 菜单包含"关于"选项
- **AND** 菜单包含"退出"选项
#### Scenario: 打开管理界面
- **WHEN** 用户点击托盘菜单"打开管理界面"
- **THEN** 系统在浏览器中打开 `http://localhost:9826`
#### Scenario: 浏览器打开失败
- **WHEN** 系统无法打开浏览器(浏览器未安装等)
- **THEN** 托盘菜单仍可正常使用
- **AND** 用户可手动访问 `http://localhost:9826`
#### Scenario: 退出应用
- **WHEN** 用户点击托盘菜单"退出"
- **THEN** 系统优雅关闭后端服务
- **AND** 托盘图标消失
- **AND** 应用进程退出
### Requirement: 静态文件服务
系统 SHALL 通过 Gin 同时服务 API 和前端静态资源。
#### Scenario: API 请求路由
- **WHEN** 请求路径以 `/api/``/v1/` 开头
- **THEN** 请求由现有业务 handler 处理
#### Scenario: 静态资源路由
- **WHEN** 请求路径为 `/assets/*`
- **THEN** 返回嵌入的前端静态资源文件
#### Scenario: SPA 路由回退
- **WHEN** 请求路径不匹配任何 API 或静态资源路由
- **THEN** 返回 `index.html`(支持前端 SPA 路由)
### Requirement: 端口冲突检测
系统 SHALL 在启动前检测端口是否可用。
#### Scenario: 端口可用
- **WHEN** 端口 9826 未被占用
- **THEN** 服务正常启动
#### Scenario: 端口被占用
- **WHEN** 端口 9826 已被其他程序占用
- **THEN** 显示错误提示"端口 9826 已被占用"
- **AND** 应用退出
### Requirement: 跨平台构建
系统 SHALL 支持跨平台构建和打包。构建 target SHALL 按平台分离,产物文件名 SHALL 使用 `nex-{os}-{arch}[.exe]` 格式。
#### Scenario: macOS 构建
- **WHEN** 执行 `desktop-mac` 构建命令
- **THEN** 生成 `nex-mac-arm64``nex-mac-amd64` 可执行文件
- **AND** 可打包为 `.app` bundle
#### Scenario: Windows 构建
- **WHEN** 执行 `desktop-win` 构建命令
- **THEN** 生成 `nex-win-amd64.exe` 可执行文件
- **AND** 使用 `-H=windowsgui` linker flag 隐藏控制台窗口
#### Scenario: Linux 构建
- **WHEN** 执行 `desktop-linux` 构建命令
- **THEN** 生成 `nex-linux-amd64` 可执行文件
### Requirement: macOS .app 打包
系统 SHALL 支持打包为 macOS .app bundle。
#### Scenario: .app 结构
- **WHEN** 执行打包脚本
- **THEN** 生成 `Nex.app` 目录结构
- **AND** 包含 `Contents/Info.plist` 元数据
- **AND** 包含 `Contents/MacOS/nex` 可执行文件
- **AND** 包含 `Contents/Resources/AppIcon.icns` 图标
- **AND** `Info.plist``LSUIElement``true`(不显示 Dock 图标)
### Requirement: 关于对话框
系统 SHALL 提供关于对话框显示应用信息。在 Windows 上 SHALL 使用 `user32.dll``MessageBoxW` API 实现。
#### Scenario: 显示关于
- **WHEN** 用户点击托盘菜单"关于"
- **THEN** 显示对话框包含应用名称、项目链接
- **AND** 在 Windows 上使用 `MessageBoxW` 原生对话框实现
### Requirement: Windows 原生对话框
系统 SHALL 在 Windows 上使用 `user32.dll``MessageBoxW` API 显示错误和关于对话框,替代 `msg *` 命令。
#### Scenario: 错误提示对话框
- **WHEN** 应用在 Windows 上遇到启动错误(端口占用、配置加载失败等)
- **THEN** 使用 `MessageBoxW` 显示模态对话框
- **AND** 对话框标题栏显示应用名称
- **AND** 对话框包含错误描述文本
- **AND** 对话框显示错误图标MB_ICONERROR
#### Scenario: 关于对话框
- **WHEN** 用户在 Windows 上点击托盘菜单"关于"
- **THEN** 使用 `MessageBoxW` 显示模态对话框
- **AND** 对话框标题栏显示"关于 Nex Gateway"
- **AND** 对话框包含应用信息文本
- **AND** 对话框显示信息图标MB_ICONINFORMATION
#### Scenario: 非 Windows 平台不受影响
- **WHEN** 应用运行在 macOS 或 Linux 上
- **THEN** 错误和关于对话框仍使用平台原有实现osascript / zenity