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

203 lines
5.4 KiB
Go

package service
import (
"context"
"fmt"
"strconv"
"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"
)
const (
_recallLt = 5 //普通用户每天可以撤回几个
_recallTO = 120 //多久以前的弹幕可以撤回
_recallCap = 20000 // 字幕君
_recallOK = "撤回成功,你还有%s次撤回机会" // 弹幕撤回成功提示
)
// Recall 撤回弹幕
func (s *Service) Recall(c context.Context, mid, cid int64, id int64) (msg string, err error) {
var (
card *account.CardReply
cnt int
ts string
isSuper bool
)
if card, err = s.accountSvc.Card3(c, &account.MidReq{Mid: mid}); err != nil {
log.Error("s.actSvc.Card3(%d) error(%v)", mid, err)
return
}
ts = "无限"
isSuper = card.GetCard().GetRank() >= _recallCap
if !isSuper {
if cnt, err = s.dao.RecallCnt(c, mid); err != nil {
log.Error("s.dao.RecallCnt(%d) error(%v)", mid, err)
return
}
if cnt >= _recallLt {
err = ecode.DMRecallLimit
return
}
ts = strconv.Itoa(_recallLt - cnt - 1)
}
dm, err := s.dao.Index(c, model.SubTypeVideo, cid, id)
if err != nil {
return
}
if dm == nil || !dm.NeedDisplay() || dm.Mid != mid {
err = ecode.DMRecallDeleted
return
}
if (time.Now().Unix()-int64(dm.Ctime)) > _recallTO && !(isSuper && (dm.Pool == 1 || dm.Pool == 2)) {
err = ecode.DMRecallTimeout
return
}
if err = s.EditDMState(c, 1, cid, mid, dm2Mdl.StateUserDelete, oplog.SourcePlayer, oplog.OperatorMember, id); err != nil {
log.Error("s.EditDMStat(%d,%d) error(%v)", cid, id, err)
err = ecode.DMRecallError
return
}
if err = s.dao.UptRecallCnt(c, mid); err != nil {
log.Error("s.dao.Item(%d,%d) error(%v)", cid, mid, err)
err = nil
}
msg = fmt.Sprintf(_recallOK, ts)
return
}
// EditDMState edit dm state used rpc method in dm2.
func (s *Service) EditDMState(c context.Context, tp int32, oid, mid int64, state int32, source oplog.Source, operatorType oplog.OperatorType, dmids ...int64) (err error) {
arg := &dm2Mdl.ArgEditDMState{
Type: tp,
Oid: oid,
Mid: mid,
State: state,
Dmids: dmids,
Source: source,
OperatorType: operatorType,
}
if err = s.dmRPC.EditDMState(c, arg); err != nil {
log.Error("dmRPC.EditDMState(%v) error(%v)", arg, err)
}
return
}
// MidHash 弹幕发送者mid hash.
func (s *Service) MidHash(c context.Context, mid int64) (hash string, err error) {
hash = model.Hash(mid, 0)
return
}
// TransferJob set task to db
func (s *Service) TransferJob(c context.Context, mid, fromCid, toCid int64, offset float64) (err error) {
job, err := s.dao.CheckTransferJob(c, fromCid, toCid)
if err != nil {
log.Error("dao.CheckTransferJob(from:%d,to:%d) err(%v)", fromCid, toCid, err)
return
}
if job != nil && job.FromCID == fromCid && job.ToCID == toCid && job.State != model.TransferJobStatFailed {
err = ecode.DMTransferRepet
return
}
_, err = s.dao.AddTransferJob(c, fromCid, toCid, mid, offset, model.TransferJobStatInit)
if err != nil {
log.Error("dao.AddTransferJob(from:%d,to:%d) err(%v)", fromCid, toCid, err)
}
return
}
// TransferList service
func (s *Service) TransferList(c context.Context, cid int64) (hiss []*model.TransferHistory, err error) {
hiss, err = s.dao.TransferList(c, cid)
if err != nil || len(hiss) == 0 {
return
}
for _, his := range hiss {
cidInfo, err := s.dao.CidInfo(c, his.CID)
if err != nil {
log.Error("dao.CidInfo(%d) err(%v)", cid, err)
continue
}
his.Title = cidInfo.Title
his.PartID = int32(cidInfo.Index)
}
return
}
// TransferRetry change transferjob state
func (s *Service) TransferRetry(c context.Context, id, mid int64) (err error) {
job, err := s.dao.CheckTransferID(c, id)
if err != nil {
log.Error("dao.CheckTransferID(%d) err(%v)", id, err)
return
}
if job.State != model.TransferJobStatFailed || job.MID != mid {
err = ecode.RequestErr
return
}
_, err = s.dao.SetTransferState(c, id, model.TransferJobStatInit)
if err != nil {
log.Error("dao.TransferList(%d %d %d) err(%v)", id, err)
}
return
}
// CheckExist check exit of up id.
func (s *Service) CheckExist(c context.Context, mid, cid int64) (err error) {
sub, err := s.subject(c, 1, cid)
if err != nil {
if ecode.Cause(err) == ecode.NothingFound {
err = ecode.DMTransferNotFound
}
return
}
if sub.Mid == 0 {
err = ecode.DMTransferNotFound
return
}
if sub.Mid != mid {
err = ecode.DMTransferNotBelong
return
}
return
}
// dms get dm list by dmid from database
func (s *Service) dms(c context.Context, tp int32, oid int64, ids []int64) (dms []*model.DM, err error) {
var (
idxMap = make(map[int64]*model.DM)
contentSpe = make(map[int64]*model.ContentSpecial)
special []int64
contents []*model.Content
)
if idxMap, special, err = s.dao.IndexsByID(c, tp, oid, ids); err != nil || len(idxMap) == 0 {
return
}
if contents, err = s.dao.Contents(c, oid, ids); err != nil {
return
}
if len(special) > 0 {
if contentSpe, err = s.dao.ContentsSpecial(c, special); err != nil {
return
}
}
for _, content := range contents {
if dm, ok := idxMap[content.ID]; ok {
dm.Content = content
if dm.Pool == model.PoolSpecial {
if _, ok = contentSpe[dm.ID]; ok {
dm.ContentSpe = contentSpe[dm.ID]
}
}
dms = append(dms, dm)
}
}
return
}