123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- package service
- import (
- "context"
- "fmt"
- "time"
- "go-common/app/interface/main/dm/model"
- dm2Mdl "go-common/app/interface/main/dm2/model"
- "go-common/app/interface/main/dm2/model/oplog"
- account "go-common/app/service/main/account/api"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/xstr"
- )
- const (
- _notifyUpTitle = "有新的弹幕保护申请"
- _notifyUpContent = `您今天新增了一些未处理弹幕保护申请,前去 #{创作中心 - 哔哩哔哩弹幕视频网 - ( ゜- ゜)つロ 乾杯~}{"http://member.bilibili.com/v/#/danmu/report/save"} 处理吧`
- _notifyUsrTitle = "弹幕保护申请情况更新~"
- _pa48 = "由于up主日理万机,您之前申请的%d条弹幕暂未受理,请稍后再次申请"
- _paa = `您在视频 #{%s}{"http://www.bilibili.com/video/av%d/"} 已被全部保护`
- _pap = `您在视频 #{%s}{"http://www.bilibili.com/video/av%d/"} 已被部分保护`
- _protectApplyLevel = 4
- _maxProtectApply = 100
- _paExpire = 48 * 3600
- )
- // AddProtectApply 批量申请保护弹幕
- func (s *Service) AddProtectApply(c context.Context, uid, cid int64, dmids []int64) (err error) {
- if len(dmids) == 0 {
- err = ecode.DMNotFound
- return
- }
- count, err := s.dao.PaUsrCnt(c, uid)
- if err != nil {
- log.Error("s.dao.PaUsrCnt(%d) error(%v)", uid, err)
- return
- }
- if (count + len(dmids)) > _maxProtectApply {
- err = ecode.DMPAUserLimit
- return
- }
- cardReply, err := s.accountSvc.Card3(c, &account.MidReq{Mid: uid})
- if err != nil {
- log.Error("s.actSvc.Card3(%d) error(%v)", uid, err)
- return
- }
- if cardReply.GetCard().GetLevel() < _protectApplyLevel {
- err = ecode.DMPAUserLevel
- return
- }
- dms, err := s.dms(c, model.SubTypeVideo, cid, dmids)
- if err != nil {
- return
- }
- dc := len(dmids)
- if len(dms) < 1 && dc == 1 {
- err = ecode.DMNotFound
- return
- }
- sub, err := s.subject(c, 1, cid)
- if err != nil {
- return
- }
- aps := make([]*model.Pa, 0, len(dms))
- now := time.Now().Unix()
- var ctime time.Time
- for _, dm := range dms {
- if dm.Mid != uid && dc == 1 {
- err = ecode.DMPADMNotOwner
- return
- }
- if dm.AttrVal(model.AttrProtect) == model.AttrYes && dc == 1 {
- err = ecode.DMPADMProtected
- return
- }
- if !dm.NeedDisplay() && dc == 1 {
- err = ecode.DMNotFound
- return
- }
- ctime, err = s.dao.ProtectApplyTime(c, dm.ID)
- if err != nil {
- log.Error("dao.ProtectApplyTime(%d) error(%v)", uid, err)
- continue
- }
- if now-ctime.Unix() < _paExpire {
- if dc == 1 {
- err = ecode.DMPADMLimit
- return
- }
- continue
- }
- ap := &model.Pa{
- CID: cid,
- UID: sub.Mid,
- ApplyUID: dm.Mid,
- AID: sub.Pid,
- Playtime: float32(dm.Progress) / 1000,
- DMID: dm.ID,
- Msg: dm.Content.Msg,
- Status: -1,
- Ctime: time.Now(),
- Mtime: time.Now(),
- }
- aps = append(aps, ap)
- }
- if len(aps) < 1 {
- err = ecode.DMPAFailed
- return
- }
- affect, err := s.dao.AddProtectApply(c, aps)
- if err != nil {
- log.Error("dao.AddProtectApply(%v) error(%v)", aps, err)
- return
- }
- if err = s.dao.UptUsrPaCnt(c, uid, affect); err != nil {
- log.Error("s.dao.UptUsrPaCnt(%d,%d) error(%v)", uid, affect, err)
- }
- return
- }
- // UptPaSwitch 保护弹幕申请开关
- func (s *Service) UptPaSwitch(c context.Context, uid int64, status int) (err error) {
- if status != 1 {
- status = 0
- }
- _, err = s.dao.UptPaNoticeSwitch(c, uid, status)
- return
- }
- // UptPaStatus 审核保护弹幕申请
- func (s *Service) UptPaStatus(c context.Context, mid int64, ids []int64, status int) (err error) {
- dmids, err := s.dao.ProtectApplyByIDs(c, mid, xstr.JoinInts(ids))
- if err != nil {
- log.Error("s.dao.ProtectApplyByIDs(%d,%s) error(%v)", mid, xstr.JoinInts(ids), err)
- return
- }
- if status != 1 {
- status = 0
- }
- if _, err = s.dao.UptPaStatus(c, mid, xstr.JoinInts(ids), status); err != nil {
- log.Error("s.dao.UptPaStatus(%d,%v,%d) error(%v)", mid, ids, status, err)
- return
- }
- if status == 0 {
- return
- }
- for oid, ids := range dmids {
- arg := &dm2Mdl.ArgEditDMAttr{
- Type: 1,
- Oid: oid,
- Mid: mid,
- Bit: dm2Mdl.AttrProtect,
- Value: dm2Mdl.AttrYes,
- Dmids: ids,
- Source: oplog.SourceUp,
- OperatorType: oplog.OperatorUp,
- }
- if err = s.dmRPC.EditDMAttr(c, arg); err != nil {
- log.Error("s.dmRPC.EditDMAttr(%+v) error(%v)", arg, err)
- return
- }
- }
- return
- }
- // ProtectApplies 保护弹幕申请列表
- func (s *Service) ProtectApplies(c context.Context, uid, aid int64, page int, sort string) (res *model.ApplyListResult, err error) {
- var (
- count int
- start int
- )
- if page < 1 {
- page = 1
- }
- res = &model.ApplyListResult{
- Pager: &model.Pager{},
- List: make([]*model.Apply, 0, model.ProtectApplyLimit),
- }
- res.List, err = s.dao.ProtectApplies(c, uid, aid, sort)
- if err != nil {
- log.Error("s.dao.PaLs(%d) error(%v)", uid, err)
- return
- }
- count = len(res.List)
- res.Pager.Current = page
- res.Pager.Total = count / model.ProtectApplyLimit
- res.Pager.Size = model.ProtectApplyLimit
- res.Pager.TotalCount = count
- if count%model.ProtectApplyLimit != 0 {
- res.Pager.Total++
- }
- if count == 0 {
- res.List = make([]*model.Apply, 0, 1)
- return
- }
- start = (page - 1) * model.ProtectApplyLimit
- if start > count {
- start = 0
- }
- end := start + model.ProtectApplyLimit
- if end > count {
- end = count
- }
- res.List = res.List[start:end]
- aids := make([]int64, 0, len(res.List))
- uids := make([]int64, 0, len(res.List))
- for _, a := range res.List {
- aids = append(aids, a.AID)
- uids = append(uids, a.ApplyUID)
- }
- infosReply, err := s.accountSvc.Infos3(c, &account.MidsReq{
- Mids: uids,
- })
- if err != nil {
- log.Error("s.actSvc.Infos2(%v) error(%v)", uids, err)
- err = nil
- }
- archives := s.archiveInfos(c, aids)
- for _, a := range res.List {
- v, ok := archives[a.AID]
- if ok {
- a.Pic = v.Pic
- a.Title = v.Title
- }
- u, ok := infosReply.GetInfos()[a.ApplyUID]
- if ok {
- a.Uname = u.GetName()
- }
- }
- return
- }
- // PaVideoLs 被申请保护弹幕的视频列表
- func (s *Service) PaVideoLs(c context.Context, uid int64) (res []*model.Video, err error) {
- aids, err := s.dao.ProtectAids(c, uid)
- if err != nil {
- log.Error("s.dao.ProtectArchives(%d) error(%v)", uid, err)
- return
- }
- archives := s.archiveInfos(c, aids)
- res = make([]*model.Video, 0, len(aids))
- for _, aid := range aids {
- a := new(model.Video)
- v, ok := archives[aid]
- a.Aid = aid
- if ok {
- a.Title = v.Title
- } else {
- a.Title = ""
- }
- res = append(res, a)
- }
- return
- }
- // sendProtectNotifyToUp 发送申请保护弹幕通知给up主
- func (s *Service) sendProtectNotifyToUp(c context.Context) (err error) {
- if time.Now().Format("15") != "20" {
- return
- }
- lk, err := s.dao.PaLock(c, "up")
- if err != nil {
- log.Error("s.dao.PaLock() error(%v)", err)
- return
- }
- if lk != 1 {
- return
- }
- uids, err := s.dao.ProtectApplyStatistics(c)
- if err != nil {
- log.Error("s.dao.PaStat() error(%v)", err)
- return
- }
- if len(uids) < 1 {
- return
- }
- m, err := s.dao.PaNoticeClose(c, uids)
- if err != nil {
- log.Error("s.dao.PaNoticeClose(%v) error(%v)", uids, err)
- return
- }
- if len(m) > 0 {
- for k, v := range uids {
- if _, ok := m[v]; ok {
- uids = append(uids[:k], uids[k+1:]...)
- }
- }
- }
- s.dao.SendNotify(c, _notifyUpTitle, _notifyUpContent, uids)
- return
- }
- // sendProtectNotifyToUser 发送申请保护弹幕处理结果给申请用户
- func (s *Service) sendProtectNotifyToUser(c context.Context) {
- if time.Now().Format("15") != "22" {
- return
- }
- incr, err := s.dao.PaLock(c, "user")
- if err != nil {
- log.Error("s.dao.PaLock() error(%v)", err)
- return
- }
- if incr != 1 {
- return
- }
- stats, err := s.dao.PaUsrStat(c)
- if err != nil {
- log.Error("s.dao.PaStat() error(%v)", err)
- return
- }
- aids := make([]int64, 0, len(stats))
- for _, stat := range stats {
- aids = append(aids, stat.Aid)
- }
- archives := s.archiveInfos(c, aids)
- userStats := make(map[int64]map[int64]*model.ApplyUserNotify)
- now := time.Now().Unix()
- untreated := make(map[int64]int)
- for _, stat := range stats {
- m, ok := userStats[stat.Aid]
- if !ok {
- m = make(map[int64]*model.ApplyUserNotify)
- userStats[stat.Aid] = m
- }
- n, ok := m[stat.UID]
- if !ok {
- n = &model.ApplyUserNotify{}
- m[stat.UID] = n
- }
- if stat.Status == 1 {
- n.Protect++
- } else {
- n.Unprotect++
- if stat.Status == -1 && (now-stat.Ctime.Unix()) > 2*24*3600 {
- untreated[stat.UID]++
- }
- }
- }
- for k, v := range untreated {
- s.dao.SendNotify(c, _notifyUsrTitle, fmt.Sprintf(_pa48, v), []int64{k})
- }
- for aid, m := range userStats {
- archive, ok := archives[aid]
- if !ok {
- continue
- }
- for uid, stat := range m {
- var content string
- if stat.Protect > 0 && stat.Unprotect == 0 {
- content = fmt.Sprintf(_paa, archive.Title, archive.Aid)
- }
- if stat.Protect > 0 && stat.Unprotect > 0 {
- content = fmt.Sprintf(_pap, archive.Title, archive.Aid)
- }
- if content == "" {
- continue
- }
- s.dao.SendNotify(c, _notifyUsrTitle, content, []int64{uid})
- }
- }
- }
|