bind_item.go 4.3 KB

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