review.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "go-common/app/admin/main/member/model"
  7. "go-common/app/admin/main/member/model/block"
  8. relation "go-common/app/service/main/relation/model"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. "go-common/library/net/metadata"
  12. "go-common/library/queue/databus/report"
  13. xtime "go-common/library/time"
  14. )
  15. const (
  16. _logActionUserPropertyAudit = "user_property_review_audit"
  17. )
  18. // Reviews is.
  19. func (s *Service) Reviews(ctx context.Context, arg *model.ArgReviewList) ([]*model.UserPropertyReview, int, error) {
  20. bySearch := func() ([]*model.UserPropertyReview, int, error) {
  21. stime := arg.STime.Time().Format("2006-01-02 15:04:05")
  22. if arg.ETime == 0 {
  23. arg.ETime = xtime.Time(time.Now().Unix())
  24. }
  25. etime := arg.ETime.Time().Format("2006-01-02 15:04:05")
  26. property := int8ToInt(arg.Property)
  27. state := int8ToInt(arg.State)
  28. result, err := s.dao.SearchUserPropertyReview(ctx, arg.Mid, property, state, arg.IsMonitor, arg.IsDesc, arg.Operator, stime, etime, arg.Pn, arg.Ps)
  29. if err != nil {
  30. return nil, 0, err
  31. }
  32. ids := result.IDs()
  33. rws, err := s.dao.ReviewByIDs(ctx, ids, arg.State)
  34. if err != nil {
  35. return nil, 0, err
  36. }
  37. rws = arrange(rws, ids)
  38. return rws, result.Total(), nil
  39. }
  40. byDB := func() ([]*model.UserPropertyReview, int, error) {
  41. return s.dao.Reviews(ctx, arg.Mid, arg.Property, arg.State, arg.IsMonitor, arg.IsDesc, arg.Operator, arg.STime, arg.ETime, arg.Pn, arg.Ps)
  42. }
  43. rws, total, err := bySearch()
  44. if arg.ForceDB {
  45. log.Info("Force user property review query to db")
  46. rws, total, err = byDB()
  47. }
  48. if err != nil {
  49. return nil, 0, err
  50. }
  51. for _, rw := range rws {
  52. if rw.Property == model.ReviewPropertyFace {
  53. rw.BuildFaceURL()
  54. }
  55. }
  56. s.reviewsName(ctx, rws)
  57. s.reviewsFaceReject(ctx, rws)
  58. s.reviewsRelationStat(ctx, rws)
  59. return rws, total, err
  60. }
  61. func (s *Service) onReviewSuccess(ctx context.Context, waitRws []*model.UserPropertyReview, arg *model.ArgReviewAudit) error {
  62. if !arg.BlockUser {
  63. return nil
  64. }
  65. blockArg := &block.ParamBatchBlock{
  66. MIDs: waitRwMids(waitRws),
  67. AdminName: arg.Operator,
  68. AdminID: arg.OperatorID,
  69. Source: arg.Source,
  70. Area: arg.Area,
  71. Reason: arg.Reason,
  72. Comment: arg.Comment,
  73. Action: arg.Action,
  74. Duration: arg.Duration,
  75. Notify: arg.Notify,
  76. }
  77. if !blockArg.Validate() {
  78. log.Error("Failed to validate block parama, arg: %v", blockArg)
  79. return ecode.RequestErr
  80. }
  81. if err := s.block.BatchBlock(ctx, blockArg); err != nil {
  82. log.Error("Failed to batch block, error: %v, arg: %v", err, blockArg)
  83. return err
  84. }
  85. return nil
  86. }
  87. // ReviewAudit is.
  88. func (s *Service) ReviewAudit(ctx context.Context, arg *model.ArgReviewAudit) error {
  89. waitRws, err := s.dao.ReviewByIDs(ctx, arg.ID, []int8{model.ReviewStateWait})
  90. if err != nil {
  91. return err
  92. }
  93. if err := s.dao.ReviewAudit(ctx, arg.ID, arg.State, arg.Remark, arg.Operator); err != nil {
  94. return err
  95. }
  96. for _, r := range waitRws {
  97. ak := auditKey(r.Property, r.IsMonitor)
  98. handler, ok := s.auditHandlers[ak]
  99. if !ok {
  100. log.Warn("Unable to handle property update: review: %+v audit: %+v", r, arg)
  101. continue
  102. }
  103. if err := handler(ctx, r, arg); err != nil {
  104. log.Error("Failed to trigger review audit event: review: %+v error: %+v", r, err)
  105. remark := fmt.Sprintf("操作异常:%s, 备注: %s", ecode.Cause(err).Message(), arg.Remark)
  106. if err = s.dao.UpdateRemark(ctx, r.ID, remark); err != nil {
  107. log.Error("Failed to update remark error: %v", err)
  108. }
  109. }
  110. report.Manager(&report.ManagerInfo{
  111. Uname: arg.Operator,
  112. UID: arg.OperatorID,
  113. Business: model.ManagerLogID,
  114. Type: 0,
  115. Oid: r.Mid,
  116. Action: _logActionUserPropertyAudit,
  117. Ctime: time.Now(),
  118. // extra
  119. Index: []interface{}{r.ID, arg.State, 0, arg.Remark, "", ""},
  120. Content: map[string]interface{}{
  121. "remark": arg.Remark,
  122. "state": arg.State,
  123. "id": r.ID,
  124. "mid": r.Mid,
  125. },
  126. })
  127. }
  128. s.onReviewSuccess(ctx, waitRws, arg)
  129. return nil
  130. }
  131. // Review is.
  132. func (s *Service) Review(ctx context.Context, arg *model.ArgReview) (*model.UserPropertyReview, error) {
  133. r, err := s.dao.Review(ctx, arg.ID)
  134. if err != nil {
  135. return nil, err
  136. }
  137. r.Block, err = s.block.History(ctx, r.Mid, 2, 1, true)
  138. if err != nil {
  139. log.Error("Failed to get block review info, error: %v, mid: %v", err, r.Mid)
  140. err = nil
  141. }
  142. return r, nil
  143. }
  144. func (s *Service) reviewsName(ctx context.Context, rws []*model.UserPropertyReview) {
  145. mids := make([]int64, 0, len(rws))
  146. for _, rw := range rws {
  147. mids = append(mids, rw.Mid)
  148. }
  149. bs, err := s.dao.Bases(ctx, mids)
  150. if err != nil {
  151. log.Error("Failed to fetch bases with mids: %+v: %+v", mids, err)
  152. return
  153. }
  154. for _, rw := range rws {
  155. b, ok := bs[rw.Mid]
  156. if !ok {
  157. continue
  158. }
  159. rw.Name = b.Name
  160. }
  161. }
  162. func (s *Service) reviewsFaceReject(ctx context.Context, rws []*model.UserPropertyReview) {
  163. mids := make([]int64, 0, len(rws))
  164. for _, rw := range rws {
  165. mids = append(mids, rw.Mid)
  166. }
  167. frs, err := s.dao.BatchUserAddit(ctx, mids)
  168. if err != nil {
  169. log.Error("Failed to fetch FaceRejects with mids: %+v: %+v", mids, err)
  170. return
  171. }
  172. for _, rw := range rws {
  173. if fr, ok := frs[rw.Mid]; ok {
  174. rw.FaceReject = fr.FaceReject
  175. }
  176. }
  177. }
  178. func (s *Service) reviewsRelationStat(ctx context.Context, rws []*model.UserPropertyReview) {
  179. mids := make([]int64, 0, len(rws))
  180. for _, rw := range rws {
  181. mids = append(mids, rw.Mid)
  182. }
  183. stats, err := s.relationRPC.Stats(ctx, &relation.ArgMids{
  184. Mids: mids,
  185. RealIP: metadata.String(ctx, metadata.RemoteIP),
  186. })
  187. if err != nil {
  188. log.Error("Failed to fetch relation stat with mids: %+v: %+v", mids, err)
  189. return
  190. }
  191. for _, rw := range rws {
  192. stat, ok := stats[rw.Mid]
  193. if !ok {
  194. continue
  195. }
  196. rw.Follower = stat.Follower
  197. }
  198. }
  199. func int8ToInt(in []int8) []int {
  200. res := []int{}
  201. for _, i := range in {
  202. res = append(res, int(i))
  203. }
  204. return res
  205. }
  206. func arrange(rws []*model.UserPropertyReview, ids []int64) []*model.UserPropertyReview {
  207. res := []*model.UserPropertyReview{}
  208. tmp := make(map[int64]*model.UserPropertyReview, len(ids))
  209. for _, rw := range rws {
  210. tmp[rw.ID] = rw
  211. }
  212. for _, id := range ids {
  213. if rw, ok := tmp[id]; ok {
  214. res = append(res, rw)
  215. }
  216. }
  217. return res
  218. }
  219. func waitRwMids(waitRws []*model.UserPropertyReview) []int64 {
  220. mids := make([]int64, 0, len(waitRws))
  221. for _, w := range waitRws {
  222. mids = append(mids, w.Mid)
  223. }
  224. return mids
  225. }