diff --git a/.gitignore b/.gitignore index cc26017..d614fa7 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser +config.toml +.pid diff --git a/app/wails/app.go b/app/wails/app.go index af53038..3d200ee 100644 --- a/app/wails/app.go +++ b/app/wails/app.go @@ -3,25 +3,121 @@ package main import ( "context" "fmt" + "github.com/wailsapp/wails/v2/pkg/runtime" + "go.uber.org/zap/zapcore" + "net" + "net/http" + "os" + "skapp/global" + "skapp/pkg/config/toml" + "skapp/pkg/logger" + "skapp/pkg/pid" + server "skapp/pkg/server" + "time" ) +var pidFile = "./.pid" + // App struct type App struct { - ctx context.Context + ctx context.Context + srv *http.Server + Handler http.Handler + pidLock *pid.PidLock } // NewApp creates a new App application struct func NewApp() *App { - return &App{} + app := &App{} + app.load() + return app +} + +func (a *App) ReloadApp() { + runtime.WindowReloadApp(a.ctx) +} + +func (a *App) ForceClose() { + a.shutdown(a.ctx) + os.Exit(0) +} + +func (a *App) load() { + a.pidLock = pid.NewPidLock(pidFile) + + conf, err := toml.LoadConfig() + if err != nil { + logger.Log.Fatalf("%s", err) + } + + global.Config = conf + + if conf.HasDebug() && conf.Debug.Enable { + logger.SetLevel(zapcore.DebugLevel) + } else { + logger.SetLevel(zapcore.ErrorLevel) + } + + engine := server.Server(conf) + + a.srv = &http.Server{ + Addr: fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port), + Handler: engine, + } + + a.Handler = engine.Handler() } // startup is called when the app starts. The context is saved // so we can call the runtime methods func (a *App) startup(ctx context.Context) { + if !global.Config.HasDebug() || !global.Config.Debug.Enable { + err := a.pidLock.Lock() + if err != nil { + os.Exit(-1) + } + } + a.ctx = ctx + + go func() { + logger.Log.Infof("启动本地后台服务: %s", a.srv.Addr) + // 服务连接 + if err := a.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { + switch err.(type) { + case *net.OpError: + _, _ = runtime.MessageDialog(ctx, runtime.MessageDialogOptions{ + Title: "错误", + Type: runtime.ErrorDialog, + Message: fmt.Sprintf("服务启动失败: 请检查 %s 是否被其他进程占用", a.srv.Addr), + }) + default: + _, _ = runtime.MessageDialog(ctx, runtime.MessageDialogOptions{ + Title: "错误", + Type: runtime.ErrorDialog, + Message: err.Error(), + }) + } + + logger.Log.Fatalf("listen: %s\n", err) + os.Exit(-1) + } + }() } -// Greet returns a greeting for the given name -func (a *App) Greet(name string) string { - return fmt.Sprintf("Hello %s, It's show time!", name) +func (a *App) beforeClose(ctx context.Context) bool { + return false +} + +func (a *App) shutdown(ctx context.Context) { + ctx2, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if !global.Config.HasDebug() || !global.Config.Debug.Enable { + a.pidLock.UnLock() + } + + if err := a.srv.Shutdown(ctx2); err != nil { + logger.Log.Fatalf("Server Shutdown:", err) + } } diff --git a/app/wails/cmd/server/main.go b/app/wails/cmd/server/main.go new file mode 100644 index 0000000..d6ef334 --- /dev/null +++ b/app/wails/cmd/server/main.go @@ -0,0 +1,7 @@ +package main + +import "skapp/pkg/server" + +func main() { + server.Main() +} diff --git a/app/wails/frontend/src/App.vue b/app/wails/frontend/src/App.vue index 39a9e1c..cf5192e 100644 --- a/app/wails/frontend/src/App.vue +++ b/app/wails/frontend/src/App.vue @@ -1,5 +1,5 @@