bind_item.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package binding
  2. import (
  3. "git.sxidc.com/go-framework/baize/framework/core/api"
  4. "git.sxidc.com/go-framework/baize/framework/core/api/request"
  5. "git.sxidc.com/go-framework/baize/framework/core/domain"
  6. "git.sxidc.com/go-tools/utils/reflectutils"
  7. "git.sxidc.com/go-tools/utils/strutils"
  8. "github.com/pkg/errors"
  9. "net/http"
  10. "reflect"
  11. "strings"
  12. )
  13. // Bind 通用绑定
  14. // 类型参数:
  15. // - O: 响应数据类型,对应response.SendResponseFunc的data的类型
  16. // 参数:
  17. // - binder: 用来执行绑定的binder
  18. // - item: 执行绑定的参数
  19. // - middlewares: 该绑定的中间件
  20. func Bind[O any](binder *Binder, item *BindItem[O], middlewares ...Middleware) {
  21. item.bind(binder, middlewares...)
  22. }
  23. // BindItem 通用BindItem
  24. type BindItem[O any] struct {
  25. Method string
  26. *SimpleBindItem[O]
  27. }
  28. func (item *BindItem[O]) bind(binder *Binder, middlewares ...Middleware) {
  29. if strutils.IsStringEmpty(item.Path) {
  30. panic("需要指定路径")
  31. }
  32. if strutils.IsStringEmpty(item.Method) {
  33. panic("需要指定方法")
  34. }
  35. if item.SendResponseFunc == nil {
  36. panic("需要指定响应函数")
  37. }
  38. if item.ServiceFunc == nil {
  39. panic("需要指定应用服务函数")
  40. }
  41. var outputZero O
  42. outputZeroValue := reflect.ValueOf(outputZero)
  43. if outputZeroValue.IsValid() && outputZeroValue.Kind() == reflect.Pointer {
  44. panic("bind的输出类型不能使用指针类型")
  45. }
  46. if outputZeroValue.IsValid() && strings.Contains(outputZeroValue.String(), "response.InfosData") {
  47. infosField := outputZeroValue.FieldByName("Infos")
  48. if infosField.IsValid() && infosField.Type().Elem().Kind() == reflect.Pointer {
  49. panic("bind的输出类型不能使用指针类型")
  50. }
  51. }
  52. apiMiddlewares := make([]api.Handler, len(middlewares))
  53. for i, middleware := range middlewares {
  54. innerMiddleware := middleware
  55. apiMiddlewares[i] = func(c *api.Context) {
  56. innerMiddleware(c, binder.i)
  57. }
  58. }
  59. handlers := append(apiMiddlewares, func(c *api.Context) {
  60. var params request.Params
  61. // 有请求数据
  62. if item.RequestParams != nil {
  63. requestParamsType := reflect.TypeOf(item.RequestParams)
  64. if !reflectutils.IsTypeStructOrStructPointer(requestParamsType) {
  65. item.SendResponseFunc(c, http.StatusOK, outputZero, errors.New("请求参数不是结构或结构指针"))
  66. return
  67. }
  68. if requestParamsType.Kind() == reflect.Pointer {
  69. params = reflect.New(requestParamsType.Elem()).Interface().(request.Params)
  70. } else {
  71. params = reflect.New(requestParamsType).Interface().(request.Params)
  72. }
  73. // 将请求数据解析到请求参数中
  74. if item.BindRequestParamsFunc != nil {
  75. err := item.BindRequestParamsFunc(c, params)
  76. if err != nil {
  77. item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
  78. return
  79. }
  80. } else {
  81. switch item.Method {
  82. case http.MethodPost:
  83. fallthrough
  84. case http.MethodPut:
  85. err := request.BindJsonBody(c, params)
  86. if err != nil {
  87. item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
  88. return
  89. }
  90. case http.MethodDelete:
  91. fallthrough
  92. case http.MethodGet:
  93. err := request.BindQueryParams(c, params)
  94. if err != nil {
  95. item.SendResponseFunc(c, http.StatusBadRequest, outputZero, err)
  96. return
  97. }
  98. }
  99. }
  100. }
  101. // 进行领域对象转化
  102. var domainObjects []domain.Object
  103. if item.FormDomainObjectsFunc != nil {
  104. innerDomainObjects, err := item.FormDomainObjectsFunc(c, params)
  105. if err != nil {
  106. item.SendResponseFunc(c, http.StatusOK, outputZero, err)
  107. return
  108. }
  109. domainObjects = innerDomainObjects
  110. } else {
  111. if item.Objects != nil && len(item.Objects) != 0 {
  112. for _, object := range item.Objects {
  113. if object == nil {
  114. continue
  115. }
  116. objectType := reflect.TypeOf(object)
  117. if !reflectutils.IsTypeStructOrStructPointer(objectType) {
  118. item.SendResponseFunc(c, http.StatusOK, outputZero, errors.New("领域对象不是结构或结构指针"))
  119. return
  120. }
  121. obj := reflect.New(reflectutils.PointerTypeElem(objectType)).Interface().(domain.Object)
  122. if params != nil {
  123. err := request.AssignRequestParamsToDomainObject(params, obj)
  124. if err != nil {
  125. item.SendResponseFunc(c, http.StatusOK, outputZero, err)
  126. return
  127. }
  128. }
  129. domainObjects = append(domainObjects, obj)
  130. }
  131. }
  132. }
  133. // 执行业务函数
  134. outputModel, err := item.ServiceFunc(c, params, domainObjects, binder.i)
  135. item.SendResponseFunc(c, http.StatusOK, outputModel, err)
  136. return
  137. })
  138. // 所有的函数加入到执行链中
  139. binder.router.AddRoute(item.Method, item.Path, handlers...)
  140. }