Create & Init Project...
This commit is contained in:
92
app/admin/main/dm/service/BUILD
Normal file
92
app/admin/main/dm/service/BUILD
Normal file
@ -0,0 +1,92 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"advance_test.go",
|
||||
"dm_test.go",
|
||||
"filter_test.go",
|
||||
"mask_test.go",
|
||||
"monitor_test.go",
|
||||
"report_test.go",
|
||||
"service_test.go",
|
||||
"subject_test.go",
|
||||
"task_test.go",
|
||||
"transfer_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
rundir = ".",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/admin/main/dm/conf:go_default_library",
|
||||
"//app/admin/main/dm/model:go_default_library",
|
||||
"//app/admin/main/dm/model/oplog:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/queue/databus/report:go_default_library",
|
||||
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"advance.go",
|
||||
"dm.go",
|
||||
"filter.go",
|
||||
"mask.go",
|
||||
"monitor.go",
|
||||
"report.go",
|
||||
"service.go",
|
||||
"shield.go",
|
||||
"subject.go",
|
||||
"subtitle.go",
|
||||
"subtitle_status.go",
|
||||
"subtitle_subject.go",
|
||||
"task.go",
|
||||
"transfer.go",
|
||||
],
|
||||
importpath = "go-common/app/admin/main/dm/service",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/admin/main/dm/conf:go_default_library",
|
||||
"//app/admin/main/dm/dao:go_default_library",
|
||||
"//app/admin/main/dm/dao/oplog:go_default_library",
|
||||
"//app/admin/main/dm/model:go_default_library",
|
||||
"//app/admin/main/dm/model/oplog:go_default_library",
|
||||
"//app/service/main/account/api:go_default_library",
|
||||
"//app/service/main/account/model:go_default_library",
|
||||
"//app/service/main/archive/api:go_default_library",
|
||||
"//app/service/main/archive/api/gorpc:go_default_library",
|
||||
"//app/service/main/archive/model/archive:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/log/infoc:go_default_library",
|
||||
"//library/queue/databus/report:go_default_library",
|
||||
"//library/sync/errgroup:go_default_library",
|
||||
"//library/sync/pipeline/fanout:go_default_library",
|
||||
"//library/xstr:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
33
app/admin/main/dm/service/advance.go
Normal file
33
app/admin/main/dm/service/advance.go
Normal file
@ -0,0 +1,33 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
accountApi "go-common/app/service/main/account/api"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// Advances 高级弹幕列表
|
||||
func (s *Service) Advances(c context.Context, dmInid int64, typ, mode string, pn, ps int64) (res []*model.Advance, total int64, err error) {
|
||||
var mids = make([]int64, 0)
|
||||
if res, total, err = s.dao.Advances(c, dmInid, typ, mode, pn, ps); err != nil {
|
||||
log.Error("dao.Advances(cid:%d, typ:%s, mode:%s, pn:%d,ps:%d) error(%v)", dmInid, typ, mode, pn, ps, err)
|
||||
return
|
||||
}
|
||||
for _, r := range res {
|
||||
mids = append(mids, r.Mid)
|
||||
}
|
||||
arg := &accountApi.MidsReq{Mids: mids}
|
||||
uInfos, err := s.accountRPC.Infos3(c, arg)
|
||||
if err != nil {
|
||||
log.Error("s.accRPC.Infos3(%v) error(%v)", mids, err)
|
||||
return
|
||||
}
|
||||
for _, r := range res {
|
||||
if v, ok := uInfos.GetInfos()[r.Mid]; ok {
|
||||
r.Name = v.Name
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
16
app/admin/main/dm/service/advance_test.go
Normal file
16
app/admin/main/dm/service/advance_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestAdvances(t *testing.T) {
|
||||
Convey("test adv", t, func() {
|
||||
res, _, err := svr.Advances(context.TODO(), 27515260, "all", "all", 1, 20)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
})
|
||||
}
|
456
app/admin/main/dm/service/dm.go
Normal file
456
app/admin/main/dm/service/dm.go
Normal file
@ -0,0 +1,456 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/app/admin/main/dm/model/oplog"
|
||||
accountApi "go-common/app/service/main/account/api"
|
||||
account "go-common/app/service/main/account/model"
|
||||
"go-common/app/service/main/archive/model/archive"
|
||||
"go-common/library/log"
|
||||
"go-common/library/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
_pageSize = 50
|
||||
)
|
||||
|
||||
// dms get dm list from database.
|
||||
func (s *Service) dms(c context.Context, tp int32, oid int64, dmids []int64) (dms []*model.DM, err error) {
|
||||
if len(dmids) == 0 {
|
||||
return
|
||||
}
|
||||
contentSpe := make(map[int64]*model.ContentSpecial)
|
||||
idxMap, special, err := s.dao.IndexsByID(c, tp, oid, dmids)
|
||||
if err != nil || len(idxMap) == 0 {
|
||||
return
|
||||
}
|
||||
contents, err := s.dao.Contents(c, oid, dmids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(special) > 0 {
|
||||
if contentSpe, err = s.dao.SpecialContents(c, special); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, content := range contents {
|
||||
if idx, ok := idxMap[content.ID]; ok {
|
||||
idx.Content = content
|
||||
if idx.Pool == model.PoolSpecial {
|
||||
if _, ok = contentSpe[idx.ID]; ok {
|
||||
idx.ContentSpe = contentSpe[idx.ID]
|
||||
}
|
||||
}
|
||||
dms = append(dms, idx)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DMSearch danmu list from search.
|
||||
func (s *Service) DMSearch(c context.Context, p *model.SearchDMParams) (res *model.SearchDMResult, err error) {
|
||||
var (
|
||||
mids, dmids []int64
|
||||
sorted []*model.DM
|
||||
protectCnt int64
|
||||
dmMap = make(map[int64]*model.DM)
|
||||
uidMap = make(map[int64]bool)
|
||||
)
|
||||
res = &model.SearchDMResult{}
|
||||
sub, err := s.dao.Subject(c, p.Type, p.Oid)
|
||||
if err != nil {
|
||||
log.Error("s.dao.Subject(%d,%d) error(%v)", p.Type, p.Oid, err)
|
||||
return
|
||||
}
|
||||
if sub == nil {
|
||||
return
|
||||
}
|
||||
srchData, err := s.dao.SearchDM(c, p)
|
||||
if err != nil {
|
||||
log.Error("s.dao.SearchDM(%v) error(%v)", p, err)
|
||||
return
|
||||
}
|
||||
if srchData == nil {
|
||||
return
|
||||
}
|
||||
for _, v := range srchData.Result {
|
||||
dmids = append(dmids, v.ID)
|
||||
}
|
||||
dms, err := s.dms(c, p.Type, p.Oid, dmids)
|
||||
if err != nil {
|
||||
log.Error("s.dms(%d,%v) error(%v)", p.Oid, dmids, err)
|
||||
return
|
||||
}
|
||||
for _, dm := range dms {
|
||||
dmMap[dm.ID] = dm
|
||||
if _, ok := uidMap[dm.Mid]; !ok && dm.Mid > 0 {
|
||||
uidMap[dm.Mid] = true
|
||||
mids = append(mids, dm.Mid)
|
||||
}
|
||||
}
|
||||
for _, dmid := range dmids {
|
||||
if dm, ok := dmMap[dmid]; ok {
|
||||
sorted = append(sorted, dm)
|
||||
}
|
||||
}
|
||||
total := len(mids)
|
||||
pageNum := total / _pageSize
|
||||
if total%_pageSize != 0 {
|
||||
pageNum++
|
||||
}
|
||||
var (
|
||||
g errgroup.Group
|
||||
lk sync.Mutex
|
||||
infoMap = make(map[int64]*account.Info, total)
|
||||
)
|
||||
for i := 0; i < pageNum; i++ {
|
||||
start := i * _pageSize
|
||||
end := (i + 1) * _pageSize
|
||||
if end > total {
|
||||
end = total
|
||||
}
|
||||
g.Go(func() (err error) {
|
||||
var (
|
||||
arg = &accountApi.MidsReq{Mids: mids[start:end]}
|
||||
res *accountApi.InfosReply
|
||||
)
|
||||
if res, err = s.accountRPC.Infos3(c, arg); err != nil {
|
||||
log.Error("s.accRPC.Infos3(%v) error(%v)", arg, err)
|
||||
} else {
|
||||
for mid, info := range res.GetInfos() {
|
||||
lk.Lock()
|
||||
infoMap[mid] = info
|
||||
lk.Unlock()
|
||||
}
|
||||
}
|
||||
return
|
||||
})
|
||||
}
|
||||
g.Go(func() (err error) {
|
||||
if protectCnt, err = s.dao.SearchProtectCount(context.TODO(), p.Type, p.Oid); err != nil {
|
||||
log.Error("s.dao.SearchProtectCount(%d,%d) error(%v)", p.Type, p.Oid, err)
|
||||
}
|
||||
return
|
||||
})
|
||||
if err = g.Wait(); err != nil {
|
||||
return
|
||||
}
|
||||
for _, dm := range sorted {
|
||||
msg := dm.Content.Msg
|
||||
if dm.Pool == model.PoolSpecial && dm.ContentSpe != nil {
|
||||
msg = dm.ContentSpe.Msg
|
||||
}
|
||||
item := &model.DMItem{
|
||||
IDStr: strconv.FormatInt(dm.ID, 10),
|
||||
ID: dm.ID,
|
||||
Type: dm.Type,
|
||||
Oid: dm.Oid,
|
||||
Mid: dm.Mid,
|
||||
Pool: dm.Pool,
|
||||
State: dm.State,
|
||||
Attrs: dm.AttrNtoA(),
|
||||
Msg: msg,
|
||||
Ctime: dm.Ctime,
|
||||
Mode: dm.Content.Mode,
|
||||
IP: dm.Content.IP,
|
||||
Color: fmt.Sprintf("#%06X", dm.Content.Color),
|
||||
Progress: dm.Progress,
|
||||
Fontsize: dm.Content.FontSize,
|
||||
}
|
||||
if info, ok := infoMap[dm.Mid]; ok {
|
||||
item.Uname = info.Name
|
||||
}
|
||||
res.Result = append(res.Result, item)
|
||||
}
|
||||
res.MaxLimit = sub.Maxlimit
|
||||
res.Total = sub.ACount
|
||||
res.Page = srchData.Page.Num
|
||||
res.Pagesize = srchData.Page.Size
|
||||
res.Deleted = sub.ACount - sub.Count
|
||||
res.Protected = protectCnt
|
||||
res.Count = srchData.Page.Total
|
||||
return
|
||||
}
|
||||
|
||||
// XMLCacheFlush 刷新弹幕缓存
|
||||
func (s *Service) XMLCacheFlush(c context.Context, tp int32, oid int64) {
|
||||
v := make(map[string]interface{})
|
||||
v["type"] = tp
|
||||
v["oid"] = oid
|
||||
v["force"] = true
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
log.Error("json.Marshal(%v) error(%v)", v, err)
|
||||
return
|
||||
}
|
||||
action := &model.Action{Action: model.ActFlushDM, Data: data, Oid: oid}
|
||||
s.addAction(action)
|
||||
}
|
||||
|
||||
// EditDMState multi edit dm state.
|
||||
func (s *Service) EditDMState(c context.Context, tp, state int32, oid int64, reason int8, dmids []int64, moral float64, adminID int64, operator, remark string) (err error) {
|
||||
if err = s.editDmState(c, tp, state, oid, reason, dmids, moral, adminID, operator, remark); err != nil {
|
||||
log.Error("s.dao.UpSearchDMState(%d,%d,%v) err (%v)", tp, oid, dmids, err)
|
||||
return
|
||||
}
|
||||
// update dm search index
|
||||
if err = s.uptSearchDmState(c, tp, state, map[int64][]int64{oid: dmids}); err != nil {
|
||||
log.Error("s.dao.UpSearchDMState(%d,%d,%v) err (%v)", tp, oid, dmids, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// editDmState multi edit dm state.
|
||||
func (s *Service) editDmState(c context.Context, tp, state int32, oid int64, reason int8, dmids []int64, moral float64, adminID int64, operator, remark string) (err error) {
|
||||
sub, err := s.dao.Subject(c, tp, oid)
|
||||
if err != nil || sub == nil {
|
||||
return
|
||||
}
|
||||
dms, err := s.dms(c, tp, oid, dmids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
count := countDMNum(dms, state)
|
||||
affect, err := s.dao.SetStateByIDs(c, tp, oid, dmids, state)
|
||||
if err != nil || affect == 0 {
|
||||
return
|
||||
}
|
||||
if sub.Count+count < 0 {
|
||||
count = -sub.Count
|
||||
}
|
||||
// update dm_index count
|
||||
if _, err = s.dao.IncrSubjectCount(c, tp, oid, count); err != nil {
|
||||
return
|
||||
}
|
||||
// write dm admin log
|
||||
if affect > 0 {
|
||||
if remark == "" {
|
||||
remark = model.AdminRptReason[reason]
|
||||
}
|
||||
s.OpLog(c, oid, adminID, tp, dmids, "status", "", fmt.Sprint(state), remark, oplog.SourceManager, oplog.OperatorAdmin)
|
||||
}
|
||||
// update dm monitor count
|
||||
if sub.IsMonitoring() {
|
||||
s.oidLock.Lock()
|
||||
s.moniOidMap[sub.Oid] = struct{}{}
|
||||
s.oidLock.Unlock()
|
||||
}
|
||||
// flush xml cache
|
||||
s.XMLCacheFlush(c, tp, oid)
|
||||
// reduce moral
|
||||
uidMap := make(map[int64]struct{})
|
||||
for _, dm := range dms {
|
||||
if _, ok := uidMap[dm.Mid]; !ok {
|
||||
uidMap[dm.Mid] = struct{}{}
|
||||
}
|
||||
}
|
||||
if len(uidMap) > 0 && moral > 0 {
|
||||
for uid := range uidMap {
|
||||
s.reduceMoral(c, uid, int64(-moral), reason, operator, "弹幕管理")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EditDMPool edit dm pool.
|
||||
func (s *Service) EditDMPool(c context.Context, tp int32, oid int64, pool int32, dmids []int64, adminID int64) (err error) {
|
||||
sub, err := s.dao.Subject(c, tp, oid)
|
||||
if err != nil || sub == nil {
|
||||
return
|
||||
}
|
||||
if sub.Childpool < pool {
|
||||
if _, err = s.dao.UpSubjectPool(c, tp, oid, pool); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
affect, err := s.dao.SetPoolIDByIDs(c, tp, oid, pool, dmids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if affect > 0 {
|
||||
if pool == model.PoolNormal {
|
||||
s.dao.IncrSubMoveCount(c, tp, oid, -affect) // NOTE update move_count,ignore error
|
||||
} else {
|
||||
s.dao.IncrSubMoveCount(c, tp, oid, affect) // NOTE update move_count,ignore error
|
||||
}
|
||||
s.OpLog(c, oid, adminID, tp, dmids, "pool", "", fmt.Sprint(pool), "弹幕池变更", oplog.SourceManager, oplog.OperatorAdmin)
|
||||
}
|
||||
if err = s.uptSearchDMPool(c, tp, oid, pool, dmids); err != nil {
|
||||
log.Error("s.dao.UpSearchDMPool(%d,%d,%v) err (%v)", tp, oid, dmids, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EditDMAttr change dm attr
|
||||
func (s *Service) EditDMAttr(c context.Context, tp int32, oid int64, dmids []int64, bit uint, value int32, adminID int64) (err error) {
|
||||
var (
|
||||
eg = errgroup.Group{}
|
||||
attrMap = make(map[int32][]int64)
|
||||
)
|
||||
dms, err := s.dms(c, tp, oid, dmids)
|
||||
if err != nil {
|
||||
log.Error("s.dms(oid:%d ids:%v) error(%v)", oid, dmids, err)
|
||||
return
|
||||
}
|
||||
for _, dm := range dms {
|
||||
dm.AttrSet(value, bit)
|
||||
attrMap[dm.Attr] = append(attrMap[dm.Attr], dm.ID)
|
||||
}
|
||||
for k, v := range attrMap {
|
||||
attr := k
|
||||
ids := v
|
||||
eg.Go(func() (err error) {
|
||||
affect, err := s.dao.SetAttrByIDs(c, tp, oid, ids, attr)
|
||||
if err != nil {
|
||||
log.Error("s.dao.SetAttrByIDs(oid:%d ids:%v) error(%v)", oid, ids, err)
|
||||
return
|
||||
}
|
||||
if affect > 0 {
|
||||
s.OpLog(c, oid, adminID, tp, ids, "attribute", "", fmt.Sprint(attr), "弹幕保护状态变更", oplog.SourceManager, oplog.OperatorAdmin)
|
||||
}
|
||||
if err = s.uptSearchDMAttr(c, tp, oid, attr, dmids); err != nil {
|
||||
log.Error("dao.UpSearchDMAttr(oid:%d,attr:%d) error(%v)", oid, attr, err)
|
||||
}
|
||||
return
|
||||
})
|
||||
}
|
||||
return eg.Wait()
|
||||
}
|
||||
|
||||
// DMIndexInfo get dm index info
|
||||
func (s *Service) DMIndexInfo(c context.Context, cid int64) (info *model.DMIndexInfo, err error) {
|
||||
info = new(model.DMIndexInfo)
|
||||
sub, err := s.dao.Subject(c, model.SubTypeVideo, cid)
|
||||
if err != nil || sub == nil {
|
||||
return
|
||||
}
|
||||
argAid2 := &archive.ArgAid2{Aid: sub.Pid}
|
||||
arc, err := s.arcRPC.Archive3(c, argAid2)
|
||||
if err != nil {
|
||||
log.Error("s.arcRPC.Archive3(%v) error(%v)", argAid2, err)
|
||||
err = nil
|
||||
} else {
|
||||
info.Title = arc.Title
|
||||
info.Cover = arc.Pic
|
||||
}
|
||||
argVideo := &archive.ArgVideo2{Aid: sub.Pid, Cid: cid}
|
||||
video, err := s.arcRPC.Video3(c, argVideo)
|
||||
if err != nil {
|
||||
log.Error("s.arcRPC.Video3(%v) error(%v)", argVideo, err)
|
||||
err = nil
|
||||
} else {
|
||||
info.Duration = video.Duration
|
||||
info.ETitle = video.Part
|
||||
}
|
||||
argMid := &accountApi.MidReq{Mid: sub.Mid}
|
||||
uInfo, err := s.accountRPC.Info3(c, argMid)
|
||||
if err != nil {
|
||||
log.Error("s.accRPC.Info3(%v) error(%v)", argMid, err)
|
||||
err = nil
|
||||
} else {
|
||||
info.UName = uInfo.GetInfo().GetName()
|
||||
}
|
||||
info.AID = sub.Pid
|
||||
info.CID = sub.Oid
|
||||
info.MID = sub.Mid
|
||||
info.Limit = sub.Maxlimit
|
||||
if sub.State == model.SubStateOpen {
|
||||
info.Active = 1
|
||||
} else {
|
||||
info.Active = 0
|
||||
}
|
||||
info.CTime = int64(sub.Ctime)
|
||||
info.MTime = int64(sub.Mtime)
|
||||
return
|
||||
}
|
||||
|
||||
// countDMNum count state changed dm count
|
||||
func countDMNum(dms []*model.DM, state int32) (count int64) {
|
||||
for _, dm := range dms {
|
||||
if model.DMVisible(dm.State) && !model.DMVisible(state) {
|
||||
count--
|
||||
} else if !model.DMVisible(dm.State) && model.DMVisible(state) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// FixDMCount fix dm acount,count of aid.
|
||||
func (s *Service) FixDMCount(c context.Context, aid int64) (err error) {
|
||||
var (
|
||||
arg = archive.ArgAid2{Aid: aid}
|
||||
oids []int64
|
||||
states = []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} // 弹幕所有状态
|
||||
normalState = []int64{0, 2, 6} // 前台可能展示的弹幕状态
|
||||
)
|
||||
pages, err := s.arcRPC.Page3(c, &arg)
|
||||
if err != nil {
|
||||
log.Error("arcRPC.Page3(%v) error(%v)", arg, err)
|
||||
return
|
||||
}
|
||||
if len(pages) == 0 {
|
||||
log.Warn("aid:%d have no pages", aid)
|
||||
return
|
||||
}
|
||||
for _, page := range pages {
|
||||
oids = append(oids, page.Cid)
|
||||
}
|
||||
subs, err := s.dao.Subjects(c, model.SubTypeVideo, oids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, sub := range subs {
|
||||
tp := sub.Type
|
||||
oid := sub.Oid
|
||||
s.cache.Do(c, func(ctx context.Context) {
|
||||
acount, err := s.dao.DMCount(ctx, tp, oid, states)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
count, err := s.dao.DMCount(ctx, tp, oid, normalState)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.dao.UpSubjectCount(ctx, tp, oid, acount, count) // 更新新库dm_subject
|
||||
log.Info("fix dm count,type:%d,oid:%d,acount:%d,count:%d", tp, oid, acount, count)
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) uptSearchDmState(c context.Context, tp int32, state int32, dmidM map[int64][]int64) (err error) {
|
||||
if err = s.dao.UpSearchDMState(c, tp, state, dmidM); err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.dao.UpSearchRecentDMState(c, tp, state, dmidM); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) uptSearchDMPool(c context.Context, tp int32, oid int64, pool int32, dmids []int64) (err error) {
|
||||
if err = s.dao.UpSearchDMPool(c, tp, oid, pool, dmids); err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.dao.UpSearchRecentDMPool(c, tp, oid, pool, dmids); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) uptSearchDMAttr(c context.Context, tp int32, oid int64, attr int32, dmids []int64) (err error) {
|
||||
if err = s.dao.UpSearchDMAttr(c, tp, oid, attr, dmids); err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.dao.UpSearchRecentDMAttr(c, tp, oid, attr, dmids); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
72
app/admin/main/dm/service/dm_test.go
Normal file
72
app/admin/main/dm/service/dm_test.go
Normal file
@ -0,0 +1,72 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestDMSearch(t *testing.T) {
|
||||
d := &model.SearchDMParams{
|
||||
Type: 1,
|
||||
Oid: 1,
|
||||
Mid: model.CondIntNil,
|
||||
ProgressFrom: model.CondIntNil,
|
||||
ProgressTo: model.CondIntNil,
|
||||
CtimeFrom: model.CondIntNil,
|
||||
CtimeTo: model.CondIntNil,
|
||||
State: "",
|
||||
Pool: "",
|
||||
Page: 1,
|
||||
Order: "id",
|
||||
Sort: "asc",
|
||||
}
|
||||
Convey("test dm list", t, func() {
|
||||
res, err := svr.DMSearch(context.TODO(), d)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeNil)
|
||||
spew.Dump(res)
|
||||
So(res.Result, ShouldNotBeEmpty)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEditDMPool(t *testing.T) {
|
||||
Convey("test change pool id", t, func() {
|
||||
err := svr.EditDMPool(context.TODO(), 1, 1, 1, []int64{1, 2}, 123)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestXMLCacheFlush(t *testing.T) {
|
||||
Convey("test flush cache", t, func() {
|
||||
svr.XMLCacheFlush(context.TODO(), 1, 1221)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEditDMState(t *testing.T) {
|
||||
dmids := []int64{1, 2}
|
||||
Convey("test content status", t, func() {
|
||||
res := svr.EditDMState(context.TODO(), 1, 1221, 1, 1, dmids, 10, 123, "admin", "test")
|
||||
So(res, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEditDMAttr(t *testing.T) {
|
||||
Convey("test change attr", t, func() {
|
||||
err := svr.EditDMAttr(context.TODO(), 1, 1, []int64{1, 2}, model.AttrProtect, 1, 123)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDMIndexInfo(t *testing.T) {
|
||||
var cid int64 = 9967205
|
||||
Convey("test dm index info", t, func() {
|
||||
idx, err := svr.DMIndexInfo(context.TODO(), cid)
|
||||
So(err, ShouldBeNil)
|
||||
So(idx, ShouldNotBeNil)
|
||||
})
|
||||
}
|
67
app/admin/main/dm/service/filter.go
Normal file
67
app/admin/main/dm/service/filter.go
Normal file
@ -0,0 +1,67 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// UpFilters return up filters
|
||||
func (s *Service) UpFilters(c context.Context, mid, ftype, pn, ps int64) (res []*model.UpFilter, total int64, err error) {
|
||||
//type all
|
||||
if ftype == int64(model.FilterTypeAll) {
|
||||
if res, total, err = s.dao.UpFiltersAll(c, mid, pn, ps); err != nil {
|
||||
log.Error("s.dao.UpFiltersAll(mid:%d) error(%v)", mid, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if res, total, err = s.dao.UpFilters(c, mid, ftype, pn, ps); err != nil {
|
||||
log.Error("s.dao.UpFilters(mid:%d, type:%d) error(%v)", mid, ftype, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EditUpFilters edit up filters.
|
||||
func (s *Service) EditUpFilters(c context.Context, id, mid int64, fType, active int8) (affect int64, err error) {
|
||||
var limit int
|
||||
tx, err := s.dao.BeginBiliDMTrans(c)
|
||||
if err != nil {
|
||||
log.Error("tx.BeginBiliDMTrans error(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if affect, err = s.dao.UpdateUpFilter(tx, mid, id, active); err != nil {
|
||||
return
|
||||
}
|
||||
switch fType {
|
||||
case model.FilterTypeText:
|
||||
limit = model.FilterMaxUpText
|
||||
case model.FilterTypeRegex:
|
||||
limit = model.FilterMaxUpReg
|
||||
case model.FilterTypeID:
|
||||
limit = model.FilterMaxUpID
|
||||
}
|
||||
if active == model.FilterUnActive {
|
||||
affect = -affect
|
||||
limit = 10000
|
||||
}
|
||||
if _, err = s.dao.UpdateUpFilterCnt(tx, mid, fType, int(affect), limit+1); err != nil {
|
||||
return
|
||||
}
|
||||
s.cache.Do(c, func(ctx context.Context) {
|
||||
s.dao.DelUpFilterCache(ctx, mid, 0)
|
||||
})
|
||||
|
||||
return
|
||||
}
|
23
app/admin/main/dm/service/filter_test.go
Normal file
23
app/admin/main/dm/service/filter_test.go
Normal file
@ -0,0 +1,23 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestUpFilters(t *testing.T) {
|
||||
Convey("test update user rule", t, func() {
|
||||
rs, _, err := svr.UpFilters(context.TODO(), 27515615, 1, 1, 20)
|
||||
So(err, ShouldBeNil)
|
||||
So(rs, ShouldNotBeEmpty)
|
||||
})
|
||||
}
|
||||
|
||||
func TestEditUpFilters(t *testing.T) {
|
||||
Convey("test edit user rule", t, func() {
|
||||
_, err := svr.EditUpFilters(context.TODO(), 66, 27515256, 1, 0)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
160
app/admin/main/dm/service/mask.go
Normal file
160
app/admin/main/dm/service/mask.go
Normal file
@ -0,0 +1,160 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
accountApi "go-common/app/service/main/account/api"
|
||||
"go-common/app/service/main/archive/api"
|
||||
arcMdl "go-common/app/service/main/archive/model/archive"
|
||||
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// MaskState get mask state
|
||||
func (s *Service) MaskState(c context.Context, tp int32, oid int64) (open, mobile, web int32, err error) {
|
||||
sub, err := s.dao.Subject(c, tp, oid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if sub == nil {
|
||||
err = ecode.ArchiveNotExist
|
||||
return
|
||||
}
|
||||
return sub.AttrVal(model.AttrSubMaskOpen), sub.AttrVal(model.AttrSubMblMaskReady), sub.AttrVal(model.AttrSubWebMaskReady), err
|
||||
}
|
||||
|
||||
// UpdateMaskState update mask state
|
||||
func (s *Service) UpdateMaskState(c context.Context, tp int32, oid int64, plat int8, state int32) (err error) {
|
||||
var (
|
||||
archive3 *api.Arc
|
||||
err1 error
|
||||
duration int64
|
||||
typeID int32
|
||||
)
|
||||
sub, err := s.dao.Subject(c, tp, oid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if sub == nil {
|
||||
err = ecode.ArchiveNotExist
|
||||
return
|
||||
}
|
||||
if archive3, err1 = s.arcRPC.Archive3(c, &arcMdl.ArgAid2{Aid: sub.Pid}); err1 == nil && archive3 != nil {
|
||||
duration = archive3.Duration
|
||||
typeID = archive3.TypeID
|
||||
}
|
||||
if state == model.AttrYes {
|
||||
switch plat {
|
||||
case model.MaskPlatMbl:
|
||||
if sub.AttrVal(model.AttrSubMblMaskReady) == model.AttrNo {
|
||||
if err = s.dao.GenerateMask(c, oid, sub.Mid, plat, 0, sub.Pid, duration, typeID); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
case model.MaskPlatWeb:
|
||||
if sub.AttrVal(model.AttrSubWebMaskReady) == model.AttrNo {
|
||||
if err = s.dao.GenerateMask(c, oid, sub.Mid, plat, 0, sub.Pid, duration, typeID); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
if sub.AttrVal(model.AttrSubMblMaskReady) == model.AttrNo || sub.AttrVal(model.AttrSubWebMaskReady) == model.AttrNo {
|
||||
if err = s.dao.GenerateMask(c, oid, sub.Mid, plat, 0, sub.Pid, duration, typeID); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sub.AttrSet(state, model.AttrSubMaskOpen)
|
||||
_, err = s.dao.UpSubjectAttr(c, tp, oid, sub.Attr)
|
||||
return
|
||||
}
|
||||
|
||||
// GenerateMask generate mask
|
||||
func (s *Service) GenerateMask(c context.Context, tp int32, oid int64, plat int8) (err error) {
|
||||
var (
|
||||
archive3 *api.Arc
|
||||
err1 error
|
||||
duration int64
|
||||
typeID int32
|
||||
)
|
||||
sub, err := s.dao.Subject(c, tp, oid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if sub == nil {
|
||||
err = ecode.ArchiveNotExist
|
||||
return
|
||||
}
|
||||
if archive3, err1 = s.arcRPC.Archive3(c, &arcMdl.ArgAid2{Aid: sub.Pid}); err1 == nil && archive3 != nil {
|
||||
duration = archive3.Duration
|
||||
typeID = archive3.TypeID
|
||||
}
|
||||
err = s.dao.GenerateMask(c, oid, sub.Mid, plat, 1, sub.Pid, duration, typeID)
|
||||
return
|
||||
}
|
||||
|
||||
// MaskUps get mask up infos.
|
||||
func (s *Service) MaskUps(c context.Context, pn, ps int64) (res *model.MaskUpRes, err error) {
|
||||
|
||||
MaskUps, total, err := s.dao.MaskUps(c, pn, ps)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mids := make([]int64, 0, len(MaskUps))
|
||||
for _, up := range MaskUps {
|
||||
mids = append(mids, up.Mid)
|
||||
}
|
||||
arg := &accountApi.MidsReq{Mids: mids}
|
||||
uInfos, err := s.accountRPC.Infos3(c, arg)
|
||||
if err != nil {
|
||||
log.Error("s.accRPC.Infos3(%v) error(%v)", mids, err)
|
||||
return
|
||||
}
|
||||
for _, up := range MaskUps {
|
||||
if info, ok := uInfos.GetInfos()[up.Mid]; ok {
|
||||
up.Name = info.Name
|
||||
}
|
||||
}
|
||||
res = &model.MaskUpRes{
|
||||
Result: MaskUps,
|
||||
Page: &model.PageInfo{
|
||||
Num: pn,
|
||||
Size: ps,
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// MaskUpOpen add mask up
|
||||
func (s *Service) MaskUpOpen(c context.Context, mids []int64, state int32, comment string) (err error) {
|
||||
midMap := make(map[int64]struct{})
|
||||
ids := make([]int64, 0, len(mids))
|
||||
for _, mid := range mids {
|
||||
if _, ok := midMap[mid]; !ok {
|
||||
midMap[mid] = struct{}{}
|
||||
ids = append(ids, mid)
|
||||
}
|
||||
}
|
||||
// 验证mids
|
||||
arg := &accountApi.MidsReq{Mids: ids}
|
||||
uInfos, err := s.accountRPC.Infos3(c, arg)
|
||||
if err != nil {
|
||||
log.Error("s.accRPC.Infos3(%v) error(%v)", ids, err)
|
||||
return
|
||||
}
|
||||
if len(uInfos.GetInfos()) < len(ids) {
|
||||
err = ecode.AccountInexistence
|
||||
log.Error("s.MaskUpOpen length diff(%d,%d)", len(ids), len(uInfos.GetInfos()))
|
||||
return
|
||||
}
|
||||
for _, id := range ids {
|
||||
if _, err = s.dao.MaskUpOpen(c, id, state, comment); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
49
app/admin/main/dm/service/mask_test.go
Normal file
49
app/admin/main/dm/service/mask_test.go
Normal file
@ -0,0 +1,49 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestMaskState(t *testing.T) {
|
||||
convey.Convey("mask state", t, func() {
|
||||
open, mobile, web, err := svr.MaskState(context.TODO(), 1, 1352)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
t.Logf("===%d,%d,%d", open, mobile, web)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateMaskState(t *testing.T) {
|
||||
convey.Convey("open mask", t, func() {
|
||||
err := svr.UpdateMaskState(context.TODO(), 1, 1352, 1, 0)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGenerateMask(t *testing.T) {
|
||||
convey.Convey("generate mask", t, func() {
|
||||
err := svr.GenerateMask(context.TODO(), 1, 1352, 1)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMaskUps(t *testing.T) {
|
||||
convey.Convey("test mask ups", t, func() {
|
||||
res, err := svr.MaskUps(context.Background(), 1, 50)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
convey.So(res, convey.ShouldNotBeNil)
|
||||
t.Log(res, res.Result, res.Page)
|
||||
for _, v := range res.Result {
|
||||
t.Log(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestMaskUpOpen(t *testing.T) {
|
||||
convey.Convey("test mask up open", t, func() {
|
||||
err := svr.MaskUpOpen(context.Background(), []int64{1111, 142341123}, 1, "")
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
109
app/admin/main/dm/service/monitor.go
Normal file
109
app/admin/main/dm/service/monitor.go
Normal file
@ -0,0 +1,109 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/sync/errgroup"
|
||||
)
|
||||
|
||||
// MonitorList get monitor list
|
||||
func (s *Service) MonitorList(c context.Context, tp int32, pid, oid, mid int64, state int32, kw, sort, order string, page, size int64) (res *model.MonitorResult, err error) {
|
||||
var attr int32
|
||||
if state > 0 {
|
||||
if state == model.MonitorBefore {
|
||||
attr = int32(model.AttrSubMonitorBefore) + 1
|
||||
} else {
|
||||
attr = int32(model.AttrSubMonitorAfter) + 1
|
||||
}
|
||||
}
|
||||
data, err := s.dao.SearchMonitor(c, tp, pid, oid, mid, attr, kw, sort, order, page, size)
|
||||
if err != nil {
|
||||
log.Error("dao.SearchMonitor(pid:%d,oid:%d) error(%v)", pid, oid, err)
|
||||
return
|
||||
}
|
||||
res = &model.MonitorResult{
|
||||
Order: data.Order,
|
||||
Sort: data.Sort,
|
||||
Page: data.Page.Num,
|
||||
PageSize: data.Page.Size,
|
||||
Total: data.Page.Total,
|
||||
Result: make([]*model.Monitor, 0, len(data.Result)),
|
||||
}
|
||||
for _, v := range data.Result {
|
||||
m := &model.Monitor{
|
||||
ID: v.ID,
|
||||
Type: v.Type,
|
||||
Pid: v.Pid,
|
||||
Oid: v.Oid,
|
||||
MCount: v.MCount,
|
||||
Ctime: v.Ctime,
|
||||
Mtime: v.Mtime,
|
||||
Mid: v.Mid,
|
||||
Title: v.Title,
|
||||
Author: v.Author,
|
||||
}
|
||||
if v.Attr>>model.AttrSubMonitorBefore&1 == model.AttrYes {
|
||||
m.State = model.MonitorBefore
|
||||
} else {
|
||||
m.State = model.MonitorAfter
|
||||
}
|
||||
res.Result = append(res.Result, m)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateMonitor update monitor state of dm subject.
|
||||
func (s *Service) UpdateMonitor(c context.Context, tp int32, oids []int64, state int32) (affect int64, err error) {
|
||||
var wg errgroup.Group
|
||||
subs, err := s.dao.Subjects(c, tp, oids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, v := range subs {
|
||||
sub := v
|
||||
switch state {
|
||||
case model.MonitorClosed:
|
||||
sub.AttrSet(model.AttrNo, model.AttrSubMonitorBefore)
|
||||
sub.AttrSet(model.AttrNo, model.AttrSubMonitorAfter)
|
||||
case model.MonitorBefore:
|
||||
sub.AttrSet(model.AttrYes, model.AttrSubMonitorBefore)
|
||||
sub.AttrSet(model.AttrNo, model.AttrSubMonitorAfter)
|
||||
case model.MonitorAfter:
|
||||
sub.AttrSet(model.AttrNo, model.AttrSubMonitorBefore)
|
||||
sub.AttrSet(model.AttrYes, model.AttrSubMonitorAfter)
|
||||
default:
|
||||
err = ecode.RequestErr
|
||||
return
|
||||
}
|
||||
wg.Go(func() (err error) {
|
||||
aft, err := s.dao.UpSubjectAttr(context.TODO(), tp, sub.Oid, sub.Attr)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
affect = affect + aft
|
||||
return
|
||||
})
|
||||
}
|
||||
err = wg.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
38
app/admin/main/dm/service/monitor_test.go
Normal file
38
app/admin/main/dm/service/monitor_test.go
Normal file
@ -0,0 +1,38 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestMonitorList(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
aid, cid, mid, p, ps int64 = 0, 0, 0, 1, 100
|
||||
kw, sort, order = "", "", ""
|
||||
state int32 = 1
|
||||
tp int32 = 1
|
||||
)
|
||||
Convey("test monitor list from search", t, func() {
|
||||
res, err := svr.MonitorList(c, tp, aid, cid, mid, state, kw, sort, order, p, ps)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateMonitor(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
tp = model.SubTypeVideo
|
||||
oids = []int64{2, 99}
|
||||
)
|
||||
Convey("update dm subject monitor", t, func() {
|
||||
affect, err := svr.UpdateMonitor(c, tp, oids, 1)
|
||||
So(affect, ShouldBeGreaterThan, 0)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
663
app/admin/main/dm/service/report.go
Normal file
663
app/admin/main/dm/service/report.go
Normal file
@ -0,0 +1,663 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/dm/dao"
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/app/service/main/archive/api"
|
||||
"go-common/app/service/main/archive/model/archive"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
_searchTimeFormat = "2006-01-02 15:04:05"
|
||||
)
|
||||
|
||||
// ChangeReportStat set dm report status by mult dmid.
|
||||
func (s *Service) ChangeReportStat(c context.Context, cidDmids map[int64][]int64, state, reason, notice int8, adminID, block, blockReason, moral int64, remark, operator string) (affect int64, err error) {
|
||||
var (
|
||||
optDur int64
|
||||
dmids []int64
|
||||
dmidList = make([]int64, 0)
|
||||
nowTime = time.Now()
|
||||
dmLogMap = make(map[int64][]*model.ReportLog)
|
||||
rptsMap = make(map[int64]*model.Report)
|
||||
uptRpts = make([]*model.UptSearchReport, 0)
|
||||
)
|
||||
for _, dmids2 := range cidDmids {
|
||||
dmids = append(dmids, dmids2...)
|
||||
}
|
||||
if state == model.StatFirstInit || state == model.StatSecondInit || state == model.StatJudgeInit {
|
||||
if rptsMap, err = s.reports(c, dmids); err != nil {
|
||||
log.Error("s.reports(cidDmids:%v) error(%v)", cidDmids, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if rptsMap, err = s.reportsDetail(c, dmids); err != nil {
|
||||
log.Error("s.reportsDetail(cidDmids:%v) error(%v)", cidDmids, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
for cid, dmids := range cidDmids {
|
||||
if state == model.StatSecondIgnore || state == model.StatFirstIgnore {
|
||||
if err = s.dao.IgnoreReport(c, cid, dmids, state); err != nil {
|
||||
log.Error("s.dao.IgnoreReport(cid:%d, dmid:%v) error(%v)", cid, dmids, err)
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
if err = s.dao.ChangeReportStat(c, cid, dmids, state); err != nil {
|
||||
log.Error("s.dao.ChangeReportStat(cid:%d, dmid:%v) error(%v)", cid, dmids, err)
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
var rpts []*model.Report
|
||||
if rpts, err = s.dao.Reports(c, cid, dmids); err != nil {
|
||||
log.Error("s.dao.Reports(cid:%d, dmids:%v) error(%v)", cid, dmids, err)
|
||||
err = nil
|
||||
} else {
|
||||
for _, rpt := range rpts {
|
||||
var ctime, mtime time.Time
|
||||
ctime, err = time.Parse(time.RFC3339, rpt.Ctime)
|
||||
if err != nil {
|
||||
log.Error("strconv.RarseInt(%s) error(%v)", rpt.Ctime, err)
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
mtime, err = time.Parse(time.RFC3339, rpt.Mtime)
|
||||
if err != nil {
|
||||
log.Error("strconv.RarseInt(%s) error(%v)", rpt.Mtime, err)
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
uptRpt := &model.UptSearchReport{
|
||||
DMid: rpt.Did,
|
||||
Ctime: ctime.Format("2006-01-02 15:04:05"),
|
||||
Mtime: mtime.Format("2006-01-02 15:04:05"),
|
||||
State: state,
|
||||
}
|
||||
uptRpts = append(uptRpts, uptRpt)
|
||||
}
|
||||
}
|
||||
for _, dmid := range dmids {
|
||||
rpt, ok := rptsMap[dmid]
|
||||
if !ok {
|
||||
err = fmt.Errorf("get report detail empty,dmid:%d", dmid)
|
||||
log.Error("s.ReportsDetail(cid:%d, dmid:%v) error(%v)", cid, dmid, err)
|
||||
continue
|
||||
}
|
||||
if isDeleteOperation(state) {
|
||||
s.addRptDelAction(rpt)
|
||||
}
|
||||
rpt.State = state
|
||||
var mtime time.Time
|
||||
if mtime, err = time.ParseInLocation("2006-01-02 15:04:05", rpt.Mtime, time.Local); err == nil {
|
||||
optDur = int64(time.Since(mtime).Seconds())
|
||||
}
|
||||
lg := &model.ReportLog{
|
||||
Did: dmid,
|
||||
AdminID: adminID,
|
||||
Reason: reason,
|
||||
Result: state,
|
||||
Remark: remark,
|
||||
Elapsed: optDur,
|
||||
Ctime: nowTime,
|
||||
Mtime: nowTime,
|
||||
}
|
||||
dmLogMap[dao.LogTable(rpt.Did)] = append(dmLogMap[dao.LogTable(rpt.Did)], lg)
|
||||
dmidList = append(dmidList, rpt.Did)
|
||||
// if moral > 0 {
|
||||
// s.reduceMoral(c, rpt.UID, moral, reason, uname, fmt.Sprintf("%s, cid:%d, dmid:%d", model.CheckStateBelong(state), cid, dmid))
|
||||
// }
|
||||
if block != 0 {
|
||||
s.blockUser(c, rpt, block, blockReason, moral, operator)
|
||||
}
|
||||
if notice == model.NoticeReporter || notice == model.NoticeAll { // 发送邮件给举报方
|
||||
if len(rpt.RptUsers) > 0 {
|
||||
s.sendMsgToReporter(c, rpt, block, blockReason, int64(reason))
|
||||
}
|
||||
}
|
||||
if notice == model.NoticePoster || notice == model.NoticeAll {
|
||||
if len(rpt.RptUsers) > 0 {
|
||||
s.sendMsgToPoster(c, rpt, block, blockReason, int64(reason))
|
||||
}
|
||||
}
|
||||
}
|
||||
// if delete or recover this danmu
|
||||
if isDeleteOperation(state) {
|
||||
tmpRemark := model.AdminRptReason[reason] + "," + model.BlockReason[int8(blockReason)]
|
||||
if len(remark) >= 0 {
|
||||
tmpRemark = remark + "," + tmpRemark
|
||||
}
|
||||
// s.dao.SetStateByIDs(c, model.SubTypeVideo, cid, dmids, model.StateReportDelete)
|
||||
// s.OpLog(c, cid, adminID, 1, dmids, "status", "", fmt.Sprint(model.StateReportDelete), tmpRemark, oplog.SourceManager, oplog.OperatorAdmin)
|
||||
s.editDmState(c, model.SubTypeVideo, model.StateReportDelete, cid, reason, dmids, float64(moral), adminID, operator, tmpRemark)
|
||||
}
|
||||
}
|
||||
if isDeleteOperation(state) {
|
||||
// search update ignore error
|
||||
s.uptSearchDmState(c, model.SubTypeVideo, model.StateReportDelete, cidDmids)
|
||||
}
|
||||
if !(state == model.StatSecondInit || state == model.StatFirstInit) {
|
||||
if err = s.ChangeReportUserStat(c, dmidList); err != nil {
|
||||
log.Error("s.ChangeReportUserStat(%v) error(%v)", dmidList, err)
|
||||
}
|
||||
}
|
||||
if len(uptRpts) > 0 {
|
||||
if err = s.dao.UptSearchReport(c, uptRpts); err != nil {
|
||||
log.Error("s.dao.UpSearchReport(%v) error(%v)", uptRpts, err)
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
for k, v := range dmLogMap {
|
||||
if len(v) <= 0 {
|
||||
continue
|
||||
}
|
||||
if err = s.dao.AddReportLog(c, k, v); err != nil {
|
||||
log.Error("s.dao.AddReportLog(%v) error(%v)", v, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isDeleteOperation(state int8) bool {
|
||||
if state == model.StatSecondDelete || state == model.StatFirstDelete || state == model.StatSecondAutoDelete || state == model.StatJudgeDelete {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Service) dmState(c context.Context, cidDmids map[int64][]int64) (stateMap map[int64]int64, err error) {
|
||||
var (
|
||||
idxMap map[int64]*model.DM
|
||||
tp = int32(1)
|
||||
)
|
||||
stateMap = make(map[int64]int64)
|
||||
for oid, dmids := range cidDmids {
|
||||
if idxMap, _, err = s.dao.IndexsByID(c, tp, oid, dmids); err != nil {
|
||||
log.Error("s.dmState(oid:%v,dmids:%v) err(%v)", oid, dmids, err)
|
||||
return
|
||||
}
|
||||
for dmid, dm := range idxMap {
|
||||
stateMap[dmid] = int64(dm.State)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ReportList2 .
|
||||
func (s *Service) ReportList2(c context.Context, params *model.ReportListParams) (rtList *model.ReportList, err error) {
|
||||
var (
|
||||
aidMap = make(map[int64]bool)
|
||||
aids []int64
|
||||
cidDmids = make(map[int64][]int64)
|
||||
stateMap = make(map[int64]int64)
|
||||
)
|
||||
if params.Start == "" {
|
||||
now := time.Now()
|
||||
params.Start = time.Date(now.Year(), now.Month(), now.Day()-3, 0, 0, 0, 0, now.Location()).Format(_searchTimeFormat)
|
||||
}
|
||||
if params.End == "" {
|
||||
now := time.Now()
|
||||
params.End = time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, now.Location()).Format(_searchTimeFormat)
|
||||
}
|
||||
rptSearch, err := s.dao.SearchReport2(c, params)
|
||||
if err != nil {
|
||||
log.Error("s.dao.SearchReport2(params:%+v) error(%v)", params, err)
|
||||
return
|
||||
}
|
||||
for _, v := range rptSearch.Result {
|
||||
aidMap[v.Aid] = true
|
||||
cidDmids[v.Cid] = append(cidDmids[v.Cid], v.Did)
|
||||
}
|
||||
for aid := range aidMap {
|
||||
aids = append(aids, aid)
|
||||
}
|
||||
archives, err := s.archiveInfos(c, aids)
|
||||
if err != nil {
|
||||
log.Error("s.archives(%v) error(%v)", aids, err)
|
||||
return
|
||||
}
|
||||
if stateMap, err = s.dmState(c, cidDmids); err != nil {
|
||||
return
|
||||
}
|
||||
for _, v := range rptSearch.Result {
|
||||
v.DidStr = strconv.FormatInt(v.Did, 10)
|
||||
if arc, ok := archives[v.Aid]; ok {
|
||||
v.Title = arc.Title
|
||||
}
|
||||
if state, ok := stateMap[v.Did]; ok {
|
||||
v.Deleted = state
|
||||
}
|
||||
}
|
||||
rtList = &model.ReportList{
|
||||
Code: rptSearch.Code,
|
||||
Order: rptSearch.Order,
|
||||
Page: rptSearch.Page.Num,
|
||||
PageSize: rptSearch.Page.Size,
|
||||
PageCount: (rptSearch.Page.Total-1)/rptSearch.Page.Size + 1,
|
||||
Total: rptSearch.Page.Total,
|
||||
Result: rptSearch.Result,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ReportList get report list from search
|
||||
func (s *Service) ReportList(c context.Context, page, size int64, start, end, order, sort, keyword string, tid, rpID, state, upOp []int64, rt *model.Report) (rtList *model.ReportList, err error) {
|
||||
var (
|
||||
aidMap = make(map[int64]bool)
|
||||
aids []int64
|
||||
cidDmids = make(map[int64][]int64)
|
||||
stateMap = make(map[int64]int64)
|
||||
)
|
||||
rptSearch, err := s.dao.SearchReport(c, page, size, start, end, order, sort, keyword, tid, rpID, state, upOp, rt)
|
||||
if err != nil {
|
||||
log.Error("s.dao.SearchReport() error(%v)", err)
|
||||
return
|
||||
}
|
||||
for _, v := range rptSearch.Result {
|
||||
aidMap[v.Aid] = true
|
||||
cidDmids[v.Cid] = append(cidDmids[v.Cid], v.Did)
|
||||
}
|
||||
for aid := range aidMap {
|
||||
aids = append(aids, aid)
|
||||
}
|
||||
archives, err := s.archiveInfos(c, aids)
|
||||
if err != nil {
|
||||
log.Error("s.archives(%v) error(%v)", aids, err)
|
||||
return
|
||||
}
|
||||
if stateMap, err = s.dmState(c, cidDmids); err != nil {
|
||||
return
|
||||
}
|
||||
for _, v := range rptSearch.Result {
|
||||
v.DidStr = strconv.FormatInt(v.Did, 10)
|
||||
if arc, ok := archives[v.Aid]; ok {
|
||||
v.Title = arc.Title
|
||||
}
|
||||
if state, ok := stateMap[v.Did]; ok {
|
||||
v.Deleted = state
|
||||
}
|
||||
}
|
||||
rtList = &model.ReportList{
|
||||
Code: rptSearch.Code,
|
||||
Order: rptSearch.Order,
|
||||
Page: rptSearch.Page.Num,
|
||||
PageSize: rptSearch.Page.Size,
|
||||
PageCount: (rptSearch.Page.Total-1)/rptSearch.Page.Size + 1,
|
||||
Total: rptSearch.Page.Total,
|
||||
Result: rptSearch.Result,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) archiveInfos(c context.Context, aids []int64) (archives map[int64]*api.Arc, err error) {
|
||||
var (
|
||||
g errgroup.Group
|
||||
mu sync.Mutex
|
||||
l = len(aids)
|
||||
pagesize = 50
|
||||
pagenum = int(math.Ceil(float64(l) / float64(pagesize)))
|
||||
)
|
||||
archives = make(map[int64]*api.Arc)
|
||||
for i := 0; i < pagenum; i++ {
|
||||
start := i * pagesize
|
||||
end := (i + 1) * pagesize
|
||||
if end > l {
|
||||
end = l
|
||||
}
|
||||
g.Go(func() (err error) {
|
||||
arg := &archive.ArgAids2{Aids: aids[start:end]}
|
||||
res, err := s.arcRPC.Archives3(c, arg)
|
||||
if err != nil {
|
||||
log.Error("s.arcRPC.Archives3(%v) error(%v)", arg, err)
|
||||
return
|
||||
}
|
||||
for aid, info := range res {
|
||||
mu.Lock()
|
||||
archives[aid] = info
|
||||
mu.Unlock()
|
||||
}
|
||||
return
|
||||
})
|
||||
}
|
||||
err = g.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
// reportUsers get mult reports users
|
||||
func (s *Service) reportUsers(c context.Context, dmids []int64) (rptUsers map[int64][]*model.ReportUser, err error) {
|
||||
var (
|
||||
g errgroup.Group
|
||||
mu sync.Mutex
|
||||
dmidsMap = map[int64][]int64{}
|
||||
)
|
||||
for _, dmid := range dmids {
|
||||
dmidsMap[dao.UserTable(dmid)] = append(dmidsMap[dao.UserTable(dmid)], dmid)
|
||||
}
|
||||
rptUsers = make(map[int64][]*model.ReportUser)
|
||||
for tableID, dmids := range dmidsMap {
|
||||
key, value := tableID, dmids
|
||||
g.Go(func() (err error) {
|
||||
userTmp, err := s.dao.ReportUsers(c, key, value, model.NoticeUnsend)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for dmid, users := range userTmp {
|
||||
mu.Lock()
|
||||
rptUsers[dmid] = users
|
||||
mu.Unlock()
|
||||
}
|
||||
return
|
||||
})
|
||||
}
|
||||
err = g.Wait()
|
||||
return
|
||||
}
|
||||
|
||||
// reportsDetail get report list from search and get user list、archive list、dm list.
|
||||
func (s *Service) reportsDetail(c context.Context, dmids []int64) (res map[int64]*model.Report, err error) {
|
||||
var (
|
||||
aidMap = make(map[int64]bool)
|
||||
aids, dmids2 []int64
|
||||
)
|
||||
reports, err := s.reports(c, dmids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for dmid, rpt := range reports {
|
||||
if _, ok := aidMap[rpt.Aid]; !ok {
|
||||
aidMap[rpt.Aid] = true
|
||||
aids = append(aids, rpt.Aid)
|
||||
}
|
||||
dmids2 = append(dmids2, dmid)
|
||||
}
|
||||
archives, err := s.archiveInfos(c, aids)
|
||||
if err != nil {
|
||||
log.Error("s.archives(%v) error(%v)", aids, err)
|
||||
return nil, err
|
||||
}
|
||||
rptUsers, err := s.reportUsers(c, dmids2)
|
||||
if err != nil {
|
||||
log.Error("s.rptUsers(%v) error(%v)", dmids2, err)
|
||||
return nil, err
|
||||
}
|
||||
res = make(map[int64]*model.Report)
|
||||
for dmid, rpt := range reports {
|
||||
if arc, ok := archives[rpt.Aid]; ok {
|
||||
rpt.Title = arc.Title
|
||||
}
|
||||
if users, ok := rptUsers[dmid]; ok {
|
||||
rpt.RptUsers = users
|
||||
} else {
|
||||
rpt.RptUsers = make([]*model.ReportUser, 0)
|
||||
}
|
||||
res[dmid] = rpt
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// reports get report list by cid and dmids from search.
|
||||
func (s *Service) reports(c context.Context, dmids []int64) (res map[int64]*model.Report, err error) {
|
||||
rptSearchList, err := s.dao.SearchReportByID(c, dmids)
|
||||
if err != nil || len(rptSearchList.Result) <= 0 {
|
||||
log.Error("dao.SearchReportByID(ids:%v) error(%v)", dmids, err)
|
||||
return
|
||||
}
|
||||
res = make(map[int64]*model.Report)
|
||||
for _, rpt := range rptSearchList.Result {
|
||||
res[rpt.Did] = rpt
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ReportLog get report log by dmid.
|
||||
func (s *Service) ReportLog(c context.Context, dmid int64) (res []*model.ReportLog, err error) {
|
||||
if res, err = s.dao.ReportLog(c, dmid); err != nil {
|
||||
log.Error("s.dao.ReportLog(dmid:%d) error(%v)", dmid, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ChangeReportUserStat change report_user data
|
||||
func (s *Service) ChangeReportUserStat(c context.Context, dmids []int64) (err error) {
|
||||
var (
|
||||
dmidMap = map[int64][]int64{}
|
||||
)
|
||||
for _, v := range dmids {
|
||||
dmidMap[dao.UserTable(v)] = append(dmidMap[dao.UserTable(v)], v)
|
||||
}
|
||||
for k, v := range dmidMap {
|
||||
if _, err = s.dao.UpReportUserState(c, k, v, model.NoticeSend); err != nil {
|
||||
log.Error("s.dao.UpReportUserState(dmids:%v) error(%v)", v, err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) sendMsgToReporter(c context.Context, rpt *model.Report, block, blockReason, rptReason int64) {
|
||||
var (
|
||||
buf bytes.Buffer
|
||||
)
|
||||
for _, user := range rpt.RptUsers {
|
||||
buf.WriteString(fmt.Sprintf("%d,", user.UID))
|
||||
}
|
||||
buf.Truncate(buf.Len() - 1)
|
||||
m := &model.ReportMsg{
|
||||
Aid: rpt.Aid,
|
||||
Did: rpt.Did,
|
||||
Title: rpt.Title,
|
||||
Msg: rpt.Msg,
|
||||
RptReason: int8(rptReason),
|
||||
Uids: buf.String(),
|
||||
State: rpt.State,
|
||||
Block: block,
|
||||
BlockReason: int8(blockReason),
|
||||
}
|
||||
select {
|
||||
case s.msgReporterChan <- m:
|
||||
default:
|
||||
log.Error("s.msgReporterChan err, channel full(msg:%v)", m)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) sendMsgToPoster(c context.Context, rpt *model.Report, block, blockReason, rptReason int64) {
|
||||
m := &model.ReportMsg{
|
||||
Aid: rpt.Aid,
|
||||
Did: rpt.Did,
|
||||
Title: rpt.Title,
|
||||
Msg: rpt.Msg,
|
||||
RptReason: int8(rptReason),
|
||||
Uids: fmt.Sprint(rpt.UID),
|
||||
Block: block,
|
||||
BlockReason: int8(blockReason),
|
||||
}
|
||||
select {
|
||||
case s.msgPosterChan <- m:
|
||||
default:
|
||||
log.Error("s.msgPosterChan err, channel full(msg:%v)", m)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) reduceMoral(c context.Context, uid, moral int64, reason int8, operator, remark string) {
|
||||
m := &model.ReduceMoral{
|
||||
UID: uid,
|
||||
Moral: moral,
|
||||
Origin: 2,
|
||||
Reason: reason,
|
||||
ReasonType: 1,
|
||||
Operator: operator,
|
||||
IsNotify: 0,
|
||||
Remark: remark,
|
||||
}
|
||||
select {
|
||||
case s.reduceMoralChan <- m:
|
||||
default:
|
||||
log.Error("s.reduceMoral err, channel full(msg:%v)", m)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) blockUser(c context.Context, rpt *model.Report, block, blockReason, moral int64, uname string) {
|
||||
var (
|
||||
blockEver int64
|
||||
blockLength int64
|
||||
)
|
||||
if block == -1 {
|
||||
blockEver = 1
|
||||
} else {
|
||||
blockLength = block
|
||||
}
|
||||
m := &model.BlockUser{
|
||||
UID: rpt.UID,
|
||||
BlockForever: blockEver,
|
||||
BlockTimeLength: blockLength,
|
||||
BlockRemark: fmt.Sprintf("%s, cid:%d, dmid:%d", model.CheckStateBelong(rpt.State), rpt.Cid, rpt.Did),
|
||||
Operator: uname,
|
||||
OriginType: 2,
|
||||
Moral: moral,
|
||||
ReasonType: blockReason,
|
||||
OriginTitle: rpt.Title,
|
||||
OriginContent: rpt.Msg,
|
||||
OriginURL: fmt.Sprintf("http://www.bilibili.com/av%d", rpt.Aid),
|
||||
IsNotify: 0,
|
||||
}
|
||||
select {
|
||||
case s.blockUserChan <- m:
|
||||
default:
|
||||
log.Error("s.blockUserChan err, channel full(msg:%v)", m)
|
||||
}
|
||||
}
|
||||
|
||||
// DMReportJudge send report judge
|
||||
func (s *Service) DMReportJudge(c context.Context, cidDmids map[int64][]int64, uid int64, uname string) (err error) {
|
||||
var (
|
||||
aids []int64
|
||||
dmids []int64
|
||||
rptJudges []*model.ReportJudge
|
||||
)
|
||||
for _, dmids2 := range cidDmids {
|
||||
dmids = append(dmids, dmids2...)
|
||||
}
|
||||
rpts, err := s.reportsDetail(c, dmids) // get report detail by multi dmids
|
||||
if len(rpts) == 0 {
|
||||
log.Error("dmjudge error! id:%v not exist in search", dmids)
|
||||
return
|
||||
}
|
||||
for _, rpt := range rpts {
|
||||
aids = append(aids, rpt.Aid)
|
||||
}
|
||||
arg := &archive.ArgAids2{Aids: aids}
|
||||
archs, err := s.arcRPC.Archives3(c, arg) // get archive info
|
||||
if err != nil {
|
||||
log.Error("s.arcSvc.Archives3(aids:%v) err(%v)", aids, err)
|
||||
return
|
||||
}
|
||||
if len(archs) == 0 {
|
||||
log.Error("dmjudge error! id:%v not exist in archive rpc", aids)
|
||||
err = ecode.ArchiveNotExist
|
||||
return
|
||||
}
|
||||
for _, rpt := range rpts {
|
||||
j := &model.ReportJudge{}
|
||||
arc, ok := archs[rpt.Aid]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
arg := &archive.ArgVideo2{
|
||||
Aid: rpt.Aid,
|
||||
Cid: rpt.Cid,
|
||||
}
|
||||
var vInfo *api.Page
|
||||
if vInfo, err = s.arcRPC.Video3(c, arg); err != nil {
|
||||
log.Error("s.arcSvc.Video3(arg:%v) err(%v)", arg, err)
|
||||
j.Page = 1
|
||||
} else {
|
||||
j.Page = int64(vInfo.Page)
|
||||
}
|
||||
j.MID = rpt.UID
|
||||
j.Operator = uname
|
||||
j.OperID = uid
|
||||
j.OContent = rpt.Msg
|
||||
j.OTitle = arc.Title
|
||||
j.OType = 2
|
||||
j.OURL = fmt.Sprintf("http://www.bilibili.com/av%d", rpt.Aid)
|
||||
j.ReasonType = int64(model.RpReasonToJudgeReason(int8(rpt.RpType)))
|
||||
j.AID = rpt.Aid
|
||||
j.OID = rpt.Cid
|
||||
j.RPID = rpt.Did
|
||||
sendTime, _ := time.Parse("2006-01-02 15:04:05", rpt.SendTime)
|
||||
j.BTime = sendTime.Unix()
|
||||
rptJudges = append(rptJudges, j)
|
||||
}
|
||||
if len(rptJudges) <= 0 {
|
||||
return
|
||||
}
|
||||
if err = s.dao.SendJudgement(c, rptJudges); err != nil {
|
||||
log.Error("s.dao.SendJudgement(data:%v) err (%v)", rptJudges, err)
|
||||
}
|
||||
_, err = s.ChangeReportStat(c, cidDmids, model.StatJudgeInit, 0, 0, uid, 0, 0, 0, "转风纪委", uname)
|
||||
if err != nil {
|
||||
log.Error("s.ChangeReportStat(id:%v) err(%v)", cidDmids, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// JudgeResult receive judge result
|
||||
func (s *Service) JudgeResult(c context.Context, cid, dmid, result int64) (err error) {
|
||||
var (
|
||||
state int8
|
||||
remark string
|
||||
)
|
||||
res, err := s.dao.Reports(c, cid, []int64{dmid})
|
||||
if err != nil {
|
||||
log.Error("s.dao.Reports(cid:%d,dmid:%d) err(%v)", cid, dmid, err)
|
||||
return
|
||||
}
|
||||
if len(res) <= 0 {
|
||||
log.Error("dmJudge: cid:%d,dmid:%d not found", cid, dmid)
|
||||
err = ecode.RequestErr
|
||||
return
|
||||
}
|
||||
m := map[int64][]int64{
|
||||
res[0].Cid: {res[0].Did},
|
||||
}
|
||||
if result == 0 {
|
||||
state = model.StatJudgeIgnore
|
||||
remark = "风纪委处理:忽略"
|
||||
} else {
|
||||
state = model.StatJudgeDelete
|
||||
remark = "风纪委处理:删除"
|
||||
}
|
||||
_, err = s.ChangeReportStat(c, m, state, int8(res[0].RpType), 0, 0, 0, 0, 0, remark, "")
|
||||
if err != nil {
|
||||
log.Error("s.ChangeReportStat(cid:%d,dmid:%d) err(%v)", cid, dmid, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) addRptDelAction(rpt *model.Report) (err error) {
|
||||
data, err := json.Marshal(rpt)
|
||||
if err != nil {
|
||||
log.Error("json.Marshal(%v) error(%v)", rpt, err)
|
||||
return
|
||||
}
|
||||
action := &model.Action{
|
||||
Oid: rpt.Cid,
|
||||
Action: model.ActReportDel,
|
||||
Data: data,
|
||||
}
|
||||
s.addAction(action)
|
||||
return
|
||||
}
|
94
app/admin/main/dm/service/report_test.go
Normal file
94
app/admin/main/dm/service/report_test.go
Normal file
@ -0,0 +1,94 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestChangeReportStat(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
cidDmids = map[int64][]int64{
|
||||
9968618: {
|
||||
719923090, 719923092,
|
||||
},
|
||||
}
|
||||
state = model.StatSecondDelete
|
||||
reason int8 = 2
|
||||
notice int8 = 3
|
||||
adminID int64 = 222
|
||||
remark = "二审删除"
|
||||
block int64 = 3
|
||||
blockReason int64
|
||||
moral int64 = 10
|
||||
uname = "zzz delete"
|
||||
)
|
||||
Convey("test change report stat", t, func() {
|
||||
affect, err := svr.ChangeReportStat(c, cidDmids, state, reason, notice, adminID, block, blockReason, moral, remark, uname)
|
||||
So(err, ShouldNotBeNil)
|
||||
So(affect, ShouldBeGreaterThan, 0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestReportLog(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
dmid int64 = 2
|
||||
)
|
||||
Convey("test report log", t, func() {
|
||||
lg, err := svr.ReportLog(c, dmid)
|
||||
So(err, ShouldBeNil)
|
||||
So(lg, ShouldNotBeEmpty)
|
||||
})
|
||||
}
|
||||
|
||||
func TestReportList(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
page int64 = 1
|
||||
size int64 = 100
|
||||
start = "2017-05-10 00:00:00"
|
||||
end = "2017-12-13 00:00:00"
|
||||
order = "rp_time"
|
||||
sort = "asc"
|
||||
keyword = ""
|
||||
tid = []int64{}
|
||||
rpID = []int64{}
|
||||
state = []int64{0, 1, 2, 3, 4, 5, 6, 7}
|
||||
upOp = []int64{0, 1, 2}
|
||||
rt = &model.Report{}
|
||||
)
|
||||
Convey("test report list", t, func() {
|
||||
list, err := svr.ReportList(c, page, size, start, end, order, sort, keyword, tid, rpID, state, upOp, rt)
|
||||
So(err, ShouldBeNil)
|
||||
So(list, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDMReportJudge(t *testing.T) {
|
||||
var (
|
||||
err error
|
||||
c = context.TODO()
|
||||
cidDmids = map[int64][]int64{
|
||||
9968618: {719923090}}
|
||||
)
|
||||
Convey("test report judge", t, func() {
|
||||
err = svr.DMReportJudge(c, cidDmids, 122, "zhang1111")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestJudgeResult(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
cid, dmid int64 = 10109084, 719213118
|
||||
)
|
||||
Convey("test judge result", t, func() {
|
||||
err := svr.JudgeResult(c, cid, dmid, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
247
app/admin/main/dm/service/service.go
Normal file
247
app/admin/main/dm/service/service.go
Normal file
@ -0,0 +1,247 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/dm/conf"
|
||||
"go-common/app/admin/main/dm/dao"
|
||||
oplogDao "go-common/app/admin/main/dm/dao/oplog"
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/app/admin/main/dm/model/oplog"
|
||||
accountApi "go-common/app/service/main/account/api"
|
||||
archive "go-common/app/service/main/archive/api/gorpc"
|
||||
"go-common/library/log"
|
||||
"go-common/library/log/infoc"
|
||||
"go-common/library/sync/pipeline/fanout"
|
||||
)
|
||||
|
||||
// Service define Service struct
|
||||
type Service struct {
|
||||
// dao
|
||||
dao *dao.Dao
|
||||
oplogDao *oplogDao.Dao
|
||||
// rpc
|
||||
accountRPC accountApi.AccountClient
|
||||
arcRPC *archive.Service2
|
||||
dmOperationLogSvc *infoc.Infoc
|
||||
bakInfoc *infoc.Infoc
|
||||
opsLogCh chan *oplog.Infoc
|
||||
reduceMoralChan chan *model.ReduceMoral
|
||||
blockUserChan chan *model.BlockUser
|
||||
msgReporterChan chan *model.ReportMsg
|
||||
msgPosterChan chan *model.ReportMsg
|
||||
actionChan chan *model.Action
|
||||
// async proc
|
||||
cache *fanout.Fanout
|
||||
moniOidMap map[int64]struct{}
|
||||
oidLock sync.Mutex
|
||||
}
|
||||
|
||||
// New new a Service and return.
|
||||
func New(c *conf.Config) *Service {
|
||||
s := &Service{
|
||||
// dao
|
||||
dao: dao.New(c),
|
||||
oplogDao: oplogDao.New(c),
|
||||
// rpc
|
||||
arcRPC: archive.New2(c.ArchiveRPC),
|
||||
dmOperationLogSvc: infoc.New(c.Infoc2),
|
||||
bakInfoc: infoc.New(c.InfocBak),
|
||||
reduceMoralChan: make(chan *model.ReduceMoral, 1024),
|
||||
blockUserChan: make(chan *model.BlockUser, 1024),
|
||||
msgReporterChan: make(chan *model.ReportMsg, 1024),
|
||||
msgPosterChan: make(chan *model.ReportMsg, 1024),
|
||||
actionChan: make(chan *model.Action, 1024),
|
||||
opsLogCh: make(chan *oplog.Infoc, 1024),
|
||||
cache: fanout.New("cache", fanout.Worker(1), fanout.Buffer(1024)),
|
||||
moniOidMap: make(map[int64]struct{}),
|
||||
}
|
||||
accountRPC, err := accountApi.NewClient(c.AccountRPC)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s.accountRPC = accountRPC
|
||||
go s.changeReportStatProc()
|
||||
go s.actionproc()
|
||||
go s.oplogproc()
|
||||
go s.monitorproc()
|
||||
return s
|
||||
}
|
||||
|
||||
// Ping check server ok
|
||||
func (s *Service) Ping(c context.Context) (err error) {
|
||||
if err = s.dao.Ping(c); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) addAction(action *model.Action) {
|
||||
select {
|
||||
case s.actionChan <- action:
|
||||
default:
|
||||
log.Error("action channel is full,action(%v) is discard", action)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) actionproc() {
|
||||
for action := range s.actionChan {
|
||||
if err := s.dao.SendAction(context.TODO(), fmt.Sprint(action.Oid), action); err != nil {
|
||||
log.Error("dao.SendAction(%v) error(%v)", action, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) changeReportStatProc() {
|
||||
for {
|
||||
select {
|
||||
case msg := <-s.reduceMoralChan:
|
||||
if err := s.dao.ReduceMoral(context.TODO(), msg); err != nil {
|
||||
log.Error("s.dao.ReduceMoral(msg:%v) error(%v)", msg, err)
|
||||
}
|
||||
case msg := <-s.msgReporterChan:
|
||||
if err := s.dao.SendMsgToReporter(context.TODO(), msg); err != nil {
|
||||
log.Error("s.dao.SendMsgToReporter(msg:%v) error(%v)", msg, err)
|
||||
}
|
||||
case msg := <-s.msgPosterChan:
|
||||
if err := s.dao.SendMsgToPoster(context.TODO(), msg); err != nil {
|
||||
log.Error("s.dao.SendMsgToPoster(msg:%v) error(%v)", msg, err)
|
||||
}
|
||||
case msg := <-s.blockUserChan:
|
||||
if err := s.dao.BlockUser(context.TODO(), msg); err != nil {
|
||||
log.Error("s.dao.BlockUser(msg:%v) error(%v)", msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) oplogproc() {
|
||||
for opLog := range s.opsLogCh {
|
||||
if len(opLog.Subject) == 0 || len(opLog.CurrentVal) == 0 || opLog.Source <= 0 ||
|
||||
opLog.Operator <= 0 || opLog.OperatorType <= 0 {
|
||||
log.Warn("oplogproc() it is an illegal log, warn(%v, %v, %v)", opLog.Subject, opLog.Subject, opLog.CurrentVal)
|
||||
continue
|
||||
} else {
|
||||
for _, dmid := range opLog.DMIds {
|
||||
s.dmOperationLogSvc.Info(opLog.Subject, strconv.FormatInt(opLog.Oid, 10), fmt.Sprint(opLog.Type),
|
||||
strconv.FormatInt(dmid, 10), opLog.Source.String(), opLog.OriginVal,
|
||||
opLog.CurrentVal, strconv.FormatInt(opLog.Operator, 10), opLog.OperatorType.String(),
|
||||
opLog.OperationTime, opLog.Remark)
|
||||
// 将管理员操作日志额外上报一份(用于验证数据报表完整性)
|
||||
s.bakInfoc.Info(opLog.Subject, strconv.FormatInt(opLog.Oid, 10), fmt.Sprint(opLog.Type),
|
||||
strconv.FormatInt(dmid, 10), opLog.Source.String(), opLog.OriginVal,
|
||||
opLog.CurrentVal, strconv.FormatInt(opLog.Operator, 10), opLog.OperatorType.String(),
|
||||
opLog.OperationTime, opLog.Remark)
|
||||
if strings.Contains(opLog.Subject, "\n") {
|
||||
log.Error("\n found in opLog.Subject(%s)", opLog.Source)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OpLog put a new infoc format operation log into the channel
|
||||
func (s *Service) OpLog(c context.Context, cid, operator int64, typ int32, dmids []int64, subject, originVal, currentVal, remark string, source oplog.Source, operatorType oplog.OperatorType) (err error) {
|
||||
infoLog := new(oplog.Infoc)
|
||||
infoLog.Oid = cid
|
||||
infoLog.Type = typ
|
||||
infoLog.DMIds = dmids
|
||||
infoLog.Subject = subject
|
||||
infoLog.OriginVal = originVal
|
||||
infoLog.CurrentVal = currentVal
|
||||
infoLog.OperationTime = strconv.FormatInt(time.Now().Unix(), 10)
|
||||
infoLog.Source = source
|
||||
infoLog.OperatorType = operatorType
|
||||
infoLog.Operator = operator
|
||||
infoLog.Remark = remark
|
||||
select {
|
||||
case s.opsLogCh <- infoLog:
|
||||
default:
|
||||
err = fmt.Errorf("opsLogCh full")
|
||||
log.Error("opsLogCh full (%v)", infoLog)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// QueryOpLogs query operation logs of damku equals dmid
|
||||
func (s *Service) QueryOpLogs(c context.Context, dmid int64) (infos []*oplog.InfocResult, err error) {
|
||||
result, err := s.oplogDao.QueryOpLogs(c, dmid)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, logVal := range result {
|
||||
var (
|
||||
tmp = &oplog.InfocResult{}
|
||||
)
|
||||
val, err := strconv.Atoi(logVal.CurrentVal)
|
||||
if err != nil {
|
||||
err = nil
|
||||
continue
|
||||
}
|
||||
switch logVal.Subject {
|
||||
case "status":
|
||||
tmp.Subject = model.StateDesc(int32(val))
|
||||
case "pool":
|
||||
if val == 0 {
|
||||
tmp.Subject = "普通弹幕池"
|
||||
} else if val == 1 {
|
||||
tmp.Subject = "字幕弹幕池"
|
||||
} else if val == 2 {
|
||||
tmp.Subject = "特殊弹幕池"
|
||||
}
|
||||
case "attribute":
|
||||
if val == 2 || (int32(val)>>model.AttrProtect)&int32(1) == 1 {
|
||||
tmp.Subject = "弹幕保护"
|
||||
} else if val == 3 || (int32(val)>>model.AttrProtect)&int32(1) == 0 {
|
||||
tmp.Subject = "取消弹幕保护"
|
||||
}
|
||||
default:
|
||||
tmp.Subject = logVal.Subject
|
||||
}
|
||||
tmp.CurrentVal = logVal.CurrentVal
|
||||
tmp.OperatorType = logVal.OperatorType
|
||||
if logVal.OperatorType == "用户" || logVal.OperatorType == "UP主" {
|
||||
mid, _ := strconv.ParseInt(logVal.Operator, 10, 64)
|
||||
arg3 := &accountApi.MidReq{Mid: mid}
|
||||
uInfo, err := s.accountRPC.Info3(c, arg3)
|
||||
if err != nil {
|
||||
tmp.Operator = logVal.Operator
|
||||
log.Error("s.accRPC.Info2(%v) error(%v)", arg3, err)
|
||||
err = nil
|
||||
} else {
|
||||
tmp.Operator = uInfo.GetInfo().GetName()
|
||||
}
|
||||
} else {
|
||||
tmp.Operator = logVal.Operator
|
||||
}
|
||||
OperationTimeStamp, _ := strconv.ParseInt(logVal.OperationTime, 10, 64)
|
||||
tmp.OperationTime = time.Unix(OperationTimeStamp, 0).Format("2006-01-02 15:04:05")
|
||||
tmp.Remark = "操作来源:" + logVal.Source + ";操作员身份:" + logVal.OperatorType + ";备注:" + logVal.Remark
|
||||
infos = append(infos, tmp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) monitorproc() {
|
||||
for {
|
||||
time.Sleep(3 * time.Second)
|
||||
s.oidLock.Lock()
|
||||
oidMap := s.moniOidMap
|
||||
s.moniOidMap = make(map[int64]struct{})
|
||||
s.oidLock.Unlock()
|
||||
for oid := range oidMap {
|
||||
sub, err := s.dao.Subject(context.TODO(), model.SubTypeVideo, oid)
|
||||
if err != nil || sub == nil {
|
||||
continue
|
||||
}
|
||||
if err := s.updateMonitorCnt(context.TODO(), sub); err != nil {
|
||||
log.Error("s.updateMonitorCnt(%+v) error(%v)", sub, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
76
app/admin/main/dm/service/service_test.go
Normal file
76
app/admin/main/dm/service/service_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"go-common/app/admin/main/dm/conf"
|
||||
"go-common/app/admin/main/dm/model/oplog"
|
||||
"go-common/library/log"
|
||||
manager "go-common/library/queue/databus/report"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
var (
|
||||
svr *Service
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
var (
|
||||
err error
|
||||
)
|
||||
dir, _ := filepath.Abs("../cmd/dm-admin-test.toml")
|
||||
if err = flag.Set("conf", dir); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err = conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// log.Init(nil)
|
||||
svr = New(conf.Conf)
|
||||
// manager log init
|
||||
manager.InitManager(conf.Conf.ManagerLog)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func WithService(f func(s *Service)) func() {
|
||||
return func() {
|
||||
f(svr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpLog(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
cid int64 = 12
|
||||
typ int32 = 1
|
||||
operator int64 = 219
|
||||
dmids = []int64{719150137}
|
||||
subject = "status"
|
||||
originVal = "1"
|
||||
currentVal = "2"
|
||||
remark = "备注"
|
||||
source = oplog.SourceManager
|
||||
operatorType = oplog.OperatorAdmin
|
||||
)
|
||||
Convey("OpLog", t, WithService(func(s *Service) {
|
||||
err := svr.OpLog(c, cid, operator, typ, dmids, subject, originVal, currentVal, remark, source, operatorType)
|
||||
So(err, ShouldBeNil)
|
||||
}))
|
||||
}
|
||||
|
||||
func TestQueryOpLogs(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
dmid int64 = 719150137
|
||||
)
|
||||
Convey("QueryOpLogs", t, WithService(func(s *Service) {
|
||||
objs, err := svr.QueryOpLogs(c, dmid)
|
||||
log.Info("%v", objs)
|
||||
So(err, ShouldBeNil)
|
||||
}))
|
||||
}
|
21
app/admin/main/dm/service/shield.go
Normal file
21
app/admin/main/dm/service/shield.go
Normal file
@ -0,0 +1,21 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_bnjShieldFileName = "bnj_shield.csv"
|
||||
_bnjShieldBucket = "dm"
|
||||
)
|
||||
|
||||
// DmShield .
|
||||
func (s *Service) DmShield(c context.Context, bs []byte) (err error) {
|
||||
if err = s.dao.Upload(c, _bnjShieldBucket, _bnjShieldFileName, "text/csv", bs); err != nil {
|
||||
log.Error("DmShield(err:%v)", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
167
app/admin/main/dm/service/subject.go
Normal file
167
app/admin/main/dm/service/subject.go
Normal file
@ -0,0 +1,167 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/app/service/main/archive/api"
|
||||
"go-common/app/service/main/archive/model/archive"
|
||||
"go-common/library/log"
|
||||
manager "go-common/library/queue/databus/report"
|
||||
)
|
||||
|
||||
// ArchiveList get archive list.
|
||||
func (s *Service) ArchiveList(c context.Context, req *model.ArchiveListReq) (res *model.ArchiveResult, err error) {
|
||||
var (
|
||||
oids, aids []int64
|
||||
aidMap = make(map[int64]struct{})
|
||||
arcMap = make(map[int64]*model.ArcVideo)
|
||||
archiveTypes = make(map[int64]*model.ArchiveType)
|
||||
subs map[int64]*model.Subject
|
||||
r = &model.SearchSubjectReq{
|
||||
State: req.State,
|
||||
Attrs: req.Attrs,
|
||||
Pn: req.Pn,
|
||||
Ps: req.Ps,
|
||||
Sort: req.Sort,
|
||||
Order: req.Order,
|
||||
}
|
||||
)
|
||||
res = &model.ArchiveResult{}
|
||||
res.Page = &model.Page{}
|
||||
if req.ID > 0 {
|
||||
switch req.IDType {
|
||||
case "oid":
|
||||
r.Oids = append(r.Oids, req.ID)
|
||||
case "mid":
|
||||
r.Mids = append(r.Mids, req.ID)
|
||||
case "aid":
|
||||
r.Aids = append(r.Aids, req.ID)
|
||||
case "ep", "ss":
|
||||
if r.Aids, r.Oids, err = s.dao.SeasonInfos(c, req.IDType, req.ID); err != nil {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
data := make([]*model.DMSubject, 0)
|
||||
if len(r.Aids) > 0 && req.Page >= 1 {
|
||||
var (
|
||||
pages []*api.Page
|
||||
arg = archive.ArgAid2{Aid: r.Aids[0]}
|
||||
)
|
||||
if pages, err = s.arcRPC.Page3(c, &arg); err != nil {
|
||||
log.Error("arcRPC.Page3(%v) error(%v)", arg, err)
|
||||
return
|
||||
}
|
||||
if len(pages) < int(req.Page) {
|
||||
log.Error("req.Page too big(%d) error(%v)", req.Page, err)
|
||||
return
|
||||
}
|
||||
r.Oids = append(r.Oids, pages[req.Page-1].Cid)
|
||||
}
|
||||
res = new(model.ArchiveResult)
|
||||
if oids, res.Page, err = s.dao.SearchSubject(c, r); err != nil {
|
||||
return
|
||||
}
|
||||
if subs, err = s.dao.Subjects(c, model.SubTypeVideo, oids); err != nil {
|
||||
return
|
||||
}
|
||||
for _, oid := range oids {
|
||||
if sub, ok := subs[oid]; ok {
|
||||
s := &model.DMSubject{
|
||||
OID: sub.Oid,
|
||||
Type: sub.Type,
|
||||
AID: sub.Pid,
|
||||
ACount: sub.ACount,
|
||||
Limit: sub.Maxlimit,
|
||||
CTime: sub.Ctime,
|
||||
MTime: sub.Mtime,
|
||||
MID: sub.Mid,
|
||||
State: sub.State,
|
||||
}
|
||||
data = append(data, s)
|
||||
}
|
||||
}
|
||||
if len(data) <= 0 {
|
||||
return
|
||||
}
|
||||
for _, idx := range data {
|
||||
if _, ok := aidMap[idx.AID]; !ok {
|
||||
aidMap[idx.AID] = struct{}{}
|
||||
aids = append(aids, idx.AID)
|
||||
}
|
||||
}
|
||||
if arcMap, err = s.dao.ArchiveVideos(c, aids); err != nil {
|
||||
return
|
||||
}
|
||||
if archiveTypes, err = s.dao.TypeInfo(c); err != nil {
|
||||
return
|
||||
}
|
||||
for _, idx := range data {
|
||||
info, ok := arcMap[idx.AID] // get archive info
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
idx.Title = info.Archive.Title
|
||||
idx.TID = info.Archive.TID
|
||||
if v, ok := archiveTypes[idx.TID]; ok {
|
||||
idx.TName = v.Name
|
||||
}
|
||||
if len(info.Videos) > 0 { // get ep_title name
|
||||
for _, video := range info.Videos {
|
||||
if video.CID == idx.OID {
|
||||
idx.ETitle = video.Title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res.ArcLists = data
|
||||
return
|
||||
}
|
||||
|
||||
// UptSubjectsState change oids subject state and send manager log.
|
||||
func (s *Service) UptSubjectsState(c context.Context, tp int32, uid int64, uname string, oids []int64, state int32, comment string) (err error) {
|
||||
var affect int64
|
||||
for _, oid := range oids {
|
||||
if affect, err = s.dao.UpSubjectState(c, tp, oid, state); err != nil {
|
||||
return
|
||||
}
|
||||
if affect == 0 {
|
||||
log.Info("s.UpSubjectState affect=0 oid(%d)", oid)
|
||||
continue
|
||||
}
|
||||
managerInfo := &manager.ManagerInfo{
|
||||
UID: uid,
|
||||
Uname: uname,
|
||||
Business: model.DMLogBizID,
|
||||
Type: int(tp),
|
||||
Oid: oid,
|
||||
Ctime: time.Now(),
|
||||
Content: map[string]interface{}{
|
||||
"comment": comment,
|
||||
},
|
||||
}
|
||||
if state == model.SubStateOpen {
|
||||
managerInfo.Action = "开启弹幕池"
|
||||
} else {
|
||||
managerInfo.Action = "关闭弹幕池"
|
||||
}
|
||||
manager.Manager(managerInfo)
|
||||
log.Info("s.managerLogSend(%+v)", managerInfo)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UpSubjectMaxLimit update maxlimit in dm subject.
|
||||
func (s *Service) UpSubjectMaxLimit(c context.Context, tp int32, oid, maxlimit int64) (err error) {
|
||||
_, err = s.dao.UpSubjectMaxlimit(c, tp, oid, maxlimit)
|
||||
return
|
||||
}
|
||||
|
||||
// SubjectLog get subject log
|
||||
func (s *Service) SubjectLog(c context.Context, tp int32, oid int64) (data []*model.SubjectLog, err error) {
|
||||
data, err = s.dao.SearchSubjectLog(c, tp, oid)
|
||||
return
|
||||
}
|
57
app/admin/main/dm/service/subject_test.go
Normal file
57
app/admin/main/dm/service/subject_test.go
Normal file
@ -0,0 +1,57 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestArchiveList(t *testing.T) {
|
||||
req := &model.ArchiveListReq{
|
||||
ID: 34261,
|
||||
IDType: "oid",
|
||||
Sort: "desc",
|
||||
Order: "mtime",
|
||||
Pn: 1,
|
||||
Ps: 50,
|
||||
Page: int64(model.CondIntNil),
|
||||
State: int64(model.CondIntNil),
|
||||
}
|
||||
convey.Convey("test last archive list", t, func() {
|
||||
res, err := svr.ArchiveList(context.TODO(), req)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
convey.So(res, convey.ShouldNotBeEmpty)
|
||||
t.Logf("===%+v", res.Page)
|
||||
for _, v := range res.ArcLists {
|
||||
t.Logf("===%+v", v)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceUptSubjectsState(t *testing.T) {
|
||||
convey.Convey("UptSubjectsState", t, func() {
|
||||
err := svr.UptSubjectsState(context.TODO(), 1, 111, "test", []int64{1221}, 1, "aaaaa")
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceUpSubjectMaxLimit(t *testing.T) {
|
||||
convey.Convey("UpSubjectMaxLimit", t, func() {
|
||||
err := svr.UpSubjectMaxLimit(context.TODO(), 1, 10131812, 333)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceSubjectLog(t *testing.T) {
|
||||
convey.Convey("SubjectLog", t, func() {
|
||||
data, err := svr.SubjectLog(context.TODO(), 1, 1221)
|
||||
convey.So(err, convey.ShouldBeNil)
|
||||
convey.So(data, convey.ShouldNotBeNil)
|
||||
for _, v := range data {
|
||||
t.Logf("====%+v", v)
|
||||
}
|
||||
})
|
||||
}
|
357
app/admin/main/dm/service/subtitle.go
Normal file
357
app/admin/main/dm/service/subtitle.go
Normal file
@ -0,0 +1,357 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
accountApi "go-common/app/service/main/account/api"
|
||||
"go-common/app/service/main/archive/api"
|
||||
archiveMdl "go-common/app/service/main/archive/model/archive"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
_workFlowSubtitleBid = 14
|
||||
)
|
||||
|
||||
// SubtitleLanList .
|
||||
func (s *Service) SubtitleLanList(c context.Context) (res map[int64]string, err error) {
|
||||
var (
|
||||
sLans []*model.SubtitleLan
|
||||
)
|
||||
if sLans, err = s.dao.SubtitleLans(c); err != nil {
|
||||
return
|
||||
}
|
||||
res = make(map[int64]string)
|
||||
for _, sLan := range sLans {
|
||||
res[sLan.Code] = sLan.DocZh
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// WorkFlowEditSubtitle .
|
||||
func (s *Service) WorkFlowEditSubtitle(c context.Context, arg *model.WorkFlowSubtitleArg) (err error) {
|
||||
var (
|
||||
argEdit *model.EditSubtitleArg
|
||||
status model.SubtitleStatus
|
||||
)
|
||||
if arg == nil || arg.Object == nil || len(arg.Object.Ids) == 0 || len(arg.Targets) == 0 {
|
||||
err = ecode.RequestErr
|
||||
return
|
||||
}
|
||||
switch arg.Object.DisposeMode {
|
||||
case model.WorkFlowSubtitleDisposeManagerBack:
|
||||
status = model.SubtitleStatusManagerBack
|
||||
case model.WorkFlowSubtitleDisposeManagerDelete:
|
||||
status = model.SubtitleStatusManagerRemove
|
||||
default:
|
||||
return
|
||||
}
|
||||
for _, target := range arg.Targets {
|
||||
if target == nil {
|
||||
continue
|
||||
}
|
||||
argEdit = &model.EditSubtitleArg{
|
||||
Oid: target.Oid,
|
||||
SubtileID: target.Eid,
|
||||
Status: uint8(status),
|
||||
}
|
||||
// 容错
|
||||
if argEdit.Oid == 0 {
|
||||
continue
|
||||
}
|
||||
if err = s.editSubtitle(c, argEdit, false); err != nil {
|
||||
log.Error("s.EditSubtitle(arg:%+v),error(%v)", argEdit, err)
|
||||
err = nil // ignore error
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EditSubtitle .
|
||||
func (s *Service) EditSubtitle(c context.Context, arg *model.EditSubtitleArg) (err error) {
|
||||
return s.editSubtitle(c, arg, true)
|
||||
}
|
||||
|
||||
func (s *Service) editSubtitle(c context.Context, arg *model.EditSubtitleArg, removeWorkFlow bool) (err error) {
|
||||
// 更新表
|
||||
var (
|
||||
subtitle *model.Subtitle
|
||||
argStatus = model.SubtitleStatus(arg.Status)
|
||||
subtitleLans model.SubtitleLans
|
||||
sLans []*model.SubtitleLan
|
||||
err1 error
|
||||
lanDoc string
|
||||
archiveInfo *api.Arc
|
||||
archiveName string
|
||||
)
|
||||
if subtitle, err = s.dao.GetSubtitle(c, arg.Oid, arg.SubtileID); err != nil {
|
||||
log.Error("params(oid:%v,subtitleID:%v),error(%v)", arg.Oid, arg.SubtileID, err)
|
||||
return
|
||||
}
|
||||
if subtitle == nil {
|
||||
err = ecode.NothingFound
|
||||
return
|
||||
}
|
||||
if argStatus == subtitle.Status {
|
||||
err = ecode.SubtitleStatusUnValid
|
||||
return
|
||||
}
|
||||
if subtitle.Status != model.SubtitleStatusPublish && argStatus != model.SubtitleStatusPublish {
|
||||
arg.NotifyUpper = false
|
||||
}
|
||||
switch argStatus {
|
||||
case model.SubtitleStatusDraft, model.SubtitleStatusToAudit,
|
||||
model.SubtitleStatusAuditBack, model.SubtitleStatusRemove,
|
||||
model.SubtitleStatusPublish, model.SubtitleStatusManagerBack,
|
||||
model.SubtitleStatusManagerRemove:
|
||||
default:
|
||||
err = ecode.SubtitleStatusUnValid
|
||||
return
|
||||
}
|
||||
if err = s.changeSubtitleStatus(c, subtitle, argStatus); err != nil {
|
||||
log.Error("params(subtitle:%+v,status:%v),error(%v)", subtitle, arg.Status, err)
|
||||
return
|
||||
}
|
||||
if arg.NotifyAuthor || arg.NotifyUpper {
|
||||
if sLans, err1 = s.dao.SubtitleLans(c); err1 == nil {
|
||||
subtitleLans = model.SubtitleLans(sLans)
|
||||
}
|
||||
_, lanDoc = subtitleLans.GetByID(int64(subtitle.Lan))
|
||||
if archiveInfo, err1 = s.arcRPC.Archive3(c, &archiveMdl.ArgAid2{
|
||||
Aid: subtitle.Aid,
|
||||
}); err1 != nil {
|
||||
log.Error("s.arcRPC.Archive3(aid:%v),error(%v)", subtitle.Aid, err1)
|
||||
err1 = nil
|
||||
} else {
|
||||
archiveName = archiveInfo.Title
|
||||
}
|
||||
}
|
||||
if arg.NotifyAuthor {
|
||||
argUser := &model.NotifySubtitleUser{
|
||||
Mid: subtitle.Mid,
|
||||
Aid: subtitle.Aid,
|
||||
Oid: subtitle.Oid,
|
||||
SubtitleID: subtitle.ID,
|
||||
ArchiveName: archiveName,
|
||||
LanDoc: lanDoc,
|
||||
Status: model.StatusContent[uint8(subtitle.Status)],
|
||||
}
|
||||
if err1 = s.dao.SendMsgToSubtitleUser(c, argUser); err1 != nil {
|
||||
log.Error("SendMsgToSubtitleUser(argUser:%+v),error(%v)", argUser, err1)
|
||||
err1 = nil
|
||||
}
|
||||
}
|
||||
if arg.NotifyUpper {
|
||||
var (
|
||||
accountInfo *accountApi.InfoReply
|
||||
authorName string
|
||||
)
|
||||
if accountInfo, err1 = s.accountRPC.Info3(c, &accountApi.MidReq{
|
||||
Mid: subtitle.Mid,
|
||||
}); err1 != nil {
|
||||
log.Error("s.accRPC.Info3(mid:%v),error(%v)", subtitle.Mid, err1)
|
||||
err1 = nil
|
||||
} else {
|
||||
authorName = accountInfo.GetInfo().GetName()
|
||||
}
|
||||
argUp := &model.NotifySubtitleUp{
|
||||
Mid: subtitle.UpMid,
|
||||
AuthorID: subtitle.Mid,
|
||||
AuthorName: authorName,
|
||||
Aid: subtitle.Aid,
|
||||
Oid: subtitle.Oid,
|
||||
SubtitleID: subtitle.ID,
|
||||
ArchiveName: archiveName,
|
||||
LanDoc: lanDoc,
|
||||
Status: model.StatusContent[uint8(subtitle.Status)],
|
||||
}
|
||||
if err1 = s.dao.SendMsgToSubtitleUp(c, argUp); err1 != nil {
|
||||
log.Error("SendMsgToSubtitleUp(argUp:%+v),error(%v)", argUp, err1)
|
||||
err1 = nil
|
||||
}
|
||||
}
|
||||
if removeWorkFlow && (argStatus == model.SubtitleStatusRemove || argStatus == model.SubtitleStatusManagerRemove) {
|
||||
if err1 := s.dao.WorkFlowAppealDelete(c, _workFlowSubtitleBid, subtitle.Oid, subtitle.ID); err1 != nil {
|
||||
log.Error("s.dao.WorkFlowAppealDelete(oid:%v,subtitleID:%v),error(%v)", subtitle.Oid, subtitle.ID, err1)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TODO 确认状态扭转
|
||||
func (s *Service) changeSubtitleStatus(c context.Context, subtitle *model.Subtitle, status model.SubtitleStatus) (err error) {
|
||||
var (
|
||||
sc *model.SubtitleContext
|
||||
hasDraft bool
|
||||
)
|
||||
sc = &model.SubtitleContext{}
|
||||
sc.Build(subtitle.Status, status)
|
||||
subtitle.PubTime = time.Now().Unix()
|
||||
if sc.CheckHasDraft {
|
||||
if hasDraft, err = s.CheckHasDraft(c, subtitle); err != nil {
|
||||
log.Error("params(subtitle:%+v),error(%v)", subtitle, err)
|
||||
return
|
||||
}
|
||||
if hasDraft {
|
||||
err = ecode.SubtitleAlreadyHasDraft
|
||||
return
|
||||
}
|
||||
subtitle.PubTime = 0
|
||||
}
|
||||
subtitle.Status = status
|
||||
if sc.RebuildPub {
|
||||
if err = s.RebuildSubtitle(c, subtitle); err != nil {
|
||||
log.Error("RebuildSubtitle.params(subtitle:%+v),error(%v)", subtitle, err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err = s.dao.UpdateSubtitle(c, subtitle); err != nil {
|
||||
log.Error("UpdateSubtitle.params(subtitle:%+v),error(%v)", subtitle, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if sc.DraftCache {
|
||||
s.dao.DelSubtitleDraftCache(c, subtitle.Oid, subtitle.Type, subtitle.Mid, subtitle.Lan)
|
||||
}
|
||||
if sc.SubtitleCache {
|
||||
s.dao.DelSubtitleCache(c, subtitle.Oid, subtitle.ID)
|
||||
}
|
||||
if sc.RebuildPub {
|
||||
s.dao.DelVideoSubtitleCache(c, subtitle.Oid, subtitle.Type)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SubtitleList .
|
||||
func (s *Service) SubtitleList(c context.Context, arg *model.SubtitleArg) (res *model.SubtitleList, err error) {
|
||||
var (
|
||||
searchResult *model.SearchSubtitleResult
|
||||
oidSubtitleIds map[int64][]int64
|
||||
eg errgroup.Group
|
||||
lock sync.Mutex
|
||||
subtitleMap map[string]*model.Subtitle
|
||||
searchSubtitles []*model.SearchSubtitle
|
||||
searchSubtitle *model.SearchSubtitle
|
||||
subtitle *model.Subtitle
|
||||
ok bool
|
||||
aids []int64
|
||||
aidMap map[int64]struct{}
|
||||
archives map[int64]*api.Arc
|
||||
archive *api.Arc
|
||||
archiveVideo *api.Page
|
||||
subtitleLans model.SubtitleLans
|
||||
searchArg *model.SubtitleSearchArg
|
||||
)
|
||||
if arg.Ps > 100 {
|
||||
err = ecode.RequestErr
|
||||
return
|
||||
}
|
||||
key := func(oid, subtitleID int64) string {
|
||||
return fmt.Sprintf("%d_%d", oid, subtitleID)
|
||||
}
|
||||
if sLans, err1 := s.dao.SubtitleLans(c); err1 == nil {
|
||||
subtitleLans = model.SubtitleLans(sLans)
|
||||
}
|
||||
lanCode := subtitleLans.GetByLan(arg.Lan)
|
||||
searchArg = &model.SubtitleSearchArg{
|
||||
Aid: arg.Aid,
|
||||
Oid: arg.Oid,
|
||||
Mid: arg.Mid,
|
||||
UpperMid: arg.UpperMid,
|
||||
Status: arg.Status,
|
||||
Lan: uint8(lanCode),
|
||||
Ps: arg.Ps,
|
||||
Pn: arg.Pn,
|
||||
}
|
||||
if searchResult, err = s.dao.SearchSubtitle(c, searchArg); err != nil {
|
||||
log.Error("params(arg:%+v).error(%v)", arg, err)
|
||||
return
|
||||
}
|
||||
if searchResult == nil || len(searchResult.Result) == 0 {
|
||||
err = ecode.NothingFound
|
||||
return
|
||||
}
|
||||
oidSubtitleIds = make(map[int64][]int64)
|
||||
subtitleMap = make(map[string]*model.Subtitle)
|
||||
aidMap = make(map[int64]struct{})
|
||||
for _, r := range searchResult.Result {
|
||||
oidSubtitleIds[r.Oid] = append(oidSubtitleIds[r.Oid], r.ID)
|
||||
}
|
||||
for oid, subtitleIds := range oidSubtitleIds {
|
||||
tempOid := oid
|
||||
tempSubtitleIds := subtitleIds
|
||||
eg.Go(func() (err error) {
|
||||
var subtitles []*model.Subtitle
|
||||
if subtitles, err = s.dao.GetSubtitles(context.Background(), tempOid, tempSubtitleIds); err != nil {
|
||||
log.Error("params(oid:%v,subtitleIds:%+v).error(%v)", tempOid, tempSubtitleIds, err)
|
||||
return
|
||||
}
|
||||
for _, subtitle := range subtitles {
|
||||
lock.Lock()
|
||||
aidMap[subtitle.Aid] = struct{}{}
|
||||
subtitleMap[key(subtitle.Oid, subtitle.ID)] = subtitle
|
||||
lock.Unlock()
|
||||
}
|
||||
return
|
||||
})
|
||||
}
|
||||
if err = eg.Wait(); err != nil {
|
||||
return
|
||||
}
|
||||
for aid := range aidMap {
|
||||
aids = append(aids, aid)
|
||||
}
|
||||
if archives, err = s.arcRPC.Archives3(c, &archiveMdl.ArgAids2{
|
||||
Aids: aids,
|
||||
}); err != nil {
|
||||
log.Error("prams(aid:%v),error(%v)", aids, err)
|
||||
archives = make(map[int64]*api.Arc)
|
||||
err = nil
|
||||
}
|
||||
searchSubtitles = make([]*model.SearchSubtitle, 0, len(searchResult.Result))
|
||||
for _, r := range searchResult.Result {
|
||||
if subtitle, ok = subtitleMap[key(r.Oid, r.ID)]; !ok {
|
||||
continue
|
||||
}
|
||||
lan, lanDoc := subtitleLans.GetByID(int64(subtitle.Lan))
|
||||
searchSubtitle = &model.SearchSubtitle{
|
||||
ID: subtitle.ID,
|
||||
Oid: subtitle.Oid,
|
||||
Aid: subtitle.Aid,
|
||||
AuthorID: subtitle.Mid,
|
||||
Status: uint8(subtitle.Status),
|
||||
Lan: lan,
|
||||
LanDoc: lanDoc,
|
||||
IsSign: subtitle.IsSign,
|
||||
IsLock: subtitle.IsLock,
|
||||
Mtime: subtitle.Mtime,
|
||||
SubtitleURL: subtitle.SubtitleURL,
|
||||
}
|
||||
if archive, ok = archives[subtitle.Aid]; ok {
|
||||
searchSubtitle.ArchiveName = archive.Title
|
||||
}
|
||||
if archiveVideo, err = s.arcRPC.Video3(c, &archiveMdl.ArgVideo2{
|
||||
Aid: subtitle.Aid,
|
||||
Cid: subtitle.Oid,
|
||||
}); err != nil {
|
||||
log.Error("params(aid:%v,oid:%v) error(%v)", subtitle.Aid, subtitle.Oid, err)
|
||||
err = nil
|
||||
} else {
|
||||
searchSubtitle.VideoName = archiveVideo.Part
|
||||
}
|
||||
searchSubtitles = append(searchSubtitles, searchSubtitle)
|
||||
}
|
||||
res = &model.SubtitleList{
|
||||
Page: searchResult.Page,
|
||||
}
|
||||
res.Subtitles = searchSubtitles
|
||||
return
|
||||
}
|
82
app/admin/main/dm/service/subtitle_status.go
Normal file
82
app/admin/main/dm/service/subtitle_status.go
Normal file
@ -0,0 +1,82 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// SubtitleStatusList .
|
||||
func (s *Service) SubtitleStatusList(c context.Context) (res map[uint8]string, err error) {
|
||||
return model.StatusContent, nil
|
||||
}
|
||||
|
||||
// CheckHasDraft .
|
||||
func (s *Service) CheckHasDraft(c context.Context, subtitle *model.Subtitle) (ok bool, err error) {
|
||||
var (
|
||||
draftCount int64
|
||||
)
|
||||
if draftCount, err = s.dao.CountSubtitleDraft(c, subtitle.Oid, subtitle.Mid, subtitle.Lan, subtitle.Type); err != nil {
|
||||
log.Error("CheckHasDraft,params(subtitle:%+v),error(%v)", subtitle, err)
|
||||
return
|
||||
}
|
||||
if draftCount > 0 {
|
||||
ok = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// RebuildSubtitle .
|
||||
// need transtaion
|
||||
// 1、更新自身状态
|
||||
// 2、重新查询发布的字幕id,插入到发布表
|
||||
// 3、删除缓存
|
||||
func (s *Service) RebuildSubtitle(c context.Context, subtitle *model.Subtitle) (err error) {
|
||||
var (
|
||||
tx *sql.Tx
|
||||
subtitlePublishID int64
|
||||
subtitlePub *model.SubtitlePub
|
||||
)
|
||||
switch subtitle.Status {
|
||||
case model.SubtitleStatusDraft, model.SubtitleStatusToAudit:
|
||||
subtitle.PubTime = 0
|
||||
default:
|
||||
subtitle.PubTime = time.Now().Unix()
|
||||
}
|
||||
if tx, err = s.dao.BeginBiliDMTrans(c); err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
return
|
||||
}
|
||||
}()
|
||||
if err = s.dao.TxUpdateSubtitle(tx, subtitle); err != nil {
|
||||
log.Error("RebuildSubtitle.TxUpdateSubtitle(subtitle:%+v),error(%v)", subtitle, err)
|
||||
return
|
||||
}
|
||||
if subtitlePublishID, err = s.dao.TxGetSubtitleID(tx, subtitle.Oid, subtitle.Type, subtitle.Lan); err != nil {
|
||||
log.Error("RebuildSubtitle.TxGetSubtitleID(params:%+v),error(%v)", subtitle, err)
|
||||
return
|
||||
}
|
||||
subtitlePub = &model.SubtitlePub{
|
||||
Oid: subtitle.Oid,
|
||||
Type: subtitle.Type,
|
||||
Lan: subtitle.Lan,
|
||||
SubtitleID: subtitlePublishID,
|
||||
}
|
||||
if subtitlePublishID <= 0 {
|
||||
subtitlePub.IsDelete = true
|
||||
}
|
||||
if err = s.dao.TxUpdateSubtitlePub(tx, subtitlePub); err != nil {
|
||||
log.Error("RebuildSubtitle.TxUpdateSubtitlePub(subtitlePub:%+v),error(%v)", subtitlePub, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
52
app/admin/main/dm/service/subtitle_subject.go
Normal file
52
app/admin/main/dm/service/subtitle_subject.go
Normal file
@ -0,0 +1,52 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// SubtitleSwitch .
|
||||
func (s *Service) SubtitleSwitch(c context.Context, aid int64, allow bool, closed bool) (err error) {
|
||||
var (
|
||||
subtitleSubject *model.SubtitleSubject
|
||||
attr = model.AttrNo
|
||||
)
|
||||
if subtitleSubject, err = s.getSubtitleSubject(c, aid); err != nil {
|
||||
log.Error("SubtitleSwitch(aid:%v) error(%v)", aid, err)
|
||||
return
|
||||
}
|
||||
if subtitleSubject == nil {
|
||||
subtitleSubject = &model.SubtitleSubject{
|
||||
Aid: aid,
|
||||
}
|
||||
}
|
||||
subtitleSubject.Allow = allow
|
||||
if closed {
|
||||
attr = model.AttrYes
|
||||
}
|
||||
subtitleSubject.AttrSet(attr, model.AttrSubtitleClose)
|
||||
if err = s.addSubtitleSubject(c, subtitleSubject); err != nil {
|
||||
log.Error("SubtitleSwitch(subtitleSubject:%+v) error(%v)", subtitleSubject, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) getSubtitleSubject(c context.Context, aid int64) (subtitleSubject *model.SubtitleSubject, err error) {
|
||||
if subtitleSubject, err = s.dao.GetSubtitleSubject(c, aid); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) addSubtitleSubject(c context.Context, subtitleSubject *model.SubtitleSubject) (err error) {
|
||||
if err = s.dao.AddSubtitleSubject(c, subtitleSubject); err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.dao.DelSubtitleSubjectCache(c, subtitleSubject.Aid); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
261
app/admin/main/dm/service/task.go
Normal file
261
app/admin/main/dm/service/task.go
Normal file
@ -0,0 +1,261 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/xstr"
|
||||
)
|
||||
|
||||
var (
|
||||
_csvTaskTitle = []string{"dmid", "oid", "mid", "state", "msg", "ip", "ctime"}
|
||||
)
|
||||
|
||||
// TaskList .
|
||||
func (s *Service) TaskList(c context.Context, v *model.TaskListArg) (res *model.TaskList, err error) {
|
||||
taskSQL := make([]string, 0)
|
||||
if v.Creator != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("creator LIKE %q", "%"+v.Creator+"%"))
|
||||
}
|
||||
if v.Reviewer != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("reviewer LIKE %q", "%"+v.Reviewer+"%"))
|
||||
}
|
||||
if v.State >= 0 {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("state=%d", v.State))
|
||||
}
|
||||
if v.Title != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("title LIKE %q", "%"+v.Title+"%"))
|
||||
}
|
||||
if v.Ctime != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("ctime>=%q", v.Ctime))
|
||||
}
|
||||
tasks, total, err := s.dao.TaskList(c, taskSQL, v.Pn, v.Ps)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res = &model.TaskList{
|
||||
Result: tasks,
|
||||
Page: &model.PageInfo{
|
||||
Num: v.Pn,
|
||||
Size: v.Ps,
|
||||
Total: total,
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AddTask .
|
||||
func (s *Service) AddTask(c context.Context, v *model.AddTaskArg) (err error) {
|
||||
var taskID int64
|
||||
var sub int32
|
||||
tx, err := s.dao.BeginBiliDMTrans(c)
|
||||
if err != nil {
|
||||
log.Error("tx.BeginBiliDMTrans error(%v)", err)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if err1 := tx.Rollback(); err1 != nil {
|
||||
log.Error("tx.Rollback() error(%v)", err1)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = tx.Commit(); err != nil {
|
||||
log.Error("tx.Commit() error(%v)", err)
|
||||
}
|
||||
}()
|
||||
if v.Regex != "" {
|
||||
if len([]rune(v.Regex)) > model.TaskRegexLen {
|
||||
err = ecode.DMTaskRegexTooLong
|
||||
return
|
||||
}
|
||||
if _, err = regexp.Compile(v.Regex); err != nil {
|
||||
log.Error("regexp.Compile(v.Regex:%s) error(%v)", v.Regex, err)
|
||||
err = ecode.DMTaskRegexIllegal
|
||||
return
|
||||
}
|
||||
}
|
||||
if v.Operation >= 0 {
|
||||
sub = 1
|
||||
}
|
||||
if taskID, err = s.dao.AddTask(tx, v, sub); err != nil {
|
||||
return
|
||||
}
|
||||
if sub > 0 {
|
||||
_, err = s.dao.AddSubTask(tx, taskID, v.Operation, v.OpTime, v.OpRate)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ReviewTask .
|
||||
func (s *Service) ReviewTask(c context.Context, v *model.ReviewTaskArg) (err error) {
|
||||
if v.State == model.TaskReviewPass {
|
||||
var (
|
||||
task *model.TaskView
|
||||
sTime, eTime time.Time
|
||||
)
|
||||
if task, err = s.dao.TaskView(c, v.ID); err != nil {
|
||||
return
|
||||
}
|
||||
taskSQL := make([]string, 0)
|
||||
if task.Regex != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("content.msg regexp %q", task.Regex))
|
||||
}
|
||||
if task.KeyWords != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("content.msg like %q", "%"+task.KeyWords+"%"))
|
||||
}
|
||||
if task.IPs != "" {
|
||||
ips := xstr.JoinInts(ipsToInts(task.IPs))
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("content.ip in (%s)", ips))
|
||||
}
|
||||
if task.Mids != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("index.mid in (%s)", task.Mids))
|
||||
}
|
||||
if task.Cids != "" {
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("index.oid in (%s)", task.Cids))
|
||||
}
|
||||
if task.Start != "" {
|
||||
if sTime, err = time.ParseInLocation("2006-01-02 15:04:05", task.Start, time.Local); err != nil {
|
||||
return
|
||||
}
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("content.log_date>=%s", sTime.Format("20060102")))
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("content.ctime>=%q", task.Start))
|
||||
}
|
||||
if task.End != "" {
|
||||
if eTime, err = time.ParseInLocation("2006-01-02 15:04:05", task.End, time.Local); err != nil {
|
||||
return
|
||||
}
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("content.log_date<=%s", eTime.Format("20060102")))
|
||||
taskSQL = append(taskSQL, fmt.Sprintf("content.ctime<=%q", task.End))
|
||||
}
|
||||
if v.Topic, err = s.dao.SendTask(c, taskSQL); err != nil {
|
||||
// err = nil
|
||||
// v.State = model.TaskStateFailed
|
||||
return
|
||||
}
|
||||
}
|
||||
_, err = s.dao.ReviewTask(c, v)
|
||||
return
|
||||
}
|
||||
|
||||
// EditTaskState .
|
||||
func (s *Service) EditTaskState(c context.Context, v *model.EditTasksStateArg) (err error) {
|
||||
if _, err = s.dao.EditTaskState(c, v); err != nil {
|
||||
return
|
||||
}
|
||||
if v.State == model.TaskStateRun {
|
||||
_, err = s.dao.EditTaskPriority(c, v.IDs, time.Now().Unix())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TaskView .
|
||||
func (s *Service) TaskView(c context.Context, v *model.TaskViewArg) (task *model.TaskView, err error) {
|
||||
if task, err = s.dao.TaskView(c, v.ID); err != nil || task == nil {
|
||||
return
|
||||
}
|
||||
if task.SubTask, err = s.dao.SubTask(c, task.ID); err != nil || task.SubTask == nil {
|
||||
return
|
||||
}
|
||||
task.Tcount = task.SubTask.Tcount
|
||||
return
|
||||
}
|
||||
|
||||
// TaskCsv .
|
||||
func (s *Service) TaskCsv(c context.Context, id int64) (bs []byte, err error) {
|
||||
var (
|
||||
task *model.TaskView
|
||||
buf *bytes.Buffer
|
||||
csvWriter *csv.Writer
|
||||
)
|
||||
if task, err = s.dao.TaskView(c, id); err != nil {
|
||||
return
|
||||
}
|
||||
if task == nil || len(task.Result) == 0 {
|
||||
err = ecode.NothingFound
|
||||
return
|
||||
}
|
||||
res, err := http.Get(task.Result)
|
||||
if err != nil {
|
||||
log.Error("s.HttpGet(%s) error(%v)", task.Result, err)
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
err = ecode.NothingFound
|
||||
return
|
||||
}
|
||||
resp, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
log.Error("s.ioutilRead error(%v)", err)
|
||||
return
|
||||
}
|
||||
buf = &bytes.Buffer{}
|
||||
csvWriter = csv.NewWriter(buf)
|
||||
if err = csvWriter.Write(_csvTaskTitle); err != nil {
|
||||
log.Error("csvWriter.Write(%v) erorr(%v)", _csvTaskTitle, err)
|
||||
return
|
||||
}
|
||||
lines := bytes.Split(resp, []byte("\n"))
|
||||
if len(lines) == 0 {
|
||||
err = ecode.NothingFound
|
||||
return
|
||||
}
|
||||
for _, line := range lines {
|
||||
var (
|
||||
items []string
|
||||
)
|
||||
fields := bytes.Split(line, []byte("\001"))
|
||||
if len(fields) < 7 {
|
||||
log.Error("fields lenth too small:%d", len(fields))
|
||||
continue
|
||||
}
|
||||
for _, field := range fields {
|
||||
items = append(items, string(field))
|
||||
}
|
||||
if err = csvWriter.Write(items); err != nil {
|
||||
log.Error("csvWriter.Write(%v) erorr(%v)", items, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
csvWriter.Flush()
|
||||
if err = csvWriter.Error(); err != nil {
|
||||
log.Error("csvWriter.Error(%v)", err)
|
||||
return
|
||||
}
|
||||
bs = buf.Bytes()
|
||||
if len(bs) == 0 {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ipsToInts(ips string) (ipInts []int64) {
|
||||
ipStrs := strings.Split(ips, ",")
|
||||
ipInts = make([]int64, 0, len(ipStrs))
|
||||
for _, ipStr := range ipStrs {
|
||||
ipInts = append(ipInts, ipToInt(ipStr))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ipToInt(ip string) (ipInt int64) {
|
||||
ret := big.NewInt(0)
|
||||
if net.ParseIP(ip) == nil {
|
||||
return
|
||||
}
|
||||
ret.SetBytes(net.ParseIP(ip).To4())
|
||||
return ret.Int64()
|
||||
}
|
108
app/admin/main/dm/service/task_test.go
Normal file
108
app/admin/main/dm/service/task_test.go
Normal file
@ -0,0 +1,108 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestServiceTaskList(t *testing.T) {
|
||||
convey.Convey("TaskList", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
v = &model.TaskListArg{
|
||||
Pn: 1,
|
||||
Ps: 10,
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
res, err := svr.TaskList(c, v)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(res, convey.ShouldNotBeNil)
|
||||
for _, v := range res.Result {
|
||||
t.Logf("=====%+v", v)
|
||||
}
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceAddTask(t *testing.T) {
|
||||
convey.Convey("AddTask", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
v = &model.AddTaskArg{
|
||||
IPs: "172.1.1.1",
|
||||
Start: "2016-10-30 16:12:21",
|
||||
End: "2018-10-30 16:12:21",
|
||||
OpTime: "2018-10-30 16:12:21",
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := svr.AddTask(c, v)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceEditTaskState(t *testing.T) {
|
||||
convey.Convey("EditTaskState", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
v = &model.EditTasksStateArg{
|
||||
IDs: "7",
|
||||
State: 3,
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := svr.EditTaskState(c, v)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceTaskView(t *testing.T) {
|
||||
convey.Convey("TaskView", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
v = &model.TaskViewArg{
|
||||
ID: int64(7),
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
task, err := svr.TaskView(c, v)
|
||||
ctx.Convey("Then err should be nil.task should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(task, convey.ShouldNotBeNil)
|
||||
t.Logf("====%+v\n", task)
|
||||
t.Logf("====%+v", task.SubTask)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceReviewTask(t *testing.T) {
|
||||
convey.Convey("ReviewTask", t, func(ctx convey.C) {
|
||||
var (
|
||||
c = context.Background()
|
||||
v = &model.ReviewTaskArg{
|
||||
ID: 21,
|
||||
}
|
||||
)
|
||||
ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
err := svr.ReviewTask(c, v)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
78
app/admin/main/dm/service/transfer.go
Normal file
78
app/admin/main/dm/service/transfer.go
Normal file
@ -0,0 +1,78 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go-common/app/admin/main/dm/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// AddTransferJob add job
|
||||
func (s *Service) AddTransferJob(c context.Context, from, to, mid int64, offset float64, state int8) (err error) {
|
||||
_, err = s.dao.InsertTransferJob(c, from, to, mid, offset, 0)
|
||||
if err != nil {
|
||||
log.Error("s.dao.InsertTransferJob(%d, %d %d %f) error(%v)", from, to, mid, offset, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TransferList transfer list
|
||||
func (s *Service) TransferList(c context.Context, cid, state, pn, ps int64) (res []*model.TransList, total int64, err error) {
|
||||
var (
|
||||
aids []int64
|
||||
cids []int64
|
||||
)
|
||||
if res, total, err = s.dao.TransferList(c, cid, state, pn, ps); err != nil {
|
||||
log.Error("s.dao.TransferList(%d, %d) error(%v)", cid, state, err)
|
||||
return
|
||||
}
|
||||
if len(res) <= 0 {
|
||||
return
|
||||
}
|
||||
for _, idx := range res {
|
||||
cids = append(cids, idx.From)
|
||||
}
|
||||
subs, err := s.dao.Subjects(c, model.SubTypeVideo, cids)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, idx := range subs {
|
||||
aids = append(aids, idx.Pid)
|
||||
}
|
||||
avm, err := s.dao.ArchiveVideos(c, aids)
|
||||
if err != nil {
|
||||
log.Error("s.dao.ArchiveInfo(aid:%v) error(%v)", aids, err)
|
||||
return
|
||||
}
|
||||
for _, idx := range res {
|
||||
sub, ok := subs[idx.From]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
info, ok := avm[sub.Pid] // get archive info
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
idx.Title = info.Archive.Title
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ReTransferJob retransfer job
|
||||
func (s *Service) ReTransferJob(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.SetTransferState(id:%d,state:%d) err(%v)", id, model.TransferJobStatInit, err)
|
||||
}
|
||||
return
|
||||
}
|
41
app/admin/main/dm/service/transfer_test.go
Normal file
41
app/admin/main/dm/service/transfer_test.go
Normal file
@ -0,0 +1,41 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestAddTransferJob(t *testing.T) {
|
||||
var (
|
||||
mid int64 = 27515615
|
||||
from int64 = 10108765
|
||||
to int64 = 10108763
|
||||
offset = 1.01
|
||||
state int8
|
||||
)
|
||||
Convey("test TransferJob", t, func() {
|
||||
err := svr.AddTransferJob(context.TODO(), from, to, mid, offset, state)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTransferList(t *testing.T) {
|
||||
Convey("test transfer list", t, func() {
|
||||
res, _, err := svr.TransferList(context.TODO(), 10109082, 3, 1, 20)
|
||||
So(err, ShouldBeNil)
|
||||
So(res, ShouldNotBeEmpty)
|
||||
})
|
||||
}
|
||||
|
||||
func TestReTransferJob(t *testing.T) {
|
||||
Convey("test transfer retry", t, func() {
|
||||
err := svr.ReTransferJob(context.TODO(), 256, 1)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
Convey("test transfer retry fail", t, func() {
|
||||
err := svr.ReTransferJob(context.TODO(), 256, 1)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user