package main import ( "fwh-toolbox-server/cache" "fwh-toolbox-server/config" "fwh-toolbox-server/controllers" "fwh-toolbox-server/database" "fwh-toolbox-server/repositories" "fwh-toolbox-server/repositories/api/fwh_pro" "fwh-toolbox-server/repositories/api/fwh_test" "fwh-toolbox-server/task" "fwh-toolbox-server/utils/casdoor" "fwh-toolbox-server/utils/minio" "log" "net/http" "os" "os/signal" // "fwh-toolbox-server/database" _ "fwh-toolbox-server/docs" // swag 自动生成文档 "fwh-toolbox-server/logger" "fwh-toolbox-server/routes" "fwh-toolbox-server/scheduler" "fwh-toolbox-server/networkEvents" "github.com/gofiber/fiber/v2" "github.com/gofiber/swagger" "github.com/hibiken/asynq" "github.com/hibiken/asynqmon" "go.uber.org/zap" "golang.org/x/sys/unix" ) func main() { var cfg *config.Config var err error cfg, err = config.LoadConfig() if err != nil { panic(err) } err = logger.Init(cfg.App.AppEnv, cfg.App.LogLevel) if err != nil { panic(err) } defer logger.Log.Sync() // 退出前同步zap缓冲区 // 初始化数据库 err = database.Init(&cfg.App) if err != nil { zap.L().Error("database init failed.", zap.String("err", err.Error())) panic(err) } // 初始化缓存 cache.Init(cfg.App.RedisAddr) // 初始化Minio minio.InitClient(&cfg.App) // 初始化FwhApi repositories.FwhHttpInit(&cfg.FwhApi) // 初始化FwhTestApi(测试环境) repositories.FwhTestHttpInit(&cfg.FwhTestApi) // 初始化Fwh ES(iotcore-stat 报文统计) repositories.EsHttpInit(&cfg.FwhEs) // 初始化PlaneApi repositories.PlaneHttpInit(&cfg.PlaneApi) // 初始化PlaneWebApi // 初始化新架构 Plane(PlaneClient + PlaneService) repositories.InitPlane(&cfg.PlaneWebApi) // 初始化计划任务 scheduler.Init() // 初始化任务 task.InitTask(task.TaskRedisOpt{ Addr: cfg.App.RedisAddr, DB: 12, }) // 初始化Casdoor casdoor.InitAuthConfig() // 初始化FWH MQTT客户端 repositories.FwhMqttInit(&cfg.FwhMqtt) // repositories.FwhMqttFaultRecordChargeChannel(context.Background(), "10060005A03X25160385") app := fiber.New() app.Use(func(c *fiber.Ctx) error { logger.Log.Info("请求", zap.String("path", c.Path())) return c.Next() }) // 注册 Swagger 路由 app.Get("/swagger/*", swagger.HandlerDefault) routes.Setup(app) // 初始化 AI Chat (ACP Client) controllers.InitAIChat(".", cfg.Kiro.RunAsUser, cfg.Kiro.Home, cfg.Kiro.DebugLog) // 启动第一个监听 go func() { if err := networkEvents.InitEvio(); err != nil { zap.L().Error("networkEvents init failed.", zap.String("err", err.Error())) panic(err) } }() // 启动Asynqmon界面 go func() { h := asynqmon.New(asynqmon.Options{ RootPath: "/asynqmon", // RootPath specifies the root for asynqmon app RedisConnOpt: asynq.RedisClientOpt{Addr: cfg.App.RedisAddr, DB: 12}, }) // Note: We need the tailing slash when using net/http.ServeMux. http.Handle("/", h) listenAddr := "0.0.0.0:" + cfg.App.AsynqmonPort // Go to http://localhost:8080/asynqmon to see asynqmon homepage. err = http.ListenAndServe(listenAddr, nil) if err != nil { zap.L().Error("Asynqmon port listening failed.", zap.String("err", err.Error())) panic(err) } log.Println("asynqmon shutdown finished") zap.L().Info("Asynqmon started successfully.", zap.String("addr", listenAddr)) }() // 提前登录FWH err = fwh_pro.Login() if err != nil { zap.L().Error("FWH login failed.", zap.String("err", err.Error())) // panic(err) } // 提前登录FWH测试环境 err = fwh_test.Login() if err != nil { zap.L().Error("FWH test login failed.", zap.String("err", err.Error())) // panic(err) } // TEST // err = task.CreateTaskSimCardCollect() // if err != nil { // zap.L().Error("CreateTaskSimCardCollect failed.", zap.String("err", err.Error()), zap.String("time(UTC)", time.Now().UTC().Format(time.DateTime))) // } go func() { sigs := make(chan os.Signal, 1) signal.Notify(sigs, unix.SIGTERM, unix.SIGINT) <-sigs log.Println("fiber shutdown") app.Shutdown() }() err = app.Listen("localhost:" + cfg.App.AppPort) if err != nil { zap.L().Error("Port listening failed.", zap.String("err", err.Error())) panic(err) } }