service.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. package one2one
  2. import (
  3. "git.sxidc.com/go-framework/baize/convenient/binding"
  4. "git.sxidc.com/go-framework/baize/convenient/binding/request"
  5. "git.sxidc.com/go-framework/baize/convenient/binding/response"
  6. "git.sxidc.com/go-framework/baize/framwork/api"
  7. "git.sxidc.com/go-framework/baize/framwork/domain"
  8. "git.sxidc.com/go-framework/baize/framwork/domain/entity"
  9. "git.sxidc.com/go-framework/baize/framwork/infrastructure"
  10. "git.sxidc.com/go-framework/baize/framwork/infrastructure/database"
  11. "git.sxidc.com/go-framework/baize/framwork/infrastructure/database/sql"
  12. "git.sxidc.com/go-framework/baize/framwork/tag/sql/sql_mapping"
  13. "git.sxidc.com/go-tools/utils/reflectutils"
  14. "git.sxidc.com/go-tools/utils/strutils"
  15. "git.sxidc.com/service-supports/fserr"
  16. "reflect"
  17. )
  18. func Update(fromTableName string, fromRelationFieldName string, fromRelationColumnName string,
  19. toTableName string, toDomainCNName string, toRelationColumnName string) binding.ServiceFunc[any] {
  20. return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
  21. object := objects[0]
  22. if object == nil {
  23. return nil, fserr.New("领域实体为空")
  24. }
  25. dbExecutor := i.DBExecutor()
  26. fromEntity, ok := object.(entity.Entity)
  27. if !ok {
  28. return nil, fserr.New("领域对象不是实体")
  29. }
  30. // 字段校验
  31. err := fromEntity.CheckFieldID(fromEntity.DomainCNName())
  32. if err != nil {
  33. return nil, err
  34. }
  35. // from存在性校验
  36. fromResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
  37. TableName: fromTableName,
  38. Conditions: sql.NewConditions().Equal(entity.ColumnID, fromEntity.GetID()),
  39. })
  40. if err != nil {
  41. if database.IsErrorDBRecordNotExist(err) {
  42. return nil, fserr.New(fromEntity.DomainCNName() + "不存在")
  43. }
  44. return nil, err
  45. }
  46. if !domain.HasField(object, fromRelationFieldName) {
  47. return nil, fserr.New("关联字段" + fromRelationFieldName + "不存在")
  48. }
  49. existFrom := reflect.New(reflect.TypeOf(object).Elem()).Interface()
  50. err = sql.ParseSqlResult(fromResult, existFrom)
  51. if err != nil {
  52. return nil, err
  53. }
  54. currentToID, err := domain.Field[string](existFrom, fromRelationFieldName)
  55. if err != nil {
  56. return nil, err
  57. }
  58. newToID, err := domain.Field[string](object, fromRelationFieldName)
  59. if err != nil {
  60. return nil, err
  61. }
  62. if strutils.IsStringNotEmpty(newToID) {
  63. // to存在性校验
  64. toExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
  65. TableName: toTableName,
  66. Conditions: sql.NewConditions().Equal(entity.ColumnID, newToID),
  67. })
  68. if err != nil {
  69. return nil, err
  70. }
  71. if !toExist {
  72. return nil, fserr.New(fromEntity.DomainCNName() + "关联的" + toDomainCNName + "不存在")
  73. }
  74. }
  75. err = database.Transaction(dbExecutor, func(tx database.Executor) error {
  76. if strutils.IsStringNotEmpty(fromTableName) {
  77. err := database.Update(tx, &sql.UpdateExecuteParams{
  78. TableName: fromTableName,
  79. TableRow: sql.NewTableRow().Add(fromRelationColumnName, newToID),
  80. Conditions: sql.NewConditions().Equal(entity.ColumnID, fromEntity.GetID()),
  81. })
  82. if err != nil {
  83. return err
  84. }
  85. }
  86. if strutils.IsStringNotEmpty(toTableName) &&
  87. (strutils.IsStringNotEmpty(currentToID) || strutils.IsStringNotEmpty(newToID)) {
  88. familyID := fromEntity.GetID()
  89. if strutils.IsStringEmpty(newToID) {
  90. familyID = ""
  91. }
  92. updateToID := currentToID
  93. if strutils.IsStringEmpty(currentToID) {
  94. updateToID = newToID
  95. }
  96. err := database.Update(tx, &sql.UpdateExecuteParams{
  97. TableName: toTableName,
  98. TableRow: sql.NewTableRow().Add(toRelationColumnName, familyID),
  99. Conditions: sql.NewConditions().Equal(entity.ColumnID, updateToID),
  100. })
  101. if err != nil {
  102. return err
  103. }
  104. }
  105. return nil
  106. })
  107. if err != nil {
  108. return nil, err
  109. }
  110. return nil, nil
  111. }
  112. }
  113. func Query[TI any](fromTableName string, toTableName string, toRelationColumnName string) binding.ServiceFunc[TI] {
  114. return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (TI, error) {
  115. outputZero := reflectutils.Zero[TI]()
  116. object := objects[0]
  117. if object == nil {
  118. return outputZero, fserr.New("领域实体为空")
  119. }
  120. dbExecutor := i.DBExecutor()
  121. fromEntity, ok := object.(entity.Entity)
  122. if !ok {
  123. return outputZero, fserr.New("领域对象不是实体")
  124. }
  125. // from存在性校验
  126. fromExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
  127. TableName: fromTableName,
  128. Conditions: sql.NewConditions().Equal(entity.ColumnID, fromEntity.GetID()),
  129. })
  130. if err != nil {
  131. return outputZero, err
  132. }
  133. if !fromExist {
  134. return outputZero, fserr.New(fromEntity.DomainCNName() + "不存在")
  135. }
  136. toResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
  137. TableName: toTableName,
  138. Conditions: sql.NewConditions().Equal(toRelationColumnName, fromEntity.GetID()),
  139. })
  140. if err != nil && !database.IsErrorDBRecordNotExist(err) {
  141. return outputZero, err
  142. }
  143. info := reflectutils.Zero[TI]()
  144. err = sql.ParseSqlResult(toResult, &info)
  145. if err != nil {
  146. return outputZero, err
  147. }
  148. return info, nil
  149. }
  150. }
  151. type ConditionFieldCallback func(conditions *sql.Conditions, fieldName string, columnName string, value any) (hasDeal bool)
  152. func QueryWithOtherInfo[FI any, TI any](fromTableName string, fromRelationColumnName string, fromFieldCallback ConditionFieldCallback, toTableName string) binding.ServiceFunc[response.InfosData[map[string]any]] {
  153. return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[map[string]any], error) {
  154. errResponse := response.InfosData[map[string]any]{
  155. Infos: make([]map[string]any, 0),
  156. }
  157. if params == nil {
  158. return errResponse, fserr.New("请求参数为空")
  159. }
  160. object := objects[0]
  161. if object == nil {
  162. return errResponse, fserr.New("领域实体为空")
  163. }
  164. dbExecutor := i.DBExecutor()
  165. queryParams, ok := params.(request.Query)
  166. if !ok {
  167. return errResponse, fserr.New("请求参数不是Query接口")
  168. }
  169. fromEntity, ok := object.(entity.Entity)
  170. if !ok {
  171. return errResponse, fserr.New("领域对象不是实体")
  172. }
  173. conditions := sql.NewConditions()
  174. fromFields, err := sql_mapping.DefaultUsage(fromEntity)
  175. if err != nil {
  176. return errResponse, err
  177. }
  178. for _, fromField := range fromFields {
  179. hasDeal := false
  180. if fromFieldCallback != nil {
  181. hasDeal = fromFieldCallback(conditions, fromField.FieldName, fromField.ColumnName, fromField.Value)
  182. }
  183. if !hasDeal {
  184. fieldValue := reflect.ValueOf(fromField.Value)
  185. if !fieldValue.IsZero() {
  186. conditions.Equal(fromField.ColumnName, fromField.Value)
  187. }
  188. }
  189. }
  190. fromResults, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{
  191. TableName: fromTableName,
  192. Conditions: conditions,
  193. PageNo: queryParams.GetPageNo(),
  194. PageSize: queryParams.GetPageSize(),
  195. })
  196. if err != nil {
  197. return errResponse, nil
  198. }
  199. if fromResults == nil || len(fromResults) == 0 {
  200. return response.InfosData[map[string]any]{
  201. Infos: make([]map[string]any, 0),
  202. TotalCount: 0,
  203. PageNo: 0,
  204. }, nil
  205. }
  206. toIDs := make([]string, 0)
  207. for _, fromResult := range fromResults {
  208. toID := fromResult.ColumnValueString(fromRelationColumnName)
  209. if strutils.IsStringNotEmpty(toID) {
  210. toIDs = append(toIDs, toID)
  211. }
  212. }
  213. toResults, _, err := database.Query(dbExecutor, &sql.QueryExecuteParams{
  214. TableName: toTableName,
  215. Conditions: sql.NewConditions().In(entity.ColumnID, toIDs),
  216. })
  217. if err != nil {
  218. return errResponse, err
  219. }
  220. toResultMap := make(map[string]sql.Result)
  221. for _, toResult := range toResults {
  222. toID := toResult.ColumnValueString(entity.ColumnID)
  223. toResultMap[toID] = toResult
  224. }
  225. infos := make([]map[string]any, len(fromResults))
  226. for index, fromResult := range fromResults {
  227. fromInfo := reflectutils.Zero[FI]()
  228. toInfo := reflectutils.Zero[TI]()
  229. err = sql.ParseSqlResult(fromResult, &fromInfo)
  230. if err != nil {
  231. return errResponse, err
  232. }
  233. toID := fromResult.ColumnValueString(fromRelationColumnName)
  234. if strutils.IsStringEmpty(toID) {
  235. infos[index] = map[string]any{
  236. "self": fromInfo,
  237. "with": toInfo,
  238. }
  239. continue
  240. }
  241. toResult, ok := toResultMap[toID]
  242. if !ok {
  243. infos[index] = map[string]any{
  244. "self": fromInfo,
  245. "with": toInfo,
  246. }
  247. continue
  248. }
  249. err = sql.ParseSqlResult(toResult, &toInfo)
  250. if err != nil {
  251. return errResponse, err
  252. }
  253. infos[index] = map[string]any{
  254. "self": fromInfo,
  255. "with": toInfo,
  256. }
  257. }
  258. return response.InfosData[map[string]any]{
  259. Infos: infos,
  260. TotalCount: totalCount,
  261. PageNo: queryParams.GetPageNo(),
  262. }, nil
  263. }
  264. }