2019-04-22 02:59:20 +00:00

364 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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})
}
}
}