resource.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. "go-common/app/admin/main/aegis/model"
  11. "go-common/app/admin/main/aegis/model/business"
  12. "go-common/app/admin/main/aegis/model/net"
  13. "go-common/app/admin/main/aegis/model/resource"
  14. "go-common/library/log"
  15. "github.com/jinzhu/gorm"
  16. )
  17. // TxAddResource .
  18. func (s *Service) TxAddResource(ormTx *gorm.DB, b *resource.Resource, r *resource.Result) (rid int64, err error) {
  19. if rid, err = s.gorm.TxAddResource(ormTx, b, r); err != nil {
  20. log.Error("s.dao.TxAddResource error(%v)", err)
  21. }
  22. return
  23. }
  24. // TxUpdateResource .
  25. func (s *Service) TxUpdateResource(tx *gorm.DB, rid int64, res map[string]interface{}, rscRes *resource.Result) (err error) {
  26. if err = s.gorm.TxUpdateResult(tx, rid, res, rscRes); err != nil {
  27. return
  28. }
  29. return s.gorm.TxUpdateResource(tx, rid, res)
  30. }
  31. // CheckResource .
  32. func (s *Service) CheckResource(c context.Context, opt *model.AddOption) (rid int64, err error) {
  33. r, err := s.gorm.ResByOID(c, opt.BusinessID, opt.OID)
  34. if err != nil || r == nil {
  35. return
  36. }
  37. if r != nil {
  38. rid = r.ID
  39. }
  40. return
  41. }
  42. // syncResource 同步到业务方
  43. func (s *Service) syncResource(c context.Context, opt *model.SubmitOptions, mid int64, restoken *net.TokenPackage) (err error) {
  44. if opt.ExtraData == nil {
  45. opt.ExtraData = make(map[string]interface{})
  46. }
  47. opt.ExtraData["mid"] = mid
  48. if opt.Forbid != nil {
  49. if opt.Forbid.Duration > 0 {
  50. opt.Forbid.Duration = opt.Forbid.Duration * 60 * 60 * 24
  51. }
  52. }
  53. act, ropt, err := s.formatSubmitRequest(c, opt, restoken)
  54. if err != nil || act == nil {
  55. log.Error("syncResource formatSubmitRequest opt(%+v) restoken(%+v) error(%v)", opt, restoken, err)
  56. return
  57. }
  58. // TODO: 偶发错误(接口超时,业务方对应错误码等),重试3次
  59. var codes = s.getConfig(c, opt.BusinessID, business.TypeTempCodes)
  60. for i := 0; i < 3; i++ {
  61. var code int
  62. code, err = s.http.SyncResource(c, act, ropt)
  63. if err == nil {
  64. break
  65. }
  66. if err != nil && code == 0 { //http错误不重试了,免得错误日志太多
  67. break
  68. }
  69. if len(codes) > 0 && !strings.Contains(","+codes+",", fmt.Sprintf(",%d,", code)) {
  70. return
  71. }
  72. }
  73. return err
  74. }
  75. // ResourceRes .
  76. func (s *Service) ResourceRes(c context.Context, args *resource.Args) (res *resource.Res, err error) {
  77. if res, err = s.gorm.ResourceRes(c, args.RID); err != nil {
  78. log.Error("s.gorm.ResourceRes error(%v)", err)
  79. }
  80. return
  81. }
  82. // TxDelResource .
  83. func (s *Service) TxDelResource(c context.Context, ormTx *gorm.DB, bizid int64, rids []int64) (delState int, err error) {
  84. delState = -10010
  85. var (
  86. ststr string
  87. )
  88. if ststr = s.getConfig(c, bizid, business.TypeDeleteState); len(ststr) != 0 {
  89. if delState, err = strconv.Atoi(ststr); err != nil {
  90. log.Error("TxDelResource strconv.Atoi error(%v)", err)
  91. return
  92. }
  93. }
  94. err = s.gorm.TxUpdateState(ormTx, rids, delState)
  95. return
  96. }
  97. func (s *Service) formatSubmitRequest(c context.Context, opt *model.SubmitOptions, restoken *net.TokenPackage) (act *model.Action, ropt map[string]interface{}, err error) {
  98. //1. 读取业务回调配置
  99. cfg := s.getConfig(c, opt.BusinessID, business.TypeCallback)
  100. if len(cfg) == 0 {
  101. err = errors.New("empty submit config")
  102. log.Error("FormatSubmitRequest(%d) error(%v)", opt.BusinessID, cfg)
  103. return
  104. }
  105. mapcfg := make(map[string]*model.Action)
  106. if err = json.Unmarshal([]byte(cfg), &mapcfg); err != nil {
  107. log.Error("FormatSubmitRequest(%d) json.Unmarshal error(%v)", opt.BusinessID, cfg)
  108. return
  109. }
  110. var ok bool
  111. //2. 根据流程结果判断,调用哪个回调
  112. if restoken.HitAudit {
  113. act, ok = mapcfg["audit"]
  114. } else {
  115. act, ok = mapcfg["noaudit"]
  116. }
  117. if !ok || act == nil {
  118. err = errors.New("empty submit config[noaudit]")
  119. log.Error("FormatSubmitRequest(%d) error(%v)", opt.BusinessID, cfg)
  120. return
  121. }
  122. ropt = make(map[string]interface{})
  123. ot := reflect.TypeOf(*opt)
  124. ov := reflect.ValueOf(*opt)
  125. for k, v := range act.Params {
  126. model.SubReflect(ot, ov, k, strings.Split(v.Value, "."), v.Default, ropt)
  127. }
  128. //3. 根据回调配置,读取需要的参数进行拼接
  129. for k, v := range restoken.Values {
  130. ropt[k] = v
  131. }
  132. return
  133. }