package api import ( "context" "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger" "git.sxidc.com/go-tools/utils/strutils" "github.com/gin-gonic/gin" "github.com/pkg/errors" "net/http" "runtime/debug" "slices" "strconv" "time" ) type Api struct { options Options server *http.Server rootRouter *RootRouter prefixRouter *PrefixRouter } func New(opts ...Option) *Api { options := new(Options) for _, opt := range opts { opt(options) } if strutils.IsStringEmpty(options.port) { options.port = "8080" } engine := gin.New() server := &http.Server{ Addr: ":" + options.port, Handler: engine, } engine.Use( // 日志中间件 func(c *gin.Context) { start := time.Now() c.Next() path := c.Request.URL.Path if slices.Contains(options.logSkipPaths, path) { return } end := time.Now() logger.GetInstance().Info(" %d | %s | %s \"%s\"", c.Writer.Status(), strconv.Itoa(int(end.Sub(start).Milliseconds()))+"ms", c.Request.Method, path, ) }, // recover func(c *gin.Context) { err := recover() if err != nil { logger.GetInstance().Error("%s", debug.Stack()) } }) api := &Api{ options: *options, server: server, rootRouter: newRootRouter(engine), } if strutils.IsStringNotEmpty(options.urlPrefix) { api.prefixRouter = newPrefixRouter(engine.Group(options.urlPrefix)) } return api } func NewWithEngine(server *http.Server, engine *gin.Engine, opts ...Option) *Api { options := new(Options) for _, opt := range opts { opt(options) } if strutils.IsStringEmpty(options.port) { options.port = "8080" } api := &Api{ options: *options, server: server, rootRouter: newRootRouter(engine), } if strutils.IsStringNotEmpty(options.urlPrefix) { api.prefixRouter = newPrefixRouter(engine.Group(options.urlPrefix)) } return api } // Start 运行Api // 参数: 无 // 返回值: // - 错误 func (api *Api) Start() error { err := api.server.ListenAndServe() if err != nil && !errors.Is(err, http.ErrServerClosed) { return errors.New(err.Error()) } return nil } // Finish 终止Api // 参数: 无 // 返回值: // - 错误 func (api *Api) Finish() error { err := api.server.Shutdown(context.Background()) if err != nil { return errors.New(err.Error()) } return nil } // Options 获取Api的选项 // 参数: 无 // 返回值: // - Api的选项 func (api *Api) Options() Options { return api.options } // RootRouter 获取Api的根路由 // 参数: 无 // 返回值: // - Api的根路由 func (api *Api) RootRouter() Router { return api.rootRouter } // PrefixRouter 获取Api的前缀路由 // 参数: 无 // 返回值: // - Api的前缀路由 func (api *Api) PrefixRouter() Router { if api.prefixRouter == nil { return api.rootRouter } return api.prefixRouter } const ( RouterRoot = "root" RouterPrefix = "prefix" ) // ChooseRouter 选择Router // 参数: // - routerType: 路由类型,有两种 // - api.RouterRoot: 根路由 // - api.RouterPrefix: 带url前缀的路由 // // - version: 版本,用于获取基于上面两中路由够造的带有版本号的路由,传空字符串则选定上面两种路由本身 // 返回值: // - 选择的Router func (api *Api) ChooseRouter(routerType string, version string) Router { var router Router switch routerType { case RouterRoot: router = api.RootRouter() case RouterPrefix: router = api.PrefixRouter() default: router = api.PrefixRouter() } if strutils.IsStringNotEmpty(version) { router = router.VersionedRouter(version) } return router }