package sql_executor import ( "git.sxidc.com/go-framework/baize/framework/core/api" "git.sxidc.com/go-framework/baize/framework/gateway" "git.sxidc.com/go-tools/utils/strutils" "github.com/gin-gonic/gin" "github.com/pkg/errors" "net/http" "net/url" "sync" ) type Option func(options *Options) type Options struct { serviceApiVersion string globalMiddlewares []api.Handler executeSqlMiddlewares []api.Handler sqlExecuteLogMiddlewares []api.Handler queryRegisteredServicesMiddlewares []api.Handler } func WithServiceApiVersion(serviceApiVersion string) Option { return func(options *Options) { options.serviceApiVersion = serviceApiVersion } } func WithGlobalMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.globalMiddlewares = middlewares } } func WithExecuteSqlMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.executeSqlMiddlewares = middlewares } } func WithSqlExecuteLogMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.sqlExecuteLogMiddlewares = middlewares } } func WithQueryRegisteredServicesMiddlewares(middlewares ...api.Handler) Option { return func(options *Options) { options.queryRegisteredServicesMiddlewares = middlewares } } var serviceBaseUrlMap sync.Map func RegisterService(serviceShortName string, baseUrl string) { serviceBaseUrlMap.Store(serviceShortName, baseUrl) } func BuildGateway(gw *gateway.Gateway, opts ...Option) { options := new(Options) for _, opt := range opts { opt(options) } executeSqlMiddlewares := append(options.globalMiddlewares, options.executeSqlMiddlewares...) sqlExecuteLogMiddlewares := append(options.globalMiddlewares, options.sqlExecuteLogMiddlewares...) queryRegisteredServicesMiddlewares := append(options.globalMiddlewares, options.queryRegisteredServicesMiddlewares...) builder := gw.NewBuilder(api.RouterPrefix, "") builder. Url(http.MethodPost, "/sql/execute"). Post(&gateway.PostRequest{ UrlFormFunc: func(c *api.Context, _ string, historyRequests []gateway.BuilderRequest, resultMap map[string]any) (string, error) { jsonBody, err := c.GetJsonBody() if err != nil { return "", err } serviceShortName, ok := jsonBody.Get("serviceShortName").(string) if !ok { return "", errors.New("没有传递服务名缩写或服务名缩写不是string类型") } jsonBody.Delete("serviceShortName") serviceBaseUrl, loaded := serviceBaseUrlMap.Load(serviceShortName) if !loaded { return "", errors.New("没有注册对应的服务: " + serviceShortName) } var serviceUrl string if strutils.IsStringEmpty(options.serviceApiVersion) { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", "/sql/execute") if err != nil { return "", err } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/sql/execute") if err != nil { return "", err } serviceUrl = innerServiceUrl } return serviceUrl, nil }, BodyFormFunc: func(c *api.Context, _ any, historyRequests []gateway.BuilderRequest, resultMap map[string]any) (any, error) { err := gateway.AddJsonBodyTenantIDAndUserID(c, "", "executorId") if err != nil { return nil, err } jsonBody, err := c.GetJsonBody() if err != nil { return nil, err } userInfo := c.GetUserInfo() if userInfo == nil { jsonBody.Set("executorName", "guest") } else { jsonBody.Set("executorName", userInfo.GetName) } return jsonBody.Map(), nil }, }). Build(executeSqlMiddlewares...) builder. Url(http.MethodGet, "/sql/execute/log"). Get(&gateway.GetRequest{ UrlFormFunc: func(c *api.Context, _ string, historyRequests []gateway.BuilderRequest, resultMap map[string]any) (string, error) { queryParams := c.GetQueryParams() serviceShortName := queryParams.Get("serviceShortName") if strutils.IsStringEmpty(serviceShortName) { return "", errors.New("没有传递服务名缩写") } queryParams.Delete("serviceShortName") serviceBaseUrl, loaded := serviceBaseUrlMap.Load(serviceShortName) if !loaded { return "", errors.New("没有注册对应的服务: " + serviceShortName) } var serviceUrl string if strutils.IsStringEmpty(options.serviceApiVersion) { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", "/sql/execute/log") if err != nil { return "", err } serviceUrl = innerServiceUrl } else { innerServiceUrl, err := url.JoinPath(serviceBaseUrl.(string), serviceShortName, "/api", options.serviceApiVersion, "/sql/execute/log") if err != nil { return "", err } serviceUrl = innerServiceUrl } return serviceUrl, nil }, QueryParamsFormFunc: gateway.FormQueryParamsWithTenantIDAndUserIDFunc("", "executorId"), }). Build(sqlExecuteLogMiddlewares...) // 查询注册的服务 builder. Url(http.MethodGet, "/sql/execute/registered/services"). Local(func(c *api.Context) { serviceShortNames := make([]string, 0) serviceBaseUrlMap.Range(func(key any, value any) bool { serviceShortNames = append(serviceShortNames, key.(string)) return true }) c.JSON(http.StatusOK, gin.H{ "services": serviceShortNames, }) }, queryRegisteredServicesMiddlewares...) }