av_charge.go 11 KB

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