view.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. package view
  2. import (
  3. "context"
  4. "crypto/md5"
  5. "encoding/hex"
  6. "net/url"
  7. "strconv"
  8. "strings"
  9. "time"
  10. cdm "go-common/app/interface/main/app-card/model"
  11. "go-common/app/interface/main/app-card/model/card"
  12. "go-common/app/interface/main/app-card/model/card/operate"
  13. "go-common/app/interface/main/app-view/model"
  14. "go-common/app/interface/main/app-view/model/creative"
  15. "go-common/app/interface/main/app-view/model/view"
  16. account "go-common/app/service/main/account/model"
  17. "go-common/app/service/main/archive/api"
  18. "go-common/app/service/main/archive/model/archive"
  19. location "go-common/app/service/main/location/model"
  20. relation "go-common/app/service/main/relation/model"
  21. resource "go-common/app/service/main/resource/model"
  22. sharerpc "go-common/app/service/main/share/api"
  23. thumbuppb "go-common/app/service/main/thumbup/api"
  24. thumbup "go-common/app/service/main/thumbup/model"
  25. "go-common/library/conf/env"
  26. "go-common/library/ecode"
  27. "go-common/library/log"
  28. "go-common/library/net/metadata"
  29. "go-common/library/sync/errgroup"
  30. egV2 "go-common/library/sync/errgroup.v2"
  31. "github.com/pkg/errors"
  32. )
  33. const (
  34. _descLen = 250
  35. _promptCoin = 1
  36. _promptFav = 2
  37. _avTypeAv = 1
  38. _businessLike = "archive"
  39. _coinAv = 1
  40. )
  41. // View all view data.
  42. func (s *Service) View(c context.Context, mid, aid, movieID int64, plat int8, build, qn, fnver, fnval, forceHost, parentMode int, ak, mobiApp, device, buvid, cdnIP, network, adExtra, from string, now time.Time) (v *view.View, err error) {
  43. if v, err = s.ViewPage(c, mid, aid, movieID, plat, build, ak, mobiApp, device, cdnIP, true, now); err != nil {
  44. ip := metadata.String(c, metadata.RemoteIP)
  45. if err == ecode.AccessDenied || err == ecode.NothingFound {
  46. log.Warn("s.ViewPage() mid(%d) aid(%d) movieID(%d) plat(%d) ak(%s) ip(%s) cdn_ip(%s) error(%v)", mid, aid, movieID, plat, ak, ip, cdnIP, err)
  47. } else {
  48. log.Error("s.ViewPage() mid(%d) aid(%d) movieID(%d) plat(%d) ak(%s) ip(%s) cdn_ip(%s) error(%v)", mid, aid, movieID, plat, ak, ip, cdnIP, err)
  49. }
  50. return
  51. }
  52. g, ctx := errgroup.WithContext(c)
  53. g.Go(func() (err error) {
  54. v.VIPActive = s.vipActiveCache[view.VIPActiveView]
  55. return
  56. })
  57. g.Go(func() (err error) {
  58. s.initReqUser(ctx, v, mid, plat, build)
  59. if v.AttrVal(archive.AttrBitIsPGC) != archive.AttrYes {
  60. s.initContributions(ctx, v)
  61. }
  62. return
  63. })
  64. g.Go(func() (err error) {
  65. s.initRelateCMTag(ctx, v, plat, build, qn, fnver, fnval, forceHost, parentMode, mid, buvid, mobiApp, device, network, adExtra, from, now)
  66. return
  67. })
  68. if v.AttrVal(archive.AttrBitIsPGC) != archive.AttrYes {
  69. g.Go(func() (err error) {
  70. s.initDM(ctx, v)
  71. return
  72. })
  73. g.Go(func() (err error) {
  74. s.initAudios(ctx, v)
  75. return
  76. })
  77. g.Go(func() (err error) {
  78. if model.IsIPhoneB(plat) || (model.IsIPhone(plat) && (build >= 7000 && build <= 8000)) {
  79. return
  80. }
  81. s.initElec(ctx, v, mid)
  82. return
  83. })
  84. if len([]rune(v.Desc)) > _descLen {
  85. g.Go(func() (err error) {
  86. if desc, _ := s.arcDao.Description(ctx, v.Aid); desc != "" {
  87. v.Desc = desc
  88. }
  89. return
  90. })
  91. }
  92. }
  93. if v.AttrVal(archive.AttrBitHasBGM) == archive.AttrYes {
  94. g.Go(func() (err error) {
  95. if v.Bgm, err = s.creativeDao.Bgm(ctx, v.Aid, v.FirstCid); err != nil {
  96. log.Error("%+v", err)
  97. err = nil
  98. }
  99. return
  100. })
  101. }
  102. if err = g.Wait(); err != nil {
  103. log.Error("%+v", err)
  104. }
  105. return
  106. }
  107. // ViewPage view page data.
  108. func (s *Service) ViewPage(c context.Context, mid, aid, movieID int64, plat int8, build int, ak, mobiApp, device, cdnIP string, nMovie bool, now time.Time) (v *view.View, err error) {
  109. if aid == 0 && movieID == 0 {
  110. err = ecode.NothingFound
  111. return
  112. }
  113. const (
  114. _androidMovie = 5220000
  115. _iPhoneMovie = 6500
  116. _iPadMovie = 6720
  117. _iPadHDMovie = 12020
  118. )
  119. var (
  120. vs *view.ViewStatic
  121. vp *archive.View3
  122. seasoninfo map[int64]int64
  123. ok bool
  124. )
  125. if movieID != 0 {
  126. if seasoninfo, err = s.banDao.SeasonidAid(c, movieID, now); err != nil {
  127. log.Error("%+v", err)
  128. err = ecode.NothingFound
  129. return
  130. }
  131. if aid, ok = seasoninfo[movieID]; !ok || aid == 0 {
  132. err = ecode.NothingFound
  133. return
  134. }
  135. var a *api.Arc
  136. if a, err = s.arcDao.Archive3(c, aid); err != nil {
  137. log.Error("%+v", err)
  138. err = ecode.NothingFound
  139. return
  140. }
  141. if a == nil {
  142. err = ecode.NothingFound
  143. return
  144. }
  145. vs = &view.ViewStatic{Archive3: archive.BuildArchive3(a)}
  146. s.prom.Incr("from_movieID")
  147. } else {
  148. if vp, err = s.arcDao.ViewCache(c, aid); err != nil {
  149. log.Error("%+v", err)
  150. }
  151. if vp == nil || vp.Archive3 == nil || len(vp.Pages) == 0 || vp.AttrVal(archive.AttrBitIsMovie) == archive.AttrYes {
  152. if vp, err = s.arcDao.View3(c, aid); err != nil {
  153. log.Error("%+v", err)
  154. err = ecode.NothingFound
  155. return
  156. }
  157. }
  158. if vp == nil || vp.Archive3 == nil || len(vp.Pages) == 0 {
  159. err = ecode.NothingFound
  160. return
  161. }
  162. vs = &view.ViewStatic{Archive3: vp.Archive3}
  163. s.initPages(c, vs, vp.Pages)
  164. s.prom.Incr("from_aid")
  165. }
  166. if _, ok := s.specialMids[vs.Author.Mid]; ok && env.DeployEnv == env.DeployEnvProd {
  167. err = ecode.NothingFound
  168. log.Error("aid(%d) mid(%d) can not view on prod", vs.Aid, vs.Author.Mid)
  169. return
  170. }
  171. // TODO 产品最帅了!
  172. vs.Stat.DisLike = 0
  173. if s.overseaCheck(vs.Archive3, plat) {
  174. err = ecode.AreaLimit
  175. return
  176. }
  177. // check region area limit
  178. if err = s.areaLimit(c, plat, int(vs.TypeID)); err != nil {
  179. return
  180. }
  181. v = &view.View{ViewStatic: vs, DMSeg: 1, PlayerIcon: s.playerIcon}
  182. if v.AttrVal(archive.AttrBitIsPGC) != archive.AttrYes {
  183. // check access
  184. if err = s.checkAceess(c, mid, v.Aid, int(v.State), int(v.Access), ak); err != nil {
  185. // archive is ForbitFixed and Transcoding and StateForbitDistributing need analysis history body .
  186. if v.State != archive.StateForbidFixed {
  187. return
  188. }
  189. err = nil
  190. }
  191. if v.Access > 0 {
  192. v.Stat.View = 0
  193. }
  194. }
  195. g, ctx := errgroup.WithContext(c)
  196. if mid != 0 {
  197. g.Go(func() (err error) {
  198. v.History, _ = s.arcDao.Progress(ctx, v.Aid, mid)
  199. return
  200. })
  201. }
  202. if v.AttrVal(archive.AttrBitIsPGC) == archive.AttrYes {
  203. if (v.AttrVal(archive.AttrBitIsMovie) != archive.AttrYes) || (plat == model.PlatAndroid && build >= _androidMovie) || (plat == model.PlatIPhone && build >= _iPhoneMovie) || (plat == model.PlatIPad && build >= _iPadMovie) ||
  204. (plat == model.PlatIpadHD && build > _iPadHDMovie) || plat == model.PlatAndroidTVYST || plat == model.PlatAndroidTV || plat == model.PlatAndroidI || plat == model.PlatIPhoneB {
  205. g.Go(func() error {
  206. return s.initPGC(ctx, v, mid, build, mobiApp, device)
  207. })
  208. } else {
  209. g.Go(func() error {
  210. return s.initMovie(ctx, v, mid, build, mobiApp, device, nMovie)
  211. })
  212. }
  213. } else {
  214. g.Go(func() (err error) {
  215. if err = s.initDownload(ctx, v, mid, cdnIP); err != nil {
  216. ip := metadata.String(ctx, metadata.RemoteIP)
  217. log.Error("aid(%d) mid(%d) ip(%s) cdn_ip(%s) error(%+v)", v.Aid, mid, ip, cdnIP, err)
  218. }
  219. return
  220. })
  221. if v.Rights.UGCPay == 1 && mid != v.Author.Mid {
  222. g.Go(func() (err error) {
  223. if err = s.initUGCPay(ctx, v, plat, mid); err != nil {
  224. log.Error("%+v", err)
  225. err = nil
  226. return
  227. }
  228. return nil
  229. })
  230. }
  231. }
  232. if err = g.Wait(); err != nil {
  233. log.Error("%+v", err)
  234. }
  235. if v.Rights.UGCPay == 1 {
  236. if (v.Asset == nil || v.Asset.Paid == 0) && mid != v.Author.Mid {
  237. v.Rights.Download = int32(location.ForbiddenDown)
  238. }
  239. }
  240. return
  241. }
  242. // AddShare add a share
  243. func (s *Service) AddShare(c context.Context, aid, mid int64, ip string) (share int, isReport bool, upID int64, err error) {
  244. var a *api.Arc
  245. if a, err = s.arcDao.Archive(c, aid); err != nil {
  246. if errors.Cause(err) == ecode.NothingFound {
  247. err = ecode.ArchiveNotExist
  248. }
  249. return
  250. }
  251. if !a.IsNormal() {
  252. err = ecode.ArchiveNotExist
  253. return
  254. }
  255. upID = a.Author.Mid
  256. shareReply, err := s.shareClient.AddShare(context.Background(), &sharerpc.AddShareRequest{
  257. Oid: aid,
  258. Mid: mid,
  259. Type: 3,
  260. Ip: ip,
  261. })
  262. if err != nil {
  263. if ecode.Cause(err).Equal(ecode.ShareAlreadyAdd) {
  264. err = nil
  265. return
  266. }
  267. log.Error("s.shareClient.AddShare(%d, %d, 3) error(%v)", aid, mid, err)
  268. return
  269. }
  270. if shareReply != nil && shareReply.Shares > int64(a.Stat.Share) {
  271. isReport = true
  272. }
  273. return
  274. }
  275. // Shot shot service
  276. func (s *Service) Shot(c context.Context, aid, cid int64) (shot *view.Videoshot, err error) {
  277. var (
  278. arcShot *archive.Videoshot
  279. points []*creative.Points
  280. )
  281. shot = new(view.Videoshot)
  282. if arcShot, err = s.arcDao.Shot(c, aid, cid); err != nil {
  283. log.Error("%+v", err)
  284. return
  285. }
  286. if arcShot == nil {
  287. return
  288. }
  289. shot.Videoshot = arcShot
  290. a := &api.Arc{Attribute: arcShot.Attr}
  291. if a.AttrVal(archive.AttrBitHasViewpoint) == archive.AttrYes {
  292. if points, err = s.creativeDao.Points(c, aid, cid); err != nil {
  293. log.Error("%+v", err)
  294. err = nil
  295. }
  296. shot.Points = points
  297. }
  298. return
  299. }
  300. // Like add a like.
  301. func (s *Service) Like(c context.Context, aid, mid int64, status int8) (upperID int64, toast string, err error) {
  302. var (
  303. a *api.Arc
  304. typ int8
  305. stat *thumbuppb.LikeReply
  306. )
  307. if a, err = s.arcDao.Archive(c, aid); err != nil {
  308. if errors.Cause(err) == ecode.NothingFound {
  309. err = ecode.ArchiveNotExist
  310. }
  311. return
  312. }
  313. if !a.IsNormal() {
  314. err = ecode.ArchiveNotExist
  315. return
  316. }
  317. upperID = a.Author.Mid
  318. if status == 0 {
  319. typ = thumbup.TypeLike
  320. } else if status == 1 {
  321. typ = thumbup.TypeCancelLike
  322. }
  323. if stat, err = s.thumbupDao.Like(c, mid, upperID, _businessLike, a.Aid, typ); err != nil {
  324. if ecode.EqualError(ecode.ThumbupDupLikeErr, err) {
  325. log.Error("%+v", err)
  326. err = nil
  327. toast = "点赞收到!视频可能推荐哦"
  328. }
  329. return
  330. }
  331. if typ == thumbup.TypeLike {
  332. if stat.LikeNumber < 100 {
  333. toast = "点赞收到!视频可能推荐哦"
  334. } else if stat.LikeNumber >= 100 && stat.LikeNumber < 1000 {
  335. toast = "感谢点赞,推荐已收到啦"
  336. } else if stat.LikeNumber >= 1000 && stat.LikeNumber < 10000 {
  337. toast = "get!视频也许更多人能看见!"
  338. } else {
  339. toast = "点赞爆棚,感谢推荐!"
  340. }
  341. }
  342. return
  343. }
  344. // Dislike add a dislike.
  345. func (s *Service) Dislike(c context.Context, aid, mid int64, status int8) (upperID int64, err error) {
  346. var (
  347. a *api.Arc
  348. typ int8
  349. )
  350. if a, err = s.arcDao.Archive(c, aid); err != nil {
  351. if errors.Cause(err) == ecode.NothingFound {
  352. err = ecode.ArchiveNotExist
  353. }
  354. return
  355. }
  356. if !a.IsNormal() {
  357. err = ecode.ArchiveNotExist
  358. return
  359. }
  360. upperID = a.Author.Mid
  361. if status == 0 {
  362. typ = thumbup.TypeDislike
  363. } else if status == 1 {
  364. typ = thumbup.TypeCancelDislike
  365. }
  366. _, err = s.thumbupDao.Like(c, mid, upperID, _businessLike, a.Aid, typ)
  367. return
  368. }
  369. // AddCoin add a coin
  370. func (s *Service) AddCoin(c context.Context, aid, mid, upID, avtype, multiply int64, ak string, selectLike int) (prompt, like bool, err error) {
  371. var maxCoin int64 = 2
  372. var typeID int16
  373. var pubTime int64
  374. if avtype == _avTypeAv {
  375. var a *api.Arc
  376. if a, err = s.arcDao.Archive(c, aid); err != nil {
  377. if errors.Cause(err) == ecode.NothingFound {
  378. err = ecode.ArchiveNotExist
  379. }
  380. return
  381. }
  382. if !a.IsNormal() {
  383. err = ecode.ArchiveNotExist
  384. return
  385. }
  386. if a.Copyright == int32(archive.CopyrightCopy) {
  387. maxCoin = 1
  388. }
  389. upID = a.Author.Mid
  390. typeID = int16(a.TypeID)
  391. pubTime = int64(a.PubDate)
  392. }
  393. if err = s.coinDao.AddCoins(c, aid, mid, upID, maxCoin, avtype, multiply, typeID, pubTime); err != nil {
  394. return
  395. }
  396. eg, ctx := errgroup.WithContext(c)
  397. eg.Go(func() (err error) {
  398. if avtype == _avTypeAv && selectLike == 1 {
  399. if _, err = s.thumbupDao.Like(ctx, mid, upID, _businessLike, aid, thumbup.TypeLike); err != nil {
  400. log.Error("%+v", err)
  401. err = nil
  402. } else {
  403. like = true
  404. }
  405. }
  406. return
  407. })
  408. eg.Go(func() (err error) {
  409. if prompt, err = s.relDao.Prompt(ctx, mid, upID, _promptCoin); err != nil {
  410. log.Error("%+v", err)
  411. err = nil
  412. }
  413. return
  414. })
  415. eg.Wait()
  416. return
  417. }
  418. // AddFav add a favorite
  419. func (s *Service) AddFav(c context.Context, mid, vmid int64, fids []int64, aid int64, ak string) (prompt bool, err error) {
  420. var a *api.Arc
  421. if a, err = s.arcDao.Archive(c, aid); err != nil {
  422. if errors.Cause(err) == ecode.NothingFound {
  423. err = ecode.ArchiveNotExist
  424. }
  425. return
  426. }
  427. if !a.IsNormal() {
  428. err = ecode.ArchiveNotExist
  429. return
  430. }
  431. if err = s.favDao.AddVideo(c, mid, fids, aid, ak); err != nil {
  432. return
  433. }
  434. if prompt, err = s.relDao.Prompt(c, mid, vmid, _promptFav); err != nil {
  435. log.Error("%+v", err)
  436. err = nil
  437. }
  438. return
  439. }
  440. // Paster get paster if nologin.
  441. func (s *Service) Paster(c context.Context, plat, adType int8, aid, typeID, buvid string) (p *resource.Paster, err error) {
  442. if p, err = s.rscDao.Paster(c, plat, adType, aid, typeID, buvid); err != nil {
  443. log.Error("%+v", err)
  444. }
  445. return
  446. }
  447. // VipPlayURL get playurl token.
  448. func (s *Service) VipPlayURL(c context.Context, aid, cid, mid int64) (res *view.VipPlayURL, err error) {
  449. var (
  450. a *api.Arc
  451. card *account.Card
  452. )
  453. res = &view.VipPlayURL{
  454. From: "app",
  455. Ts: time.Now().Unix(),
  456. Aid: aid,
  457. Cid: cid,
  458. Mid: mid,
  459. }
  460. if card, err = s.accDao.Card3(c, mid); err != nil {
  461. log.Error("%+v", err)
  462. err = ecode.AccessDenied
  463. return
  464. }
  465. if res.VIP = int(card.Level); res.VIP > 6 {
  466. res.VIP = 6
  467. }
  468. if card.Vip.Type != 0 && card.Vip.Status == 1 {
  469. res.SVIP = 1
  470. }
  471. if a, err = s.arcDao.Archive(c, aid); err != nil {
  472. log.Error("%+v", err)
  473. err = ecode.NothingFound
  474. return
  475. }
  476. if mid == a.Author.Mid {
  477. res.Owner = 1
  478. }
  479. params := url.Values{}
  480. params.Set("from", res.From)
  481. params.Set("ts", strconv.FormatInt(res.Ts, 10))
  482. params.Set("aid", strconv.FormatInt(res.Aid, 10))
  483. params.Set("cid", strconv.FormatInt(res.Cid, 10))
  484. params.Set("mid", strconv.FormatInt(res.Mid, 10))
  485. params.Set("vip", strconv.Itoa(res.VIP))
  486. params.Set("svip", strconv.Itoa(res.SVIP))
  487. params.Set("owner", strconv.Itoa(res.Owner))
  488. tmp := params.Encode()
  489. if strings.IndexByte(tmp, '+') > -1 {
  490. tmp = strings.Replace(tmp, "+", "%20", -1)
  491. }
  492. mh := md5.Sum([]byte(strings.ToLower(tmp) + s.c.PlayURL.Secret))
  493. res.Fcs = hex.EncodeToString(mh[:])
  494. return
  495. }
  496. // Follow get auto follow switch from creative and acc.
  497. func (s *Service) Follow(c context.Context, vmid, mid int64) (res *creative.PlayerFollow, err error) {
  498. var (
  499. fl bool
  500. profile *relation.Stat
  501. fs *creative.FollowSwitch
  502. )
  503. g, ctx := errgroup.WithContext(c)
  504. g.Go(func() (err error) {
  505. profile, err = s.relDao.Stat(ctx, vmid)
  506. if err != nil {
  507. log.Error("%+v", err)
  508. }
  509. return
  510. })
  511. if mid > 0 {
  512. g.Go(func() (err error) {
  513. fl, err = s.accDao.Following3(ctx, mid, vmid)
  514. if err != nil {
  515. log.Error("%+v", err)
  516. }
  517. return
  518. })
  519. }
  520. g.Go(func() (err error) {
  521. fs, err = s.creativeDao.FollowSwitch(ctx, vmid)
  522. if err != nil {
  523. log.Error("%+v", err)
  524. }
  525. return
  526. })
  527. if err = g.Wait(); err != nil {
  528. log.Error("%+v", err)
  529. return
  530. }
  531. res = &creative.PlayerFollow{}
  532. if profile.Follower >= s.c.AutoLimit && fs.State == 1 && !fl {
  533. res.Show = true
  534. }
  535. return
  536. }
  537. // UpperRecmd is
  538. func (s *Service) UpperRecmd(c context.Context, plat int8, platform, mobiApp, device, buvid string, build int, mid, vimd int64) (res card.Handler, err error) {
  539. var (
  540. upIDs []int64
  541. follow *operate.Card
  542. cardm map[int64]*account.Card
  543. statm map[int64]*relation.Stat
  544. isAtten map[int64]int8
  545. )
  546. if follow, err = s.searchFollow(c, platform, mobiApp, device, buvid, build, mid, vimd); err != nil {
  547. log.Error("%+v", err)
  548. return
  549. }
  550. if follow == nil {
  551. err = ecode.AppNotData
  552. log.Error("follow is nil")
  553. return
  554. }
  555. for _, item := range follow.Items {
  556. upIDs = append(upIDs, item.ID)
  557. }
  558. g, ctx := errgroup.WithContext(c)
  559. if len(upIDs) != 0 {
  560. g.Go(func() (err error) {
  561. if cardm, err = s.accDao.Cards3(ctx, upIDs); err != nil {
  562. log.Error("%+v", err)
  563. err = nil
  564. }
  565. return
  566. })
  567. g.Go(func() (err error) {
  568. if statm, err = s.relDao.Stats(ctx, upIDs); err != nil {
  569. log.Error("%+v", err)
  570. err = nil
  571. }
  572. return
  573. })
  574. if mid != 0 {
  575. g.Go(func() error {
  576. isAtten = s.accDao.IsAttention(ctx, upIDs, mid)
  577. return nil
  578. })
  579. }
  580. }
  581. g.Wait()
  582. op := &operate.Card{}
  583. op.From(cdm.CardGt(model.GotoSearchUpper), 0, 0, plat, build)
  584. h := card.Handle(plat, cdm.CardGt(model.GotoSearchUpper), "", cdm.ColumnSvrSingle, nil, nil, isAtten, statm, cardm)
  585. if h == nil {
  586. err = ecode.AppNotData
  587. return
  588. }
  589. op = follow
  590. h.From(nil, op)
  591. if h.Get().Right {
  592. res = h
  593. } else {
  594. err = ecode.AppNotData
  595. }
  596. return
  597. }
  598. // LikeTriple like & coin & fav
  599. func (s *Service) LikeTriple(c context.Context, aid, mid int64, ak string) (res *view.TripleRes, err error) {
  600. res = new(view.TripleRes)
  601. maxCoin := int64(1)
  602. multiply := int64(1)
  603. var a *api.Arc
  604. if a, err = s.arcDao.Archive(c, aid); err != nil {
  605. if errors.Cause(err) == ecode.NothingFound {
  606. err = ecode.ArchiveNotExist
  607. }
  608. return
  609. }
  610. if !a.IsNormal() {
  611. err = ecode.ArchiveNotExist
  612. return
  613. }
  614. if a.Copyright == int32(archive.CopyrightOriginal) {
  615. maxCoin = 2
  616. multiply = 2
  617. }
  618. res.UpID = a.Author.Mid
  619. eg := egV2.WithContext(c)
  620. eg.Go(func(ctx context.Context) (err error) {
  621. if multiply == 2 {
  622. userCoins, _ := s.coinDao.UserCoins(ctx, mid)
  623. if userCoins < 1 {
  624. return
  625. }
  626. if userCoins < 2 {
  627. multiply = 1
  628. }
  629. }
  630. err = s.coinDao.AddCoins(ctx, aid, mid, a.Author.Mid, maxCoin, _coinAv, multiply, int16(a.TypeID), int64(a.PubDate))
  631. if err == nil || ecode.EqualError(ecode.CoinOverMax, err) {
  632. res.Multiply = multiply
  633. res.Anticheat = true
  634. res.Coin = true
  635. err = nil
  636. } else {
  637. log.Error("s.coinDao.AddCoins err(%+v) aid(%d) mid(%d)", err, aid, mid)
  638. err = nil
  639. arcUserCoins, _ := s.coinDao.ArchiveUserCoins(ctx, aid, mid, _coinAv)
  640. if arcUserCoins != nil && arcUserCoins.Multiply > 0 {
  641. res.Coin = true
  642. }
  643. }
  644. return
  645. })
  646. eg.Go(func(ctx context.Context) (err error) {
  647. var isFav bool
  648. if isFav, err = s.favDao.IsFavVideo(ctx, mid, aid); err != nil {
  649. log.Error("s.favDao.IsFavVideo err(%+v) aid(%d) mid(%d)", err, aid, mid)
  650. err = nil
  651. } else if isFav {
  652. res.Fav = true
  653. return
  654. }
  655. if err = s.favDao.AddFav(ctx, mid, aid); err != nil {
  656. log.Error("s.favDao.AddFav err(%+v) aid(%d) mid(%d)", err, aid, mid)
  657. if ecode.EqualError(ecode.FavVideoExist, err) || ecode.EqualError(ecode.FavResourceExist, err) {
  658. res.Fav = true
  659. }
  660. err = nil
  661. } else {
  662. res.Fav = true
  663. res.Anticheat = true
  664. }
  665. return
  666. })
  667. eg.Go(func(ctx context.Context) (err error) {
  668. if _, err = s.thumbupDao.Like(ctx, mid, res.UpID, _businessLike, aid, thumbup.TypeLike); err != nil {
  669. log.Error("s.thumbupDao.Like err(%+v) aid(%d) mid(%d)", err, aid, mid)
  670. if ecode.EqualError(ecode.ThumbupDupLikeErr, err) {
  671. res.Like = true
  672. }
  673. err = nil
  674. } else {
  675. res.Like = true
  676. res.Anticheat = true
  677. }
  678. return
  679. })
  680. eg.Go(func(ctx context.Context) (err error) {
  681. if res.Prompt, err = s.relDao.Prompt(ctx, mid, a.Author.Mid, _promptFav); err != nil {
  682. log.Error("s.relDao.Prompt err(%+v)", err)
  683. err = nil
  684. }
  685. return
  686. })
  687. eg.Wait()
  688. if !res.Coin && !res.Fav {
  689. res.Prompt = false
  690. }
  691. return
  692. }