overview.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. package data
  2. import (
  3. "context"
  4. "sort"
  5. "time"
  6. "go-common/app/interface/main/creative/model/data"
  7. "go-common/app/interface/main/creative/model/tag"
  8. "go-common/library/ecode"
  9. "go-common/library/log"
  10. )
  11. func beginningOfDay(t time.Time) time.Time {
  12. d := time.Duration(-t.Hour()) * time.Hour
  13. return t.Truncate(time.Hour).Add(d)
  14. }
  15. func getTuesday(now time.Time) time.Time {
  16. t := beginningOfDay(now)
  17. weekday := int(t.Weekday())
  18. if weekday == 0 {
  19. weekday = 7
  20. }
  21. d := time.Duration(-weekday+2) * 24 * time.Hour
  22. return t.Truncate(time.Hour).Add(d)
  23. }
  24. func getSunday(now time.Time) time.Time {
  25. t := beginningOfDay(now)
  26. weekday := int(t.Weekday())
  27. if weekday == 0 {
  28. return t
  29. }
  30. d := time.Duration(7-weekday) * 24 * time.Hour
  31. return t.Truncate(time.Hour).Add(d)
  32. }
  33. func getDate() (sd string) {
  34. t := time.Now()
  35. td := getTuesday(t).Add(12 * time.Hour)
  36. if t.Before(td) { //当前时间在本周二12点之前,则取上上周日的数据,否则取上周日的数据
  37. sd = getSunday(t.AddDate(0, 0, -14)).Format("20060102")
  38. } else {
  39. sd = getSunday(t.AddDate(0, 0, -7)).Format("20060102")
  40. }
  41. log.Info("current time (%s) tuesday (%s) sunday (%s)", t.Format("2006-01-02 15:04:05"), td, sd)
  42. return
  43. }
  44. // NewStat get stat from hbase.
  45. func (s *Service) NewStat(c context.Context, mid int64, ip string) (r *data.Stat, err error) {
  46. hbaseDate1 := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
  47. hbaseDate2 := time.Now().AddDate(0, 0, -2).Add(-12 * time.Hour).Format("20060102")
  48. var r1, r2 *data.UpBaseStat
  49. if r1, err = s.data.UpStat(c, mid, hbaseDate1); err != nil || r1 == nil {
  50. log.Error("s.data.NewStat error(%v) mid(%d) r1(%v) ip(%s)", err, mid, r1, ip)
  51. err = ecode.CreativeDataErr
  52. return
  53. }
  54. if r2, err = s.data.UpStat(c, mid, hbaseDate2); err != nil || r2 == nil {
  55. log.Error("s.data.NewStat error(%v) mid(%d) r2(%v) ip(%s)", err, mid, r2, ip)
  56. err = ecode.CreativeDataErr
  57. return
  58. }
  59. r = &data.Stat{}
  60. if r1 != nil {
  61. r.Play = r1.View
  62. r.Dm = r1.Dm
  63. r.Comment = r1.Reply
  64. r.Fan = r1.Fans
  65. r.Fav = r1.Fav
  66. r.Like = r1.Like
  67. r.Share = r1.Share
  68. r.Coin = r1.Coin
  69. r.Elec = r1.Elec
  70. }
  71. log.Info("s.data.UpStat hbaseDate1(%+v) mid(%d)", r1, mid)
  72. if r2 != nil {
  73. r.PlayLast = r2.View
  74. r.DmLast = r2.Dm
  75. r.CommentLast = r2.Reply
  76. r.FanLast = r2.Fans
  77. r.FavLast = r2.Fav
  78. r.LikeLast = r2.Like
  79. r.ShareLast = r2.Share
  80. r.CoinLast = r2.Coin
  81. r.ElecLast = r2.Elec
  82. }
  83. log.Info("s.data.UpStat hbaseDate2 (%+v) mid(%d)", r2, mid)
  84. pfl, err := s.acc.ProfileWithStat(c, mid)
  85. if err != nil {
  86. return
  87. }
  88. r.Fan = int64(pfl.Follower)
  89. return
  90. }
  91. // ViewerBase get up viewer base data.
  92. func (s *Service) ViewerBase(c context.Context, mid int64) (res map[string]*data.ViewerBase, err error) {
  93. dt := getDate()
  94. // try cache
  95. if res, _ = s.data.ViewerBaseCache(c, mid, dt); res != nil {
  96. s.pCacheHit.Incr("viewer_base_cache")
  97. return
  98. }
  99. // from data source
  100. if res, err = s.data.ViewerBase(c, mid, dt); len(res) != 0 {
  101. s.pCacheMiss.Incr("viewer_base_cache")
  102. s.data.AddCache(func() {
  103. s.data.AddViewerBaseCache(context.Background(), mid, dt, res)
  104. })
  105. }
  106. return
  107. }
  108. // ViewerArea get up viewer area data.
  109. func (s *Service) ViewerArea(c context.Context, mid int64) (res map[string]map[string]int64, err error) {
  110. dt := getDate()
  111. // try cache
  112. if res, _ = s.data.ViewerAreaCache(c, mid, dt); res != nil {
  113. s.pCacheHit.Incr("viewer_area_cache")
  114. return
  115. }
  116. // from data source
  117. if res, err = s.data.ViewerArea(c, mid, dt); len(res) != 0 {
  118. s.pCacheMiss.Incr("viewer_area_cache")
  119. s.data.AddCache(func() {
  120. s.data.AddViewerAreaCache(context.Background(), mid, dt, res)
  121. })
  122. }
  123. return
  124. }
  125. // CacheTrend get trend from mc.
  126. func (s *Service) CacheTrend(c context.Context, mid int64) (res map[string]*data.ViewerTrend, err error) {
  127. dt := getDate()
  128. // try cache
  129. if res, err = s.data.TrendCache(c, mid, dt); err != nil {
  130. log.Error("trend s.data.TrendCache err(%v)", err)
  131. return
  132. }
  133. if len(res) != 0 {
  134. s.pCacheHit.Incr("trend_cache")
  135. return
  136. }
  137. // from data source
  138. if res, err = s.viewerTrend(c, mid, dt); err != nil {
  139. return
  140. }
  141. s.pCacheMiss.Incr("trend_cache")
  142. if len(res) != 0 {
  143. s.data.AddCache(func() {
  144. s.data.AddTrendCache(context.Background(), mid, dt, res)
  145. })
  146. }
  147. return
  148. }
  149. // ViewerTrend get up viewer trend data.
  150. func (s *Service) viewerTrend(c context.Context, mid int64, dt string) (res map[string]*data.ViewerTrend, err error) {
  151. ut, err := s.data.ViewerTrend(c, mid, dt)
  152. if err != nil || ut == nil {
  153. log.Error("trend s.data.ViewerTrend err(%v)", err)
  154. return
  155. }
  156. f := []string{"fan", "not_fan"}
  157. skeys := make([]int, 0) //for tag sort.
  158. tgs := make([]int64, 0) // for request tag name.
  159. res = make(map[string]*data.ViewerTrend)
  160. for _, fk := range f {
  161. td := ut[fk]
  162. vt := &data.ViewerTrend{}
  163. if td == nil {
  164. vt.Ty = nil
  165. vt.Tag = nil
  166. res[fk] = vt
  167. continue
  168. }
  169. tg := make(map[int]string) //return tag map to user.
  170. ty := make(map[string]int64) //return type map to user.
  171. //deal type for type name.
  172. if td.Ty != nil {
  173. for k, v := range td.Ty {
  174. ke := int16(k)
  175. if t, ok := s.p.TypeMapCache[ke]; ok {
  176. ty[t.Name] = v
  177. }
  178. }
  179. } else {
  180. ty = nil
  181. }
  182. // deal tag for tag name.
  183. if td.Tag != nil {
  184. for k, v := range td.Tag {
  185. tgs = append(tgs, v)
  186. skeys = append(skeys, k)
  187. }
  188. var tlist []*tag.Meta
  189. if tlist, err = s.dtag.TagList(c, tgs); err != nil {
  190. log.Error("trend s.dtag.TagList err(%v)", err)
  191. }
  192. tNameMap := make(map[int64]string)
  193. for _, v := range tlist {
  194. tNameMap[v.TagID] = v.TagName
  195. }
  196. for _, k := range skeys {
  197. if _, ok := tNameMap[td.Tag[k]]; ok {
  198. tg[k] = tNameMap[td.Tag[k]]
  199. }
  200. }
  201. } else {
  202. tg = nil
  203. }
  204. vt.Ty = ty
  205. vt.Tag = tg
  206. res[fk] = vt
  207. }
  208. return
  209. }
  210. // RelationFansDay get up viewer trend data.
  211. func (s *Service) RelationFansDay(c context.Context, mid int64) (res map[string]map[string]int, err error) {
  212. dt := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
  213. // try cache
  214. if res, _ = s.data.RelationFansDayCache(c, mid, dt); res != nil {
  215. s.pCacheHit.Incr("relation_fans_day_cache")
  216. return
  217. }
  218. // from data source
  219. if res, err = s.data.RelationFansDay(c, mid); len(res) != 0 {
  220. s.pCacheMiss.Incr("relation_fans_day_cache")
  221. s.data.AddCache(func() {
  222. s.data.AddRelationFansDayCache(context.Background(), mid, dt, res)
  223. })
  224. }
  225. return
  226. }
  227. // RelationFansHistory get relation history data by month.
  228. func (s *Service) RelationFansHistory(c context.Context, mid int64, month string) (res map[string]map[string]int, err error) {
  229. if res, err = s.data.RelationFansHistory(c, mid, month); err != nil {
  230. log.Error("s.data.RelationFansHistory err(%v)", err)
  231. }
  232. return
  233. }
  234. // RelationFansMonth get up viewer trend data.
  235. func (s *Service) RelationFansMonth(c context.Context, mid int64) (res map[string]map[string]int, err error) {
  236. dt := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour).Format("20060102")
  237. // try cache
  238. if res, _ = s.data.RelationFansMonthCache(c, mid, dt); res != nil {
  239. s.pCacheHit.Incr("relation_fans_month_cache")
  240. return
  241. }
  242. // from data source
  243. if res, err = s.data.RelationFansMonth(c, mid); len(res) != 0 {
  244. s.pCacheMiss.Incr("relation_fans_month_cache")
  245. s.data.AddCache(func() {
  246. s.data.AddRelationFansMonthCache(context.Background(), mid, dt, res)
  247. })
  248. }
  249. return
  250. }
  251. // ViewerActionHour get up viewer action hour data.
  252. func (s *Service) ViewerActionHour(c context.Context, mid int64) (res map[string]*data.ViewerActionHour, err error) {
  253. dt := getDate()
  254. // try cache
  255. if res, _ = s.data.ViewerActionHourCache(c, mid, dt); res != nil {
  256. s.pCacheHit.Incr("viewer_action_hour_cache")
  257. return
  258. }
  259. // from data source
  260. if res, err = s.data.ViewerActionHour(c, mid, dt); len(res) != 0 {
  261. s.data.AddCache(func() {
  262. s.pCacheMiss.Incr("viewer_action_hour_cache")
  263. s.data.AddViewerActionHourCache(context.Background(), mid, dt, res)
  264. })
  265. }
  266. return
  267. }
  268. // UpIncr for Play/Dm/Reply/Fav/Share/Elec/Coin incr.
  269. func (s *Service) UpIncr(c context.Context, mid int64, ty int8, ip string) (res map[string]*data.ViewerIncr, err error) {
  270. tyStr, _ := data.IncrTy(ty)
  271. res = make(map[string]*data.ViewerIncr)
  272. daytime := time.Now().AddDate(0, 0, -1).Add(-12 * time.Hour)
  273. datekey := daytime.Format("20060102")
  274. dt := daytime.Format("20060102")
  275. vic, _ := s.data.ViewerIncrCache(c, mid, tyStr, dt)
  276. if vic != nil {
  277. s.pCacheHit.Incr("viewer_incr_cache")
  278. res[datekey] = vic
  279. log.Info("s.data.ViewerIncrCache mid(%d) cache(%v) err(%v)", mid, vic, err)
  280. return
  281. }
  282. incr, _ := s.data.UpIncr(c, mid, ty, dt)
  283. if incr == nil {
  284. res[datekey] = nil
  285. log.Info("s.data.UpIncr mid(%d) incr(%v) err(%v)", incr, err)
  286. return
  287. }
  288. tyRank := make(map[string]int) //return type map to user.
  289. for k, v := range incr.Rank {
  290. ke := int16(k)
  291. if t, ok := s.p.TypeMapCache[ke]; ok {
  292. tyRank[t.Name] = v
  293. }
  294. }
  295. sortK := make([]int, 0, len(incr.TopAIDList))
  296. aids := make([]int64, 0, len(incr.TopAIDList))
  297. for k, v := range incr.TopAIDList {
  298. aids = append(aids, v)
  299. sortK = append(sortK, k)
  300. }
  301. avm, _ := s.p.BatchArchives(c, mid, aids, ip)
  302. if len(avm) == 0 {
  303. return
  304. }
  305. sort.Ints(sortK)
  306. arcs := make([]*data.ArcInc, 0, len(avm))
  307. for _, k := range sortK {
  308. if aid, ok := incr.TopAIDList[k]; ok {
  309. if av, ok := avm[aid]; ok {
  310. al := &data.ArcInc{}
  311. al.AID = av.Archive.Aid
  312. al.PTime = av.Archive.PTime
  313. al.Title = av.Archive.Title
  314. al.DayTime = daytime.Unix()
  315. if _, ok := incr.TopIncrList[k]; ok {
  316. al.Incr = incr.TopIncrList[k]
  317. }
  318. arcs = append(arcs, al)
  319. }
  320. }
  321. }
  322. vi := &data.ViewerIncr{}
  323. vi.Arcs = arcs
  324. vi.TotalIncr = incr.Incr
  325. if len(tyRank) == 0 {
  326. vi.TyRank = nil
  327. } else {
  328. vi.TyRank = tyRank
  329. }
  330. res[datekey] = vi
  331. // insert cache. NOTE: sync reason?
  332. s.data.AddCache(func() {
  333. s.pCacheMiss.Incr("viewer_incr_cache")
  334. s.data.AddViewerIncrCache(context.Background(), mid, tyStr, dt, vi)
  335. })
  336. return
  337. }