av_charge.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. package charge
  2. import (
  3. "bytes"
  4. "context"
  5. "strconv"
  6. "time"
  7. dao "go-common/app/job/main/growup/dao/charge"
  8. model "go-common/app/job/main/growup/model/charge"
  9. "go-common/library/log"
  10. xtime "go-common/library/time"
  11. "golang.org/x/sync/errgroup"
  12. )
  13. func (s *Service) handleAvCharge(c context.Context, date time.Time,
  14. dailyChannel chan []*model.AvCharge) (weeklyChargeMap, monthlyChargeMap map[int64]*model.AvCharge, chargeStatisMap map[int64]*model.AvChargeStatis, err error) {
  15. var eg errgroup.Group
  16. weeklyChargeMap = make(map[int64]*model.AvCharge)
  17. monthlyChargeMap = make(map[int64]*model.AvCharge)
  18. eg.Go(func() (err error) {
  19. avWeeklyCharge, err := s.GetAvCharge(c, getStartWeeklyDate(date), s.dao.AvWeeklyCharge)
  20. if err != nil {
  21. log.Error("s.GetAvCharge(av_weekly_charge) error(%v)", err)
  22. return
  23. }
  24. for _, weeklyCharge := range avWeeklyCharge {
  25. weeklyChargeMap[weeklyCharge.AvID] = weeklyCharge
  26. }
  27. return
  28. })
  29. eg.Go(func() (err error) {
  30. avMonthlyCharge, err := s.GetAvCharge(c, getStartMonthlyDate(date), s.dao.AvMonthlyCharge)
  31. if err != nil {
  32. log.Error("s.GetAvCharge(av_monthly_charge) error(%v)", err)
  33. return
  34. }
  35. for _, monthlyCharge := range avMonthlyCharge {
  36. monthlyChargeMap[monthlyCharge.AvID] = monthlyCharge
  37. }
  38. return
  39. })
  40. eg.Go(func() (err error) {
  41. chargeStatisMap, err = s.GetAvChargeStatisMap(c)
  42. if err != nil {
  43. log.Error("s.GetAvChargeStatisMap error(%v)", err)
  44. }
  45. return
  46. })
  47. if err = eg.Wait(); err != nil {
  48. log.Error("HandleAvCharge eg.Wait error(%v)", err)
  49. return
  50. }
  51. s.calAvCharges(date, weeklyChargeMap, monthlyChargeMap, chargeStatisMap, dailyChannel)
  52. return
  53. }
  54. func (s *Service) avDailyCharges(c context.Context, date time.Time, ch chan []*model.AvCharge) (err error) {
  55. defer func() {
  56. close(ch)
  57. }()
  58. var id int64
  59. for {
  60. var charges []*model.AvCharge
  61. charges, err = s.dao.AvDailyCharge(c, date, id, _limitSize)
  62. if err != nil {
  63. return
  64. }
  65. ch <- charges
  66. if len(charges) < _limitSize {
  67. break
  68. }
  69. id = charges[len(charges)-1].ID
  70. }
  71. return
  72. }
  73. // GetAvCharge get av charge
  74. func (s *Service) GetAvCharge(c context.Context, date time.Time, fn dao.IAvCharge) (avCharges []*model.AvCharge, err error) {
  75. var id int64
  76. for {
  77. var avCharge []*model.AvCharge
  78. avCharge, err = fn(c, date, id, _limitSize)
  79. if err != nil {
  80. return
  81. }
  82. avCharges = append(avCharges, avCharge...)
  83. if len(avCharge) < _limitSize {
  84. break
  85. }
  86. id = avCharge[len(avCharge)-1].ID
  87. }
  88. return
  89. }
  90. func (s *Service) calAvCharges(date time.Time, weeklyChargeMap, monthlyChargeMap map[int64]*model.AvCharge, chargeStatisMap map[int64]*model.AvChargeStatis, dailyChannel chan []*model.AvCharge) {
  91. for avDailyCharge := range dailyChannel {
  92. s.calAvCharge(date, avDailyCharge, weeklyChargeMap, monthlyChargeMap, chargeStatisMap)
  93. }
  94. }
  95. func (s *Service) calAvCharge(date time.Time, avDailyCharge []*model.AvCharge, weeklyChargeMap, monthlyChargeMap map[int64]*model.AvCharge, chargeStatisMap map[int64]*model.AvChargeStatis) {
  96. for _, dailyCharge := range avDailyCharge {
  97. if weeklyCharge, ok := weeklyChargeMap[dailyCharge.AvID]; ok {
  98. updateAvCharge(weeklyCharge, dailyCharge)
  99. } else {
  100. weeklyChargeMap[dailyCharge.AvID] = addAvCharge(dailyCharge, startWeeklyDate)
  101. }
  102. if monthlyCharge, ok := monthlyChargeMap[dailyCharge.AvID]; ok {
  103. updateAvCharge(monthlyCharge, dailyCharge)
  104. } else {
  105. monthlyChargeMap[dailyCharge.AvID] = addAvCharge(dailyCharge, startMonthlyDate)
  106. }
  107. s.CalAvChargeStatis(dailyCharge, chargeStatisMap)
  108. }
  109. }
  110. func addAvCharge(daily *model.AvCharge, fixDate time.Time) *model.AvCharge {
  111. return &model.AvCharge{
  112. AvID: daily.AvID,
  113. MID: daily.MID,
  114. TagID: daily.TagID,
  115. IsOriginal: daily.IsOriginal,
  116. DanmakuCount: daily.DanmakuCount,
  117. CommentCount: daily.CommentCount,
  118. CollectCount: daily.CollectCount,
  119. CoinCount: daily.CoinCount,
  120. ShareCount: daily.ShareCount,
  121. ElecPayCount: daily.ElecPayCount,
  122. TotalPlayCount: daily.TotalPlayCount,
  123. WebPlayCount: daily.WebPlayCount,
  124. AppPlayCount: daily.AppPlayCount,
  125. H5PlayCount: daily.H5PlayCount,
  126. LvUnknown: daily.LvUnknown,
  127. Lv0: daily.Lv0,
  128. Lv1: daily.Lv1,
  129. Lv2: daily.Lv2,
  130. Lv3: daily.Lv3,
  131. Lv4: daily.Lv4,
  132. Lv5: daily.Lv5,
  133. Lv6: daily.Lv6,
  134. VScore: daily.VScore,
  135. IncCharge: daily.IncCharge,
  136. TotalCharge: daily.IncCharge,
  137. Date: xtime.Time(fixDate.Unix()),
  138. UploadTime: daily.UploadTime,
  139. DBState: _dbInsert,
  140. }
  141. }
  142. func updateAvCharge(origin, daily *model.AvCharge) {
  143. origin.DanmakuCount += daily.DanmakuCount
  144. origin.CommentCount += daily.CommentCount
  145. origin.CollectCount += daily.CollectCount
  146. origin.CoinCount += daily.CoinCount
  147. origin.ShareCount += daily.ShareCount
  148. origin.ElecPayCount += daily.ElecPayCount
  149. origin.TotalPlayCount += daily.TotalPlayCount
  150. origin.WebPlayCount += daily.WebPlayCount
  151. origin.AppPlayCount += daily.AppPlayCount
  152. origin.H5PlayCount += daily.H5PlayCount
  153. origin.LvUnknown += daily.LvUnknown
  154. origin.Lv0 += daily.Lv0
  155. origin.Lv1 += daily.Lv1
  156. origin.Lv2 += daily.Lv2
  157. origin.Lv3 += daily.Lv3
  158. origin.Lv4 += daily.Lv4
  159. origin.Lv5 += daily.Lv5
  160. origin.Lv6 += daily.Lv6
  161. origin.VScore += daily.VScore
  162. origin.IncCharge += daily.IncCharge
  163. origin.TotalCharge += daily.IncCharge
  164. origin.DBState = _dbUpdate
  165. }
  166. // AvChargeDBStore store data
  167. func (s *Service) AvChargeDBStore(c context.Context, table string, avChargeMap map[int64]*model.AvCharge) error {
  168. insert, update := make([]*model.AvCharge, _batchSize), make([]*model.AvCharge, _batchSize)
  169. insertIndex, updateIndex := 0, 0
  170. for _, charge := range avChargeMap {
  171. if charge.DBState == _dbInsert {
  172. insert[insertIndex] = charge
  173. insertIndex++
  174. } else if charge.DBState == _dbUpdate {
  175. update[updateIndex] = charge
  176. updateIndex++
  177. }
  178. if insertIndex >= _batchSize {
  179. _, err := s.avChargeBatchInsert(c, insert[:insertIndex], table)
  180. if err != nil {
  181. log.Error("s.avChargeBatchInsert error(%v)", err)
  182. return err
  183. }
  184. insertIndex = 0
  185. }
  186. if updateIndex >= _batchSize {
  187. _, err := s.avChargeBatchInsert(c, update[:updateIndex], table)
  188. if err != nil {
  189. log.Error("s.avChargeBatchInsert error(%v)", err)
  190. return err
  191. }
  192. updateIndex = 0
  193. }
  194. }
  195. if insertIndex > 0 {
  196. _, err := s.avChargeBatchInsert(c, insert[:insertIndex], table)
  197. if err != nil {
  198. log.Error("s.avChargeBatchInsert error(%v)", err)
  199. return err
  200. }
  201. }
  202. if updateIndex > 0 {
  203. _, err := s.avChargeBatchInsert(c, update[:updateIndex], table)
  204. if err != nil {
  205. log.Error("s.avChargeBatchInsert error(%v)", err)
  206. return err
  207. }
  208. }
  209. return nil
  210. }
  211. func assembleAvCharge(avCharge []*model.AvCharge) (vals string) {
  212. var buf bytes.Buffer
  213. for _, row := range avCharge {
  214. buf.WriteString("(")
  215. buf.WriteString(strconv.FormatInt(row.AvID, 10))
  216. buf.WriteByte(',')
  217. buf.WriteString(strconv.FormatInt(row.MID, 10))
  218. buf.WriteByte(',')
  219. buf.WriteString(strconv.FormatInt(row.TagID, 10))
  220. buf.WriteByte(',')
  221. buf.WriteString(strconv.Itoa(row.IsOriginal))
  222. buf.WriteByte(',')
  223. buf.WriteString(strconv.FormatInt(row.DanmakuCount, 10))
  224. buf.WriteByte(',')
  225. buf.WriteString(strconv.FormatInt(row.CommentCount, 10))
  226. buf.WriteByte(',')
  227. buf.WriteString(strconv.FormatInt(row.CollectCount, 10))
  228. buf.WriteByte(',')
  229. buf.WriteString(strconv.FormatInt(row.CoinCount, 10))
  230. buf.WriteByte(',')
  231. buf.WriteString(strconv.FormatInt(row.ShareCount, 10))
  232. buf.WriteByte(',')
  233. buf.WriteString(strconv.FormatInt(row.ElecPayCount, 10))
  234. buf.WriteByte(',')
  235. buf.WriteString(strconv.FormatInt(row.TotalPlayCount, 10))
  236. buf.WriteByte(',')
  237. buf.WriteString(strconv.FormatInt(row.WebPlayCount, 10))
  238. buf.WriteByte(',')
  239. buf.WriteString(strconv.FormatInt(row.AppPlayCount, 10))
  240. buf.WriteByte(',')
  241. buf.WriteString(strconv.FormatInt(row.H5PlayCount, 10))
  242. buf.WriteByte(',')
  243. buf.WriteString(strconv.FormatInt(row.LvUnknown, 10))
  244. buf.WriteByte(',')
  245. buf.WriteString(strconv.FormatInt(row.Lv0, 10))
  246. buf.WriteByte(',')
  247. buf.WriteString(strconv.FormatInt(row.Lv1, 10))
  248. buf.WriteByte(',')
  249. buf.WriteString(strconv.FormatInt(row.Lv2, 10))
  250. buf.WriteByte(',')
  251. buf.WriteString(strconv.FormatInt(row.Lv3, 10))
  252. buf.WriteByte(',')
  253. buf.WriteString(strconv.FormatInt(row.Lv4, 10))
  254. buf.WriteByte(',')
  255. buf.WriteString(strconv.FormatInt(row.Lv5, 10))
  256. buf.WriteByte(',')
  257. buf.WriteString(strconv.FormatInt(row.Lv6, 10))
  258. buf.WriteByte(',')
  259. buf.WriteString(strconv.FormatInt(row.VScore, 10))
  260. buf.WriteByte(',')
  261. buf.WriteString(strconv.FormatInt(row.IncCharge, 10))
  262. buf.WriteByte(',')
  263. buf.WriteString(strconv.FormatInt(row.TotalCharge, 10))
  264. buf.WriteByte(',')
  265. buf.WriteString("'" + row.Date.Time().Format(_layout) + "'")
  266. buf.WriteByte(',')
  267. buf.WriteString("'" + row.UploadTime.Time().Format(_layoutSec) + "'")
  268. buf.WriteString(")")
  269. buf.WriteByte(',')
  270. }
  271. if buf.Len() > 0 {
  272. buf.Truncate(buf.Len() - 1)
  273. }
  274. vals = buf.String()
  275. buf.Reset()
  276. return
  277. }
  278. func (s *Service) avChargeBatchInsert(c context.Context, avCharge []*model.AvCharge, table string) (rows int64, err error) {
  279. vals := assembleAvCharge(avCharge)
  280. rows, err = s.dao.InsertAvChargeTable(c, vals, table)
  281. return
  282. }