package http import ( "context" "mime" "path/filepath" appHttp "quyun/app/http" "quyun/app/jobs" "quyun/app/middlewares" "quyun/app/models" "quyun/app/service" _ "quyun/docs" "quyun/providers/ali" "quyun/providers/app" "quyun/providers/hashids" "quyun/providers/http" "quyun/providers/http/swagger" "quyun/providers/job" "quyun/providers/jwt" "quyun/providers/postgres" "quyun/providers/wechat" "quyun/providers/wepay" "go.ipao.vip/atom" "go.ipao.vip/atom/container" "go.ipao.vip/atom/contracts" "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/favicon" "github.com/rogeecn/fabfile" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "go.uber.org/dig" ) func defaultProviders() container.Providers { return service.Default(container.Providers{ ali.DefaultProvider(), wechat.DefaultProvider(), wepay.DefaultProvider(), http.DefaultProvider(), postgres.DefaultProvider(), jwt.DefaultProvider(), hashids.DefaultProvider(), job.DefaultProvider(), }...) } func Command() atom.Option { return atom.Command( atom.Name("serve"), atom.Short("run http server"), atom.RunE(Serve), atom.Providers( defaultProviders(). With( jobs.Provide, models.Provide, middlewares.Provide, ). WithProviders( appHttp.Providers(), ), ), ) } type Service struct { dig.In Initials []contracts.Initial `group:"initials"` App *app.Config Job *job.Job Http *http.Service Middlewares *middlewares.Middlewares Routes []contracts.HttpRoute `group:"routes"` } func Serve(cmd *cobra.Command, args []string) error { return container.Container.Invoke(func(ctx context.Context, svc Service) error { log.SetFormatter(&log.TextFormatter{}) if svc.App.Mode == app.AppModeDevelopment { log.SetLevel(log.DebugLevel) svc.Http.Engine.Get("/swagger/*", swagger.HandlerDefault) } // svc.Http.Engine.Use(errorx.Middleware) svc.Http.Engine.Use(svc.Middlewares.DebugMode) svc.Http.Engine.Use(favicon.New(favicon.Config{ Data: []byte{}, })) group := svc.Http.Engine. Group("v1"). Use( svc.Middlewares.WechatMpVerify, svc.Middlewares.Auth, svc.Middlewares.AuthAdmin, ) for _, route := range svc.Routes { if route.Name() == "admin" { route.Register(group) continue } route.Register(group) } // statics svc.Http.Engine.Get("/admin*", func(ctx fiber.Ctx) error { f := ctx.Params("*") if f == "/" { f = "index.html" } ext := filepath.Ext(f) mime := mime.TypeByExtension(ext) log.Infof("mime type: %s %s", ext, mime) ctx.Set(fiber.HeaderContentType, mime) file, err := fabfile.Find(filepath.Join(svc.App.DistAdmin, f)) if err != nil { return ctx.SendStatus(fiber.StatusNotFound) } return ctx.SendFile(file) }) svc.Http.Engine.Get("*", func(ctx fiber.Ctx) error { f := ctx.Params("*") if f == "/" || f == "" { f = "index.html" } ext := filepath.Ext(f) mime := mime.TypeByExtension(ext) log.Infof("mime type: %s %s", ext, mime) ctx.Set(fiber.HeaderContentType, mime) file, err := fabfile.Find(filepath.Join(svc.App.DistWeChat, f)) if err != nil { file, err = fabfile.Find(filepath.Join(svc.App.DistWeChat, "index.html")) if err != nil { return ctx.SendStatus(fiber.StatusNotFound) } } return ctx.SendFile(file) }) // job if err := svc.Job.Start(ctx); err != nil { log.WithError(err).Error("job start failed") return err } defer svc.Job.StopAndCancel(ctx) return svc.Http.Serve() }) }