bind_item.go 4.1 KB

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