| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package main
- import (
- "context"
- "embed"
- "fmt"
- "io/fs"
- "log"
- "net/http"
- "net/http/httputil"
- "net/url"
- "os"
- "path/filepath"
- "runtime/debug"
- "time"
- "wails-app/internal"
- "github.com/wailsapp/wails/v2"
- "github.com/wailsapp/wails/v2/pkg/options"
- "github.com/wailsapp/wails/v2/pkg/options/assetserver"
- "github.com/wailsapp/wails/v2/pkg/options/windows"
- )
- //go:embed all:frontend/dist
- var assets embed.FS
- func main() {
- defer func() {
- if recovered := recover(); recovered != nil {
- writeStartupError(fmt.Sprintf("panic: %v\n%s", recovered, debug.Stack()))
- }
- }()
- // Initialize the Gin backend (non-blocking goroutine, listens on :8888)
- internal.InitBackend()
- // Reverse proxy for /api/* requests to Gin backend (strips /api prefix)
- backendURL, _ := url.Parse("http://127.0.0.1:8888")
- proxy := httputil.NewSingleHostReverseProxy(backendURL)
- // Flush each MJPEG chunk immediately through the Wails asset proxy instead
- // of buffering it until the response is considered complete.
- proxy.FlushInterval = -1
- // Embedded frontend static files
- distFS, err := fs.Sub(assets, "frontend/dist")
- if err != nil {
- writeStartupError(fmt.Sprintf("failed to get embedded frontend: %v", err))
- return
- }
- fileServer := http.FileServer(http.FS(distFS))
- // Create a handler that proxies /api to Gin, serves everything else from embed
- mux := http.NewServeMux()
- mux.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
- // Strip /api prefix before forwarding to Gin
- r.URL.Path = r.URL.Path[4:] // remove "/api"
- if r.URL.Path == "" {
- r.URL.Path = "/"
- }
- r.RequestURI = r.URL.RequestURI()
- proxy.ServeHTTP(w, r)
- })
- mux.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
- r.URL.Path = "/"
- r.RequestURI = "/"
- proxy.ServeHTTP(w, r)
- })
- // Proxy uploaded edge images to the Gin backend. The backend owns the
- // configured local storage directory and serves /uploads/file/*.
- mux.HandleFunc("/uploads/", func(w http.ResponseWriter, r *http.Request) {
- proxy.ServeHTTP(w, r)
- })
- mux.Handle("/", fileServer)
- err = wails.Run(&options.App{
- Title: "智慧停车管理系统",
- Width: 1400,
- Height: 900,
- MinWidth: 1024,
- MinHeight: 768,
- AssetServer: &assetserver.Options{
- Assets: assets,
- Handler: mux,
- },
- OnStartup: func(ctx context.Context) {
- log.Println("Wails app started, backend running on :8888")
- },
- Windows: &windows.Options{
- WebviewIsTransparent: false,
- WindowIsTranslucent: false,
- },
- })
- if err != nil {
- writeStartupError(fmt.Sprintf("Wails failed to start: %v", err))
- log.Print(err)
- }
- }
- // writeStartupError runs before the configured logger may exist. Keep the
- // diagnostic beside the executable so production deployment failures are visible.
- func writeStartupError(message string) {
- directory, err := os.Executable()
- if err == nil {
- directory = filepath.Dir(directory)
- } else if directory, err = os.Getwd(); err != nil {
- return
- }
- file, err := os.OpenFile(filepath.Join(directory, "startup-error.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
- if err != nil {
- return
- }
- defer file.Close()
- _, _ = fmt.Fprintf(file, "[%s] %s\n\n", time.Now().Format(time.RFC3339), message)
- }
|