1
0

feat: 新增桌面应用支持

- 新增 desktop 应用入口,将后端与前端打包为单一可执行文件
- 集成系统托盘功能(getlantern/systray)
- 支持单实例锁和端口冲突检测
- 启动时自动打开浏览器显示管理界面
- 新增 embedfs 模块嵌入静态资源
- 新增跨平台构建脚本(macOS/Windows/Linux)
- 新增 macOS .app 打包脚本
- 统一 Makefile,移除 backend/Makefile
- 更新 README 添加桌面应用使用说明
This commit is contained in:
2026-04-22 19:27:27 +08:00
parent f5e45d032e
commit 0b05e08705
22 changed files with 1297 additions and 88 deletions

View File

@@ -0,0 +1,39 @@
package main
import (
"os"
"path/filepath"
"syscall"
"testing"
)
func TestAcquireSingleInstance(t *testing.T) {
lockPath := filepath.Join(os.TempDir(), "nex-gateway-test.lock")
origLockFile := lockFile
lockFile = nil
defer func() { lockFile = origLockFile }()
f, err := os.OpenFile(lockPath, os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
t.Fatalf("无法创建锁文件: %v", err)
}
defer f.Close()
defer os.Remove(lockPath)
err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
if err != nil {
t.Fatalf("无法获取文件锁: %v", err)
}
defer syscall.Flock(int(f.Fd()), syscall.LOCK_UN)
t.Log("单实例锁测试通过")
}
func TestReleaseSingleInstance(t *testing.T) {
lockFile = nil
releaseSingleInstance()
t.Log("释放空锁测试通过")
}