package main import ( "changeme/api" "changeme/initFunc" "context" "embed" "fmt" "os/exec" "runtime" "strings" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" "github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2/pkg/menu" "github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options/assetserver" ) //go:embed all:frontend/dist var assets embed.FS //go:embed wails.json var wailsjson embed.FS var wailsConfig map[string]interface{} func init() { wailsConfig = make(map[string]interface{}) } type App struct { ctx context.Context } func main() { // Create an instance of the app structure app := NewApp() //开启视频监控的exe go initFunc.RunPiServerExe() go initFunc.SetupCert() go HttpServer() wilsJon,_ := wailsjson.ReadFile("wails.json") wailsConfig = gconv.Map(wilsJon) //读取wails.json配置文件 wailsConfigOem := initFunc.RequestOemSettingInfo(gconv.Map(wilsJon)) //将 wailsConfig 保存起来 if wailsConfigOem == nil { wailsConfigOem = g.Map{ "brand_name": "Error-config", "website_url": "https://www.baidu.com", } } //增加菜单 AppMenu := menu.NewMenu() // SubMenu := AppMenu.AddSubmenu("工具") // SubMenu.AddText("刷新", keys.CmdOrCtrl("F5"), func(_ *menu.CallbackData) { // runtime.Reload(app.ctx) // }) // Create application with options err := wails.Run(&options.App{ Title: wailsConfigOem["brand_name"].(string), Width: 1024, Height: 768, AssetServer: &assetserver.Options{ Assets: assets, }, BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1}, OnStartup: app.startup, Menu: AppMenu, Bind: []interface{}{ app, }, }) if err != nil { println("Error:", err.Error()) } } // NewApp creates a new App application struct func NewApp() *App { return &App{} } // 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) { a.ctx = ctx } // oem的门店管理地址 func (a *App) ShopUrl() string { wailsConfigOem := initFunc.RequestOemSettingInfo(wailsConfig) if wailsConfigOem == nil { return "https://www.baidu.com" } domain := wailsConfigOem["domain"].(string) if !strings.Contains(domain, "http") { domain = "https://"+domain } return domain+"?oem_id="+gconv.String(wailsConfigOem["id"])+"&t="+gconv.String(gtime.TimestampMilli()) } func releasePort(port int) error { var cmd *exec.Cmd // 根据操作系统选择不同的命令 if runtime.GOOS == "windows" { // Windows: 使用 netstat 查找占用端口的 PID // netstat -ano | findstr : 获取对应的 PID,然后使用 taskkill 杀死进程 cmd = exec.Command("cmd", "/C", fmt.Sprintf("netstat -ano | findstr :%d", port)) output, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("error running netstat: %v", err) } // 在 Windows 上,输出格式是:TCP [::]: [::]:0 LISTENING // 需要提取出 PID lines := string(output) for _, line := range strings.Split(lines, "\n") { if strings.Contains(line, fmt.Sprintf(":%d", port)) { // 提取 PID(PID 是最后一个字段) fields := strings.Fields(line) if len(fields) >= 5 { pid := fields[len(fields)-1] // 使用 taskkill 结束进程 cmdKill := exec.Command("taskkill", "/PID", pid, "/F") err := cmdKill.Run() if err != nil { return fmt.Errorf("failed to kill process with PID %s: %v", pid, err) } fmt.Printf("Killed process with PID %s on port %d\n", pid, port) return nil } } } return fmt.Errorf("no process found listening on port %d", port) } else { // Linux/MacOS: 使用 lsof 和 kill 杀死占用端口的进程 exec.Command("bash", "-c", "lsof -i :${port} | grep LISTEN | awk '{print 8383}' | xargs kill -9") } return nil } func HttpServer(){ releasePort(8383) s := ghttp.GetServer() // 处理 /take_photo_page 路由 s.BindHandler("/take_photo_page",api.Page) s.BindHandler("/add_take_photo",api.AddDbData) s.BindHandler("/update_take_photo",api.UpdateDbData) s.BindHandler("/delete_take_photo",api.DeleteDbData) s.BindHandler("/download_camera_jpg",api.DownLoadCameraJpg) s.BindHandler("/download_master_jpg",api.DownLoadMasterJpg) s.SetPort(8383) s.Run() }