123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- package service
- import (
- "context"
- "fmt"
- "strconv"
- "time"
- "go-common/app/interface/main/dm2/model"
- "go-common/app/interface/main/dm2/model/oplog"
- account "go-common/app/service/main/account/api"
- assmdl "go-common/app/service/main/assist/model/assist"
- "go-common/library/ecode"
- "go-common/library/log"
- )
- const (
- _assistUpperLimit = 100
- )
- // isAssist check if the user is assist of upper or not.
- func (s *Service) isAssist(c context.Context, mid, uid int64) (err error) {
- arg := assmdl.ArgAssist{
- Mid: mid,
- AssistMid: uid,
- Type: assmdl.TypeDm,
- RealIP: "",
- }
- res, err := s.assRPC.Assist(c, &arg)
- if err != nil {
- log.Error("s.assRPC.Assist(%v) error(%v)", arg, err)
- return ecode.AccessDenied
- }
- if res.Assist == 1 && res.Allow == 1 {
- return nil
- }
- if res.Assist == 1 && res.Count > _assistUpperLimit {
- return ecode.DMAssistOpToMuch
- }
- return ecode.AccessDenied
- }
- // isUpper check if the user is upper.
- func (s *Service) isUpper(mid, uid int64) bool {
- return mid == uid
- }
- // EditDMState change dm state
- // 0:正常、1:删除、10:用户删除、11:举报脚本删除
- func (s *Service) EditDMState(c context.Context, tp int32, mid, oid int64, state int32, dmids []int64, source oplog.Source, operatorType oplog.OperatorType) (err error) {
- var (
- affect, action int64
- )
- if source <= 0 {
- source = oplog.SourceUp
- }
- if operatorType <= 0 {
- operatorType = oplog.OperatorUp
- }
- sub, err := s.subject(c, tp, oid)
- if err != nil {
- return
- }
- switch state {
- case model.StateNormal, model.StateDelete:
- var isAssist bool
- if !s.isUpper(sub.Mid, mid) {
- if err = s.isAssist(c, sub.Mid, mid); err != nil {
- return
- }
- }
- affect, err = s.dao.UpdateDMStat(c, tp, oid, state, dmids)
- if err != nil {
- log.Error("s.dao.UpdateDMStat(oid:%d state:%d dmids:%v) error(%v)", oid, state, dmids, err)
- return
- }
- if affect > 0 {
- if state == model.StateDelete && sub.IsMonitoring() {
- s.oidLock.Lock()
- s.moniOidMap[sub.Oid] = struct{}{}
- s.oidLock.Unlock()
- }
- s.OpLog(c, oid, mid, time.Now().Unix(), int(tp), dmids, "status", "", strconv.FormatInt(int64(state), 10), "更新弹幕状态", source, operatorType)
- if state == model.StateDelete {
- action = assmdl.ActDelete
- affect = -affect
- }
- if sub.Count+affect < 0 {
- affect = -sub.Count
- }
- if _, err = s.dao.IncrSubjectCount(c, tp, oid, affect); err != nil {
- return
- }
- if isAssist {
- for _, dmid := range dmids {
- s.addAssistLog(sub.Mid, mid, oid, action, dmid)
- }
- }
- }
- case model.StateUserDelete:
- affect, err = s.dao.UpdateUserDMStat(c, tp, oid, mid, state, dmids)
- if err != nil {
- log.Error("s.dao.UpdateUserDMStat(mid:%d oid:%d state:%d dmids:%v) error(%v)", mid, oid, state, dmids, err)
- return
- }
- if affect > 0 {
- if sub.IsMonitoring() {
- s.oidLock.Lock()
- s.moniOidMap[sub.Oid] = struct{}{}
- s.oidLock.Unlock()
- }
- s.OpLog(c, oid, mid, time.Now().Unix(), int(tp), dmids, "status", "", fmt.Sprint(state), "更新弹幕状态", source, operatorType)
- affect = -affect
- if sub.Count+affect < 0 {
- affect = -sub.Count
- }
- if _, err = s.dao.IncrSubjectCount(c, tp, oid, affect); err != nil {
- return
- }
- }
- case model.StateScriptDelete:
- affect, err = s.dao.UpdateDMStat(c, tp, oid, state, dmids)
- if err != nil {
- log.Error("s.dao.UpdateDMStat(oid:%d state:%d dmids:%v) error(%v)", oid, state, dmids, err)
- return
- }
- if affect > 0 {
- if sub.IsMonitoring() {
- s.oidLock.Lock()
- s.moniOidMap[sub.Oid] = struct{}{}
- s.oidLock.Unlock()
- }
- s.OpLog(c, oid, mid, time.Now().Unix(), int(tp), dmids, "status", "", fmt.Sprint(state), "更新弹幕状态", source, operatorType)
- affect = -affect
- if sub.Count+affect < 0 {
- affect = -sub.Count
- }
- if _, err = s.dao.IncrSubjectCount(c, tp, oid, affect); err != nil {
- return
- }
- }
- default:
- err = ecode.RequestErr
- }
- return
- }
- // EditDMPool edit dm pool.
- func (s *Service) EditDMPool(c context.Context, tp int32, mid, oid int64, pool int32, ids []int64, source oplog.Source, operatorType oplog.OperatorType) (err error) {
- var (
- isAssist bool
- affect int64
- )
- if pool != model.PoolNormal && pool != model.PoolSubtitle {
- err = ecode.RequestErr
- return
- }
- // pool 2 dm can't move to other pool
- dmids := make([]int64, 0, len(ids))
- indexs, _, err := s.dao.IndexsByid(c, tp, oid, ids)
- for dmid, index := range indexs {
- if index.Pool != model.PoolSpecial {
- dmids = append(dmids, dmid)
- }
- }
- if len(dmids) <= 0 {
- return
- }
- if source <= 0 {
- source = oplog.SourceUp
- }
- if operatorType <= 0 {
- operatorType = oplog.OperatorUp
- }
- sub, err := s.subject(c, tp, oid)
- if err != nil {
- return
- }
- // maximum batch move count to subtitle pool is 300 when the rank of
- // user is equal or less than 15000
- if pool == model.PoolSubtitle {
- var (
- reply *account.ProfileReply
- )
- if reply, err = s.accountRPC.Profile3(c, &account.MidReq{Mid: mid}); err != nil {
- log.Error("accRPC.Profile3(%v) error(%v)", mid, err)
- return
- }
- if reply.Profile.Rank <= 15000 && int(sub.MoveCnt)+len(dmids) > 300 {
- err = ecode.DMPoolLimit
- return
- }
- }
- if !s.isUpper(sub.Mid, mid) {
- if err = s.isAssist(c, sub.Mid, mid); err != nil {
- return
- }
- }
- if sub.Childpool < pool {
- if _, err = s.dao.UpSubjectPool(c, tp, oid, pool); err != nil {
- return
- }
- }
- if affect, err = s.dao.UpdateDMPool(c, tp, oid, pool, dmids); err != nil {
- log.Error("s.dao.UpdateDMPool(oid:%d pool:%d dmids:%v) error(%v)", oid, pool, dmids, err)
- return
- }
- if affect > 0 {
- if pool == model.PoolNormal {
- s.dao.IncrSubMoveCount(c, sub.Type, sub.Oid, -affect) // NOTE update move_count,ignore error
- } else {
- s.dao.IncrSubMoveCount(c, sub.Type, sub.Oid, affect) // NOTE update move_count,ignore error
- }
- s.OpLog(c, oid, mid, time.Now().Unix(), int(tp), dmids, "pool", "", strconv.FormatInt(int64(pool), 10), "弹幕池变更", source, operatorType)
- }
- if isAssist {
- for _, dmid := range dmids {
- s.addAssistLog(sub.Mid, mid, oid, assmdl.ActProtect, dmid)
- }
- }
- return
- }
- // EditDMAttr update dm attribute.
- func (s *Service) EditDMAttr(c context.Context, tp int32, mid, oid int64, bit uint, value int32, dmids []int64, source oplog.Source, operatorType oplog.OperatorType) (affectIds []int64, err error) {
- var isAssist bool
- affectIds = make([]int64, 0, len(dmids))
- if value != model.AttrNo && value != model.AttrYes {
- err = ecode.RequestErr
- return
- }
- if source <= 0 {
- source = oplog.SourceUp
- }
- if operatorType <= 0 {
- operatorType = oplog.OperatorUp
- }
- sub, err := s.subject(c, tp, oid)
- if err != nil {
- return
- }
- if !s.isUpper(sub.Mid, mid) {
- if err = s.isAssist(c, sub.Mid, mid); err != nil {
- return
- }
- }
- idxMap, _, err := s.dao.IndexsByid(c, tp, oid, dmids)
- if err != nil {
- return
- }
- for dmid, idx := range idxMap {
- if !model.IsDMEditAble(idx.State) {
- continue
- }
- idx.AttrSet(value, bit)
- if _, err = s.dao.UpdateDMAttr(c, tp, oid, dmid, idx.Attr); err != nil {
- continue
- }
- s.OpLog(c, oid, mid, time.Now().Unix(), int(tp), []int64{dmid}, "attribute", "", fmt.Sprintf("bit:%d,value:%d", bit, value), "弹幕保护状态变更", source, operatorType)
- if isAssist {
- s.addAssistLog(sub.Mid, mid, oid, assmdl.ActProtect, dmid)
- }
- affectIds = append(affectIds, dmid)
- }
- return
- }
- func (s *Service) addAssistLog(mid, assistMid, oid, action, dmid int64) {
- ct, err := s.dao.Content(context.TODO(), oid, dmid)
- if err != nil || ct == nil {
- return
- }
- detail := ct.Msg
- if len([]rune(ct.Msg)) > 50 {
- detail = string([]rune(ct.Msg)[:50])
- }
- arg := &assmdl.ArgAssistLogAdd{
- Mid: mid,
- AssistMid: assistMid,
- Type: assmdl.TypeDm,
- Action: action,
- SubjectID: oid,
- ObjectID: fmt.Sprint(dmid),
- Detail: detail,
- }
- select {
- case s.assistLogChan <- arg:
- default:
- log.Error("assistLogChan is full")
- }
- }
- func (s *Service) assistLogproc() {
- for arg := range s.assistLogChan {
- if err := s.assRPC.AssistLogAdd(context.TODO(), arg); err != nil {
- log.Error("assRPC.AssistLogAdd(%v) error(%v)", arg, err)
- } else {
- log.Info("assRPC.AssistLogAdd(%v) success", arg)
- }
- }
- }
- // updateMonitorCnt update mcount of subject.
- func (s *Service) updateMonitorCnt(c context.Context, sub *model.Subject) (err error) {
- var state, mcount int64
- if sub.AttrVal(model.AttrSubMonitorBefore) == model.AttrYes {
- state = int64(model.StateMonitorBefore)
- } else if sub.AttrVal(model.AttrSubMonitorAfter) == model.AttrYes {
- state = int64(model.StateMonitorAfter)
- } else {
- return
- }
- if mcount, err = s.dao.DMCount(c, sub.Type, sub.Oid, []int64{state}); err != nil {
- return
- }
- _, err = s.dao.UpSubjectMCount(c, sub.Type, sub.Oid, mcount)
- return
- }
|