package one2many import ( "fmt" "git.sxidc.com/go-framework/baize/framework/binding" "git.sxidc.com/go-framework/baize/framework/core/api/request" "git.sxidc.com/go-framework/baize/framework/core/api/response" "git.sxidc.com/go-framework/baize/framework/core/domain" "git.sxidc.com/go-framework/baize/framework/core/domain/entity" ) // Simple 关联的Bind参数 // LI 为左边实体的Info类型 // RI 为右边实体的Info类型 type Simple[LI any, RI any] struct { // 左领域实体,注意是Entity类型 Left entity.Entity // 右领域实体,注意是Entity类型 Right entity.Entity // 数据库Schema Schema string // 更新左实体关联使用的请求参数 LeftUpdateJsonBody request.Params // 查询左实体关联使用的请求参数,注意是Query类型 LeftQueryQueryParams request.QueryWithIDRequestParams // 更新左实体关联使用的请求参数 RightUpdateJsonBody request.Params // 查询右实体关联使用的请求参数,注意是QueryWithID类型 RightQueryQueryParams request.QueryWithIDRequestParams // 查询右实体带左实体信息使用的请求参数,注意是Query类型 RightQueryWithLeftQueryParams request.QueryRequestParams // 可选配置项,通过WithXXX配置 options *Options } func (simple *Simple[LI, RI]) bind(binder *binding.Binder) { options := simple.options leftDomainPath := domain.RelativeDomainPath(simple.Left) rightDomainPath := domain.RelativeDomainPath(simple.Right) leftRelationFieldName := fmt.Sprintf("%sIDs", simple.Right.DomainCamelName()) rightRelationFieldName := fmt.Sprintf("%sID", simple.Left.DomainCamelName()) leftTableName := domain.TableName(simple.Schema, simple.Left) leftRelationColumnName := domain.RelationColumnName(simple.Left) rightTableName := domain.TableName(simple.Schema, simple.Right) if !options.disableLeft { if !options.disableLeftUpdate { leftUpdateMiddlewares := append(options.globalMiddlewares, options.leftUpdateMiddlewares...) // 左到右更新 binding.PostBind(binder, &binding.SimpleBindItem[any]{ Path: leftDomainPath + rightDomainPath + "/update", SendResponseFunc: response.SendMsgResponse, RequestParams: simple.LeftUpdateJsonBody, Objects: []domain.Object{simple.Left}, ServiceFunc: UpdateLeft(leftTableName, simple.Left.DomainCNName(), leftRelationFieldName, leftRelationColumnName, rightTableName, simple.Right.DomainCNName()), }, leftUpdateMiddlewares...) } if !options.disableLeftQuery { leftQueryMiddlewares := append(options.globalMiddlewares, options.leftQueryMiddlewares...) // 左到右查询 binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[RI]]{ Path: leftDomainPath + rightDomainPath + "/query", SendResponseFunc: response.SendInfosResponse[RI], RequestParams: simple.LeftQueryQueryParams, Objects: []domain.Object{simple.Left}, ServiceFunc: QueryLeft[RI](leftTableName, leftRelationColumnName, rightTableName), }, leftQueryMiddlewares...) } } if !options.disableRight { if !options.disableRightUpdate { rightUpdateMiddlewares := append(options.globalMiddlewares, options.rightUpdateMiddlewares...) // 右到左更新 binding.PostBind(binder, &binding.SimpleBindItem[any]{ Path: rightDomainPath + leftDomainPath + "/update", SendResponseFunc: response.SendMsgResponse, RequestParams: simple.RightUpdateJsonBody, Objects: []domain.Object{simple.Right}, ServiceFunc: UpdateRight(rightTableName, rightRelationFieldName, leftTableName, simple.Left.DomainCNName(), leftRelationColumnName), }, rightUpdateMiddlewares...) } if !options.disableRightQuery { rightQueryMiddlewares := append(options.globalMiddlewares, options.rightQueryMiddlewares...) // 右到左查询 binding.GetBind(binder, &binding.SimpleBindItem[LI]{ Path: rightDomainPath + leftDomainPath + "/query", SendResponseFunc: response.SendInfoResponse[LI], RequestParams: simple.RightQueryQueryParams, Objects: []domain.Object{simple.Right}, ServiceFunc: QueryRight[LI](rightTableName, rightRelationFieldName, leftTableName), }, rightQueryMiddlewares...) } if !options.disableRightWithLeftQuery { rightWithLeftQueryMiddlewares := append(options.globalMiddlewares, options.rightWithLeftQueryMiddlewares...) // 右到左查询,携带左方信息 binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[map[string]any]]{ Path: rightDomainPath + leftDomainPath + "/queryWith", SendResponseFunc: response.SendInfosResponse[map[string]any], RequestParams: simple.RightQueryWithLeftQueryParams, Objects: []domain.Object{simple.Right}, ServiceFunc: QueryRightWithLeftInfo[RI, LI](rightTableName, options.rightQueryWithConditionFieldCallback, leftTableName, leftRelationColumnName), }, rightWithLeftQueryMiddlewares...) } } } func BindSimple[LI any, RI any](binder *binding.Binder, simple *Simple[LI, RI], opts ...Option) { options := new(Options) for _, opt := range opts { opt(options) } simple.options = options simple.bind(binder) } type Option func(options *Options) type Options struct { // 关闭左侧到右侧关联 disableLeft bool // 关闭右侧到左侧关联 disableRight bool // 关闭左侧更新 disableLeftUpdate bool // 关闭左侧查询 disableLeftQuery bool // 关闭右侧更新 disableRightUpdate bool // 关闭右侧查询 disableRightQuery bool // 关闭右实体带左实体信息查询 disableRightWithLeftQuery bool // 右查询条件构造回调 rightQueryWithConditionFieldCallback ConditionFieldCallback // 全局中间件 globalMiddlewares []binding.Middleware // 左侧更新中间件 leftUpdateMiddlewares []binding.Middleware // 左侧查询中间件 leftQueryMiddlewares []binding.Middleware // 右侧更新中间件 rightUpdateMiddlewares []binding.Middleware // 右侧查询中间件 rightQueryMiddlewares []binding.Middleware // 右实体带左实体查询中间件 rightWithLeftQueryMiddlewares []binding.Middleware } func WithGlobalMiddlewares(middlewares ...binding.Middleware) Option { return func(options *Options) { options.globalMiddlewares = middlewares } } func WithDisableLeft() Option { return func(options *Options) { options.disableLeft = true } } func WithDisableRight() Option { return func(options *Options) { options.disableRight = true } } func WithDisableLeftUpdate() Option { return func(options *Options) { options.disableLeftUpdate = true } } func WithDisableLeftQuery() Option { return func(options *Options) { options.disableLeftQuery = true } } func WithDisableRightUpdate() Option { return func(options *Options) { options.disableRightUpdate = true } } func WithDisableRightQuery() Option { return func(options *Options) { options.disableRightQuery = true } } func WithDisableRightWithLeftQuery() Option { return func(options *Options) { options.disableRightWithLeftQuery = true } } func WithRightQueryWithConditionFieldCallback(callbacks ConditionFieldCallback) Option { return func(options *Options) { options.rightQueryWithConditionFieldCallback = callbacks } } func WithLeftUpdateMiddlewares(middlewares ...binding.Middleware) Option { return func(options *Options) { options.leftUpdateMiddlewares = middlewares } } func WithLeftQueryMiddlewares(middlewares ...binding.Middleware) Option { return func(options *Options) { options.leftQueryMiddlewares = middlewares } } func WithRightUpdateMiddlewares(middlewares ...binding.Middleware) Option { return func(options *Options) { options.rightUpdateMiddlewares = middlewares } } func WithRightQueryMiddlewares(middlewares ...binding.Middleware) Option { return func(options *Options) { options.rightQueryMiddlewares = middlewares } } func WithRightWithLeftQueryMiddlewares(middlewares ...binding.Middleware) Option { return func(options *Options) { options.rightWithLeftQueryMiddlewares = middlewares } }