simple.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package remote
  2. import (
  3. "fmt"
  4. "git.sxidc.com/go-framework/baize/framework/binding"
  5. "git.sxidc.com/go-framework/baize/framework/binding/request"
  6. "git.sxidc.com/go-framework/baize/framework/binding/response"
  7. "git.sxidc.com/go-framework/baize/framework/core/domain"
  8. "git.sxidc.com/go-framework/baize/framework/core/domain/entity"
  9. "github.com/iancoleman/strcase"
  10. "reflect"
  11. )
  12. // Simple 关联的Bind参数
  13. // I 为本地实体的Info类型
  14. type Simple[LI any, RI any] struct {
  15. // 左领域实体,注意是Entity类型
  16. Left entity.Entity
  17. // 右领域实体,注意是Entity类型
  18. Right entity.Entity
  19. // 数据库Schema
  20. Schema string
  21. // 更新左实体关联使用的请求参数
  22. LeftUpdateJsonBody request.Params
  23. // 查询左实体关联使用的请求参数,注意是Query类型
  24. LeftQueryQueryParams request.QueryWithIDRequestParams
  25. // 更新右实体关联使用的请求参数
  26. RightUpdateJsonBody request.Params
  27. // 查询右实体关联使用的请求参数,注意是Query类型
  28. RightQueryQueryParams request.QueryWithIDRequestParams
  29. // 可选配置项,通过WithXXX配置
  30. options *Options
  31. }
  32. func (simple *Simple[LI, RI]) bind(binder *binding.Binder) {
  33. options := simple.options
  34. leftDomainPath := domain.RelativeDomainPath(simple.Left)
  35. rightDomainPath := domain.RelativeDomainPath(simple.Right)
  36. leftRelationFieldName := fmt.Sprintf("%sIDs", simple.Right.DomainCamelName())
  37. rightRelationFieldName := fmt.Sprintf("%sIDs", simple.Left.DomainCamelName())
  38. middleTableName := domain.SnakeDomainName(simple.Left) + "_and_" + domain.SnakeDomainName(simple.Right)
  39. leftTableName := domain.TableName(simple.Schema, simple.Left)
  40. leftRelationColumnName := fmt.Sprintf("%s_id", strcase.ToSnake(simple.Right.DomainCamelName()))
  41. rightTableName := domain.TableName(simple.Schema, simple.Right)
  42. rightRelationColumnName := fmt.Sprintf("%s_id", strcase.ToSnake(simple.Left.DomainCamelName()))
  43. leftRemote := false
  44. if reflect.TypeOf(new(LI)).Elem().Kind() == reflect.String {
  45. leftRemote = true
  46. }
  47. rightRemote := false
  48. if reflect.TypeOf(new(RI)).Elem().Kind() == reflect.String {
  49. rightRemote = true
  50. }
  51. if !options.disableLeft {
  52. if !options.disableLeftUpdate {
  53. // 左到右更新
  54. binding.PostBind(binder, &binding.SimpleBindItem[any]{
  55. Path: leftDomainPath + rightDomainPath + "/update",
  56. ResponseFunc: response.SendMsgResponse,
  57. RequestParams: simple.LeftUpdateJsonBody,
  58. Objects: []domain.Object{simple.Left},
  59. ServiceFunc: Update(middleTableName,
  60. leftRemote, leftTableName, simple.Left.DomainCNName(), leftRelationFieldName, leftRelationColumnName,
  61. rightRemote, rightTableName, rightRelationColumnName),
  62. })
  63. }
  64. if !options.disableLeftQuery {
  65. // 左到右查询
  66. if rightRemote {
  67. binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[string]]{
  68. Path: leftDomainPath + rightDomainPath + "/query",
  69. ResponseFunc: response.SendInfosResponse[string],
  70. RequestParams: simple.LeftQueryQueryParams,
  71. Objects: []domain.Object{simple.Left},
  72. ServiceFunc: QueryToRemote(middleTableName, leftRemote, leftTableName, leftRelationColumnName, rightRelationColumnName),
  73. })
  74. } else {
  75. binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[RI]]{
  76. Path: leftDomainPath + rightDomainPath + "/query",
  77. ResponseFunc: response.SendInfosResponse[RI],
  78. RequestParams: simple.LeftQueryQueryParams,
  79. Objects: []domain.Object{simple.Left},
  80. ServiceFunc: QueryToExist[RI](middleTableName,
  81. leftRemote, leftTableName, leftRelationColumnName,
  82. rightTableName, rightRelationColumnName),
  83. })
  84. }
  85. }
  86. }
  87. if !options.disableRight {
  88. if !options.disableRightUpdate {
  89. // 右到左更新
  90. binding.PostBind(binder, &binding.SimpleBindItem[any]{
  91. Path: rightDomainPath + leftDomainPath + "/update",
  92. ResponseFunc: response.SendMsgResponse,
  93. RequestParams: simple.RightUpdateJsonBody,
  94. Objects: []domain.Object{simple.Right},
  95. ServiceFunc: Update(middleTableName,
  96. rightRemote, rightTableName, simple.Right.DomainCNName(), rightRelationFieldName, rightRelationColumnName,
  97. leftRemote, leftTableName, leftRelationColumnName),
  98. })
  99. }
  100. if !options.disableRightQuery {
  101. // 右到左查询
  102. if leftRemote {
  103. binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[string]]{
  104. Path: rightDomainPath + leftDomainPath + "/query",
  105. ResponseFunc: response.SendInfosResponse[string],
  106. RequestParams: simple.RightQueryQueryParams,
  107. Objects: []domain.Object{simple.Right},
  108. ServiceFunc: QueryToRemote(middleTableName, rightRemote, rightTableName, rightRelationColumnName, leftRelationColumnName),
  109. })
  110. } else {
  111. binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[LI]]{
  112. Path: rightDomainPath + leftDomainPath + "/query",
  113. ResponseFunc: response.SendInfosResponse[LI],
  114. RequestParams: simple.RightQueryQueryParams,
  115. Objects: []domain.Object{simple.Right},
  116. ServiceFunc: QueryToExist[LI](middleTableName,
  117. rightRemote, rightTableName, rightRelationColumnName,
  118. leftTableName, leftRelationColumnName),
  119. })
  120. }
  121. }
  122. }
  123. }
  124. func BindSimple[LI any, RI any](binder *binding.Binder, simple *Simple[LI, RI], opts ...Option) {
  125. options := new(Options)
  126. for _, opt := range opts {
  127. opt(options)
  128. }
  129. simple.options = options
  130. simple.bind(binder)
  131. }
  132. type Option func(options *Options)
  133. type Options struct {
  134. // 关闭左侧到右侧关联
  135. disableLeft bool
  136. // 关闭右侧到左侧关联
  137. disableRight bool
  138. // 关闭左侧更新
  139. disableLeftUpdate bool
  140. // 关闭左侧查询
  141. disableLeftQuery bool
  142. // 关闭右侧更新
  143. disableRightUpdate bool
  144. // 关闭右侧查询
  145. disableRightQuery bool
  146. }
  147. func WithDisableLeft() Option {
  148. return func(options *Options) {
  149. options.disableLeft = true
  150. }
  151. }
  152. func WithDisableRight() Option {
  153. return func(options *Options) {
  154. options.disableRight = true
  155. }
  156. }
  157. func WithDisableLeftUpdate() Option {
  158. return func(options *Options) {
  159. options.disableLeftUpdate = true
  160. }
  161. }
  162. func WithDisableLeftQuery() Option {
  163. return func(options *Options) {
  164. options.disableLeftQuery = true
  165. }
  166. }
  167. func WithDisableRightUpdate() Option {
  168. return func(options *Options) {
  169. options.disableRightUpdate = true
  170. }
  171. }
  172. func WithDisableRightQuery() Option {
  173. return func(options *Options) {
  174. options.disableRightQuery = true
  175. }
  176. }