favorite.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. package service
  2. import (
  3. "context"
  4. "time"
  5. "go-common/app/interface/main/esports/model"
  6. favmdl "go-common/app/service/main/favorite/model"
  7. "go-common/library/ecode"
  8. "go-common/library/log"
  9. "go-common/library/net/metadata"
  10. "go-common/library/sync/errgroup"
  11. )
  12. const (
  13. _firstPs = 5
  14. _firstAppPs = 50
  15. _favDay = 15
  16. )
  17. var _empStime = make([]string, 0)
  18. // AddFav add favorite contest.
  19. func (s *Service) AddFav(c context.Context, mid, cid int64) (err error) {
  20. var (
  21. contest *model.Contest
  22. mapC map[int64]*model.Contest
  23. ip = metadata.String(c, metadata.RemoteIP)
  24. )
  25. if mapC, err = s.dao.EpContests(c, []int64{cid}); err != nil {
  26. return
  27. }
  28. contest = mapC[cid]
  29. if contest == nil || contest.ID == 0 {
  30. err = ecode.EsportsContestNotExist
  31. return
  32. }
  33. if contest.LiveRoom <= 0 {
  34. err = ecode.EsportsContestFavNot
  35. return
  36. }
  37. nowTime := time.Now().Unix()
  38. if contest.Etime > 0 && nowTime >= contest.Etime {
  39. err = ecode.EsportsContestEnd
  40. return
  41. }
  42. if contest.Stime == 0 || nowTime >= contest.Stime {
  43. err = ecode.EsportsContestStart
  44. return
  45. }
  46. subDay := timeSub(contest.Stime)
  47. if subDay > _favDay {
  48. err = ecode.EsportsContestNotDay
  49. return
  50. }
  51. arg := &favmdl.ArgAdd{Type: favmdl.TypeEsports, Mid: mid, Oid: cid, Fid: 0, RealIP: ip}
  52. if err = s.fav.Add(c, arg); err != nil {
  53. log.Error("AddFav s.fav.Add(%+v) error(%v)", arg, err)
  54. return
  55. }
  56. if err = s.dao.DelFavCoCache(c, mid); err != nil {
  57. log.Error("AddFav s.dao.DelFavCoCache mid(%d) error(%v)", mid, err)
  58. return
  59. }
  60. return
  61. }
  62. func timeSub(stime int64) int {
  63. var (
  64. nowTime, endTime time.Time
  65. )
  66. nowTime = time.Now()
  67. endTime = time.Unix(stime, 0)
  68. nowTime = time.Date(nowTime.Year(), nowTime.Month(), nowTime.Day(), 0, 0, 0, 0, time.Local)
  69. endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, time.Local)
  70. return int(endTime.Sub(nowTime).Hours() / 24)
  71. }
  72. // DelFav delete favorite contest.
  73. func (s *Service) DelFav(c context.Context, mid, cid int64) (err error) {
  74. var (
  75. contest *model.Contest
  76. mapC map[int64]*model.Contest
  77. ip = metadata.String(c, metadata.RemoteIP)
  78. )
  79. if mapC, err = s.dao.EpContests(c, []int64{cid}); err != nil {
  80. return
  81. }
  82. contest = mapC[cid]
  83. if contest == nil || contest.ID == 0 {
  84. err = ecode.EsportsContestNotExist
  85. return
  86. }
  87. arg := &favmdl.ArgDel{Type: favmdl.TypeEsports, Mid: mid, Oid: cid, Fid: 0, RealIP: ip}
  88. if err = s.fav.Del(c, arg); err != nil {
  89. log.Error("DelFav s.fav.Del(%+v) error(%v)", arg, err)
  90. return
  91. }
  92. if err = s.dao.DelFavCoCache(c, mid); err != nil {
  93. log.Error("DelFav s.dao.DelFavCoCache mid(%d) error(%v)", mid, err)
  94. return
  95. }
  96. return
  97. }
  98. // ListFav list favorite contests.
  99. func (s *Service) ListFav(c context.Context, mid, vmid int64, pn, ps int) (rs []*model.Contest, count int, err error) {
  100. var (
  101. isFirst bool
  102. uid int64
  103. favRes *favmdl.Favorites
  104. cids []int64
  105. ip = metadata.String(c, metadata.RemoteIP)
  106. teams, seasons []*model.Filter
  107. cData map[int64]*model.Contest
  108. favContest []*model.Contest
  109. group *errgroup.Group
  110. contErr, teamErr, seasonErr error
  111. )
  112. if vmid > 0 {
  113. uid = vmid
  114. } else {
  115. uid = mid
  116. }
  117. isFirst = pn == 1 && ps == _firstPs
  118. if isFirst {
  119. if rs, count, err = s.dao.FavCoCache(c, uid); err != nil {
  120. err = nil
  121. }
  122. if len(rs) > 0 {
  123. s.fmtContest(c, rs, mid)
  124. return
  125. }
  126. }
  127. arg := &favmdl.ArgFavs{Type: favmdl.TypeEsports, Mid: mid, Vmid: vmid, Fid: 0, Pn: pn, Ps: ps, RealIP: ip}
  128. if favRes, err = s.fav.Favorites(c, arg); err != nil {
  129. log.Error("ListFav s.fav.Favorites(%+v) error(%v)", arg, err)
  130. return
  131. }
  132. count = favRes.Page.Count
  133. if favRes == nil || len(favRes.List) == 0 || count == 0 {
  134. rs = _emptContest
  135. return
  136. }
  137. for _, fav := range favRes.List {
  138. cids = append(cids, fav.Oid)
  139. }
  140. group, errCtx := errgroup.WithContext(c)
  141. group.Go(func() error {
  142. if cData, contErr = s.dao.EpContests(c, cids); contErr != nil {
  143. log.Error("s.dao.Contest error(%v)", contErr)
  144. }
  145. return contErr
  146. })
  147. group.Go(func() error {
  148. if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
  149. log.Error("s.dao.Teams error %v", teamErr)
  150. }
  151. return nil
  152. })
  153. group.Go(func() error {
  154. if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
  155. log.Error("s.dao.SeasonAll error %v", seasonErr)
  156. }
  157. return nil
  158. })
  159. err = group.Wait()
  160. if err != nil {
  161. return
  162. }
  163. for _, fav := range favRes.List {
  164. if contest, ok := cData[fav.Oid]; ok {
  165. favContest = append(favContest, contest)
  166. }
  167. }
  168. rs = s.ContestInfo(c, cids, favContest, teams, seasons, mid)
  169. if isFirst {
  170. s.cache.Do(c, func(c context.Context) {
  171. s.dao.SetFavCoCache(c, uid, rs, count)
  172. })
  173. }
  174. return
  175. }
  176. // SeasonFav list favorite season.
  177. func (s *Service) SeasonFav(c context.Context, mid int64, p *model.ParamSeason) (rs []*model.Season, count int, err error) {
  178. var (
  179. uid int64
  180. elaContest []*model.ElaSub
  181. mapSeasons map[int64]*model.Season
  182. cids []int64
  183. sids []int64
  184. dbContests map[int64]*model.Contest
  185. )
  186. if p.VMID > 0 {
  187. uid = p.VMID
  188. } else {
  189. uid = mid
  190. }
  191. if elaContest, count, err = s.dao.SeasonFav(c, uid, p); err != nil {
  192. log.Error("s.dao.StimeFav error(%v)", err)
  193. return
  194. }
  195. for _, contest := range elaContest {
  196. cids = append(cids, contest.Oid)
  197. sids = append(sids, contest.Sid)
  198. }
  199. if len(cids) > 0 {
  200. if dbContests, err = s.dao.EpContests(c, cids); err != nil {
  201. log.Error("s.dao.EpContests error(%v)", err)
  202. return
  203. }
  204. } else {
  205. rs = _emptSeason
  206. return
  207. }
  208. if mapSeasons, err = s.dao.EpSeasons(c, sids); err != nil {
  209. log.Error("s.dao.EpSeasons error(%v)", err)
  210. return
  211. }
  212. ms := make(map[int64]struct{}, len(cids))
  213. for _, contest := range elaContest {
  214. if _, ok := ms[contest.Sid]; ok {
  215. continue
  216. }
  217. // del over contest stime.
  218. if contest, ok := dbContests[contest.Oid]; ok {
  219. if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
  220. continue
  221. }
  222. }
  223. ms[contest.Sid] = struct{}{}
  224. if season, ok := mapSeasons[contest.Sid]; ok {
  225. rs = append(rs, season)
  226. }
  227. }
  228. if len(rs) == 0 {
  229. rs = _emptSeason
  230. }
  231. return
  232. }
  233. // StimeFav list favorite contests stime.
  234. func (s *Service) StimeFav(c context.Context, mid int64, p *model.ParamSeason) (rs []string, count int, err error) {
  235. var (
  236. uid int64
  237. elaContest []*model.ElaSub
  238. cids []int64
  239. dbContests map[int64]*model.Contest
  240. )
  241. if p.VMID > 0 {
  242. uid = p.VMID
  243. } else {
  244. uid = mid
  245. }
  246. if elaContest, count, err = s.dao.StimeFav(c, uid, p); err != nil {
  247. log.Error("s.dao.StimeFav error(%v)", err)
  248. }
  249. for _, contest := range elaContest {
  250. cids = append(cids, contest.Oid)
  251. }
  252. if len(cids) > 0 {
  253. if dbContests, err = s.dao.EpContests(c, cids); err != nil {
  254. log.Error("s.dao.EpContests error(%v)", err)
  255. return
  256. }
  257. } else {
  258. rs = _empStime
  259. return
  260. }
  261. ms := make(map[string]struct{}, len(cids))
  262. for _, contest := range elaContest {
  263. tm := time.Unix(contest.Stime, 0)
  264. stime := tm.Format("2006-01-02")
  265. if _, ok := ms[stime]; ok {
  266. continue
  267. }
  268. ms[stime] = struct{}{}
  269. // del over contest stime.
  270. if contest, ok := dbContests[contest.Oid]; ok {
  271. if contest.Etime > 0 && time.Now().Unix() > contest.Etime {
  272. continue
  273. }
  274. }
  275. rs = append(rs, stime)
  276. }
  277. if len(rs) == 0 {
  278. rs = _empStime
  279. }
  280. return
  281. }
  282. // ListAppFav list favorite contests.
  283. func (s *Service) ListAppFav(c context.Context, mid int64, p *model.ParamFav) (rs []*model.Contest, count int, err error) {
  284. var (
  285. uid int64
  286. cids []int64
  287. isFirst bool
  288. teams, seasons []*model.Filter
  289. cData map[int64]*model.Contest
  290. favContest []*model.Contest
  291. group *errgroup.Group
  292. contErr, teamErr, seasonErr error
  293. )
  294. if p.VMID > 0 {
  295. uid = p.VMID
  296. } else {
  297. uid = mid
  298. }
  299. isFirst = p.Pn == 1 && p.Ps == _firstAppPs && p.Stime == "" && p.Etime == "" && len(p.Sids) == 0 && p.Sort == 0
  300. if isFirst {
  301. if rs, count, err = s.dao.FavCoAppCache(c, uid); err != nil {
  302. err = nil
  303. }
  304. if len(rs) > 0 {
  305. s.fmtContest(c, rs, uid)
  306. return
  307. }
  308. }
  309. if cids, count, err = s.dao.SearchFav(c, uid, p); err != nil {
  310. log.Error("s.dao.SearchFav error(%v)", err)
  311. return
  312. }
  313. if len(cids) == 0 || count == 0 {
  314. rs = _emptContest
  315. return
  316. }
  317. group, errCtx := errgroup.WithContext(c)
  318. group.Go(func() error {
  319. if cData, contErr = s.dao.EpContests(c, cids); contErr != nil {
  320. log.Error("s.dao.Contest error(%v)", contErr)
  321. }
  322. return contErr
  323. })
  324. group.Go(func() error {
  325. if teams, teamErr = s.dao.Teams(errCtx); teamErr != nil {
  326. log.Error("s.dao.Teams error %v", teamErr)
  327. }
  328. return nil
  329. })
  330. group.Go(func() error {
  331. if seasons, seasonErr = s.dao.SeasonAll(errCtx); seasonErr != nil {
  332. log.Error("s.dao.SeasonAll error %v", seasonErr)
  333. }
  334. return nil
  335. })
  336. err = group.Wait()
  337. if err != nil {
  338. return
  339. }
  340. for _, cid := range cids {
  341. if contest, ok := cData[cid]; ok {
  342. favContest = append(favContest, contest)
  343. }
  344. }
  345. rs = s.ContestInfo(c, cids, favContest, teams, seasons, uid)
  346. if isFirst {
  347. s.cache.Do(c, func(c context.Context) {
  348. s.dao.SetAppFavCoCache(c, uid, rs, count)
  349. })
  350. }
  351. return
  352. }
  353. func (s *Service) isFavs(c context.Context, mid int64, cids []int64) (res map[int64]bool, err error) {
  354. if mid > 0 {
  355. ip := metadata.String(c, metadata.RemoteIP)
  356. if res, err = s.fav.IsFavs(c, &favmdl.ArgIsFavs{Type: favmdl.TypeEsports, Mid: mid, Oids: cids, RealIP: ip}); err != nil {
  357. log.Error("s.fav.IsFavs(%d,%+v) error(%d)", mid, cids, err)
  358. err = nil
  359. }
  360. }
  361. return
  362. }