danmu.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. package danmu
  2. import (
  3. "context"
  4. "encoding/json"
  5. "go-common/app/interface/main/creative/model/danmu"
  6. pubSvc "go-common/app/interface/main/creative/service"
  7. dmMdl "go-common/app/interface/main/dm/model"
  8. "go-common/app/service/main/account/model"
  9. account "go-common/app/service/main/account/model"
  10. "go-common/app/service/main/archive/api"
  11. "go-common/library/ecode"
  12. "go-common/library/log"
  13. "go-common/library/sync/errgroup"
  14. "strconv"
  15. "time"
  16. )
  17. var (
  18. stateMap = map[int8]int8{
  19. 0: 0, // 正常
  20. 1: 1, // 删除
  21. 2: 2, // 保护
  22. 3: 3, // 取消保护
  23. }
  24. poolMap = map[int8]int8{
  25. 0: 0, // 普通弹幕池
  26. 1: 1, // 字幕弹幕池
  27. 2: 2, // 特殊弹幕池
  28. }
  29. )
  30. // AdvDmPurchaseList fn
  31. func (s *Service) AdvDmPurchaseList(c context.Context, mid int64, ip string) (danmus []*danmu.AdvanceDanmu, err error) {
  32. if danmus, err = s.dm.GetAdvDmPurchases(c, mid, ip); err != nil {
  33. log.Error("s.dm.ListAdvDmPurchases err(%v) | mid(%d), ip(%s)", err, mid, ip)
  34. return
  35. }
  36. return
  37. }
  38. // PassDmPurchase fn
  39. func (s *Service) PassDmPurchase(c context.Context, mid, id int64, ip string) (err error) {
  40. if err = s.dm.PassAdvDmPurchase(c, mid, id, ip); err != nil {
  41. log.Error("s.dm.PassDmPurchase err(%v) | mid(%d), id(%d), ip(%s)", err, mid, id, ip)
  42. return
  43. }
  44. return
  45. }
  46. // DenyDmPurchase fn
  47. func (s *Service) DenyDmPurchase(c context.Context, mid, id int64, ip string) (err error) {
  48. if err = s.dm.DenyAdvDmPurchase(c, mid, id, ip); err != nil {
  49. log.Error("s.dm.DenyDmPurchase err(%v) | mid(%d), id(%d), ip(%s)", err, mid, id, ip)
  50. return
  51. }
  52. return
  53. }
  54. // CancelDmPurchase fn
  55. func (s *Service) CancelDmPurchase(c context.Context, mid, id int64, ip string) (err error) {
  56. if err = s.dm.CancelAdvDmPurchase(c, mid, id, ip); err != nil {
  57. log.Error("s.dm.CancelDmPurchase err(%v) | mid(%d), id(%d), ip(%s)", err, mid, id, ip)
  58. return
  59. }
  60. return
  61. }
  62. // Edit fn
  63. func (s *Service) Edit(c context.Context, mid, id int64, state int8, dmids []int64, ip string) (err error) {
  64. if len(dmids) == 0 {
  65. err = ecode.CreativeDanmuFilterParamError
  66. return
  67. }
  68. okState := false
  69. for _, v := range stateMap {
  70. if v == state {
  71. okState = true
  72. }
  73. }
  74. if !okState {
  75. err = ecode.RequestErr
  76. return
  77. }
  78. if err = s.dm.Edit(c, mid, id, state, dmids, ip); err != nil {
  79. log.Error("s.dm.DmList err(%v)|mid(%d),id(%d),state(%d),dmids(%+v),ip(%s)", err, mid, id, state, dmids, ip)
  80. return
  81. }
  82. return
  83. }
  84. // Transfer fn
  85. func (s *Service) Transfer(c context.Context, mid, fromCID, toCID int64, offset float64, ak, ck, ip string) (err error) {
  86. if err = s.dm.Transfer(c, mid, fromCID, toCID, offset, ak, ck, ip); err != nil {
  87. log.Error("s.dm.Transfer err(%v) | mid(%d),fromCID(%d),toCID(%d),offset(%+v),ak(%s),ck(%s),ip(%s)", err, mid, fromCID, toCID, offset, ak, ck, ip)
  88. return
  89. }
  90. return
  91. }
  92. // UpPool fn
  93. func (s *Service) UpPool(c context.Context, cid int64, dmids []int64, pool int8, mid int64, ip string) (err error) {
  94. okPool := false
  95. for _, v := range poolMap {
  96. if v == pool {
  97. okPool = true
  98. }
  99. }
  100. if !okPool {
  101. err = ecode.RequestErr
  102. return
  103. }
  104. if err = s.dm.UpPool(c, mid, cid, dmids, pool); err != nil {
  105. log.Error("s.dm.UpPool err(%v)|cid(%d),dmids(%+v),pool(%+v),mid(%d),ip(%s)", err, cid, dmids, pool, mid, ip)
  106. return
  107. }
  108. return
  109. }
  110. // Distri fn
  111. func (s *Service) Distri(c context.Context, mid, cid int64, ip string) (dmDistri map[int64]int64, err error) {
  112. if dmDistri, err = s.dm.Distri(c, mid, cid, ip); err != nil {
  113. log.Error("s.dm.Distri err(%v) | mid(%d),cid(%d)|ip(%s)", err, mid, cid, ip)
  114. return
  115. }
  116. return
  117. }
  118. // List fn
  119. func (s *Service) List(c context.Context, mid, aid, cid int64, pn, ps int, order, pool, midStr, ip string) (dmList *danmu.DmList, err error) {
  120. var (
  121. v *api.Page
  122. a *api.Arc
  123. mids []int64
  124. elecs map[int64]int
  125. followers map[int64]int
  126. senders map[int64]*account.Info
  127. )
  128. a, _ = s.arc.Archive(c, aid, ip)
  129. v, _ = s.arc.Video(c, aid, cid, ip)
  130. if dmList, err = s.dm.List(c, cid, mid, pn, ps, order, pool, midStr, ip); err != nil {
  131. log.Error("s.dm.List err(%v) | mid(%d), cid(%d),pn(%d),ps(%d),order(%s),midStr(%s),ip(%s)", err, mid, cid, pn, ps, order, midStr, ip)
  132. return
  133. }
  134. for _, l := range dmList.List {
  135. mids = append(mids, l.Mid)
  136. }
  137. if len(mids) > 0 {
  138. var g, ctx = errgroup.WithContext(c)
  139. g.Go(func() error { //获取被充电状态
  140. elecs, _ = s.elec.ElecRelation(ctx, mid, mids, ip)
  141. return nil
  142. })
  143. g.Go(func() error { //获取用户信息
  144. senders, _ = s.acc.Infos(ctx, mids, ip)
  145. return nil
  146. })
  147. g.Go(func() error { //获取被关注状态
  148. followers, _ = s.acc.Followers(ctx, mid, mids, ip)
  149. return nil
  150. })
  151. g.Wait()
  152. for _, l := range dmList.List {
  153. l.VTitle = v.Part
  154. l.ArcTitle = a.Title
  155. l.Aid = aid
  156. l.Cover = pubSvc.CoverURL(a.Pic)
  157. if elec, ok := elecs[l.Mid]; ok { //设置充电状态
  158. l.IsElec = elec
  159. }
  160. if u, ok := senders[l.Mid]; ok { //设置图像和用户名
  161. l.Uname = u.Name
  162. l.Uface = u.Face
  163. }
  164. if relation, ok := followers[l.Mid]; ok { //设置关注状态
  165. l.Relation = relation
  166. }
  167. }
  168. }
  169. return
  170. }
  171. // Recent fn
  172. func (s *Service) Recent(c context.Context, mid, pn, ps int64, ip string) (dmRecent *danmu.DmRecent, err error) {
  173. var (
  174. aids []int64
  175. mids []int64
  176. elecs map[int64]int
  177. followers map[int64]int
  178. senders map[int64]*account.Info
  179. )
  180. if dmRecent, aids, err = s.dm.Recent(c, mid, pn, ps, ip); err != nil {
  181. log.Error("s.dm.Recent err(%v)|(%v),(%v),(%v),(%v),", err, mid, pn, ps, ip)
  182. return
  183. }
  184. if len(dmRecent.List) > 0 && len(aids) > 0 {
  185. var avm map[int64]*api.Arc
  186. if avm, err = s.arc.Archives(c, aids, ip); err != nil {
  187. log.Error("s.arc.Archives mid(%d)|aids(%+v)|ip(%s)|err(%v)", mid, aids, ip, err)
  188. err = nil
  189. }
  190. for _, l := range dmRecent.List {
  191. mids = append(mids, l.Mid)
  192. }
  193. var g, ctx = errgroup.WithContext(c)
  194. g.Go(func() error { //获取被充电状态
  195. elecs, _ = s.elec.ElecRelation(ctx, mid, mids, ip)
  196. return nil
  197. })
  198. g.Go(func() error { //获取用户信息
  199. senders, _ = s.acc.Infos(ctx, mids, ip)
  200. return nil
  201. })
  202. g.Go(func() error { //获取被关注状态
  203. followers, _ = s.acc.Followers(ctx, mid, mids, ip)
  204. return nil
  205. })
  206. g.Wait()
  207. for _, l := range dmRecent.List {
  208. if av, ok := avm[l.Aid]; ok && av != nil {
  209. l.Cover = pubSvc.CoverURL(av.Pic)
  210. }
  211. if elec, ok := elecs[l.Mid]; ok { //设置充电状态
  212. l.IsElec = elec
  213. }
  214. if u, ok := senders[l.Mid]; ok { //设置图像和用户名
  215. l.Uname = u.Name
  216. l.Uface = u.Face
  217. }
  218. if relation, ok := followers[l.Mid]; ok { //设置关注状态
  219. l.Relation = relation
  220. }
  221. }
  222. }
  223. return
  224. }
  225. // DmReportCheck fn
  226. func (s *Service) DmReportCheck(c context.Context, mid, cid, dmid, op int64, ip string) (err error) {
  227. if err = s.dm.ReportUpEdit(c, mid, dmid, cid, op, ip); err != nil {
  228. log.Error("s.dm.ReportUpEdit err(%v) | mid(%d), dmid(%d),cid(%d),op(%d),ip(%s)", err, mid, dmid, cid, op, ip)
  229. return
  230. }
  231. return
  232. }
  233. // DmProtectArchive fn
  234. func (s *Service) DmProtectArchive(c context.Context, mid int64, ip string) (vlist []*dmMdl.Video, err error) {
  235. if vlist, err = s.dm.ProtectApplyVideoList(c, mid, ip); err != nil {
  236. log.Error("s.dm.ProtectApplyVideoList err(%v) | mid(%d),ip(%s)", err, mid, ip)
  237. return
  238. }
  239. return
  240. }
  241. // DmProtectList fn
  242. func (s *Service) DmProtectList(c context.Context, mid int64, page int64, aidStr, sort, ip string) (list *danmu.ApplyList, err error) {
  243. if list, err = s.dm.ProtectApplyList(c, mid, page, aidStr, sort, ip); err != nil {
  244. log.Error("s.dm.ProtectApplyList err(%v) | mid(%d),aidStr(%s),page(%d),sort(%s),ip(%s)", err, mid, aidStr, page, sort, ip)
  245. return
  246. }
  247. return
  248. }
  249. // DmProtectOper fn
  250. func (s *Service) DmProtectOper(c context.Context, mid, status int64, idsStr, ip string) (err error) {
  251. if err = s.dm.ProtectOper(c, mid, status, idsStr, ip); err != nil {
  252. log.Error("s.dm.ProtectOper err(%v) | mid(%d), status(%d),ids(%s),ip(%s)", err, mid, status, idsStr, ip)
  253. return
  254. }
  255. return
  256. }
  257. // UserMid for dm search by name
  258. func (s *Service) UserMid(c context.Context, name, ip string) (mid int64, err error) {
  259. if mid, err = s.acc.MidByName(c, name); err != nil {
  260. log.Error("UserMid err(%v) | name(%s), ip(%s)", err, name, ip)
  261. if err == ecode.AccountInexistence {
  262. err = nil
  263. }
  264. return
  265. }
  266. return
  267. }
  268. // DmReportList fn
  269. func (s *Service) DmReportList(c context.Context, mid, pn, ps int64, aidStr, ip string) (res map[string]interface{}, err error) {
  270. var (
  271. pager = map[string]int64{
  272. "total": 0,
  273. "current": pn,
  274. "size": ps,
  275. }
  276. list = []*danmu.DmReport{}
  277. srchs = []*dmMdl.RptSearch{}
  278. ars = []*danmu.DmArc{}
  279. total = int64(0)
  280. owners = []int64{}
  281. )
  282. res = map[string]interface{}{
  283. "pager": pager,
  284. "list": list,
  285. "archives": ars,
  286. }
  287. if srchs, total, err = s.dm.ReportUpList(c, mid, pn, ps, aidStr, ip); err != nil {
  288. log.Error("s.dm.ReportUpList err(%v) | mid(%d),pn(%d),ps(%d),aidStr(%s),ip(%s)", err, mid, pn, ps, aidStr, ip)
  289. return
  290. }
  291. if len(srchs) > 0 {
  292. for _, v := range srchs {
  293. owners = append(owners, v.Owner)
  294. }
  295. var ownerProfiles map[int64]*model.Info
  296. if ownerProfiles, err = s.acc.Infos(c, owners, ip); err != nil {
  297. log.Error("s.cc.Infos err(%v) | mid(%d),pn(%d),ps(%d),aidStr(%s),ip(%s)", err, mid, pn, ps, aidStr, ip)
  298. return
  299. }
  300. for _, s := range srchs {
  301. t, _ := time.ParseInLocation("2006-01-02 15:04:05", s.RpTime, time.Local)
  302. report := &danmu.DmReport{
  303. RpID: s.ID,
  304. DmInID: s.Cid,
  305. AID: s.Aid,
  306. Pic: pubSvc.CoverURL(s.Cover),
  307. ReportTime: t.Unix(),
  308. Title: s.Title,
  309. Reason: s.Content,
  310. DmID: s.Did,
  311. DmIDStr: strconv.FormatInt(s.Did, 10),
  312. UpUID: s.UPUid,
  313. Content: s.Msg,
  314. UID: s.Owner,
  315. }
  316. if profile, ok := ownerProfiles[s.Owner]; ok {
  317. report.UserName = profile.Name
  318. }
  319. list = append(list, report)
  320. }
  321. if ars, err = s.dm.ReportUpArchives(c, mid, ip); err != nil {
  322. log.Error("s.dm.ReportUpArchives err(%v) | mid(%d),ip(%s)", err, mid, ip)
  323. return
  324. }
  325. }
  326. pager["total"] = total
  327. res["pager"] = pager
  328. res["list"] = list
  329. res["archives"] = ars
  330. return
  331. }
  332. // EditBatch fn
  333. func (s *Service) EditBatch(c context.Context, mid int64, paramsJSON, ip string) (err error) {
  334. type P struct {
  335. CID int64 `json:"cid"`
  336. DmID int64 `json:"dmid"`
  337. State int8 `json:"state"`
  338. }
  339. var filtersJSONData []*P
  340. if err = json.Unmarshal([]byte(paramsJSON), &filtersJSONData); err != nil {
  341. err = ecode.RequestErr
  342. return
  343. }
  344. if len(filtersJSONData) == 0 {
  345. err = ecode.CreativeDanmuFilterParamError
  346. return
  347. }
  348. var (
  349. g errgroup.Group
  350. )
  351. for _, v := range filtersJSONData {
  352. dmids := []int64{}
  353. dmids = append(dmids, v.DmID)
  354. cid := v.CID
  355. state := v.State
  356. g.Go(func() (err error) {
  357. if err = s.dm.Edit(c, mid, cid, state, dmids, ip); err != nil {
  358. log.Error("s.d.Edit v(%+v)|dmids(%+v)|cid(%+v)|state(%+v)|err(%+v)", v, dmids, cid, state, err)
  359. }
  360. log.Info("filtersJSONData v(%+v)|dmids(%+v)|cid(%+v)|state(%+v)|err(%+v)", v, dmids, cid, state, err)
  361. return
  362. })
  363. }
  364. g.Wait()
  365. return
  366. }