package starter import ( "fmt" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" "joylink.club/bj-rtsts-server/api" "joylink.club/bj-rtsts-server/docs" "joylink.club/bj-rtsts-server/middleware" "joylink.club/bj-rtsts-server/mqtt" "joylink.club/bj-rtsts-server/third_party" "log/slog" "net" "net/http" "os" "runtime/debug" "strings" "joylink.club/bj-rtsts-server/db/dbquery" "joylink.club/bj-rtsts-server/dto" "joylink.club/bj-rtsts-server/sys_error" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" sloggin "github.com/samber/slog-gin" "joylink.club/bj-rtsts-server/config" "joylink.club/bj-rtsts-server/db" "joylink.club/bj-rtsts-server/logger" ) func Start() { engine := initServer() mqtt.Startup(mqtt.NewMqttOptions(config.Config.Messaging.Mqtt.Address, config.Config.Messaging.Mqtt.Username, config.Config.Messaging.Mqtt.Password)) third_party.Init() authMiddleware := middleware.InitGinJwtMiddleware() router := engine.Group("/api") api.InitUserRouter(router, authMiddleware) api.InitDraftingRouter(router, authMiddleware) api.InitPublishedGiRouter(router, authMiddleware) api.InitSimulationRouter(router, authMiddleware) api.InitCategoryRouter(router, authMiddleware) api.InitProjectRouter(router, authMiddleware) api.InitTrainManageRouter(router, authMiddleware) api.InitProjectLinkRouter(router, authMiddleware) api.InitAuthRouter(router, authMiddleware) api.InitProjectRunConfigRouter(router, authMiddleware) docs.SwaggerInfo.Title = "CBTC测试系统API" engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) serverConfig := config.Config.Server if serverConfig.Port == 0 { serverConfig.Port = 8080 } engine.Run(fmt.Sprintf(":%d", config.Config.Server.Port)) } func initServer() *gin.Engine { config.LoadConfig() err := logger.InitLogger() if err != nil { panic(err) } err = db.InitDb() if err != nil { panic(err) } dbquery.SetDefault(db.DB) engine := gin.New() conf := cors.DefaultConfig() conf.AllowHeaders = []string{"*"} conf.AllowAllOrigins = true engine.Use(sloggin.New(slog.Default())) engine.Use(cors.New(conf)) // gin panic 异常处理,默认处理为 engine.Use(customRecoveryWithSlog(slog.Default(), true, func(c *gin.Context, e interface{}) { be, ok := e.(*sys_error.BusinessError) if !ok { e, ok := e.(error) if ok { be = sys_error.New("未知错误", e) } else { be = sys_error.New("未知错误", fmt.Errorf("%v", e)) } } c.Error(be) statusCode := http.StatusInternalServerError if be.ErrorCode > 0 { statusCode = http.StatusForbidden } c.JSON(statusCode, &dto.ErrorDto{ Tip: be.UserMsg, Message: be.Error(), }) c.Writer.WriteHeaderNow() c.Abort() })) return engine } func customRecoveryWithSlog(logger *slog.Logger, stack bool, recovery gin.RecoveryFunc) gin.HandlerFunc { return func(c *gin.Context) { defer func() { if err := recover(); err != nil { // Check for a broken connection, as it is not really a // condition that warrants a panic stack trace. var brokenPipe bool if ne, ok := err.(*net.OpError); ok { if se, ok := ne.Err.(*os.SyscallError); ok { if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") { brokenPipe = true } } } if brokenPipe { logger.Error(c.Request.URL.Path, "error", err, ) // If the connection is dead, we can't write a status to it. c.Error(err.(error)) // nolint: errcheck c.Abort() return } if stack { logger.Error("请求处理Panic异常", "error", err, "stack", string(debug.Stack())) } else { logger.Error("请求处理Panic异常", "error", err, ) } recovery(c, err) } }() c.Next() } }