service.go 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  1. package music
  2. import (
  3. "context"
  4. "go-common/app/interface/main/creative/conf"
  5. "go-common/app/interface/main/creative/dao/account"
  6. "go-common/app/interface/main/creative/dao/archive"
  7. material "go-common/app/interface/main/creative/dao/material"
  8. music "go-common/app/interface/main/creative/dao/music"
  9. "go-common/app/interface/main/creative/dao/up"
  10. appMdl "go-common/app/interface/main/creative/model/app"
  11. mMdl "go-common/app/interface/main/creative/model/music"
  12. sMdl "go-common/app/interface/main/creative/model/search"
  13. "go-common/app/interface/main/creative/service"
  14. accMdl "go-common/app/service/main/account/model"
  15. "go-common/app/service/main/archive/api"
  16. "go-common/library/ecode"
  17. "go-common/library/log"
  18. "go-common/library/net/metadata"
  19. "go-common/library/queue/databus/report"
  20. "go-common/library/sync/errgroup"
  21. "sort"
  22. "time"
  23. )
  24. const hotvalArcFactor = int(357)
  25. //Service struct.
  26. type Service struct {
  27. c *conf.Config
  28. music *music.Dao
  29. material *material.Dao
  30. acc *account.Dao
  31. archive *archive.Dao
  32. up *up.Dao
  33. LatestBgm *mMdl.Music
  34. MscWithTypes map[int][]*mMdl.Music
  35. AllMsc map[int64]*mMdl.Music
  36. Types []*mMdl.Category
  37. Subtitles []*mMdl.Subtitle
  38. Fonts []*mMdl.Font
  39. Filters []*mMdl.Filter
  40. FilterWithCategory []*mMdl.FilterCategory
  41. VstickerWithCategory []*mMdl.VstickerCategory
  42. Hotwords []*mMdl.Hotword
  43. Stickers []*mMdl.Sticker
  44. Intros []*mMdl.Intro
  45. Vstickers []*mMdl.VSticker
  46. Transitions []*mMdl.Transition
  47. // from app535 for sticker whitelist
  48. stickerUps map[int64]int64
  49. Themes []*mMdl.Theme
  50. Cooperates []*mMdl.Cooperate
  51. p *service.Public
  52. }
  53. //New get service.
  54. func New(c *conf.Config, rpcdaos *service.RPCDaos, p *service.Public) *Service {
  55. s := &Service{
  56. c: c,
  57. music: music.New(c),
  58. material: material.New(c),
  59. acc: rpcdaos.Acc,
  60. archive: rpcdaos.Arc,
  61. up: rpcdaos.Up,
  62. Types: make([]*mMdl.Category, 0),
  63. MscWithTypes: make(map[int][]*mMdl.Music),
  64. AllMsc: make(map[int64]*mMdl.Music),
  65. Subtitles: make([]*mMdl.Subtitle, 0),
  66. Fonts: make([]*mMdl.Font, 0),
  67. Filters: make([]*mMdl.Filter, 0),
  68. FilterWithCategory: make([]*mMdl.FilterCategory, 0),
  69. VstickerWithCategory: make([]*mMdl.VstickerCategory, 0),
  70. Hotwords: make([]*mMdl.Hotword, 0),
  71. Stickers: make([]*mMdl.Sticker, 0),
  72. Intros: make([]*mMdl.Intro, 0),
  73. Vstickers: make([]*mMdl.VSticker, 0),
  74. Transitions: make([]*mMdl.Transition, 0),
  75. Themes: make([]*mMdl.Theme, 0),
  76. Cooperates: make([]*mMdl.Cooperate, 0),
  77. p: p,
  78. }
  79. s.loadUpSpecialSticker()
  80. s.loadPreValues()
  81. s.loadMaterial()
  82. go s.loadproc()
  83. return s
  84. }
  85. // loadUpSpecialSticker 拍摄贴纸支持灰度分发,配合Sticker.white字段使用
  86. func (s *Service) loadUpSpecialSticker() {
  87. ups, err := s.up.UpSpecial(context.TODO(), 18)
  88. if err != nil {
  89. return
  90. }
  91. s.stickerUps = ups
  92. }
  93. func (s *Service) loadproc() {
  94. for {
  95. time.Sleep(time.Duration(2 * time.Minute))
  96. s.loadPreValues()
  97. s.loadMaterial()
  98. s.loadUpSpecialSticker()
  99. }
  100. }
  101. func (s *Service) loadMaterial() {
  102. var (
  103. basic = make(map[string]interface{})
  104. err error
  105. g = &errgroup.Group{}
  106. ctx = context.TODO()
  107. )
  108. c := context.TODO()
  109. if basic, err = s.material.Basic(c); err != nil {
  110. log.Error("s.material.basic err(%+v)", err)
  111. return
  112. }
  113. if subtitles, ok := basic["subs"].([]*mMdl.Subtitle); ok {
  114. log.Info("s.material.subs (%+d)", len(subtitles))
  115. s.Subtitles = subtitles
  116. }
  117. if fonts, ok := basic["fons"].([]*mMdl.Font); ok {
  118. log.Info("s.material.fons (%+d)", len(fonts))
  119. s.Fonts = fonts
  120. }
  121. if hotwords, ok := basic["hots"].([]*mMdl.Hotword); ok {
  122. log.Info("s.material.hots (%+d)", len(hotwords))
  123. s.Hotwords = hotwords
  124. }
  125. if stickers, ok := basic["stis"].([]*mMdl.Sticker); ok {
  126. log.Info("s.material.stis (%+d)", len(stickers))
  127. s.Stickers = stickers
  128. }
  129. if intros, ok := basic["ints"].([]*mMdl.Intro); ok {
  130. log.Info("s.material.ints (%+d)", len(intros))
  131. s.Intros = intros
  132. }
  133. if trans, ok := basic["trans"].([]*mMdl.Transition); ok {
  134. log.Info("s.material.trans (%+d)", len(trans))
  135. s.Transitions = trans
  136. }
  137. if themes, ok := basic["themes"].([]*mMdl.Theme); ok {
  138. log.Info("s.material.themes (%+d)", len(themes))
  139. s.Themes = themes
  140. }
  141. g.Go(func() error {
  142. s.getFilterAndItsCategory(ctx)
  143. return nil
  144. })
  145. g.Go(func() error {
  146. s.getVStickerAndItsCategory(ctx)
  147. return nil
  148. })
  149. g.Go(func() error {
  150. s.getCooperates(ctx)
  151. return nil
  152. })
  153. g.Wait()
  154. }
  155. func (s *Service) loadPreValues() {
  156. var (
  157. mcategory []*mMdl.Mcategory
  158. resCategorys []*mMdl.Category
  159. tids []int64
  160. sids []int64
  161. err error
  162. musicMap map[int64]*mMdl.Music
  163. // latestBgm *mMdl.Music
  164. jointimeMap = make(map[int64]int64)
  165. jointimes = make([]int64, 0)
  166. c = context.TODO()
  167. sidTidMapIdx = make(map[int64][](map[int]int))
  168. sidTidMapJoinUnix = make(map[int64][](map[int]int64))
  169. categoryMaps = make(map[int]*mMdl.Category)
  170. )
  171. if mcategory, err = s.music.MCategorys(c); err != nil {
  172. log.Error("s.music.MCategorys err(%+v)", err)
  173. return
  174. }
  175. for _, v := range mcategory {
  176. joinUnix := v.CTime.Time().Unix()
  177. jointimeMap[joinUnix] = v.SID
  178. jointimes = append(jointimes, joinUnix)
  179. tid := v.Tid
  180. tidx := v.Index
  181. sid := v.SID
  182. tids = append(tids, int64(tid))
  183. sids = append(sids, sid)
  184. if _, ok := sidTidMapIdx[sid]; !ok {
  185. sidTidMapIdx[sid] = make([](map[int]int), 0)
  186. }
  187. sidTidMapIdx[sid] = append(sidTidMapIdx[sid], map[int]int{
  188. tid: tidx,
  189. })
  190. if _, ok := sidTidMapJoinUnix[sid]; !ok {
  191. sidTidMapJoinUnix[sid] = make([](map[int]int64), 0)
  192. }
  193. sidTidMapJoinUnix[sid] = append(sidTidMapJoinUnix[sid], map[int]int64{
  194. tid: joinUnix,
  195. })
  196. }
  197. if len(tids) > 0 {
  198. if resCategorys, categoryMaps, err = s.music.Categorys(c, tids); err != nil {
  199. log.Error("s.music.Categorys tids(%+v)|err(%+v)", tids, err)
  200. return
  201. }
  202. if len(resCategorys) > 0 && len(sids) > 0 {
  203. if musicMap, err = s.music.Music(c, sids); err != nil {
  204. log.Error("s.music.Music tids(%+v)|sids(%+v)|err(%+v)", tids, sids, err)
  205. return
  206. }
  207. // get last jointime bgm
  208. if len(jointimes) > 0 {
  209. sort.Slice(jointimes, func(i, j int) bool {
  210. return jointimes[i] >= jointimes[j]
  211. })
  212. lastJoinUnix := jointimes[0]
  213. lastSid := jointimeMap[lastJoinUnix]
  214. if bgm, ok := musicMap[lastSid]; ok {
  215. s.LatestBgm = bgm
  216. }
  217. }
  218. s.AllMsc = musicMap
  219. bgms := make(map[int][]*mMdl.Music)
  220. upNamesMap, _ := s.getUpNames(c, musicMap)
  221. for sid, msc := range musicMap {
  222. if tpsSlice, okM := sidTidMapIdx[sid]; okM {
  223. for _, tpIdx := range tpsSlice {
  224. for tp, idx := range tpIdx {
  225. if _, ok := categoryMaps[tp]; !ok {
  226. continue
  227. }
  228. if _, ok := bgms[tp]; !ok {
  229. bgms[tp] = make([]*mMdl.Music, 0)
  230. }
  231. var (
  232. junix int64
  233. upName string
  234. )
  235. if name, okU := upNamesMap[msc.UpMID]; okU {
  236. upName = name
  237. }
  238. for _, Jmap := range sidTidMapJoinUnix[sid] {
  239. if joinUnix, okJ := Jmap[tp]; okJ {
  240. junix = joinUnix
  241. }
  242. }
  243. bgm := &mMdl.Music{
  244. ID: msc.ID,
  245. TID: tp,
  246. Index: idx,
  247. SID: msc.SID,
  248. Name: msc.Name,
  249. Musicians: upName,
  250. UpMID: msc.UpMID,
  251. Cover: msc.Cover,
  252. Stat: msc.Stat,
  253. Playurl: msc.Playurl,
  254. Duration: msc.Duration,
  255. FileSize: msc.FileSize,
  256. CTime: msc.CTime,
  257. MTime: msc.MTime,
  258. Pubtime: msc.Pubtime,
  259. Tl: msc.Tl,
  260. RecommendPoint: msc.RecommendPoint,
  261. Cooperate: msc.Cooperate,
  262. CooperateURL: msc.CooperateURL,
  263. }
  264. // freash bgm.Tags by joinunix
  265. if junix+86400*7 >= time.Now().Unix() {
  266. bgm.New = 1
  267. bgm.Tags = []string{"NEW"}
  268. } else {
  269. bgm.Tags = make([]string, 0)
  270. }
  271. if len(msc.Tags) > 0 {
  272. bgm.Tags = append(bgm.Tags, msc.Tags...)
  273. }
  274. topLen := 3
  275. if len(bgm.Tags) > topLen {
  276. bgm.Tags = bgm.Tags[:topLen]
  277. }
  278. bgms[tp] = append(bgms[tp], bgm)
  279. }
  280. }
  281. }
  282. }
  283. if len(bgms) > 0 {
  284. s.MscWithTypes = bgms
  285. }
  286. var filterdCategorys []*mMdl.Category
  287. for _, t := range resCategorys {
  288. if len(bgms[t.ID]) > 0 {
  289. sort.Slice(bgms[t.ID], func(i, j int) bool {
  290. return bgms[t.ID][i].Index < bgms[t.ID][j].Index
  291. })
  292. t.Children = bgms[t.ID]
  293. filterdCategorys = append(filterdCategorys, t)
  294. }
  295. }
  296. s.Types = filterdCategorys
  297. }
  298. }
  299. log.Info("loadPreValues (%d)|(%d)", len(s.MscWithTypes), len(s.Types))
  300. }
  301. // BgmExt fn
  302. func (s *Service) BgmExt(c context.Context, mid, sid int64) (ret *mMdl.BgmExt, err error) {
  303. var (
  304. bgm *mMdl.Music
  305. upMid int64
  306. shouldFollowMids []int64
  307. g = &errgroup.Group{}
  308. ctx = context.TODO()
  309. extSidMap map[int]int64
  310. )
  311. log.Warn("BgmExt allMsc(%d)", len(s.AllMsc))
  312. if v, ok := s.AllMsc[sid]; ok {
  313. bgm = v
  314. ret = &mMdl.BgmExt{
  315. Msc: bgm,
  316. }
  317. } else {
  318. return
  319. }
  320. log.Warn("BgmExt finish find bgm allMsc(%d)|bgm(%+v)", len(s.AllMsc), bgm)
  321. if bgm == nil {
  322. return
  323. }
  324. log.Warn("BgmExt bgm info (%+v)", bgm)
  325. upMid = bgm.UpMID
  326. ret.ExtMscs, extSidMap = s.UperOtherBgmsFromRecom(ctx, upMid, sid)
  327. ip := metadata.String(c, metadata.RemoteIP)
  328. // step 1: get ext aids and rpc archives
  329. g.Go(func() error {
  330. ret.ExtArcs, ret.Msc.Hotval, err = s.ExtArcsWithSameBgm(ctx, sid)
  331. log.Warn("BgmExt step 1: extArcs(%+v)|hotVal(%+v)|sid(%+d)|err(%+v)", ret.ExtArcs, ret.Msc.Hotval, sid, err)
  332. return nil
  333. })
  334. // step 2: get ext mscs
  335. g.Go(func() error {
  336. ret.ExtMscs, err = s.ExtSidHotMapAndSort(ctx, ret.ExtMscs, extSidMap)
  337. log.Warn("BgmExt step 2: ExtMscs(%+v)|extSidMap(%+v)|err(%+v)", ret.ExtMscs, extSidMap, err)
  338. return nil
  339. })
  340. // step 3: get up info and if should follow
  341. g.Go(func() error {
  342. ret.UpProfile, err = s.acc.Profile(ctx, upMid, ip)
  343. log.Warn("BgmExt step 3: profile mid(%+v)", upMid)
  344. return nil
  345. })
  346. // step 4: get up info and if should follow
  347. g.Go(func() error {
  348. shouldFollowMids, err = s.acc.ShouldFollow(ctx, mid, []int64{upMid}, ip)
  349. if len(shouldFollowMids) == 1 {
  350. ret.ShouldFollow = true
  351. }
  352. log.Warn("BgmExt step 4: shouldFollow(%+v)", ret.ShouldFollow)
  353. return nil
  354. })
  355. g.Wait()
  356. return
  357. }
  358. // ExtSidHotMapAndSort fn, sorry ...
  359. func (s *Service) ExtSidHotMapAndSort(c context.Context, ExtMscs []*mMdl.Music, extSidMap map[int]int64) (res []*mMdl.Music, err error) {
  360. var (
  361. s1total, s2total, s3total int
  362. s1hot, s2hot, s3hot int
  363. )
  364. if len(extSidMap) > 0 {
  365. var (
  366. g = &errgroup.Group{}
  367. ctx = context.TODO()
  368. )
  369. if sid, ok := extSidMap[1]; ok {
  370. g.Go(func() error {
  371. if _, s1total, err = s.music.ExtAidsWithSameBgm(ctx, sid, 1); err != nil {
  372. log.Error("ExtAidsWithSameBgm S1 error(%v)", err)
  373. }
  374. s1hot = s1total * hotvalArcFactor
  375. return nil
  376. })
  377. }
  378. if sid, ok := extSidMap[2]; ok {
  379. g.Go(func() error {
  380. if _, s2total, err = s.music.ExtAidsWithSameBgm(ctx, sid, 1); err != nil {
  381. log.Error("ExtAidsWithSameBgm S2 error(%v)", err)
  382. }
  383. s2hot = s2total * hotvalArcFactor
  384. return nil
  385. })
  386. }
  387. if sid, ok := extSidMap[3]; ok {
  388. g.Go(func() error {
  389. if _, s3total, err = s.music.ExtAidsWithSameBgm(ctx, sid, 1); err != nil {
  390. log.Error("ExtAidsWithSameBgm S3 error(%v)", err)
  391. }
  392. s3hot = s3total * hotvalArcFactor
  393. return nil
  394. })
  395. }
  396. g.Wait()
  397. }
  398. for idx, v := range ExtMscs {
  399. if idx == 0 {
  400. v.Hotval = s1hot
  401. }
  402. if idx == 1 {
  403. v.Hotval = s2hot
  404. }
  405. if idx == 2 {
  406. v.Hotval = s3hot
  407. }
  408. }
  409. sort.Slice(ExtMscs, func(i, j int) bool {
  410. return ExtMscs[i].Hotval > ExtMscs[j].Hotval
  411. })
  412. res = ExtMscs
  413. return
  414. }
  415. // ExtArcsWithSameBgm fn
  416. func (s *Service) ExtArcsWithSameBgm(c context.Context, sid int64) (res []*api.Arc, hot int, err error) {
  417. var (
  418. arcMap map[int64]*api.Arc
  419. aids []int64
  420. total int
  421. )
  422. aids, total, err = s.music.ExtAidsWithSameBgm(c, sid, 100)
  423. if len(aids) > 0 {
  424. ip := metadata.String(c, metadata.RemoteIP)
  425. if arcMap, err = s.archive.Archives(c, aids, ip); err != nil {
  426. log.Error("s.archive.Archives Stats (%v) error(%v)", aids, err)
  427. err = ecode.CreativeArcServiceErr
  428. return
  429. }
  430. for _, aid := range aids {
  431. if arc, ok := arcMap[aid]; ok && arc.State >= 0 {
  432. res = append(res, arc)
  433. }
  434. }
  435. }
  436. topLen := 20
  437. if len(res) > topLen {
  438. res = res[:topLen]
  439. }
  440. hot = total * hotvalArcFactor
  441. return
  442. }
  443. // UperOtherBgmsFromRecom fn, 最多三个同一个Up主的bgms
  444. func (s *Service) UperOtherBgmsFromRecom(c context.Context, upmid, sid int64) (res []*mMdl.Music, extSidMap map[int]int64) {
  445. extSidMap = make(map[int]int64)
  446. idx := int(1)
  447. for _, mscs := range s.MscWithTypes {
  448. for _, msc := range mscs {
  449. if msc.SID != sid &&
  450. msc.UpMID == upmid &&
  451. len(extSidMap) < 3 {
  452. res = append(res, msc)
  453. extSidMap[idx] = msc.SID
  454. idx++
  455. }
  456. }
  457. }
  458. return
  459. }
  460. // BgmView fn
  461. func (s *Service) BgmView(c context.Context, sid int64) (ret *mMdl.Music) {
  462. for _, msc := range s.AllMsc {
  463. if msc.ID == sid {
  464. ret = msc
  465. break
  466. }
  467. }
  468. return
  469. }
  470. // PreByFrom fn
  471. func (s *Service) PreByFrom(c context.Context, from int) (types []*mMdl.Category) {
  472. if from == 1 {
  473. sort.Slice(s.Types, func(i, j int) bool {
  474. return s.Types[i].CameraIndex <= s.Types[j].CameraIndex
  475. })
  476. } else {
  477. sort.Slice(s.Types, func(i, j int) bool {
  478. return s.Types[i].Index <= s.Types[j].Index
  479. })
  480. }
  481. types = s.Types
  482. return
  483. }
  484. // BgmList fn
  485. func (s *Service) BgmList(c context.Context, tid int) (ret []*mMdl.Music) {
  486. if len(s.MscWithTypes) > 0 {
  487. if mics, ok := s.MscWithTypes[tid]; ok {
  488. ret = mics
  489. }
  490. }
  491. return
  492. }
  493. // getUpNames fn
  494. func (s *Service) getUpNames(c context.Context, mmap map[int64]*mMdl.Music) (ret map[int64]string, err error) {
  495. var (
  496. minfos map[int64]*accMdl.Info
  497. mids []int64
  498. )
  499. ret = make(map[int64]string)
  500. for _, msc := range mmap {
  501. mids = append(mids, msc.UpMID)
  502. }
  503. if len(mids) > 0 {
  504. minfos, err = s.acc.Infos(c, mids, "localhost")
  505. if err != nil {
  506. log.Info("minfos err mids (%+v)|err(%+v)", mids, err)
  507. return
  508. }
  509. for _, info := range minfos {
  510. ret[info.Mid] = info.Name
  511. }
  512. }
  513. return
  514. }
  515. // Cooperate fn
  516. func (s *Service) Cooperate(c context.Context, id, mid int64) (res *mMdl.Cooperate) {
  517. _, white := s.stickerUps[mid]
  518. for _, v := range s.Cooperates {
  519. if v.White == 1 && !white {
  520. return
  521. }
  522. if v.ID == id {
  523. return v
  524. }
  525. }
  526. return
  527. }
  528. // Material fn
  529. func (s *Service) Material(c context.Context, id int64, tp int8, mid int64) (res interface{}) {
  530. if _, ok := mMdl.ViewTpMap[tp]; !ok {
  531. return
  532. }
  533. _, white := s.stickerUps[mid]
  534. switch tp {
  535. case appMdl.TypeSubtitle:
  536. for _, v := range s.Subtitles {
  537. if v.White == 1 && !white {
  538. return
  539. }
  540. if v.ID == id {
  541. return v
  542. }
  543. }
  544. case appMdl.TypeFont:
  545. for _, v := range s.Fonts {
  546. if v.White == 1 && !white {
  547. return
  548. }
  549. if v.ID == id {
  550. return v
  551. }
  552. }
  553. case appMdl.TypeFilter:
  554. for _, v := range s.Filters {
  555. if v.White == 1 && !white {
  556. return
  557. }
  558. if v.ID == id {
  559. return v
  560. }
  561. }
  562. case appMdl.TypeSticker:
  563. for _, v := range s.Stickers {
  564. if v.White == 1 && !white {
  565. return
  566. }
  567. if v.ID == id {
  568. return v
  569. }
  570. }
  571. case appMdl.TypeVideoupSticker:
  572. for _, v := range s.Vstickers {
  573. if v.White == 1 && !white {
  574. return
  575. }
  576. if v.ID == id {
  577. return v
  578. }
  579. }
  580. case appMdl.TypeTransition:
  581. for _, v := range s.Transitions {
  582. if v.White == 1 && !white {
  583. return
  584. }
  585. if v.ID == id {
  586. return v
  587. }
  588. }
  589. case appMdl.TypeCooperate:
  590. for _, v := range s.Cooperates {
  591. if v.White == 1 && !white {
  592. return
  593. }
  594. if v.ID == id {
  595. return v
  596. }
  597. }
  598. case appMdl.TypeTheme:
  599. for _, v := range s.Themes {
  600. if v.White == 1 && !white {
  601. return
  602. }
  603. if v.ID == id {
  604. return v
  605. }
  606. }
  607. }
  608. return
  609. }
  610. // MaterialPre fn
  611. func (s *Service) MaterialPre(c context.Context, mid int64, platStr string, build int) (res map[string]interface{}) {
  612. var (
  613. hotwords = []*mMdl.Hotword{}
  614. stickers = []*mMdl.Sticker{}
  615. vstickers = []*mMdl.VSticker{}
  616. trans = []*mMdl.Transition{}
  617. cooperates = []*mMdl.Cooperate{}
  618. themes = []*mMdl.Theme{}
  619. intros = []*mMdl.Intro{}
  620. intro = &mMdl.Intro{}
  621. subs = []*mMdl.Subtitle{}
  622. fonts = []*mMdl.Font{}
  623. filters = []*mMdl.Filter{}
  624. filterWithCategory = make([]*mMdl.FilterCategory, 0)
  625. vstickerWithCategory = make([]*mMdl.VstickerCategory, 0)
  626. white bool
  627. )
  628. _, white = s.stickerUps[mid]
  629. for _, v := range s.Subtitles {
  630. if !v.AllowMaterial(v.Material, platStr, build, white) {
  631. continue
  632. }
  633. subs = append(subs, v)
  634. }
  635. for _, v := range s.Fonts {
  636. if !v.AllowMaterial(v.Material, platStr, build, white) {
  637. continue
  638. }
  639. fonts = append(fonts, v)
  640. }
  641. for _, v := range s.Filters {
  642. if !v.AllowMaterial(v.Material, platStr, build, white) {
  643. continue
  644. }
  645. filters = append(filters, v)
  646. }
  647. for _, v := range s.Hotwords {
  648. if !v.AllowMaterial(v.Material, platStr, build, white) {
  649. continue
  650. }
  651. hotwords = append(hotwords, v)
  652. }
  653. for _, v := range s.Stickers {
  654. if !v.AllowMaterial(v.Material, platStr, build, white) {
  655. continue
  656. }
  657. stickers = append(stickers, v)
  658. }
  659. for _, v := range s.Intros {
  660. if !v.AllowMaterial(v.Material, platStr, build, white) {
  661. continue
  662. }
  663. intros = append(intros, v)
  664. }
  665. for _, v := range s.Vstickers {
  666. if !v.AllowMaterial(v.Material, platStr, build, white) {
  667. continue
  668. }
  669. vstickers = append(vstickers, v)
  670. }
  671. for _, v := range s.Transitions {
  672. if !v.AllowMaterial(v.Material, platStr, build, white) {
  673. continue
  674. }
  675. trans = append(trans, v)
  676. }
  677. for _, v := range s.Themes {
  678. if !v.AllowMaterial(v.Material, platStr, build, white) {
  679. continue
  680. }
  681. themes = append(themes, v)
  682. }
  683. for _, v := range s.Cooperates {
  684. if !v.AllowMaterial(v.Material, platStr, build, white) {
  685. continue
  686. }
  687. cooperates = append(cooperates, v)
  688. }
  689. for _, fcategory := range s.FilterWithCategory {
  690. fcategoryChilds := make([]*mMdl.Filter, 0)
  691. for _, v := range fcategory.Children {
  692. if !v.AllowMaterial(v.Material, platStr, build, white) {
  693. continue
  694. }
  695. fcategoryChilds = append(fcategoryChilds, v)
  696. }
  697. if len(fcategoryChilds) > 0 {
  698. filterWithCategory = append(filterWithCategory, &mMdl.FilterCategory{
  699. ID: fcategory.ID,
  700. Name: fcategory.Name,
  701. Rank: fcategory.Rank,
  702. Tp: fcategory.Tp,
  703. Children: fcategoryChilds,
  704. })
  705. }
  706. }
  707. for _, vscategory := range s.VstickerWithCategory {
  708. vscategoryChilds := make([]*mMdl.VSticker, 0)
  709. for _, v := range vscategory.Children {
  710. if !v.AllowMaterial(v.Material, platStr, build, white) {
  711. continue
  712. }
  713. vscategoryChilds = append(vscategoryChilds, v)
  714. }
  715. if len(vscategoryChilds) > 0 {
  716. vstickerWithCategory = append(vstickerWithCategory, &mMdl.VstickerCategory{
  717. ID: vscategory.ID,
  718. Name: vscategory.Name,
  719. Rank: vscategory.Rank,
  720. Tp: vscategory.Tp,
  721. Children: vscategoryChilds,
  722. })
  723. }
  724. }
  725. if len(intros) > 0 {
  726. intro = intros[0]
  727. }
  728. res = map[string]interface{}{
  729. "filter": filters,
  730. "filter_with_category": filterWithCategory,
  731. "hotword": hotwords,
  732. "sticker": stickers,
  733. "intro": intro,
  734. "subtitle": subs,
  735. "font": fonts,
  736. "trans": trans,
  737. "themes": themes,
  738. "cooperates": cooperates,
  739. "videoup_sticker": vstickers,
  740. "vsticker_with_category": vstickerWithCategory,
  741. "latests": s.genLatests(intros, filters, subs, fonts, hotwords, stickers, vstickers, trans, cooperates, themes),
  742. }
  743. return
  744. }
  745. // begin from app 536
  746. func (s *Service) genLatests(intros []*mMdl.Intro, filters []*mMdl.Filter, subs []*mMdl.Subtitle, fonts []*mMdl.Font, hotwords []*mMdl.Hotword, stickers []*mMdl.Sticker, vstickers []*mMdl.VSticker, trans []*mMdl.Transition, coos []*mMdl.Cooperate, themes []*mMdl.Theme) (latests map[int8]interface{}) {
  747. latests = make(map[int8]interface{})
  748. latests[appMdl.TypeBGM] = s.LatestBgm
  749. if len(intros) > 0 {
  750. sort.Slice(intros, func(i, j int) bool {
  751. return intros[i].MTime >= intros[j].MTime
  752. })
  753. latests[appMdl.TypeIntro] = intros[0]
  754. }
  755. if len(themes) > 0 {
  756. cthemes := make([]*mMdl.Theme, len(themes))
  757. copy(cthemes, themes)
  758. sort.Slice(cthemes, func(i, j int) bool {
  759. return cthemes[i].MTime >= cthemes[j].MTime
  760. })
  761. latests[appMdl.TypeTheme] = cthemes[0]
  762. }
  763. if len(coos) > 0 {
  764. ccoos := make([]*mMdl.Cooperate, len(coos))
  765. copy(ccoos, coos)
  766. sort.Slice(ccoos, func(i, j int) bool {
  767. return ccoos[i].MTime >= ccoos[j].MTime
  768. })
  769. latests[appMdl.TypeCooperate] = ccoos[0]
  770. }
  771. if len(trans) > 0 {
  772. ctrans := make([]*mMdl.Transition, len(trans))
  773. copy(ctrans, trans)
  774. sort.Slice(ctrans, func(i, j int) bool {
  775. return ctrans[i].MTime >= ctrans[j].MTime
  776. })
  777. latests[appMdl.TypeTransition] = ctrans[0]
  778. }
  779. if len(vstickers) > 0 {
  780. cvstickers := make([]*mMdl.VSticker, len(vstickers))
  781. copy(cvstickers, vstickers)
  782. sort.Slice(cvstickers, func(i, j int) bool {
  783. return cvstickers[i].MTime >= cvstickers[j].MTime
  784. })
  785. latests[appMdl.TypeVideoupSticker] = cvstickers[0]
  786. }
  787. if len(stickers) > 0 {
  788. cstickers := make([]*mMdl.Sticker, len(stickers))
  789. copy(cstickers, stickers)
  790. sort.Slice(cstickers, func(i, j int) bool {
  791. return cstickers[i].MTime >= cstickers[j].MTime
  792. })
  793. latests[appMdl.TypeSticker] = cstickers[0]
  794. }
  795. if len(hotwords) > 0 {
  796. chotwords := make([]*mMdl.Hotword, len(hotwords))
  797. copy(chotwords, hotwords)
  798. sort.Slice(chotwords, func(i, j int) bool {
  799. return chotwords[i].MTime >= chotwords[j].MTime
  800. })
  801. latests[appMdl.TypeHotWord] = chotwords[0]
  802. }
  803. if len(fonts) > 0 {
  804. cfonts := make([]*mMdl.Font, len(fonts))
  805. copy(cfonts, fonts)
  806. sort.Slice(cfonts, func(i, j int) bool {
  807. return cfonts[i].MTime >= cfonts[j].MTime
  808. })
  809. latests[appMdl.TypeFont] = cfonts[0]
  810. }
  811. if len(filters) > 0 {
  812. cfilters := make([]*mMdl.Filter, len(filters))
  813. copy(cfilters, filters)
  814. sort.Slice(cfilters, func(i, j int) bool {
  815. return cfilters[i].MTime >= cfilters[j].MTime
  816. })
  817. latests[appMdl.TypeFilter] = cfilters[0]
  818. }
  819. if len(subs) > 0 {
  820. csubs := make([]*mMdl.Subtitle, len(subs))
  821. copy(csubs, subs)
  822. sort.Slice(csubs, func(i, j int) bool {
  823. return csubs[i].MTime >= csubs[j].MTime
  824. })
  825. latests[appMdl.TypeSubtitle] = csubs[0]
  826. }
  827. return
  828. }
  829. // AddBgmFeedBack send to log service
  830. func (s *Service) AddBgmFeedBack(c context.Context, name, musicians, platform string, mid int64) (err error) {
  831. uInfo := &report.UserInfo{
  832. Mid: mid,
  833. Platform: platform,
  834. Business: 82, // app投稿业务
  835. Type: 1, //投稿bgm反馈
  836. Oid: mid,
  837. Action: "add_bgm_feedback",
  838. Ctime: time.Now(),
  839. IP: metadata.String(c, metadata.RemoteIP),
  840. Index: []interface{}{name, musicians, mid},
  841. }
  842. uInfo.Content = map[string]interface{}{
  843. "name": name,
  844. "musicians": musicians,
  845. "mid": mid,
  846. }
  847. report.User(uInfo)
  848. log.Info("send AddBgmFeedBack Log data(%+v)", uInfo)
  849. return
  850. }
  851. // BgmSearch fn
  852. func (s *Service) BgmSearch(c context.Context, kw string, mid int64, pn, ps int) (res *sMdl.BgmSearchRes) {
  853. res = &sMdl.BgmSearchRes{
  854. Bgms: make([]*mMdl.Music, 0),
  855. Pager: &sMdl.Pager{
  856. Num: pn,
  857. Size: ps,
  858. Total: 0,
  859. },
  860. }
  861. if len(kw) == 0 {
  862. return
  863. }
  864. var (
  865. err error
  866. resIDS = make([]int64, 0)
  867. mids = make([]int64, 0)
  868. pager *sMdl.Pager
  869. minfos map[int64]*accMdl.Info
  870. )
  871. if resIDS, pager, err = s.music.SearchBgmSIDs(c, kw, pn, ps); err != nil {
  872. log.Error("s.music.SearchBgmSIDs kw(%s)|pn(%d)|ps(%d) error(%v)", kw, pn, ps, err)
  873. return
  874. }
  875. for _, sid := range resIDS {
  876. if msc, ok := s.AllMsc[sid]; ok {
  877. res.Bgms = append(res.Bgms, msc)
  878. mids = append(mids, msc.UpMID)
  879. }
  880. }
  881. if len(mids) > 0 {
  882. minfos, err = s.acc.Infos(c, mids, "localhost")
  883. if err != nil {
  884. log.Info("minfos err mids (%+v)|err(%+v)", mids, err)
  885. return
  886. }
  887. for _, v := range res.Bgms {
  888. if up, ok := minfos[v.UpMID]; ok {
  889. v.Musicians = up.Name
  890. }
  891. }
  892. }
  893. if pager != nil {
  894. res.Pager.Total = pager.Total
  895. }
  896. return
  897. }
  898. func (s *Service) getFilterAndItsCategory(ctx context.Context) {
  899. var (
  900. err error
  901. filters []*mMdl.Filter
  902. filterMap map[int64]*mMdl.Filter
  903. filterCategory = make([]*mMdl.FilterCategory, 0)
  904. filterBinds []*mMdl.MaterialBind
  905. )
  906. c := context.Background()
  907. if filters, filterMap, err = s.material.Filters(c); err != nil {
  908. log.Error("s.material.Filters err(%+v)", err)
  909. return
  910. }
  911. s.Filters = filters
  912. if filterBinds, err = s.material.CategoryBind(c, appMdl.TypeFilter); err != nil {
  913. log.Error("s.material.CategoryBind err(%+v)", err)
  914. return
  915. }
  916. mapsByCID := make(map[int64]*mMdl.FilterCategory)
  917. for _, bind := range filterBinds {
  918. oldF := filterMap[bind.MID]
  919. if oldF == nil {
  920. continue
  921. }
  922. newF := &mMdl.Filter{
  923. ID: oldF.ID,
  924. Name: oldF.Name,
  925. Cover: oldF.Cover,
  926. DownloadURL: oldF.DownloadURL,
  927. Rank: bind.BRank,
  928. Extra: oldF.Extra,
  929. Material: oldF.Material,
  930. MTime: oldF.MTime,
  931. New: oldF.New,
  932. Tags: oldF.Tags,
  933. FilterType: oldF.FilterType,
  934. }
  935. if _, ok := mapsByCID[bind.CID]; !ok {
  936. mapsByCID[bind.CID] = &mMdl.FilterCategory{
  937. ID: bind.CID,
  938. Name: bind.CName,
  939. Rank: bind.CRank,
  940. Tp: bind.Tp,
  941. New: bind.New,
  942. Children: []*mMdl.Filter{newF},
  943. }
  944. } else {
  945. mapsByCID[bind.CID].Children = append(mapsByCID[bind.CID].Children, newF)
  946. }
  947. }
  948. for _, v := range mapsByCID {
  949. sort.Slice(v.Children, func(i, j int) bool {
  950. return v.Children[i].Rank <= v.Children[j].Rank
  951. })
  952. filterCategory = append(filterCategory, v)
  953. }
  954. sort.Slice(filterCategory, func(i, j int) bool {
  955. return filterCategory[i].Rank <= filterCategory[j].Rank
  956. })
  957. s.FilterWithCategory = filterCategory
  958. }
  959. func (s *Service) getCooperates(ctx context.Context) {
  960. var (
  961. err error
  962. coos []*mMdl.Cooperate
  963. daids []int64
  964. darcMap map[int64]*api.Arc
  965. )
  966. c := context.Background()
  967. if coos, daids, err = s.material.Cooperates(c); err != nil {
  968. log.Error("s.material.Cooperates err(%+v)", err)
  969. return
  970. }
  971. ip := metadata.String(c, metadata.RemoteIP)
  972. if len(daids) > 0 {
  973. if darcMap, err = s.archive.Archives(c, daids, ip); err != nil {
  974. log.Error("s.archive.Archives err(%+v)", err)
  975. return
  976. }
  977. }
  978. for _, v := range coos {
  979. mtime := v.MTime.Time()
  980. hot1 := 20000
  981. hot2 := mtime.Hour()*100 + mtime.Minute()
  982. hot3 := 567 * v.ArcCnt
  983. v.HotVal = hot1 + hot2 + hot3
  984. if arc, ok := darcMap[v.DemoAID]; ok {
  985. v.Cover = arc.Pic
  986. }
  987. }
  988. s.Cooperates = coos
  989. }
  990. func (s *Service) getVStickerAndItsCategory(ctx context.Context) {
  991. var (
  992. err error
  993. vstickers []*mMdl.VSticker
  994. vstickersMap map[int64]*mMdl.VSticker
  995. vstickerCategory = make([]*mMdl.VstickerCategory, 0)
  996. vstickerBinds []*mMdl.MaterialBind
  997. )
  998. c := context.Background()
  999. if vstickers, vstickersMap, err = s.material.Vstickers(c); err != nil {
  1000. log.Error("s.material.vstickers err(%+v)", err)
  1001. return
  1002. }
  1003. s.Vstickers = vstickers
  1004. if vstickerBinds, err = s.material.CategoryBind(c, appMdl.TypeVideoupSticker); err != nil {
  1005. log.Error("s.material.CategoryBind err(%+v)", err)
  1006. return
  1007. }
  1008. mapsByCID := make(map[int64]*mMdl.VstickerCategory)
  1009. for _, bind := range vstickerBinds {
  1010. oldF := vstickersMap[bind.MID]
  1011. if oldF == nil {
  1012. continue
  1013. }
  1014. newF := &mMdl.VSticker{
  1015. ID: oldF.ID,
  1016. Name: oldF.Name,
  1017. Cover: oldF.Cover,
  1018. DownloadURL: oldF.DownloadURL,
  1019. Rank: bind.BRank,
  1020. Extra: oldF.Extra,
  1021. Material: oldF.Material,
  1022. }
  1023. if _, ok := mapsByCID[bind.CID]; !ok {
  1024. mapsByCID[bind.CID] = &mMdl.VstickerCategory{
  1025. ID: bind.CID,
  1026. Name: bind.CName,
  1027. Rank: bind.CRank,
  1028. Tp: bind.Tp,
  1029. New: bind.New,
  1030. Children: []*mMdl.VSticker{newF},
  1031. }
  1032. } else {
  1033. mapsByCID[bind.CID].Children = append(mapsByCID[bind.CID].Children, newF)
  1034. }
  1035. }
  1036. for _, v := range mapsByCID {
  1037. sort.Slice(v.Children, func(i, j int) bool {
  1038. return v.Children[i].Rank <= v.Children[j].Rank
  1039. })
  1040. vstickerCategory = append(vstickerCategory, v)
  1041. }
  1042. sort.Slice(vstickerCategory, func(i, j int) bool {
  1043. return vstickerCategory[i].Rank <= vstickerCategory[j].Rank
  1044. })
  1045. s.VstickerWithCategory = vstickerCategory
  1046. }
  1047. // CooperatePre fn
  1048. func (s *Service) CooperatePre(c context.Context, mid int64, platStr string, build int) (cooperates []*mMdl.Cooperate) {
  1049. var (
  1050. white bool
  1051. )
  1052. cooperates = make([]*mMdl.Cooperate, 0)
  1053. _, white = s.stickerUps[mid]
  1054. for _, v := range s.Cooperates {
  1055. if !v.AllowMaterial(v.Material, platStr, build, white) {
  1056. continue
  1057. }
  1058. cooperates = append(cooperates, v)
  1059. }
  1060. for _, x := range cooperates {
  1061. if x.MissionID > 0 {
  1062. if mis, ok := s.p.ActMapCache[x.MissionID]; ok {
  1063. x.Mission = mis
  1064. }
  1065. }
  1066. }
  1067. return
  1068. }