task.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "sync"
  6. "time"
  7. "go-common/app/admin/main/videoup-task/model"
  8. "go-common/library/log"
  9. "go-common/library/sync/errgroup"
  10. )
  11. // GetStats .
  12. func (s *Service) GetStats(c context.Context) (stats []*model.MemberStat, err error) {
  13. s.memberCache.RLock()
  14. defer s.memberCache.RUnlock()
  15. st := s.memberCache.uptime
  16. if st.IsZero() {
  17. st = time.Now().Add(-30 * time.Minute)
  18. }
  19. rst, err := s.memberStats(c, st, time.Now())
  20. if err != nil {
  21. log.Error("s.MemberStats error(%v)", err)
  22. err = nil
  23. }
  24. for uid, omst := range s.memberCache.ms {
  25. if nmst, ok := rst[uid]; ok {
  26. mst := &model.MemberStat{UID: uid}
  27. mst.DispatchCount = omst.DispatchCount + nmst.DispatchCount
  28. mst.ReleaseCount = omst.ReleaseCount + nmst.ReleaseCount
  29. mst.SubmitCount = omst.SubmitCount + nmst.SubmitCount
  30. mst.OSubmitCount = omst.OSubmitCount + nmst.OSubmitCount
  31. mst.NSubmitCount = omst.NSubmitCount + nmst.NSubmitCount
  32. mst.BelongCount = omst.BelongCount + nmst.BelongCount
  33. mst.PassCount = omst.PassCount + nmst.PassCount
  34. mst.NormalCount = omst.NormalCount + nmst.NormalCount
  35. mst.SubjectCount = omst.SubjectCount + nmst.SubjectCount
  36. mst.SumDu = omst.SumDu + nmst.SumDu
  37. mst.SumDuration = fmt.Sprintf("%.2d:%.2d:%.2d", mst.SumDu/3600, (mst.SumDu%3600)/60, (mst.SumDu%3600)%60)
  38. var CompleteRate, PassRate = 100.0, 100.0
  39. if mst.SubmitCount < mst.BelongCount {
  40. CompleteRate = float64(mst.SubmitCount) / float64(mst.BelongCount) * 100.0
  41. }
  42. if mst.PassCount < mst.SubmitCount {
  43. PassRate = float64(mst.PassCount) / float64(mst.SubmitCount) * 100.0
  44. }
  45. mst.CompleteRate = fmt.Sprintf("%.2f%%", CompleteRate)
  46. mst.PassRate = fmt.Sprintf("%.2f%%", PassRate)
  47. if mst.NSubmitCount == 0 {
  48. mst.AvgUtime = "00:00:00"
  49. } else {
  50. mst.AvgUt = (omst.AvgUt*float64(omst.NSubmitCount) + nmst.AvgUt*float64(nmst.NSubmitCount)) / float64(mst.NSubmitCount)
  51. mst.AvgUtime = fmt.Sprintf("%.2d:%.2d:%.2d", int64(mst.AvgUt)/3600, (int64(mst.AvgUt)%3600)/60, (int64(mst.AvgUt)%3600)%60)
  52. }
  53. delete(rst, uid)
  54. stats = append(stats, mst)
  55. } else {
  56. stats = append(stats, omst)
  57. }
  58. }
  59. if len(rst) > 0 {
  60. for _, nmst := range rst {
  61. stats = append(stats, nmst)
  62. }
  63. }
  64. if len(stats) > 0 {
  65. wg, ctx := errgroup.WithContext(c)
  66. wg.Go(func() error {
  67. if err := s.mulIDtoName(ctx, stats, s.lastInTime, "UID", "InTime"); err != nil {
  68. log.Error("mulIDtoName s.lastInTime error(%v)", err)
  69. }
  70. return nil
  71. })
  72. wg.Go(func() error {
  73. if err := s.mulIDtoName(ctx, stats, s.lastOutTime, "UID", "QuitTime"); err != nil {
  74. log.Error("mulIDtoName s.lastOutTime error(%v)", err)
  75. }
  76. return nil
  77. })
  78. wg.Wait()
  79. }
  80. for _, st := range stats {
  81. if st.QuitTime <= st.InTime {
  82. st.QuitTime = ""
  83. }
  84. }
  85. return
  86. }
  87. // MemberStats 审核人员统计数据[通过旧一审提交。会导致同一个任务被多次完成]
  88. func (s *Service) memberStats(c context.Context, st, et time.Time) (stats map[int64]*model.MemberStat, err error) {
  89. var (
  90. mx sync.Mutex
  91. uids []int64
  92. )
  93. stats = make(map[int64]*model.MemberStat)
  94. if uids, err = s.dao.ActiveUids(c, st, et); err != nil || len(uids) == 0 {
  95. return
  96. }
  97. log.Info("MemberStats,st(%s),et(%s) count(%d) uids(%v) ", st.String(), et.String(), len(uids), uids)
  98. wg := errgroup.Group{}
  99. for _, uid := range uids {
  100. id := uid
  101. wg.Go(func() error {
  102. st, e := s.singleStat(context.TODO(), id, st, et)
  103. if e != nil || st == nil {
  104. log.Error("s.singleStat(%d) error(%v)", id, e)
  105. return nil
  106. }
  107. mx.Lock()
  108. stats[st.UID] = st
  109. mx.Unlock()
  110. return nil
  111. })
  112. }
  113. err = wg.Wait()
  114. return
  115. }
  116. func (s *Service) singleStat(c context.Context, uid int64, stime, etime time.Time) (stat *model.MemberStat, err error) {
  117. var (
  118. SumDuration int64
  119. AvgUtime float64
  120. )
  121. stat = &model.MemberStat{UID: uid}
  122. mapAction, err := s.dao.ActionCountByUID(c, uid, stime, etime)
  123. if err != nil {
  124. return
  125. }
  126. stat.OSubmitCount = mapAction[model.ActionOldSubmit]
  127. stat.NSubmitCount = mapAction[model.ActionSubmit]
  128. stat.SubmitCount = stat.OSubmitCount + stat.NSubmitCount
  129. stat.DispatchCount = mapAction[model.ActionDispatch]
  130. stat.ReleaseCount = mapAction[model.ActionRelease]
  131. if stat.PassCount, err = s.dao.PassCountByUID(c, uid, stime, etime); err != nil {
  132. return
  133. }
  134. if stat.SubjectCount, err = s.dao.SubjectCountByUID(c, uid, stime, etime); err != nil {
  135. return
  136. }
  137. if SumDuration, err = s.dao.SumDurationByUID(c, uid, stime, etime); err != nil {
  138. return
  139. }
  140. if AvgUtime, err = s.dao.AvgUtimeByUID(c, uid, stime, etime); err != nil {
  141. return
  142. }
  143. stat.BelongCount = stat.DispatchCount - stat.ReleaseCount
  144. var CompleteRate, PassRate = 100.0, 100.0
  145. if stat.SubmitCount < stat.BelongCount {
  146. CompleteRate = float64(stat.SubmitCount) / float64(stat.BelongCount) * 100.0
  147. }
  148. if stat.PassCount < stat.SubmitCount {
  149. PassRate = float64(stat.PassCount) / float64(stat.SubmitCount) * 100.0
  150. }
  151. stat.CompleteRate = fmt.Sprintf("%.2f%%", CompleteRate)
  152. stat.PassRate = fmt.Sprintf("%.2f%%", PassRate)
  153. stat.NormalCount = stat.SubmitCount - stat.SubjectCount
  154. stat.SumDu = SumDuration
  155. stat.AvgUt = AvgUtime
  156. stat.SumDuration = fmt.Sprintf("%.2d:%.2d:%.2d", SumDuration/3600, (SumDuration%3600)/60, (SumDuration%3600)%60)
  157. stat.AvgUtime = fmt.Sprintf("%.2d:%.2d:%.2d", int64(AvgUtime)/3600, (int64(AvgUtime)%3600)/60, (int64(AvgUtime)%3600)%60)
  158. return
  159. }
  160. func (s *Service) memberproc() {
  161. for {
  162. st := time.Now()
  163. stats, err := s.memberStats(context.TODO(), st.Add(-24*time.Hour), st)
  164. if err != nil {
  165. log.Error("s.MemberStats error(%v)", err)
  166. } else {
  167. s.memberCache.Lock()
  168. s.memberCache.uptime = st
  169. s.memberCache.ms = stats
  170. s.memberCache.Unlock()
  171. }
  172. log.Info("s.MemberStats ut(%.2f)", time.Since(st).Seconds())
  173. time.Sleep(30 * time.Minute)
  174. }
  175. }