Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

104
app/admin/main/dm/dao/BUILD Normal file
View File

@@ -0,0 +1,104 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"account_test.go",
"credit_test.go",
"dao_test.go",
"mask_test.go",
"mc_filter_test.go",
"mc_subtitle_test.go",
"message_test.go",
"mysql_advance_test.go",
"mysql_filter_test.go",
"mysql_mask_test.go",
"mysql_report_test.go",
"mysql_subtitle_test.go",
"mysql_task_test.go",
"mysql_test.go",
"mysql_transfer_test.go",
"search_subtitle_test.go",
"search_test.go",
"task_test.go",
"videoup_test.go",
"workflow_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",
"//library/log:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"account.go",
"bfs.go",
"credit.go",
"dao.go",
"mask.go",
"mc_filter.go",
"mc_subtitle.go",
"message.go",
"mysql.go",
"mysql_advance.go",
"mysql_filter.go",
"mysql_mask.go",
"mysql_report.go",
"mysql_subtitle.go",
"mysql_task.go",
"mysql_transfer.go",
"search.go",
"search_subtitle.go",
"task.go",
"videoup.go",
"workflow.go",
],
importpath = "go-common/app/admin/main/dm/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/dm/conf:go_default_library",
"//app/admin/main/dm/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/bfs:go_default_library",
"//library/database/elastic:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//library/queue/databus:go_default_library",
"//library/sync/errgroup: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",
"//app/admin/main/dm/dao/oplog:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,136 @@
package dao
import (
"context"
"fmt"
"math"
"net/url"
"time"
"go-common/app/admin/main/dm/model"
"go-common/library/log"
)
const (
_addMoral = "/api/moral/add"
_blockUser = "/x/internal/block/block"
_blockInfoAdd = "/x/internal/credit/blocked/info/add"
_blockArea = "2"
_blockSource = "1"
_blockForever = "2"
_blockTimeLimit = "1"
)
// ReduceMoral change moral
func (d *Dao) ReduceMoral(c context.Context, moral *model.ReduceMoral) (err error) {
var (
res = &struct {
Code int64 `json:"code"`
Morals map[int64]float64 `json:"morals"`
}{}
)
params := url.Values{}
params.Set("mid", fmt.Sprint(moral.UID))
params.Set("addMoral", fmt.Sprint(-math.Abs(float64(moral.Moral))))
params.Set("origin", "2")
params.Set("reason", model.AdminRptReason[moral.Reason])
params.Set("reason_type", "1")
params.Set("operater", moral.Operator)
params.Set("is_notify", fmt.Sprint(moral.IsNotify))
params.Set("remark", moral.Remark)
err = d.httpCli.Get(c, d.addMoralURI, "", params, res)
if err != nil {
log.Error("d.httpCli.Get(%s) error(%v)", d.addMoralURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpCli.Get(%s) error(%v)", d.addMoralURI+"?"+params.Encode(), err)
}
return
}
// BlockUser block user
func (d *Dao) BlockUser(c context.Context, blu *model.BlockUser) (err error) {
if err = d.blockUser(c, blu); err != nil {
return
}
if err = d.blockInfoAdd(c, blu); err != nil {
return
}
return
}
func (d *Dao) blockUser(c context.Context, blu *model.BlockUser) (err error) {
var (
res = new(struct {
Code int `json:"data"`
})
params = url.Values{}
)
params.Set("mid", fmt.Sprint(blu.UID))
params.Set("source", _blockSource)
params.Set("area", _blockArea)
if blu.BlockForever == 1 {
params.Set("action", _blockForever)
} else {
params.Set("action", _blockTimeLimit)
}
params.Set("duration", fmt.Sprint(blu.BlockTimeLength*24*3600))
params.Set("start_time", fmt.Sprint(time.Now().Unix()))
params.Set("operator", blu.Operator)
params.Set("reason", fmt.Sprint(blu.ReasonType))
params.Set("comment", blu.BlockRemark)
params.Set("notify", "0")
err = d.httpCli.Post(c, d.blockUserURI, "", params, res)
if err != nil {
log.Error("d.httpCli.Post(%s) error(%v)", d.blockUserURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpCli.Post(%s) error(%v)", d.blockUserURI+"?"+params.Encode(), err)
}
return
}
func (d *Dao) blockInfoAdd(c context.Context, blu *model.BlockUser) (err error) {
var (
res = new(struct {
Code int `json:"data"`
})
params = url.Values{}
)
params.Set("mid", fmt.Sprint(blu.UID))
if blu.BlockForever == 1 {
params.Set("blocked_forever", "1")
params.Set("punish_type", "3")
} else {
params.Set("blocked_forever", "0")
params.Set("punish_type", "2")
if blu.BlockTimeLength == 0 {
params.Set("punish_type", "1")
}
}
params.Set("blocked_days", fmt.Sprint(blu.BlockTimeLength))
params.Set("blocked_remark", blu.BlockRemark)
params.Set("moral_num", fmt.Sprint(blu.Moral))
params.Set("origin_content", fmt.Sprint(blu.OriginContent))
params.Set("origin_title", fmt.Sprint(blu.OriginTitle))
params.Set("origin_type", fmt.Sprint(blu.OriginType))
params.Set("origin_url", fmt.Sprint(blu.OriginURL))
params.Set("punish_time", fmt.Sprint(time.Now().Unix()))
params.Set("reason_type", fmt.Sprint(blu.ReasonType))
params.Set("operator_name", blu.Operator)
err = d.httpCli.Post(c, d.blockInfoAddURI, "", params, res)
if err != nil {
log.Error("d.httpCli.Post(%s) error(%v)", d.blockInfoAddURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpCli.Post(%s) error(%v)", d.blockInfoAddURI+"?"+params.Encode(), err)
}
return
}

View File

@@ -0,0 +1,69 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/dm/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestReduceMoral(t *testing.T) {
arg := &model.ReduceMoral{
UID: 150781,
Moral: -1,
Origin: 2,
Reason: 1,
ReasonType: 1,
Operator: "zhang",
IsNotify: 1,
Remark: "dm admin test",
}
Convey("", t, func() {
err := testDao.ReduceMoral(context.TODO(), arg)
So(err, ShouldBeNil)
})
}
func TestBlockUser1(t *testing.T) {
arg := &model.BlockUser{
UID: 150781,
BlockForever: 1,
BlockTimeLength: 0,
BlockRemark: model.BlockReason[5],
ReasonType: 5,
Operator: "zhang",
OriginType: 2,
Moral: 10,
OriginURL: "aaaaa",
OriginContent: "test delete1",
OriginTitle: "test title",
IsNotify: 0,
}
Convey("", t, func() {
err := testDao.BlockUser(context.TODO(), arg)
So(err, ShouldBeNil)
})
}
func TestBlockUser2(t *testing.T) {
arg := &model.BlockUser{
UID: 150781,
BlockForever: 0,
BlockTimeLength: 5,
BlockRemark: model.BlockReason[5],
ReasonType: 5,
Operator: "zhang",
OriginType: 2,
Moral: 10,
OriginURL: "aaaaa",
OriginContent: "test delete2",
OriginTitle: "test title",
IsNotify: 0,
}
Convey("", t, func() {
err := testDao.BlockUser(context.TODO(), arg)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,21 @@
package dao
import (
"context"
"go-common/library/database/bfs"
"go-common/library/log"
)
// Upload .
func (d *Dao) Upload(c context.Context, bucket, fileName, contentType string, file []byte) (err error) {
if _, err = d.bfsCli.Upload(c, &bfs.Request{
Bucket: bucket,
ContentType: contentType,
Filename: fileName,
File: file,
}); err != nil {
log.Error("Upload(err:%v)", err)
}
return
}

View File

@@ -0,0 +1,39 @@
package dao
import (
"context"
"encoding/json"
"fmt"
"net/url"
"go-common/app/admin/main/dm/model"
"go-common/library/log"
)
const (
_sendJudge = "/x/internal/credit/blocked/case/add"
)
// SendJudgement send to judgement
func (d *Dao) SendJudgement(c context.Context, judges []*model.ReportJudge) (err error) {
params := url.Values{}
ret := struct {
Code int64 `json:"code"`
Message string `json:"message"`
}{}
data, err := json.Marshal(judges)
if err != nil {
log.Error("send judgement params(%s) create error(%v)", data, err)
return
}
params.Set("data", string(data))
if err = d.httpCli.Post(c, d.sendJudgeURI, "", params, &ret); err != nil {
log.Error("send judgement request(data: %s) error(%v)", data, err)
return
}
if ret.Code != 0 {
err = fmt.Errorf("%v", ret)
log.Error("send judgement request(data: %s) error(%v)", data, err)
}
return
}

View File

@@ -0,0 +1 @@
package dao

View File

@@ -0,0 +1,117 @@
package dao
import (
"context"
"go-common/app/admin/main/dm/conf"
"go-common/app/admin/main/dm/model"
"go-common/library/cache/memcache"
"go-common/library/database/bfs"
"go-common/library/database/elastic"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/queue/databus"
)
// Dao dao layer.
type Dao struct {
actionPub *databus.Databus
// http
httpSearch *bm.Client
httpCli *bm.Client
// mysql
dmMetaWriter *sql.DB
dmMetaReader *sql.DB
biliDM *sql.DB
// memcache
filterMC *memcache.Pool
// subtitle mc
subtitleMC *memcache.Pool
// elastic client
esCli *elastic.Elastic
// bfs client
bfsCli *bfs.BFS
// http uri
sendNotifyURI string
addMoralURI string
blockUserURI string
blockInfoAddURI string
sendJudgeURI string
viewsURI string
typesURI string
seasonURI string
maskURI string
workFlowURI string
berserkerURI string
}
// New new a dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
actionPub: databus.New(c.ActionPub),
// mysql
dmMetaWriter: sql.NewMySQL(c.DB.DMMetaWriter),
dmMetaReader: sql.NewMySQL(c.DB.DMMetaReader),
biliDM: sql.NewMySQL(c.DB.DM),
// memcache
filterMC: memcache.NewPool(c.Memcache.Filter.Config),
subtitleMC: memcache.NewPool(c.Memcache.Subtitle.Config),
// elastic client
esCli: elastic.NewElastic(c.Elastic),
// http client
sendNotifyURI: c.Host.Message + _sendNotify,
addMoralURI: c.Host.Account + _addMoral,
blockUserURI: c.Host.API + _blockUser,
blockInfoAddURI: c.Host.API + _blockInfoAdd,
sendJudgeURI: c.Host.API + _sendJudge,
viewsURI: c.Host.Videoup + _views,
typesURI: c.Host.Videoup + _types,
seasonURI: c.Host.Season + _season,
maskURI: c.Host.Mask + _mask,
berserkerURI: c.Host.Berserker,
workFlowURI: c.Host.API + _workFlowAppealDelete,
httpCli: bm.NewClient(c.HTTPClient.ClientConfig),
httpSearch: bm.NewClient(c.HTTPSearch.ClientConfig),
bfsCli: bfs.New(c.BFS),
}
return
}
// SendAction send action to job.
func (d *Dao) SendAction(c context.Context, k string, action *model.Action) (err error) {
if err = d.actionPub.Send(c, k, action); err != nil {
log.Error("actionPub.Send(action:%s,data:%s) error(%v)", action.Action, action.Data, err)
} else {
log.Info("actionPub.Send(action:%s,data:%s) success", action.Action, action.Data)
}
return
}
//BeginBiliDMTrans begin a transsaction of biliDM
func (d *Dao) BeginBiliDMTrans(c context.Context) (*sql.Tx, error) {
return d.biliDM.Begin(c)
}
// Ping ping success.
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.dmMetaWriter.Ping(c); err != nil {
log.Error("d.dmMetaWriter error(%v)", err)
return
}
if err = d.dmMetaReader.Ping(c); err != nil {
log.Error("d.dmMetaReader error(%v)", err)
return
}
if err = d.biliDM.Ping(c); err != nil {
log.Error("d.biliDM error(%v)", err)
}
// mc
filterMC := d.filterMC.Get(c)
defer filterMC.Close()
if err = filterMC.Set(&memcache.Item{Key: "ping", Value: []byte("pong"), Expiration: 0}); err != nil {
log.Error("filterMC.Set error(%v)", err)
return
}
return
}

View File

@@ -0,0 +1,32 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/admin/main/dm/conf"
"go-common/library/log"
)
var testDao *Dao
func TestMain(m *testing.M) {
flag.Set("app_id", "main.community.dm-admin")
flag.Set("conf_token", "dk9fifw9DT7wyCyrdMF0Qw9pQqUnuyIS")
flag.Set("tree_id", "2293")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
log.Init(conf.Conf.Xlog)
defer log.Close()
testDao = New(conf.Conf)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,57 @@
package dao
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"go-common/library/log"
)
const _mask = "/dl/api/masks/v1"
// GenerateMask ask AI to generate dm mask
func (d *Dao) GenerateMask(c context.Context, cid, mid int64, plat int8, force int8, aid int64, duration int64, typeID int32) (err error) {
var (
res struct {
Code int64 `json:"errcode"`
Message string `json:"errmsg"`
}
params = make(map[string]interface{})
)
params["cid"] = cid
params["mask_platform"] = plat
params["force"] = force
params["mid"] = mid
params["aid"] = aid
params["duration"] = duration
params["region_2"] = typeID
data, err := json.Marshal(params)
if err != nil {
log.Error("json.Marshal(%v) error(%v)", params, err)
return
}
reader := bytes.NewReader(data)
req, err := http.NewRequest("POST", d.maskURI, reader)
if err != nil {
log.Error("http.NewRequest error(%v)", err)
return
}
req.Header.Set("Content-Type", "application/json")
for i := 0; i < 3; i++ {
if err = d.httpCli.Do(c, req, &res); err != nil {
continue
}
if res.Code != 200 {
err = fmt.Errorf("uri:%s,code:%d", d.maskURI, res.Code)
continue
}
break
}
if err != nil {
log.Error("d.GenerateMask(cid:%d, plat:%d) error(%v)", cid, plat, err)
}
return
}

View File

@@ -0,0 +1,14 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestGenerateMask(t *testing.T) {
Convey("Test generate mask", t, func() {
testDao.GenerateMask(context.TODO(), 32, 11, 1, 0, 0, 0, 0)
})
}

View File

@@ -0,0 +1,32 @@
package dao
import (
"context"
"go-common/library/cache/memcache"
"go-common/library/log"
"strconv"
)
const _prefixUpFilter = "filter_up_"
func keyUpFilter(mid, oid int64) string {
return _prefixUpFilter + strconv.FormatInt(mid, 10) + "_" + strconv.FormatInt(oid, 10)
}
// DelUpFilterCache delete up filters from cache.
func (d *Dao) DelUpFilterCache(c context.Context, mid, oid int64) (err error) {
key := keyUpFilter(mid, oid)
conn := d.filterMC.Get(c)
err = conn.Delete(key)
conn.Close()
if err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("memcache.Delete(%s) error(%v)", key, err)
}
}
return
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaokeyUpFilter(t *testing.T) {
convey.Convey("keyUpFilter", t, func(ctx convey.C) {
var (
mid = int64(0)
oid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := keyUpFilter(mid, oid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDelUpFilterCache(t *testing.T) {
convey.Convey("DelUpFilterCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(0)
oid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.DelUpFilterCache(c, mid, oid)
})
})
}

View File

@@ -0,0 +1,100 @@
package dao
import (
"context"
"fmt"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_fmtSubtitle = "s_subtitle_%d_%d"
_fmtVideoSubtitle = "s_video_%d_%d"
_fmtSubtitleDraft = "s_draft_%v_%v_%v_%v"
_fmtSubtitleSubject = "s_subtitle_allow_%d"
)
func (d *Dao) subtitleKey(oid int64, subtitleID int64) string {
return fmt.Sprintf(_fmtSubtitle, oid, subtitleID)
}
func (d *Dao) subtitleVideoKey(oid int64, tp int32) string {
return fmt.Sprintf(_fmtVideoSubtitle, oid, tp)
}
func (d *Dao) subtitleDraftKey(oid int64, tp int32, mid int64, lan uint8) string {
return fmt.Sprintf(_fmtSubtitleDraft, oid, tp, mid, lan)
}
func (d *Dao) subtitleSubjectKey(aid int64) string {
return fmt.Sprintf(_fmtSubtitleSubject, aid)
}
// DelVideoSubtitleCache .
func (d *Dao) DelVideoSubtitleCache(c context.Context, oid int64, tp int32) (err error) {
var (
key = d.subtitleVideoKey(oid, tp)
conn = d.subtitleMC.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("memcache.Delete(%s) error(%v)", key, err)
}
}
return
}
// DelSubtitleDraftCache .
func (d *Dao) DelSubtitleDraftCache(c context.Context, oid int64, tp int32, mid int64, lan uint8) (err error) {
var (
key = d.subtitleDraftKey(oid, tp, mid, lan)
conn = d.subtitleMC.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("memcache.Delete(%s) error(%v)", key, err)
}
}
return
}
// DelSubtitleCache .
func (d *Dao) DelSubtitleCache(c context.Context, oid int64, subtitleID int64) (err error) {
var (
key = d.subtitleKey(oid, subtitleID)
conn = d.subtitleMC.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("memcache.Delete(%s) error(%v)", key, err)
}
}
return
}
// DelSubtitleSubjectCache .
func (d *Dao) DelSubtitleSubjectCache(c context.Context, aid int64) (err error) {
var (
key = d.subtitleSubjectKey(aid)
conn = d.subtitleMC.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("memcache.Delete(%s) error(%v)", key, err)
}
}
return
}

View File

@@ -0,0 +1,122 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaosubtitleKey(t *testing.T) {
convey.Convey("subtitleKey", t, func(ctx convey.C) {
var (
oid = int64(0)
subtitleID = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := testDao.subtitleKey(oid, subtitleID)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaosubtitleVideoKey(t *testing.T) {
convey.Convey("subtitleVideoKey", t, func(ctx convey.C) {
var (
oid = int64(0)
tp = int32(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := testDao.subtitleVideoKey(oid, tp)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaosubtitleDraftKey(t *testing.T) {
convey.Convey("subtitleDraftKey", t, func(ctx convey.C) {
var (
oid = int64(0)
tp = int32(0)
mid = int64(0)
lan = uint8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := testDao.subtitleDraftKey(oid, tp, mid, lan)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaosubtitleSubjectKey(t *testing.T) {
convey.Convey("subtitleSubjectKey", t, func(ctx convey.C) {
var (
aid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := testDao.subtitleSubjectKey(aid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDelVideoSubtitleCache(t *testing.T) {
convey.Convey("DelVideoSubtitleCache", t, func(ctx convey.C) {
var (
c = context.Background()
oid = int64(0)
tp = int32(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.DelVideoSubtitleCache(c, oid, tp)
})
})
}
func TestDaoDelSubtitleDraftCache(t *testing.T) {
convey.Convey("DelSubtitleDraftCache", t, func(ctx convey.C) {
var (
c = context.Background()
oid = int64(0)
tp = int32(0)
mid = int64(0)
lan = uint8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.DelSubtitleDraftCache(c, oid, tp, mid, lan)
})
})
}
func TestDaoDelSubtitleCache(t *testing.T) {
convey.Convey("DelSubtitleCache", t, func(ctx convey.C) {
var (
c = context.Background()
oid = int64(0)
subtitleID = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.DelSubtitleCache(c, oid, subtitleID)
})
})
}
func TestDaoDelSubtitleSubjectCache(t *testing.T) {
convey.Convey("DelSubtitleSubjectCache", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.DelSubtitleSubjectCache(c, aid)
})
})
}

View File

@@ -0,0 +1,181 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/app/admin/main/dm/model"
"go-common/library/log"
)
const (
_sendNotify = "/api/notify/send.user.notify.do"
_msgReporterTitle = "举报处理结果通知"
_msgPosterTitle = "弹幕违规处理通知"
_msgReporterKey = "1_6_4"
_msgPosterKey = "1_6_5"
_msgSubtitleTitle = "字幕状态变更"
_msgSubtitleUpKey = "1_6_8"
_msgSubtitleUserKey = "1_6_7"
)
type msgReturn struct {
Code int64 `json:"code"`
Ts interface{} `json:"ts"`
Data *struct {
Mc string `json:"mc"`
DataType int8 `json:"data_type"`
TotalCount int64 `json:"total_count"`
ErrorCount int64 `json:"error_count"`
ErrorMids []int64 `json:"error_mid_list"`
} `json:"data"`
}
// SendMsgToReporter send message
func (d *Dao) SendMsgToReporter(c context.Context, rptMsg *model.ReportMsg) (err error) {
var (
res = &msgReturn{}
)
params := url.Values{}
params.Set("mc", _msgReporterKey)
params.Set("title", _msgReporterTitle)
params.Set("data_type", "4")
params.Set("context", d.createReportContent(rptMsg))
params.Set("mid_list", rptMsg.Uids)
err = d.httpCli.Post(c, d.sendNotifyURI, "", params, res)
if err != nil {
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
}
return
}
func (d *Dao) createReportContent(rptMsg *model.ReportMsg) (content string) {
if rptMsg.State == model.StatSecondAutoDelete ||
rptMsg.State == model.StatFirstDelete ||
rptMsg.State == model.StatSecondDelete {
if rptMsg.Block != 0 { // 如果未封禁
content = fmt.Sprintf(model.RptTemplate["del"], rptMsg.Title, rptMsg.Aid, rptMsg.Msg, ",该用户已被封禁", model.BlockReason[rptMsg.BlockReason])
} else {
content = fmt.Sprintf(model.RptTemplate["del"], rptMsg.Title, rptMsg.Aid, rptMsg.Msg, "", model.AdminRptReason[rptMsg.RptReason])
}
} else {
content = fmt.Sprintf(model.RptTemplate["ignore"], rptMsg.Title, rptMsg.Aid, rptMsg.Msg)
}
return
}
// SendMsgToPoster send message
func (d *Dao) SendMsgToPoster(c context.Context, rptMsg *model.ReportMsg) (err error) {
var (
res = &msgReturn{}
)
params := url.Values{}
params.Set("mc", _msgPosterKey)
params.Set("title", _msgPosterTitle)
params.Set("data_type", "4")
msgContent, err := d.createPosterContent(rptMsg)
if err != nil {
log.Error("d.SendMsgToPoster error(%v)", err)
return
}
params.Set("context", msgContent)
params.Set("mid_list", rptMsg.Uids)
err = d.httpCli.Post(c, d.sendNotifyURI, "", params, res)
if err != nil {
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
}
return
}
func (d *Dao) createPosterContent(rptMsg *model.ReportMsg) (content string, err error) {
var (
part1, part2, tmpl string
)
if rptMsg.Block > 0 {
part1 = fmt.Sprintf(",并被封禁%d天", rptMsg.Block)
part2 = model.BlockReason[rptMsg.BlockReason]
tmpl, err = model.PosterBlockMsg(rptMsg.BlockReason)
if err != nil {
log.Error("reportModel.PosterBlockMsg error(%v)", err)
return
}
content = fmt.Sprintf(tmpl, rptMsg.Title, rptMsg.Aid, rptMsg.Msg, part1, part2)
} else if rptMsg.Block == -1 {
part1 = ",并被永久封禁"
part2 = model.BlockReason[rptMsg.BlockReason]
tmpl, err = model.PosterBlockMsg(rptMsg.BlockReason)
if err != nil {
log.Error("reportModel.PosterBlockMsg error(%v)", err)
return
}
content = fmt.Sprintf(tmpl, rptMsg.Title, rptMsg.Aid, rptMsg.Msg, part1, part2)
} else {
part1 = ""
part2 = model.AdminRptReason[rptMsg.RptReason]
tmpl, err = model.PosterAdminRptMsg(rptMsg.RptReason)
if err != nil {
log.Error("report.PosterAdminRptMsg error(%v)", err)
return
}
content = fmt.Sprintf(tmpl, rptMsg.Title, rptMsg.Aid, rptMsg.Msg, part1, part2)
}
return
}
// SendMsgToSubtitleUp .
func (d *Dao) SendMsgToSubtitleUp(c context.Context, arg *model.NotifySubtitleUp) (err error) {
var (
res = &msgReturn{}
)
params := url.Values{}
params.Set("mc", _msgSubtitleUpKey)
params.Set("title", _msgSubtitleTitle)
params.Set("data_type", "4")
params.Set("context", arg.Msg())
params.Set("mid_list", fmt.Sprint(arg.Mid))
err = d.httpCli.Post(c, d.sendNotifyURI, "", params, res)
if err != nil {
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
}
return
}
// SendMsgToSubtitleUser .
func (d *Dao) SendMsgToSubtitleUser(c context.Context, arg *model.NotifySubtitleUser) (err error) {
var (
res = &msgReturn{}
)
params := url.Values{}
params.Set("mc", _msgSubtitleUserKey)
params.Set("title", _msgSubtitleTitle)
params.Set("data_type", "4")
params.Set("context", arg.Msg())
params.Set("mid_list", fmt.Sprint(arg.Mid))
err = d.httpCli.Post(c, d.sendNotifyURI, "", params, res)
if err != nil {
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("return code:%d", res.Code)
log.Error("d.httpCli.Post(%s) error(%v)", d.sendNotifyURI+"?"+params.Encode(), err)
}
return
}

View File

@@ -0,0 +1,170 @@
package dao
import (
"testing"
"go-common/app/admin/main/dm/model"
. "github.com/smartystreets/goconvey/convey"
)
//func TestDao_SendMsgToReporter1(t *testing.T) {
// var (
// d = New(conf.Conf)
// c = context.TODO()
// err error
// rptMsg = &model.ReportMsg{
// Aid: 1,
// Title: "test title1",
// Did: 1,
// Msg: "dm msg1",
// Uids: "150781",
// State: model.StatFirstDelete,
// RptReason: 1,
// BlockReason: 1,
// Block: -1,
// }
// )
// err = d.SendMsgToReporter(c, rptMsg)
// if err != nil {
// t.Errorf("dao.SendMsgToReporter(rptMsg:%v) err(%v)", rptMsg, err)
// t.Fail()
// }
//}
//
//func TestDao_SendMsgToReporter2(t *testing.T) {
// var (
// d = New(conf.Conf)
// c = context.TODO()
// err error
// rptMsg = &model.ReportMsg{
// Aid: 1,
// Title: "test title2",
// Did: 1,
// Msg: "dm msg2",
// Uids: "150781",
// State: model.StatSecondDelete,
// RptReason: 3,
// BlockReason: 5,
// Block: -1,
// }
// )
// err = d.SendMsgToReporter(c, rptMsg)
// if err != nil {
// t.Errorf("dao.SendMsgToReporter(rptMsg:%v) err(%v)", rptMsg, err)
// t.Fail()
// }
//}
//
//func TestDao_SendMsgToReporter3(t *testing.T) {
// var (
// d = New(conf.Conf)
// c = context.TODO()
// err error
// rptMsg = &model.ReportMsg{
// Aid: 1,
// Title: "test title3",
// Did: 1,
// Msg: "dm msg3",
// Uids: "150781",
// State: model.StatFirstIgnore,
// RptReason: 1,
// BlockReason: 1,
// Block: -1,
// }
// )
// err = d.SendMsgToReporter(c, rptMsg)
// if err != nil {
// t.Errorf("dao.SendMsgToReporter(rptMsg:%v) err(%v)", rptMsg, err)
// t.Fail()
// }
//}
//
//func TestDao_SendMsgToReporter4(t *testing.T) {
// var (
// d = New(conf.Conf)
// c = context.TODO()
// err error
// rptMsg = &model.ReportMsg{
// Aid: 1,
// Title: "test title4",
// Did: 1,
// Msg: "dm msg4",
// Uids: "150781",
// State: model.StatSecondIgnore,
// RptReason: 1,
// BlockReason: 1,
// Block: -1,
// }
// )
// err = d.SendMsgToReporter(c, rptMsg)
// if err != nil {
// t.Errorf("dao.SendMsgToReporter(rptMsg:%v) err(%v)", rptMsg, err)
// t.Fail()
// }
//}
//
//func TestDao_SendMsgToReporter5(t *testing.T) {
// var (
// d = New(conf.Conf)
// c = context.TODO()
// err error
// rptMsg = &model.ReportMsg{
// Aid: 1,
// Title: "test title5",
// Did: 1,
// Msg: "dm msg5",
// Uids: "150781",
// State: model.StatSecondAutoDelete,
// RptReason: 1,
// BlockReason: 5,
// Block: -1,
// }
// )
// err = d.SendMsgToReporter(c, rptMsg)
// if err != nil {
// t.Errorf("dao.SendMsgToReporter(rptMsg:%v) err(%v)", rptMsg, err)
// t.Fail()
// }
//}
//
//func TestDao_SendMsgToPoster1(t *testing.T) {
// var (
// d = New(conf.Conf)
// c = context.TODO()
// err error
// rptMsg = &model.ReportMsg{
// Aid: 1,
// Title: "test title1",
// Did: 1,
// Msg: "dm msg1",
// Uids: "150781",
// State: model.StatSecondAutoDelete,
// RptReason: 1,
// BlockReason: 5,
// Block: 10,
// }
// )
// err = d.SendMsgToPoster(c, rptMsg)
// if err != nil {
// t.Errorf("dao.SendMsgToPoster(rptMsg:%v) err(%v)", rptMsg, err)
// t.Fail()
// }
//}
func TestCreatePosterContent(t *testing.T) {
msg := &model.ReportMsg{
Aid: 1,
Uids: "1,2",
Did: 11,
Title: "test title",
Msg: "test dm content",
State: 1,
RptReason: 16,
Block: 0,
BlockReason: 0,
}
Convey("test poster content", t, func() {
_, err := testDao.createPosterContent(msg)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,323 @@
package dao
import (
"context"
"fmt"
"sync"
"go-common/app/admin/main/dm/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
)
const (
_pageSize = 1000
_subjectSharding = 100
_indexSharding = 1000
_contentSharding = 1000
// subject
_updateSubAttr = "UPDATE dm_subject_%02d SET attr=? WHERE type=? AND oid=?"
_updateSubCount = "UPDATE dm_subject_%02d SET acount=?,count=? WHERE type=? AND oid=?"
_updateSubMCountSQL = "UPDATE dm_subject_%02d SET mcount=? WHERE type=? AND oid=?"
_incrSubMoveCntSQL = "UPDATE dm_subject_%02d SET move_count=move_count+? WHERE type=? AND oid=?"
_updateSubPoolSQL = "UPDATE dm_subject_%02d SET childpool=? WHERE type=? AND oid=?"
_updateSubStateSQL = "UPDATE dm_subject_%02d SET state=? WHERE type=? AND oid=?"
_updateSubMaxlimitSQL = "UPDATE dm_subject_%02d SET maxlimit=? WHERE type=? AND oid=?"
_incrSubCountSQL = "UPDATE dm_subject_%02d SET count=count+? WHERE type=? AND oid=?"
_selectDMCount = "SELECT count(*) from dm_index_%03d WHERE type=? AND oid=? AND state IN(%s)"
_subSQL = "SELECT id,type,oid,pid,mid,state,attr,acount,count,mcount,move_count,maxlimit,childpool,ctime,mtime FROM dm_subject_%02d WHERE type=? AND oid=?"
_getSubjectsSQL = "SELECT id,type,oid,pid,mid,state,attr,acount,count,mcount,move_count,maxlimit,childpool,ctime,mtime FROM dm_subject_%02d WHERE type=? AND oid IN(%s)"
_contentsSQL = "SELECT dmid,fontsize,color,mode,ip,plat,msg,ctime,mtime FROM dm_content_%03d WHERE dmid IN(%s)"
_contentsSpeSQL = "SELECT dmid,msg,ctime,mtime FROM dm_special_content WHERE dmid IN(%s)"
_idxsByidSQL = "SELECT id,type,oid,mid,progress,state,pool,attr,ctime,mtime FROM dm_index_%03d WHERE type=? AND oid=? AND id IN(%s)"
_updatePoolID = "UPDATE dm_index_%03d SET pool=? WHERE type=? AND id IN (%s)"
_updateDMState = "UPDATE dm_index_%03d SET state=? WHERE type=? AND id IN (%s)"
_updateDMAttr = "UPDATE dm_index_%03d SET attr=? WHERE type=? AND id IN (%s)"
)
func (d *Dao) hitSubject(oid int64) int64 {
return oid % _subjectSharding
}
func (d *Dao) hitIndex(oid int64) int64 {
return oid % _indexSharding
}
func (d *Dao) hitContent(oid int64) int64 {
return oid % _contentSharding
}
// UpSubjectAttr update subject attr.
func (d *Dao) UpSubjectAttr(c context.Context, tp int32, oid int64, attr int32) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_updateSubAttr, d.hitSubject(oid)), attr, tp, oid)
if err != nil {
log.Error("dmMetaWriter.Exec() error(%v)", err)
return
}
return res.RowsAffected()
}
// UpSubjectCount update acount,count of subject.
func (d *Dao) UpSubjectCount(c context.Context, tp int32, oid, acount, count int64) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_updateSubCount, d.hitSubject(oid)), acount, count, tp, oid)
if err != nil {
log.Error("dmMetaWriter.Exec() error(%v)", err)
return
}
return res.RowsAffected()
}
// IncrSubjectCount update count.
func (d *Dao) IncrSubjectCount(c context.Context, tp int32, oid, count int64) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_incrSubCountSQL, d.hitSubject(oid)), count, tp, oid)
if err != nil {
log.Error("dmMetaWriter.Exec() error(%v)", err)
return
}
return res.RowsAffected()
}
// UpSubjectMCount update monitor dm count.
func (d *Dao) UpSubjectMCount(c context.Context, tp int32, oid, cnt int64) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_updateSubMCountSQL, d.hitSubject(oid)), cnt, tp, oid)
if err != nil {
log.Error("d.dmMetaWriter.Exect(%s,%d,%d,%d) error(%v)", _updateSubMCountSQL, cnt, tp, oid, err)
return
}
return res.RowsAffected()
}
// IncrSubMoveCount update move_count in dm_subject.
func (d *Dao) IncrSubMoveCount(c context.Context, tp int32, oid, count int64) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_incrSubMoveCntSQL, d.hitSubject(oid)), count, tp, oid)
if err != nil {
log.Error("d.dmMetaWriter.Exec(%s,%d,%d,%d) error(%v)", _incrSubMoveCntSQL, tp, oid, count, err)
return
}
return res.RowsAffected()
}
// UpSubjectPool update childpool in dm subject.
func (d *Dao) UpSubjectPool(c context.Context, tp int32, oid int64, childpool int32) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_updateSubPoolSQL, d.hitSubject(oid)), childpool, tp, oid)
if err != nil {
log.Error("d.dmWriter.Exect(%s,%d,%d,%d) error(%v)", _updateSubPoolSQL, childpool, tp, oid, err)
return
}
return res.RowsAffected()
}
// UpSubjectState update state in dm subject.
func (d *Dao) UpSubjectState(c context.Context, tp int32, oid int64, state int32) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_updateSubStateSQL, d.hitSubject(oid)), state, tp, oid)
if err != nil {
log.Error("d.dmWriter.Exect(%s,%d,%d,%d) error(%v)", _updateSubStateSQL, state, tp, oid, err)
return
}
return res.RowsAffected()
}
// UpSubjectMaxlimit update maxlimit in dm subject.
func (d *Dao) UpSubjectMaxlimit(c context.Context, tp int32, oid, maxlimit int64) (affect int64, err error) {
res, err := d.dmMetaWriter.Exec(c, fmt.Sprintf(_updateSubMaxlimitSQL, d.hitSubject(oid)), maxlimit, tp, oid)
if err != nil {
log.Error("d.dmWriter.Exect(%s,%d,%d,%d) error(%v)", _updateSubMaxlimitSQL, maxlimit, tp, oid, err)
return
}
return res.RowsAffected()
}
// DMCount statistics dm count by dm state.
func (d *Dao) DMCount(c context.Context, tp int32, oid int64, states []int64) (count int64, err error) {
row := d.dmMetaReader.QueryRow(c, fmt.Sprintf(_selectDMCount, d.hitIndex(oid), xstr.JoinInts(states)), tp, oid)
if err = row.Scan(&count); err != nil {
log.Error("row.Scan() error(%v)", err)
}
return
}
// Subject get subject info from db.
func (d *Dao) Subject(c context.Context, tp int32, oid int64) (s *model.Subject, err error) {
s = &model.Subject{}
row := d.dmMetaReader.QueryRow(c, fmt.Sprintf(_subSQL, d.hitSubject(oid)), tp, oid)
if err = row.Scan(&s.ID, &s.Type, &s.Oid, &s.Pid, &s.Mid, &s.State, &s.Attr, &s.ACount, &s.Count, &s.MCount, &s.MoveCnt, &s.Maxlimit, &s.Childpool, &s.Ctime, &s.Mtime); err != nil {
if err == sql.ErrNoRows {
s = nil
err = nil
} else {
log.Error("row.Scan() error(%v)", err)
}
}
return
}
// Subjects multi get subjects.
func (d *Dao) Subjects(c context.Context, tp int32, oids []int64) (res map[int64]*model.Subject, err error) {
var (
oidMap = make(map[int64][]int64)
mutext = &sync.Mutex{}
wg, errCtx = errgroup.WithContext(c)
)
if len(oids) == 0 {
return
}
res = make(map[int64]*model.Subject, len(oids))
for _, oid := range oids {
if _, ok := oidMap[d.hitSubject(oid)]; !ok {
oidMap[d.hitSubject(oid)] = make([]int64, 0)
}
oidMap[d.hitSubject(oid)] = append(oidMap[d.hitSubject(oid)], oid)
}
for key, value := range oidMap {
k := key
v := value
wg.Go(func() (err error) {
rows, err := d.dmMetaReader.Query(errCtx, fmt.Sprintf(_getSubjectsSQL, k, xstr.JoinInts(v)), tp)
if err != nil {
log.Error("dmMetaReader.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
s := &model.Subject{}
err = rows.Scan(&s.ID, &s.Type, &s.Oid, &s.Pid, &s.Mid, &s.State, &s.Attr, &s.ACount, &s.Count, &s.MCount, &s.MoveCnt, &s.Maxlimit, &s.Childpool, &s.Ctime, &s.Mtime)
if err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
mutext.Lock()
res[s.Oid] = s
mutext.Unlock()
}
return
})
}
if err = wg.Wait(); err != nil {
log.Error("d.Subjects() error(%v)", err)
return
}
if len(res) == 0 {
res = nil
}
return
}
// SetStateByIDs change danmu state in new db
func (d *Dao) SetStateByIDs(c context.Context, tp int32, oid int64, ids []int64, state int32) (affect int64, err error) {
sqlStr := fmt.Sprintf(_updateDMState, d.hitIndex(oid), xstr.JoinInts(ids))
res, err := d.dmMetaWriter.Exec(c, sqlStr, state, tp)
if err != nil {
log.Error("d.dmMetaWriter.Exec(%s %d) error(%v)", sqlStr, state, err)
return
}
return res.RowsAffected()
}
// SetAttrByIDs set attr by mult dmids in new db
func (d *Dao) SetAttrByIDs(c context.Context, tp int32, oid int64, ids []int64, val int32) (affect int64, err error) {
sqlStr := fmt.Sprintf(_updateDMAttr, d.hitIndex(oid), xstr.JoinInts(ids))
res, err := d.dmMetaWriter.Exec(c, sqlStr, val, tp)
if err != nil {
log.Error("d.dmMetaWriter.Exec(%s %d) error(%v)", sqlStr, val, err)
return
}
return res.RowsAffected()
}
// SetPoolIDByIDs change danmu poolid
func (d *Dao) SetPoolIDByIDs(c context.Context, tp int32, oid int64, pool int32, dmids []int64) (affect int64, err error) {
sqlStr := fmt.Sprintf(_updatePoolID, d.hitIndex(oid), xstr.JoinInts(dmids))
res, err := d.dmMetaWriter.Exec(c, sqlStr, pool, tp)
if err != nil {
log.Error("d.dbComment.Exec(%v) error(%v)", sqlStr, err)
return
}
return res.RowsAffected()
}
// IndexsByID get dm index by dmids.
func (d *Dao) IndexsByID(c context.Context, tp int32, oid int64, dmids []int64) (idxMap map[int64]*model.DM, special []int64, err error) {
query := fmt.Sprintf(_idxsByidSQL, d.hitIndex(oid), xstr.JoinInts(dmids))
rows, err := d.dmMetaReader.Query(c, query, tp, oid)
if err != nil {
log.Error("db.Query() error(%v)", err)
return
}
defer rows.Close()
idxMap = make(map[int64]*model.DM, len(dmids))
for rows.Next() {
idx := new(model.DM)
if err = rows.Scan(&idx.ID, &idx.Type, &idx.Oid, &idx.Mid, &idx.Progress, &idx.State, &idx.Pool, &idx.Attr, &idx.Ctime, &idx.Mtime); err != nil {
log.Error("row.Scan() error(%v)", err)
return
}
idxMap[idx.ID] = idx
if idx.Pool == model.PoolSpecial {
special = append(special, idx.ID)
}
}
return
}
// Contents multi get dm content by dmids.
func (d *Dao) Contents(c context.Context, oid int64, dmids []int64) (res []*model.Content, err error) {
var (
wg errgroup.Group
lock sync.Mutex
)
pageNum := len(dmids) / _pageSize
if len(dmids)%_pageSize > 0 {
pageNum = pageNum + 1
}
for i := 0; i < pageNum; i++ {
start := i * _pageSize
end := (i + 1) * _pageSize
if end > len(dmids) {
end = len(dmids)
}
wg.Go(func() (err error) {
rows, err := d.dmMetaReader.Query(c, fmt.Sprintf(_contentsSQL, d.hitContent(oid), xstr.JoinInts(dmids[start:end])))
if err != nil {
log.Error("db.Query(%s) error(%v)", fmt.Sprintf(_contentsSQL, d.hitContent(oid), xstr.JoinInts(dmids)), err)
return
}
defer rows.Close()
for rows.Next() {
ct := &model.Content{}
if err = rows.Scan(&ct.ID, &ct.FontSize, &ct.Color, &ct.Mode, &ct.IP, &ct.Plat, &ct.Msg, &ct.Ctime, &ct.Mtime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
lock.Lock()
res = append(res, ct)
lock.Unlock()
}
return
})
}
err = wg.Wait()
return
}
// SpecialContents multi get special dm content by dmids.
func (d *Dao) SpecialContents(c context.Context, dmids []int64) (res map[int64]*model.ContentSpecial, err error) {
res = make(map[int64]*model.ContentSpecial, len(dmids))
rows, err := d.dmMetaReader.Query(c, fmt.Sprintf(_contentsSpeSQL, xstr.JoinInts(dmids)))
if err != nil {
log.Error("db.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
content := &model.ContentSpecial{}
if err = rows.Scan(&content.ID, &content.Msg, &content.Ctime, &content.Mtime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
res[content.ID] = content
}
return
}

View File

@@ -0,0 +1,85 @@
package dao
import (
"context"
"go-common/app/admin/main/dm/model"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_countAdvsSQLAll = "SELECT count(*) FROM dm_advancecomment WHERE dm_inid=? "
_countAdvsSQLMode = "SELECT count(*) FROM dm_advancecomment WHERE dm_inid=? AND mode=? "
_countAdvsSQLType = "SELECT count(*) FROM dm_advancecomment WHERE dm_inid=? AND type=? "
_countAdvsSQLTypeMode = "SELECT count(*) FROM dm_advancecomment WHERE dm_inid=? AND type=? AND mode=? "
_selAdvsSQLAll = "SELECT buy_id,type,mode,mid,timestamp FROM dm_advancecomment WHERE dm_inid=? ORDER BY buy_id DESC limit ?,?"
_selAdvsSQLMode = "SELECT buy_id,type,mode,mid,timestamp FROM dm_advancecomment WHERE dm_inid=? AND mode=? ORDER BY buy_id DESC limit ?,?"
_selAdvsSQLType = "SELECT buy_id,type,mode,mid,timestamp FROM dm_advancecomment WHERE dm_inid=? AND type=? ORDER BY buy_id DESC limit ?,?"
_selAdvsSQLTypeMode = "SELECT buy_id,type,mode,mid,timestamp FROM dm_advancecomment WHERE dm_inid=? AND type=? AND mode=? ORDER BY buy_id DESC ?,?"
)
// Advances 获取高级弹幕申请
func (d *Dao) Advances(c context.Context, dmInid int64, typ, mode string, pn, ps int64) (res []*model.Advance, total int64, err error) {
var rows *sql.Rows
res = make([]*model.Advance, 0)
if typ == model.AdvTypeAll {
if mode == model.AdvModeAll {
countRow := d.biliDM.QueryRow(c, _countAdvsSQLAll, dmInid)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err = d.biliDM.Query(c, _selAdvsSQLAll, dmInid, (pn-1)*ps, ps)
if err != nil {
log.Error("d.dbDM.Query(%s,%d,%d,%d) error(%v)", _selAdvsSQLAll, dmInid, (pn-1)*ps, ps, err)
return
}
} else {
countRow := d.biliDM.QueryRow(c, _countAdvsSQLMode, dmInid, mode)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err = d.biliDM.Query(c, _selAdvsSQLMode, dmInid, mode, (pn-1)*ps, ps)
if err != nil {
log.Error("d.dbDM.Query(%s,%d,%s,%d,%d) error(%v)", _selAdvsSQLMode, dmInid, mode, (pn-1)*ps, ps, err)
return
}
}
} else {
if mode == model.AdvModeAll {
countRow := d.biliDM.QueryRow(c, _countAdvsSQLType, dmInid, typ)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err = d.biliDM.Query(c, _selAdvsSQLType, dmInid, typ, (pn-1)*ps, ps)
if err != nil {
log.Error("d.dbDM.Query(%s,%d,%s,%d,%d) error(%v)", _selAdvsSQLType, dmInid, typ, (pn-1)*ps, ps, err)
return
}
} else {
countRow := d.biliDM.QueryRow(c, _countAdvsSQLTypeMode, dmInid, typ)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err = d.biliDM.Query(c, _selAdvsSQLTypeMode, dmInid, typ, mode, (pn-1)*ps, ps)
if err != nil {
log.Error("d.dbDM.Query(%s,%d,%s,%s,%d,%d) error(%v)", _selAdvsSQLTypeMode, dmInid, typ, mode, (pn-1)*ps, ps, err)
return
}
}
}
defer rows.Close()
for rows.Next() {
adv := &model.Advance{}
if err = rows.Scan(&adv.ID, &adv.Type, &adv.Mode, &adv.Mid, &adv.Timestamp); err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
res = append(res, adv)
}
return
}

View File

@@ -0,0 +1,13 @@
package dao
import (
"context"
"testing"
)
func TestAdvances(t *testing.T) {
_, _, err := testDao.Advances(context.TODO(), 27515260, "all", "all", 1, 20)
if err != nil {
t.Error(err)
}
}

View File

@@ -0,0 +1,94 @@
package dao
import (
"context"
"fmt"
"go-common/app/admin/main/dm/model"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_upFilterSharding = 10
_countUpFiltersSQL = "SELECT count(*) FROM dm_filter_up_%02d WHERE mid=? AND type=? AND active=1"
_countUpFiltersAllSQL = "SELECT count(*) FROM dm_filter_up_%02d WHERE mid=? AND active=1"
_getUpFiltersSQL = "SELECT id,oid,type,filter,ctime FROM dm_filter_up_%02d WHERE mid=? AND type=? AND active=1 ORDER BY id DESC limit ?,?"
_getUpFiltersAllSQL = "SELECT id,oid,type,filter,ctime FROM dm_filter_up_%02d WHERE mid=? AND active=1 ORDER BY id DESC limit ?,?"
_uptUpFilterSQL = "UPDATE dm_filter_up_%02d SET active=? WHERE id=?"
_updateUpFilterCntSQL = "UPDATE dm_filter_up_count SET count=count+? WHERE mid=? AND type=? AND count<?"
)
func (d *Dao) hitUpFilter(mid int64) int64 {
return mid % _upFilterSharding
}
// UpFilters return filter rules according type
func (d *Dao) UpFilters(c context.Context, mid, tp, pn, ps int64) (res []*model.UpFilter, total int64, err error) {
res = make([]*model.UpFilter, 0)
countRow := d.biliDM.QueryRow(c, fmt.Sprintf(_countUpFiltersSQL, d.hitUpFilter(mid)), mid, tp)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err := d.biliDM.Query(c, fmt.Sprintf(_getUpFiltersSQL, d.hitUpFilter(mid)), mid, tp, (pn-1)*ps, ps)
if err != nil {
log.Error("dbDM.Query(mid:%d, oid:%d) error(%v)", mid, tp, err)
return
}
defer rows.Close()
for rows.Next() {
f := &model.UpFilter{}
if err = rows.Scan(&f.ID, &f.Oid, &f.Type, &f.Filter, &f.Ctime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
res = append(res, f)
}
return
}
// UpFiltersAll return all filter rules
func (d *Dao) UpFiltersAll(c context.Context, mid, pn, ps int64) (res []*model.UpFilter, total int64, err error) {
res = make([]*model.UpFilter, 0)
countRow := d.biliDM.QueryRow(c, fmt.Sprintf(_countUpFiltersAllSQL, d.hitUpFilter(mid)), mid)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err := d.biliDM.Query(c, fmt.Sprintf(_getUpFiltersAllSQL, d.hitUpFilter(mid)), mid, (pn-1)*ps, ps)
if err != nil {
log.Error("dbDM.Query(mid:%d) error(%v)", mid, err)
return
}
defer rows.Close()
for rows.Next() {
f := &model.UpFilter{}
if err = rows.Scan(&f.ID, &f.Oid, &f.Type, &f.Filter, &f.Ctime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
res = append(res, f)
}
return
}
// UpdateUpFilter batch edit filter.
func (d *Dao) UpdateUpFilter(tx *sql.Tx, mid, id int64, active int8) (affect int64, err error) {
res, err := tx.Exec(fmt.Sprintf(_uptUpFilterSQL, d.hitUpFilter(mid)), active, id)
if err != nil {
log.Error("tx.Exec(mid:%d,id:%d,active:%d) error(%v)", mid, id, active, err)
return
}
return res.RowsAffected()
}
// UpdateUpFilterCnt set count
func (d *Dao) UpdateUpFilterCnt(tx *sql.Tx, mid int64, ftype int8, count, limit int) (affect int64, err error) {
res, err := tx.Exec(_updateUpFilterCntSQL, count, mid, ftype, limit)
if err != nil {
log.Error("d.UpdateUpFilterCnt(mid:%d, type:%d, count:%d) error(%v)", mid, ftype, count, err)
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,25 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestMultiAddUpFilters(t *testing.T) {
Convey("", t, func() {
tx, err := testDao.BeginBiliDMTrans(context.TODO())
So(err, ShouldBeNil)
So(tx, ShouldNotBeNil)
Convey("", func() {
_, err := testDao.UpdateUpFilter(tx, 16299551, 33, 0)
So(err, ShouldBeNil)
if err != nil {
_, err = testDao.UpdateUpFilterCnt(tx, 162, 1, 1, 1000)
So(err, ShouldBeNil)
}
tx.Commit()
})
})
}

View File

@@ -0,0 +1,52 @@
package dao
import (
"context"
"go-common/app/admin/main/dm/model"
"go-common/library/log"
)
const (
_countMaskUp = "SELECT count(*) FROM dm_mask_up WHERE state=1"
_getMaskUp = "SELECT id,mid,state,comment,ctime,mtime from dm_mask_up where state=1 ORDER BY mtime DESC limit ?,? "
_maskUpOpen = "INSERT INTO dm_mask_up(mid,state,comment) VALUES (?,?,?) ON DUPLICATE KEY UPDATE state=?,comment=?"
)
// MaskUps get mask up info from db.
func (d *Dao) MaskUps(c context.Context, pn, ps int64) (maskUps []*model.MaskUp, total int64, err error) {
maskUps = make([]*model.MaskUp, 0)
countRow := d.biliDM.QueryRow(c, _countMaskUp)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err := d.biliDM.Query(c, _getMaskUp, (pn-1)*ps, ps)
if err != nil {
log.Error("biliDM.Query(%s) error(%v)", _getMaskUp, err)
return
}
defer rows.Close()
for rows.Next() {
maskUp := &model.MaskUp{}
if err = rows.Scan(&maskUp.ID, &maskUp.Mid, &maskUp.State, &maskUp.Comment, &maskUp.CTime, &maskUp.MTime); err != nil {
log.Error("biliDM.Scan(%s) error(%v)", _getMaskUp, err)
return
}
maskUps = append(maskUps, maskUp)
}
if err = rows.Err(); err != nil {
log.Error("biliDM.rows.Err() error(%v)", err)
}
return
}
// MaskUpOpen mask up open.
func (d *Dao) MaskUpOpen(c context.Context, mid int64, state int32, comment string) (affect int64, err error) {
res, err := d.biliDM.Exec(c, _maskUpOpen, mid, state, comment, state, comment)
if err != nil {
log.Error("d.biliDM.Exec(%s,%d,%v,%v) error(%v)", _maskUpOpen, mid, state, comment, err)
return
}
return res.RowsAffected()
}

View File

@@ -0,0 +1,27 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestMaskUps(t *testing.T) {
Convey("test mask ups", t, func() {
res, total, err := testDao.MaskUps(context.Background(), 1, 50)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
So(total, ShouldNotBeNil)
t.Log(res, total)
})
}
func TestMaskUpOpen(t *testing.T) {
Convey("test mask up open", t, func() {
res, err := testDao.MaskUpOpen(context.Background(), 27515266, 1, "")
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
t.Log(res)
})
}

View File

@@ -0,0 +1,153 @@
package dao
import (
"bytes"
"context"
"fmt"
"go-common/app/admin/main/dm/model"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_userSharding = 100
_logSharding = 100
_reportSharding = 100
// dm report
_updateStatSQL = "UPDATE dm_report_%d SET state=? WHERE dmid IN (%s)"
_ignoreStatSQL = "UPDATE dm_report_%d SET state=?,count=0 WHERE dmid IN (%s)"
_selectRpt = "SELECT id,dmid,cid,uid,reason,count,up_op,state,score,rp_time,ctime,mtime FROM dm_report_%d WHERE dmid IN (%s)"
_selectUsers = "SELECT id,dmid,uid,reason,state,ctime,mtime FROM dm_report_user_%d WHERE dmid IN (%s) AND state=? ORDER BY id"
_updateUser = "UPDATE dm_report_user_%d SET state=? WHERE dmid IN (%s) AND state !=?"
_insertLog = "INSERT dm_report_admin_log_%d (dmid,adminid,reason,result,remark,elapsed) VALUES"
_selectLog = "SELECT id,dmid,adminid,reason,result,remark,elapsed,ctime,mtime FROM dm_report_admin_log_%d WHERE dmid=? ORDER BY mtime"
)
// RptTable return report table id by cid
func RptTable(cid int64) int64 {
return cid % _reportSharding
}
// UserTable return user table id by dmid
func UserTable(dmid int64) int64 {
return dmid % _userSharding
}
// LogTable return log table id by dmid
func LogTable(dmid int64) int64 {
return dmid % _logSharding
}
// ChangeReportStat change report state
func (d *Dao) ChangeReportStat(c context.Context, cid int64, dmids []int64, state int8) (err error) {
updateSQL := fmt.Sprintf(_updateStatSQL, RptTable(cid), xstr.JoinInts(dmids))
if _, err = d.biliDM.Exec(c, updateSQL, state); err != nil {
log.Error("d.biliDM.Exec(%d) error(%v)", state, err)
}
return
}
// IgnoreReport change report state to SecondIgnore or FirstIngnore
func (d *Dao) IgnoreReport(c context.Context, cid int64, dmids []int64, state int8) (err error) {
updateSQL := fmt.Sprintf(_ignoreStatSQL, RptTable(cid), xstr.JoinInts(dmids))
if _, err = d.biliDM.Exec(c, updateSQL, state); err != nil {
log.Error("d.biliDM.Exec(%d) error(%v)", state, err)
}
return
}
// Reports get multi dm report info.
func (d *Dao) Reports(c context.Context, cid int64, dmids []int64) (res []*model.Report, err error) {
res = []*model.Report{}
selectSQL := fmt.Sprintf(_selectRpt, RptTable(cid), xstr.JoinInts(dmids))
rows, err := d.biliDM.Query(c, selectSQL)
if err != nil {
log.Error("d.biliDM.Exec(cid:%d,dmids:%v) error(%v)", cid, dmids, err)
return
}
defer rows.Close()
for rows.Next() {
r := &model.Report{}
err = rows.Scan(&r.ID, &r.Did, &r.Cid, &r.UID, &r.RpType, &r.Count, &r.UpOP, &r.State, &r.Score, &r.RpTime, &r.Ctime, &r.Mtime)
if err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
res = append(res, r)
}
return
}
// ReportUsers get user list.
func (d *Dao) ReportUsers(c context.Context, tableID int64, dmids []int64, state int8) (res map[int64][]*model.ReportUser, err error) {
res = make(map[int64][]*model.ReportUser, 100)
selectSQL := fmt.Sprintf(_selectUsers, tableID, xstr.JoinInts(dmids))
rows, err := d.biliDM.Query(c, selectSQL, state)
if err != nil {
log.Error("d.biliDM.Query(sql:%s) error(%v)", selectSQL, err)
return
}
defer rows.Close()
for rows.Next() {
u := &model.ReportUser{}
if err = rows.Scan(&u.ID, &u.Did, &u.UID, &u.Reason, &u.State, &u.Ctime, &u.Mtime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
res[u.Did] = append(res[u.Did], u)
}
return
}
// UpReportUserState update report user state.
func (d *Dao) UpReportUserState(c context.Context, tableID int64, dmids []int64, state int8) (affect int64, err error) {
selectSQL := fmt.Sprintf(_updateUser, tableID, xstr.JoinInts(dmids))
res, err := d.biliDM.Exec(c, selectSQL, state, state)
if err != nil {
log.Error("d.updateUserStmt.Exec(dmid:%v) error(%v)", dmids, err)
return
}
return res.RowsAffected()
}
// AddReportLog add dm report admin log.
func (d *Dao) AddReportLog(c context.Context, tableID int64, lg []*model.ReportLog) (err error) {
var (
buffer bytes.Buffer
insertTp string
)
insertTp = "(%d,%d,%d,%d,'%s',%d),"
buffer.WriteString(fmt.Sprintf(_insertLog, tableID))
for _, v := range lg {
buffer.WriteString(fmt.Sprintf(insertTp, v.Did, v.AdminID, v.Reason, v.Result, v.Remark, v.Elapsed))
}
//truncate the last ','
buffer.Truncate(buffer.Len() - 1)
_, err = d.biliDM.Exec(c, buffer.String())
if err != nil {
log.Error("d.insertLogStmt.Exec(%v) error(%v)", lg, err)
return
}
return
}
// ReportLog get dm report log.
func (d *Dao) ReportLog(c context.Context, dmid int64) (res []*model.ReportLog, err error) {
selectSQL := fmt.Sprintf(_selectLog, LogTable(dmid))
rows, err := d.biliDM.Query(c, selectSQL, dmid)
if err != nil {
log.Error("dmreport:d.biliDM.Query(sql:%s) error(%v)", selectSQL, err)
return
}
defer rows.Close()
for rows.Next() {
r := &model.ReportLog{}
if err = rows.Scan(&r.ID, &r.Did, &r.AdminID, &r.Reason, &r.Result, &r.Remark, &r.Elapsed, &r.Ctime, &r.Mtime); err != nil {
log.Error("rows.Scan() error(%v)", err)
return
}
res = append(res, r)
}
return
}

View File

@@ -0,0 +1,149 @@
package dao
import (
"context"
"go-common/app/admin/main/dm/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoRptTable(t *testing.T) {
convey.Convey("RptTable", t, func(ctx convey.C) {
var (
cid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := RptTable(cid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUserTable(t *testing.T) {
convey.Convey("UserTable", t, func(ctx convey.C) {
var (
dmid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := UserTable(dmid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoLogTable(t *testing.T) {
convey.Convey("LogTable", t, func(ctx convey.C) {
var (
dmid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := LogTable(dmid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoChangeReportStat(t *testing.T) {
convey.Convey("ChangeReportStat", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(0)
dmids = []int64{}
state = int8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.ChangeReportStat(c, cid, dmids, state)
})
})
}
func TestDaoIgnoreReport(t *testing.T) {
convey.Convey("IgnoreReport", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(0)
dmids = []int64{}
state = int8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.IgnoreReport(c, cid, dmids, state)
})
})
}
func TestDaoReports(t *testing.T) {
convey.Convey("Reports", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(0)
dmids = []int64{}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.Reports(c, cid, dmids)
})
})
}
func TestDaoReportUsers(t *testing.T) {
convey.Convey("ReportUsers", t, func(ctx convey.C) {
var (
c = context.Background()
tableID = int64(0)
dmids = []int64{}
state = int8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.ReportUsers(c, tableID, dmids, state)
})
})
}
func TestDaoUpReportUserState(t *testing.T) {
convey.Convey("UpReportUserState", t, func(ctx convey.C) {
var (
c = context.Background()
tableID = int64(0)
dmids = []int64{}
state = int8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.UpReportUserState(c, tableID, dmids, state)
})
})
}
func TestDaoAddReportLog(t *testing.T) {
convey.Convey("AddReportLog", t, func(ctx convey.C) {
var (
c = context.Background()
tableID = int64(0)
lg = []*model.ReportLog{}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.AddReportLog(c, tableID, lg)
})
})
}
func TestDaoReportLog(t *testing.T) {
convey.Convey("ReportLog", t, func(ctx convey.C) {
var (
c = context.Background()
dmid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
res, err := testDao.ReportLog(c, dmid)
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)
})
})
})
}

View File

@@ -0,0 +1,182 @@
package dao
import (
"context"
"fmt"
"time"
"go-common/app/admin/main/dm/model"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_subtitleSharding = 100
_getSubtitles = "SELECT id,oid,type,lan,aid,mid,author_mid,up_mid,is_sign,is_lock,status,subtitle_url,pub_time,mtime FROM subtitle_%02d WHERE id in (%s)"
_getSubtitle = "SELECT id,oid,type,lan,aid,mid,author_mid,up_mid,is_sign,is_lock,status,subtitle_url,pub_time,mtime FROM subtitle_%02d WHERE id=?"
_countSubtitleDraft = "SELECT COUNT(id) FROM subtitle_%02d WHERE oid=? AND type=? AND lan=? AND mid=? AND pub_time=0"
_updateSubtitle = "UPDATE subtitle_%02d set status=?,pub_time=? where id=?"
_getSubtitlePubID = "SELECT id FROM subtitle_%02d WHERE oid=? AND type=? AND lan=? AND status=5 ORDER BY pub_time DESC limit 1"
_addSubtitlePub = "INSERT INTO subtitle_pub(oid,type,lan,subtitle_id,is_delete) VALUES(?,?,?,?,?) ON DUPLICATE KEY UPDATE subtitle_id=?,is_delete=?"
_getSubtitleLans = "SELECT code,lan,doc_zh FROM subtitle_language WHERE is_delete=0"
_addSubtitleSubject = "INSERT INTO subtitle_subject(aid,allow,attr,lan_code) VALUES(?,?,?,?) ON DUPLICATE KEY UPDATE allow=?,attr=?,lan_code=?"
_getSubtitleSubject = "SELECT aid,allow,attr,lan_code from subtitle_subject WHERE aid=?"
)
func (d *Dao) hitSubtitle(oid int64) int64 {
return oid % _subtitleSharding
}
// GetSubtitles .
func (d *Dao) GetSubtitles(c context.Context, oid int64, subtitleIds []int64) (subtitles []*model.Subtitle, err error) {
rows, err := d.biliDM.Query(c, fmt.Sprintf(_getSubtitles, d.hitSubtitle(oid), xstr.JoinInts(subtitleIds)))
if err != nil {
log.Error("params(subtitleIds:%v),error(%v)", subtitleIds, err)
return
}
defer rows.Close()
for rows.Next() {
subtitle := &model.Subtitle{}
var t time.Time
if err = rows.Scan(&subtitle.ID, &subtitle.Oid, &subtitle.Type, &subtitle.Lan, &subtitle.Aid, &subtitle.Mid, &subtitle.AuthorID, &subtitle.UpMid, &subtitle.IsSign, &subtitle.IsLock, &subtitle.Status, &subtitle.SubtitleURL, &subtitle.PubTime, &t); err != nil {
log.Error("params(subtitleIds:%v),error(%v)", subtitleIds, err)
return
}
subtitle.Mtime = t.Unix()
subtitles = append(subtitles, subtitle)
}
if err = rows.Err(); err != nil {
log.Error("params(subtitleIds:%v),error(%v)", subtitleIds, err)
return
}
return
}
// GetSubtitle .
func (d *Dao) GetSubtitle(c context.Context, oid, subtitleID int64) (subtitle *model.Subtitle, err error) {
row := d.biliDM.QueryRow(c, fmt.Sprintf(_getSubtitle, d.hitSubtitle(oid)), subtitleID)
subtitle = &model.Subtitle{}
var t time.Time
if err = row.Scan(&subtitle.ID, &subtitle.Oid, &subtitle.Type, &subtitle.Lan, &subtitle.Aid, &subtitle.Mid, &subtitle.AuthorID, &subtitle.UpMid, &subtitle.IsSign, &subtitle.IsLock, &subtitle.Status, &subtitle.SubtitleURL, &subtitle.PubTime, &t); err != nil {
if err == sql.ErrNoRows {
err = nil
subtitle = nil
return
}
log.Error("params(subtitleIds:%v),error(%v)", subtitleID, err)
return
}
subtitle.Mtime = t.Unix()
return
}
// UpdateSubtitle .
func (d *Dao) UpdateSubtitle(c context.Context, subtitle *model.Subtitle) (err error) {
if _, err = d.biliDM.Exec(c, fmt.Sprintf(_updateSubtitle, d.hitSubtitle(subtitle.Oid)), subtitle.Status, subtitle.PubTime, subtitle.ID); err != nil {
log.Error("UpdateSubtitle.params(subtitle:%+v),error(%v)", subtitle, err)
return
}
return
}
// CountSubtitleDraft .
func (d *Dao) CountSubtitleDraft(c context.Context, oid int64, mid int64, lan uint8, tp int32) (count int64, err error) {
row := d.biliDM.QueryRow(c, fmt.Sprintf(_countSubtitleDraft, d.hitSubtitle(oid)), oid, tp, lan, mid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
count = 0
return
}
log.Error("params(oid:%v, tp:%v, mid:%v, lan:%v),error(%v)", oid, tp, mid, lan, err)
return
}
return
}
// TxUpdateSubtitle .
func (d *Dao) TxUpdateSubtitle(tx *sql.Tx, subtitle *model.Subtitle) (err error) {
if _, err = tx.Exec(fmt.Sprintf(_updateSubtitle, d.hitSubtitle(subtitle.Oid)), subtitle.Status, subtitle.PubTime, subtitle.ID); err != nil {
log.Error("TxUpdateSubtitle.params(subtitle:%+v),error(%v)", subtitle, err)
return
}
return
}
// TxGetSubtitleID .
func (d *Dao) TxGetSubtitleID(tx *sql.Tx, oid int64, tp int32, lan uint8) (subtitleID int64, err error) {
row := tx.QueryRow(fmt.Sprintf(_getSubtitlePubID, d.hitSubtitle(oid)), oid, tp, lan)
if err = row.Scan(&subtitleID); err != nil {
if err == sql.ErrNoRows {
err = nil
subtitleID = 0
return
}
log.Error("TxGetSubtitleID.Scac(err:%v)", err)
return
}
return
}
// TxUpdateSubtitlePub .
func (d *Dao) TxUpdateSubtitlePub(tx *sql.Tx, subtitlePub *model.SubtitlePub) (err error) {
if _, err = tx.Exec(_addSubtitlePub, subtitlePub.Oid, subtitlePub.Type, subtitlePub.Lan, subtitlePub.SubtitleID, subtitlePub.IsDelete, subtitlePub.SubtitleID, subtitlePub.IsDelete); err != nil {
log.Error("params(%+v),error(%v)", subtitlePub, err)
return
}
return
}
// SubtitleLans .
func (d *Dao) SubtitleLans(c context.Context) (subtitleLans []*model.SubtitleLan, err error) {
rows, err := d.biliDM.Query(c, _getSubtitleLans)
if err != nil {
log.Error("params(query:%v),error(%v)", _getSubtitleLans, err)
return
}
defer rows.Close()
for rows.Next() {
subtitleLan := new(model.SubtitleLan)
if err = rows.Scan(&subtitleLan.Code, &subtitleLan.Lan, &subtitleLan.DocZh); err != nil {
log.Error("params.Sacn(query:%v),error(%v)", _getSubtitleLans, err)
return
}
subtitleLans = append(subtitleLans, subtitleLan)
}
if err = rows.Err(); err != nil {
log.Error("params.Err(query:%v),error(%v)", _getSubtitleLans, err)
return
}
return
}
// AddSubtitleSubject .
func (d *Dao) AddSubtitleSubject(c context.Context, subtitleSubject *model.SubtitleSubject) (err error) {
if _, err = d.biliDM.Exec(c, _addSubtitleSubject, subtitleSubject.Aid, subtitleSubject.Allow, subtitleSubject.Attr, subtitleSubject.Lan, subtitleSubject.Allow, subtitleSubject.Attr, subtitleSubject.Lan); err != nil {
log.Error("params(subtitleSubject:%+v),error(%v)", subtitleSubject, err)
return
}
return
}
// GetSubtitleSubject .
func (d *Dao) GetSubtitleSubject(c context.Context, aid int64) (subtitleSubject *model.SubtitleSubject, err error) {
subtitleSubject = new(model.SubtitleSubject)
row := d.biliDM.QueryRow(c, _getSubtitleSubject, aid)
if err = row.Scan(&subtitleSubject.Aid, &subtitleSubject.Allow, &subtitleSubject.Attr, &subtitleSubject.Lan); err != nil {
if err == sql.ErrNoRows {
err = nil
subtitleSubject = nil
return
}
log.Error("params(aid:%v),error(%v)", aid, err)
return
}
return
}

View File

@@ -0,0 +1,177 @@
package dao
import (
"context"
"go-common/app/admin/main/dm/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaohitSubtitle(t *testing.T) {
convey.Convey("hitSubtitle", t, func(ctx convey.C) {
var (
oid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
p1 := testDao.hitSubtitle(oid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGetSubtitles(t *testing.T) {
convey.Convey("GetSubtitles", t, func(ctx convey.C) {
var (
c = context.Background()
oid = int64(0)
subtitleIds = []int64{}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.GetSubtitles(c, oid, subtitleIds)
})
})
}
func TestDaoGetSubtitle(t *testing.T) {
convey.Convey("GetSubtitle", t, func(ctx convey.C) {
var (
c = context.Background()
oid = int64(0)
subtitleID = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.GetSubtitle(c, oid, subtitleID)
})
})
}
func TestDaoUpdateSubtitle(t *testing.T) {
convey.Convey("UpdateSubtitle", t, func(ctx convey.C) {
var (
c = context.Background()
subtitle = &model.Subtitle{}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
err := testDao.UpdateSubtitle(c, subtitle)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoCountSubtitleDraft(t *testing.T) {
convey.Convey("CountSubtitleDraft", t, func(ctx convey.C) {
var (
c = context.Background()
oid = int64(0)
mid = int64(0)
lan = uint8(0)
tp = int32(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
count, err := testDao.CountSubtitleDraft(c, oid, mid, lan, tp)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxUpdateSubtitle(t *testing.T) {
convey.Convey("TxUpdateSubtitle", t, func(ctx convey.C) {
var (
tx, _ = testDao.BeginBiliDMTrans(context.TODO())
subtitle = &model.Subtitle{}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.TxUpdateSubtitle(tx, subtitle)
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoTxGetSubtitleID(t *testing.T) {
convey.Convey("TxGetSubtitleID", t, func(ctx convey.C) {
var (
tx, _ = testDao.BeginBiliDMTrans(context.TODO())
oid = int64(0)
tp = int32(0)
lan = uint8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.TxGetSubtitleID(tx, oid, tp, lan)
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoTxUpdateSubtitlePub(t *testing.T) {
convey.Convey("TxUpdateSubtitlePub", t, func(ctx convey.C) {
var (
tx, _ = testDao.BeginBiliDMTrans(context.TODO())
subtitlePub = &model.SubtitlePub{}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.TxUpdateSubtitlePub(tx, subtitlePub)
})
ctx.Reset(func() {
tx.Commit()
})
})
}
func TestDaoSubtitleLans(t *testing.T) {
convey.Convey("SubtitleLans", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
subtitleLans, err := testDao.SubtitleLans(c)
ctx.Convey("Then err should be nil.subtitleLans should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(subtitleLans, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddSubtitleSubject(t *testing.T) {
convey.Convey("AddSubtitleSubject", t, func(ctx convey.C) {
var (
c = context.Background()
subtitleSubject = &model.SubtitleSubject{}
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
err := testDao.AddSubtitleSubject(c, subtitleSubject)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoGetSubtitleSubject(t *testing.T) {
convey.Convey("GetSubtitleSubject", t, func(ctx convey.C) {
var (
c = context.Background()
aid = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
subtitleSubject, err := testDao.GetSubtitleSubject(c, aid)
ctx.Convey("Then err should be nil.subtitleSubject should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(subtitleSubject, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,166 @@
package dao
import (
"context"
"fmt"
"strings"
"time"
"go-common/app/admin/main/dm/model"
"go-common/library/database/sql"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_countDMTask = "SELECT count(*) FROM dm_task"
_selectDMTask = "SELECT id,title,creator,reviewer,state,result,ctime,mtime FROM dm_task%s order by ctime limit ?,? "
_insertDMTask = "INSERT INTO dm_task(title,creator,regex,keywords,ips,mids,cids,start,end,state,sub) VALUES(?,?,?,?,?,?,?,?,?,?,?)"
_insertDMSubTask = "INSERT INTO dm_sub_task(task_id,operation,start,rate) VALUES(?,?,?,?)"
_updateDMTaskState = "UPDATE dm_task SET state=? WHERE id IN (%s) AND state!=?"
_reviewDmTask = "UPDATE dm_task SET state=?,reviewer=?,topic=? WHERE id=? AND state=0"
_selectTaskByID = "SELECT id,title,creator,reviewer,regex,keywords,ips,mids,cids,start,end,qcount,state,result,ctime,mtime FROM dm_task WHERE id=?"
_selectSubTask = "SELECT id,operation,rate,tcount,start,end FROM dm_sub_task WHERE task_id=?"
_editTaskPriority = "UPDATE dm_task SET priority=? WHERE id IN (%s)"
)
// TaskList dm task list
func (d *Dao) TaskList(c context.Context, taskSQL []string, pn, ps int64) (tasks []*model.TaskInfo, total int64, err error) {
var sql string
tasks = make([]*model.TaskInfo, 0)
if len(taskSQL) > 0 {
sql = fmt.Sprintf(" WHERE %s", strings.Join(taskSQL, " AND "))
}
countRow := d.biliDM.QueryRow(c, _countDMTask+sql)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount(%s) error(%v)", _countDMTask+sql, err)
return
}
rows, err := d.biliDM.Query(c, fmt.Sprintf(_selectDMTask, sql), (pn-1)*ps, ps)
if err != nil {
log.Error("biliDM.Query(%s) error(%v)", fmt.Sprintf(_selectDMTask, sql), err)
return
}
defer rows.Close()
for rows.Next() {
task := &model.TaskInfo{}
var cTime, mTime time.Time
if err = rows.Scan(&task.ID, &task.Title, &task.Creator, &task.Reviewer, &task.State, &task.Result, &cTime, &mTime); err != nil {
log.Error("biliDM.Scan(%s) error(%v)", fmt.Sprintf(_selectDMTask, sql), err)
return
}
task.Ctime = cTime.Format("2006-01-02 15:04:05")
task.Mtime = mTime.Format("2006-01-02 15:04:05")
tasks = append(tasks, task)
}
if err = rows.Err(); err != nil {
log.Error("biliDM.rows.Err() error(%v)", err)
}
return
}
// AddTask add dm task
func (d *Dao) AddTask(tx *sql.Tx, v *model.AddTaskArg, sub int32) (taskID int64, err error) {
var sTime, eTime time.Time
if sTime, err = time.ParseInLocation("2006-01-02 15:04:05", v.Start, time.Local); err != nil {
log.Error("d.AddTask time.Parse(%s) error(%v)", v.Start, err)
return
}
if eTime, err = time.ParseInLocation("2006-01-02 15:04:05", v.End, time.Local); err != nil {
log.Error("d.AddTask time.Parse(%s) error(%v)", v.End, err)
return
}
// regex add slash
rows, err := tx.Exec(_insertDMTask, v.Title, v.Creator, v.Regex, v.KeyWords, v.IPs, v.Mids, v.Cids, sTime, eTime, v.State, sub)
if err != nil {
log.Error("tx.Exec(%s params:%+v) error(%v)", _insertDMTask, v, err)
return
}
return rows.LastInsertId()
}
// AddSubTask add dm sub task
func (d *Dao) AddSubTask(tx *sql.Tx, taskID int64, operation int32, start string, rate int32) (id int64, err error) {
sTime, err := time.ParseInLocation("2006-01-02 15:04:05", start, time.Local)
if err != nil {
log.Error("d.AddSubTask time.Parse(%s) error(%v)", start, err)
return
}
rows, err := tx.Exec(_insertDMSubTask, taskID, operation, sTime, rate)
if err != nil {
log.Error("tx.Exec(%s,%d,%d,%s,%d) error(%v)", _insertDMSubTask, taskID, operation, start, rate, err)
return
}
return rows.LastInsertId()
}
// EditTaskState .
func (d *Dao) EditTaskState(c context.Context, v *model.EditTasksStateArg) (affected int64, err error) {
updateSQL := fmt.Sprintf(_updateDMTaskState, v.IDs)
rows, err := d.biliDM.Exec(c, updateSQL, v.State, v.State)
if err != nil {
log.Error("d.EditTaskState.Exec(id:%s, state:%d) error(%v)", v.IDs, v.State, err)
return
}
return rows.RowsAffected()
}
// EditTaskPriority .
func (d *Dao) EditTaskPriority(c context.Context, ids string, priority int64) (affected int64, err error) {
updateSQL := fmt.Sprintf(_editTaskPriority, ids)
rows, err := d.biliDM.Exec(c, updateSQL, priority)
if err != nil {
log.Error("d.EditTaskPriority.Exec(ids:%s, priority:%d) error(%v)", ids, priority, err)
return
}
return rows.RowsAffected()
}
// ReviewTask .
func (d *Dao) ReviewTask(c context.Context, v *model.ReviewTaskArg) (affected int64, err error) {
row, err := d.biliDM.Exec(c, _reviewDmTask, v.State, v.Reviewer, v.Topic, v.ID)
if err != nil {
log.Error("d.ReviewTask.Exec(id:%d, state:%d) error(%v)", v.ID, v.State, err)
return
}
return row.RowsAffected()
}
// TaskView .
func (d *Dao) TaskView(c context.Context, id int64) (task *model.TaskView, err error) {
task = new(model.TaskView)
row := d.biliDM.QueryRow(c, _selectTaskByID, id)
var sTime, eTime, cTime, mTime time.Time
if err = row.Scan(&task.ID, &task.Title, &task.Creator, &task.Reviewer, &task.Regex, &task.KeyWords, &task.IPs, &task.Mids, &task.Cids, &sTime, &eTime, &task.QCount, &task.State, &task.Result, &cTime, &mTime); err != nil {
if err == sql.ErrNoRows {
err = ecode.NothingFound
}
log.Error("biliDM.Scan(%s, id:%d) error(%v)", _selectTaskByID, id, err)
return
}
task.Start = sTime.Format("2006-01-02 15:04:05")
task.End = eTime.Format("2006-01-02 15:04:05")
task.Ctime = cTime.Format("2006-01-02 15:04:05")
task.Mtime = mTime.Format("2006-01-02 15:04:05")
return
}
// SubTask .
func (d *Dao) SubTask(c context.Context, id int64) (subTask *model.SubTask, err error) {
// TODO: operation time
subTask = new(model.SubTask)
row := d.biliDM.QueryRow(c, _selectSubTask, id)
var sTime time.Time
var eTime time.Time
if err = row.Scan(&subTask.ID, &subTask.Operation, &subTask.Rate, &subTask.Tcount, &sTime, &eTime); err != nil {
if err == sql.ErrNoRows {
err = nil
subTask = nil
}
log.Error("biliDM.Scan(%s, taskID:%d) error*(%v)", _selectSubTask, id, err)
return
}
subTask.Start = sTime.Format("2006-01-02 15:04:05")
subTask.End = eTime.Format("2006-01-02 15:04:05")
return
}

View File

@@ -0,0 +1,159 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/dm/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoTaskList(t *testing.T) {
convey.Convey("TaskList", t, func(ctx convey.C) {
var (
c = context.Background()
taskSQL = []string{}
pn = int64(1)
ps = int64(50)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
tasks, total, err := testDao.TaskList(c, taskSQL, pn, ps)
ctx.Convey("Then err should be nil.tasks,total should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(total, convey.ShouldNotBeNil)
t.Logf("====%d", total)
ctx.So(tasks, convey.ShouldNotBeNil)
// t.Logf("====%+v", tasks[0])
})
})
})
}
func TestDaoAddTask(t *testing.T) {
convey.Convey("AddTask", t, func(ctx convey.C) {
var (
tx, _ = testDao.BeginBiliDMTrans(context.Background())
v = &model.AddTaskArg{
Title: "test",
Start: "2016-10-30 16:12:21",
End: "2018-10-30 16:12:21",
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
taskID, err := testDao.AddTask(tx, v, 1)
ctx.Convey("Then err should be nil.taskID should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(taskID, convey.ShouldNotBeNil)
t.Logf("====%d", taskID)
tx.Commit()
})
})
})
}
func TestDaoAddSubTask(t *testing.T) {
convey.Convey("AddSubTask", t, func(ctx convey.C) {
var (
tx, _ = testDao.BeginBiliDMTrans(context.Background())
taskID = int64(8)
operation = int32(0)
start = "2018-10-30 16:12:21"
rate = int32(100)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
id, err := testDao.AddSubTask(tx, taskID, operation, start, rate)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
t.Logf("====%d", id)
})
tx.Commit()
})
})
}
func TestDaoEditTaskState(t *testing.T) {
convey.Convey("EditTaskState", t, func(ctx convey.C) {
var (
c = context.Background()
v = &model.EditTasksStateArg{
IDs: "1,7",
State: 1,
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affected, err := testDao.EditTaskState(c, v)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTaskView(t *testing.T) {
convey.Convey("TaskView", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
task, err := testDao.TaskView(c, id)
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", task)
})
})
})
}
func TestDaoSubTask(t *testing.T) {
convey.Convey("SubTask", t, func(ctx convey.C) {
var (
c = context.Background()
id = int64(8)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
subTask, err := testDao.SubTask(c, id)
ctx.Convey("Then err should be nil.subTask should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(subTask, convey.ShouldNotBeNil)
t.Logf("====%+v", subTask)
})
})
})
}
func TestDaoReviewTask(t *testing.T) {
convey.Convey("ReviewTask", t, func(ctx convey.C) {
var (
c = context.Background()
v = &model.ReviewTaskArg{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affected, err := testDao.ReviewTask(c, v)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoEditTaskPriority(t *testing.T) {
convey.Convey("EditTaskPriority", t, func(ctx convey.C) {
var (
c = context.Background()
ids = "12"
priority = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affected, err := testDao.EditTaskPriority(c, ids, priority)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,183 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/dm/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestUpSubjectAttr(t *testing.T) {
Convey("test update subject attr", t, func() {
_, err := testDao.UpSubjectAttr(context.TODO(), 1, 1221, 16)
So(err, ShouldBeNil)
})
}
func TestUpSubjectCount(t *testing.T) {
Convey("update count in subject", t, func() {
_, err := testDao.UpSubjectCount(context.TODO(), 1, 1221, 1, 1)
So(err, ShouldBeNil)
})
}
func TestIncrSubjectCount(t *testing.T) {
Convey("update count in subject", t, func() {
_, err := testDao.IncrSubjectCount(context.TODO(), 1, 1221, 1)
So(err, ShouldBeNil)
})
}
func TestIncrSubMoveCount(t *testing.T) {
Convey("update move count in subject", t, func() {
_, err := testDao.IncrSubMoveCount(context.TODO(), 1, 1221, 1)
So(err, ShouldBeNil)
})
}
func TestIncrSubCount(t *testing.T) {
Convey("update count in subject", t, func() {
_, err := testDao.IncrSubjectCount(context.TODO(), 1, 1221, 1)
So(err, ShouldBeNil)
})
}
func TestUpSubjectPool(t *testing.T) {
Convey("update childpool in subject", t, func() {
_, err := testDao.UpSubjectPool(context.TODO(), 1, 1221, 1)
So(err, ShouldBeNil)
})
}
func TestUpSubjectState(t *testing.T) {
Convey("update state in subject", t, func() {
_, err := testDao.UpSubjectState(context.TODO(), 1, 1221, 1)
So(err, ShouldBeNil)
})
}
func TestUpSubjectMaxlimit(t *testing.T) {
Convey("update maxlimit in subject", t, func() {
_, err := testDao.UpSubjectMaxlimit(context.TODO(), 1, 1221, 8000)
So(err, ShouldBeNil)
})
}
func TestSubject(t *testing.T) {
var (
tp int32 = 1
oid int64 = 1508
c = context.TODO()
)
Convey("subject test", t, func() {
_, err := testDao.Subject(c, tp, oid)
So(err, ShouldBeNil)
})
}
func TestSubjects(t *testing.T) {
oids := []int64{1221, 1321}
Convey("subject test", t, func() {
res, err := testDao.Subjects(context.TODO(), 1, oids)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}
func TestChangeReportStat(t *testing.T) {
var (
c = context.TODO()
cid int64 = 1
dmids = []int64{1, 2, 3, 4, 5}
state = model.StatFirstDelete
)
Convey("update dm report state and err shoule be nil", t, func() {
err := testDao.ChangeReportStat(c, cid, dmids, state)
So(err, ShouldBeNil)
})
}
func TestIgnoreReport(t *testing.T) {
var (
cid int64 = 1
c = context.TODO()
dmids = []int64{1, 2, 3, 4, 5}
state int8 = 4
)
Convey("ignore dm report state and err shoule be nil", t, func() {
err := testDao.IgnoreReport(c, cid, dmids, state)
So(err, ShouldBeNil)
})
}
func TestReports(t *testing.T) {
var (
cid int64 = 10109027
c = context.TODO()
dmids = []int64{719218595}
)
Convey("", t, func() {
res, err := testDao.Reports(c, cid, dmids)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
for _, r := range res {
t.Logf("===:%+v", r)
}
})
}
func TestReportUsers(t *testing.T) {
var (
tableID int64 = 1
c = context.TODO()
state = model.NoticeUnsend
dmids = []int64{1, 2, 3, 4, 5}
)
Convey("", t, func() {
_, err := testDao.ReportUsers(c, tableID, dmids, state)
So(err, ShouldBeNil)
})
}
func TestUpReportUserState(t *testing.T) {
var (
tableID int64 = 1
c = context.TODO()
state = model.NoticeSend
dmids = []int64{1, 2, 3, 4, 5}
)
Convey("", t, func() {
_, err := testDao.UpReportUserState(c, tableID, dmids, state)
So(err, ShouldBeNil)
})
}
func TestAddReportLog(t *testing.T) {
var (
tableID int64 = 1
c = context.TODO()
lg = &model.ReportLog{
ID: 1,
Did: 1234,
AdminID: 1,
}
)
Convey("", t, func() {
err := testDao.AddReportLog(c, tableID, []*model.ReportLog{lg})
So(err, ShouldBeNil)
})
}
func TestReportLog(t *testing.T) {
var (
dmid int64 = 719918888
c = context.TODO()
)
Convey("", t, func() {
res, err := testDao.ReportLog(c, dmid)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,93 @@
package dao
import (
"context"
"go-common/app/admin/main/dm/model"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_InstTrJobSQL = "INSERT INTO dm_transfer_job(from_cid,to_cid,mid,offset,state) VALUES(?,?,?,?,?)"
_countTransList = "SELECT count(*) FROM dm_transfer_job WHERE to_cid=?"
_countTransListState = "SELECT count(*) FROM dm_transfer_job WHERE to_cid=? AND state=?"
_TransList = "SELECT id,from_cid,to_cid,state,ctime FROM dm_transfer_job WHERE to_cid=? limit ?,?"
_TransListState = "SELECT id,from_cid,to_cid,state,ctime FROM dm_transfer_job WHERE to_cid=? AND state=? limit ?, ?"
_selTransferID = "SELECT id,from_cid,to_cid,mid,offset,state,ctime,mtime from dm_transfer_job WHERE id=?"
_uptTransferSQL = "UPDATE dm_transfer_job SET state=? WHERE id=?"
)
// InsertTransferJob add transfer job
func (d *Dao) InsertTransferJob(c context.Context, from, to, mid int64, offset float64, state int8) (affect int64, err error) {
row, err := d.biliDM.Exec(c, _InstTrJobSQL, from, to, mid, offset, state)
if err != nil {
log.Error("biliDM.Exec(%s, %d %d %d %v) error(%v)", _InstTrJobSQL, from, to, mid, offset, err)
return
}
return row.LastInsertId()
}
// TransferList transfer list
func (d *Dao) TransferList(c context.Context, cid, state, pn, ps int64) (res []*model.TransList, total int64, err error) {
var rows *sql.Rows
res = make([]*model.TransList, 0)
if state == int64(model.TransferJobStateAll) {
countRow := d.biliDM.QueryRow(c, _countTransList, cid)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err = d.biliDM.Query(c, _TransList, cid, (pn-1)*ps, ps)
if err != nil {
log.Error("biliDM.Query(%s, %d ) error(%v)", _TransList, cid, err)
return
}
} else {
countRow := d.biliDM.QueryRow(c, _countTransListState, cid, state)
if err = countRow.Scan(&total); err != nil {
log.Error("row.ScanCount error(%v)", err)
return
}
rows, err = d.biliDM.Query(c, _TransListState, cid, state, (pn-1)*ps, ps)
if err != nil {
log.Error("biliDM.Query(%s, %d, %d) error(%v)", _TransList, cid, state, err)
return
}
}
defer rows.Close()
for rows.Next() {
dm := &model.TransList{}
if err = rows.Scan(&dm.ID, &dm.From, &dm.To, &dm.State, &dm.Ctime); err != nil {
log.Error("rows.Scan error(%v)", err)
return
}
res = append(res, dm)
}
return
}
// CheckTransferID check transfer job state by id
func (d *Dao) CheckTransferID(c context.Context, id int64) (job *model.TransferJobInfo, err error) {
job = new(model.TransferJobInfo)
row := d.biliDM.QueryRow(c, _selTransferID, id)
if err = row.Scan(&job.ID, &job.FromCID, &job.ToCID, &job.MID, &job.Offset, &job.State, &job.Ctime, &job.Mtime); err != nil {
if err == sql.ErrNoRows {
job = nil
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}
// SetTransferState change transfer state
func (d *Dao) SetTransferState(c context.Context, id int64, state int8) (affect int64, err error) {
row, err := d.biliDM.Exec(c, _uptTransferSQL, state, id)
if err != nil {
log.Error("d.biliDM.Exec(%s,%d) error(%v)", _uptTransferSQL, id, err)
return
}
return row.RowsAffected()
}

View File

@@ -0,0 +1,51 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestInsertTransferJob(t *testing.T) {
var (
from, to, mid int64 = 1, 2, 3
offset = 1.11
)
Convey("insert a transfer job to mysql", t, func() {
_, err := testDao.InsertTransferJob(context.TODO(), from, to, mid, offset, 0)
So(err, ShouldBeNil)
})
}
func TestTransferList(t *testing.T) {
var cid, state int64 = 2, 3
Convey("test transfer job list ", t, func() {
res, _, err := testDao.TransferList(context.TODO(), cid, state, 1, 20)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestCheckTransferID(t *testing.T) {
var (
c = context.TODO()
id int64 = 265
)
Convey("test check trans by id", t, func() {
_, err := testDao.CheckTransferID(c, id)
So(err, ShouldBeNil)
})
}
func TestSetTransferState(t *testing.T) {
var (
c = context.TODO()
id int64 = 265
state int8
)
Convey("test change transfer job state", t, func() {
_, err := testDao.SetTransferState(c, id, state)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,56 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"query_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/dm/conf:go_default_library",
"//library/log:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"query.go",
],
importpath = "go-common/app/admin/main/dm/dao/oplog",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/dm/conf:go_default_library",
"//app/admin/main/dm/model/oplog:go_default_library",
"//library/conf/env:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/pkg/errors: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"],
)

View File

@@ -0,0 +1,23 @@
package oplog
import (
"go-common/app/admin/main/dm/conf"
bm "go-common/library/net/http/blademaster"
)
// Dao dao struct for querying infoc data storing in hbase
type Dao struct {
httpCli *bm.Client
key, secret, infocQueryURL string
}
// New new a Dao instance and init.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
key: c.HTTPInfoc.ClientConfig.Key,
secret: c.HTTPInfoc.ClientConfig.Secret,
httpCli: bm.NewClient(c.HTTPInfoc.ClientConfig),
infocQueryURL: c.HTTPInfoc.InfocQueryURL,
}
return
}

View File

@@ -0,0 +1,24 @@
package oplog
import (
"testing"
"go-common/app/admin/main/dm/conf"
"go-common/library/log"
)
var (
dao *Dao
)
func TestMain(m *testing.M) {
var err error
conf.ConfPath = "../../cmd/dm-admin-test.toml"
if err = conf.Init(); err != nil {
log.Error("conf.Init(%v)", err)
return
}
dao = New(conf.Conf)
m.Run()
//log.Close()
}

View File

@@ -0,0 +1,154 @@
package oplog
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"math"
"net/url"
"sort"
"strconv"
"strings"
"time"
"go-common/app/admin/main/dm/model/oplog"
"go-common/library/conf/env"
"go-common/library/log"
xhttp "net/http"
pkgerr "github.com/pkg/errors"
)
const (
_singleQueryDMLogHbase = `{"startRow": "%s","stopRow": "%s","columns": {"family":"%s"}}`
_userAgent = "User-Agent"
)
var (
signParams = []string{"appKey", "timestamp", "version"}
)
// QueryOpLogs 查找弹幕操作日志前方高能这是一段极其恶心的代码1. 数据平台的key和secret是根据个人用户生成目前是我的账号madou 2.sign算法是根据appkeytimestampversion生成并大小写敏感
func (d *Dao) QueryOpLogs(c context.Context, dmid int64) (infos []*oplog.InfocResult, err error) {
v := make(url.Values, 8)
v.Set("appKey", d.key)
v.Set("signMethod", "md5")
v.Set("timestamp", time.Now().Format("2006-01-02 15:04:05"))
v.Set("version", "1.0")
//默认只查询三个月
startRow, stopRow := d.makeRowKeyScope(dmid, -3)
query := fmt.Sprintf(_singleQueryDMLogHbase, startRow, stopRow, "i")
v.Set("query", query)
var res struct {
Code int `json:"code"`
Result []*oplog.InfocResult `json:"result"`
}
if err = d.doHTTPRequest(c, d.infocQueryURL, "", v, &res); err != nil {
log.Error("berserker url(%v), err(%v)", d.infocQueryURL+"?"+v.Encode(), err)
return
}
if res.Code == 200 && len(res.Result) > 0 {
infos = res.Result
}
return
}
// doHttpRequest make a http request for data platform api
func (d *Dao) doHTTPRequest(c context.Context, uri, ip string, params url.Values, res interface{}) (err error) {
enc, err := d.sign(params)
if err != nil {
err = pkgerr.Wrapf(err, "uri:%s,params:%v", uri, params)
return
}
if enc != "" {
uri = uri + "?" + enc
}
req, err := xhttp.NewRequest(xhttp.MethodGet, uri, nil)
if err != nil {
err = pkgerr.Wrapf(err, "method:%s,uri:%s", xhttp.MethodGet, uri)
return
}
req.Header.Set(_userAgent, "haoguanwei@bilibili.com "+env.AppID)
if err != nil {
return
}
return d.httpCli.Do(c, req, res)
}
// Sign calc appkey and appsecret sign.
func (d *Dao) sign(params url.Values) (query string, err error) {
tmp := params.Encode()
signTmp := d.encode(params)
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
var b bytes.Buffer
b.WriteString(d.secret)
b.WriteString(signTmp)
b.WriteString(d.secret)
mh := md5.Sum(b.Bytes())
// query
var qb bytes.Buffer
qb.WriteString(tmp)
qb.WriteString("&sign=")
qb.WriteString(strings.ToUpper(hex.EncodeToString(mh[:])))
query = qb.String()
return
}
// Encode encodes the values into ``URL encoded'' form
// ("bar=baz&foo=quux") sorted by key.
func (d *Dao) encode(v url.Values) string {
if v == nil {
return ""
}
var buf bytes.Buffer
keys := make([]string, 0, len(v))
for k := range v {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
found := false
for _, p := range signParams {
if p == k {
found = true
break
}
}
if !found {
continue
}
vs := v[k]
prefix := k
for _, v := range vs {
buf.WriteString(prefix)
buf.WriteString(v)
}
}
return buf.String()
}
// rowkey存储方式 [dmid倒序补零20位][(Long.Max_Value - timestamp) 的结果后10位]
func (d *Dao) makeRowKeyScope(dmid int64, months int) (startRow, endRow string) {
endTime := time.Now()
startTime := endTime.AddDate(0, months, 0)
startTmp := strconv.FormatInt(math.MaxInt64-startTime.Unix(), 10)
endTmp := strconv.FormatInt(math.MaxInt64-endTime.Unix(), 10)
endRow = d.reverse(fmt.Sprintf("%020d", dmid)) + startTmp[len(startTmp)-10:]
startRow = d.reverse(fmt.Sprintf("%020d", dmid)) + endTmp[len(endTmp)-10:]
return
}
func (d *Dao) reverse(s string) string {
n := len(s)
runes := make([]rune, n)
for _, rune := range s {
n--
runes[n] = rune
}
return string(runes[n:])
}

View File

@@ -0,0 +1,20 @@
package oplog
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_QueryOpLogs(t *testing.T) {
var (
c = context.TODO()
dmid int64 = 1222
)
Convey("QueryOpLogs", t, func() {
rets, err := dao.QueryOpLogs(c, dmid)
So(err, ShouldBeNil)
So(len(rets), ShouldBeGreaterThan, 0)
})
}

View File

@@ -0,0 +1,513 @@
package dao
import (
"context"
"encoding/json"
"fmt"
"strconv"
"time"
"go-common/app/admin/main/dm/model"
"go-common/library/database/elastic"
"go-common/library/log"
"go-common/library/xstr"
)
var (
_dmMointorFields = []string{"id", "type", "pid", "oid", "state", "attr", "mcount", "ctime", "mtime", "mid", "title", "author"}
_dmReportFields = []string{"id", "dmid", "cid", "arc_aid", "arc_typeid", "dm_owner_uid", "dm_msg", "count", "content", "up_op",
"state", "uid", "rp_time", "reason", "arc_title", "dm_deleted", "arc_mid", "pool_id", "model", "score", "dm_ctime", "ctime", "mtime"}
)
// return recent two years report search index.
func (d *Dao) rptSearchIndex() string {
year := time.Now().Year()
return fmt.Sprintf("dmreport_%d,dmreport_%d", year-1, year)
}
// SearchMonitor get monitor list from search
func (d *Dao) SearchMonitor(c context.Context, tp int32, pid, oid, mid int64, attr int32, kw, sort, order string, page, size int64) (data *model.SearchMonitorResult, err error) {
req := d.esCli.NewRequest("dm_monitor_list").Index("dm_monitoring").Fields(_dmMointorFields...).Pn(int(page)).Ps(int(size))
if tp > 0 {
req.WhereEq("type", tp)
}
if pid > 0 {
req.WhereEq("pid", pid)
}
if oid > 0 {
req.WhereEq("oid", oid)
}
if mid > 0 {
req.WhereEq("mid", mid)
}
if len(kw) > 0 {
req.WhereLike([]string{"title"}, []string{kw}, false, elastic.LikeLevelLow)
}
if attr != 0 {
req.WhereEq("attr_format", attr)
} else {
req.WhereIn("attr_format", []int64{int64(model.AttrSubMonitorBefore + 1), int64(model.AttrSubMonitorAfter + 1)})
}
if len(sort) > 0 && len(order) > 0 {
req.Order(order, sort)
}
if err = req.Scan(c, &data); err != nil {
log.Error("SearchMonitor:Scan params(%s) error(%v)", req.Params(), err)
return
}
if data == nil || data.Page == nil {
err = fmt.Errorf("data or data.Page nil")
log.Error("SearchMonitor params(%s) error(%v)", req.Params(), err)
return
}
return
}
// SearchReport2 .
func (d *Dao) SearchReport2(c context.Context, params *model.ReportListParams) (data *model.SearchReportResult, err error) {
req := d.esCli.NewRequest("dmreport").Index(d.rptSearchIndex()).Fields(_dmReportFields...).Ps(int(params.PageSize)).Pn(int(params.Page))
if len(params.Tids) > 0 {
req.WhereIn("arc_typeid", params.Tids)
}
if len(params.RpTypes) > 0 {
req.WhereIn("reason", params.RpTypes)
}
if params.Aid > 0 {
req.WhereEq("arc_aid", params.Aid)
}
if params.Cid > 0 {
req.WhereEq("cid", params.Cid)
}
if params.UID > 0 {
req.WhereEq("dm_owner_uid", params.UID)
} else {
req.WhereNot(elastic.NotTypeEq, "dm_owner_uid").WhereEq("dm_owner_uid", 0)
}
if params.RpUID > 0 {
req.WhereEq("uid", params.RpUID)
}
if len(params.States) > 0 {
req.WhereIn("state", params.States)
}
if len(params.UpOps) > 0 {
req.WhereIn("up_op", params.UpOps)
}
if params.Start != "" || params.End != "" {
req.WhereRange("rp_time", params.Start, params.End, elastic.RangeScopeLcRc)
}
if params.Keyword != "" {
req.WhereLike([]string{"dm_msg"}, []string{params.Keyword}, false, elastic.LikeLevelLow)
}
if len(params.Sort) > 0 && len(params.Order) > 0 {
req.Order(params.Order, params.Sort)
}
if err = req.Scan(c, &data); err != nil {
log.Error("SearchReport:Scan params(%s) error(%v)", req.Params(), err)
return
}
if data == nil || data.Page == nil {
err = fmt.Errorf("data or data.Page nil")
log.Error("SearchReport params(%s) error(%v)", req.Params(), err)
return
}
return
}
// SearchReport get report list from search
func (d *Dao) SearchReport(c context.Context, page, size int64, start, end, order, sort, keyword string, tid, rpID, state, upOp []int64, rt *model.Report) (data *model.SearchReportResult, err error) {
req := d.esCli.NewRequest("dmreport").Index(d.rptSearchIndex()).Fields(_dmReportFields...).Ps(int(size)).Pn(int(page))
if len(tid) > 0 {
req.WhereIn("arc_typeid", tid)
}
if len(rpID) > 0 {
req.WhereIn("reason", rpID)
}
if rt.Aid != -1 {
req.WhereEq("arc_aid", rt.Aid)
}
if rt.Cid != -1 {
req.WhereEq("cid", rt.Cid)
}
if rt.UID != -1 {
req.WhereEq("dm_owner_uid", rt.UID)
} else {
req.WhereNot(elastic.NotTypeEq, "dm_owner_uid").WhereEq("dm_owner_uid", 0)
}
if rt.RpUID != -1 {
req.WhereEq("uid", rt.RpUID)
}
if len(state) > 0 {
req.WhereIn("state", state)
}
if len(upOp) > 0 {
req.WhereIn("up_op", (upOp))
}
if start != "" || end != "" {
req.WhereRange("rp_time", start, end, elastic.RangeScopeLcRc)
}
if keyword != "" {
req.WhereLike([]string{"dm_msg"}, []string{keyword}, false, elastic.LikeLevelLow)
}
if len(sort) > 0 && len(order) > 0 {
req.Order(order, sort)
}
if err = req.Scan(c, &data); err != nil {
log.Error("SearchReport:Scan params(%s) error(%v)", req.Params(), err)
return
}
if data == nil || data.Page == nil {
err = fmt.Errorf("data or data.Page nil")
log.Error("SearchReport params(%s) error(%v)", req.Params(), err)
return
}
return
}
// SearchReportByID search report by cid and dmids.
func (d *Dao) SearchReportByID(c context.Context, dmids []int64) (data *model.SearchReportResult, err error) {
req := d.esCli.NewRequest("dmreport").Index(d.rptSearchIndex()).Fields(_dmReportFields...).Ps(100)
req.WhereIn("dmid", dmids)
if err = req.Scan(c, &data); err != nil {
log.Error("SearchReportByID:Scan params(%s) error(%v)", req.Params(), err)
return
}
if data == nil || data.Page == nil {
err = fmt.Errorf("data or data.Page nil")
log.Error("SearchReportByID params(%s) error(%v)", req.Params(), err)
return
}
return
}
// UptSearchReport 强制更新举报搜索索引 使用 v3
func (d *Dao) UptSearchReport(c context.Context, uptRpts []*model.UptSearchReport) (err error) {
upt := d.esCli.NewUpdate("dmreport")
var t time.Time
for _, rpt := range uptRpts {
t, err = time.ParseInLocation("2006-01-02 15:04:05", rpt.Ctime, time.Local)
if err != nil {
log.Error("time.ParseInLocation(%s) error(%v)", rpt.Ctime, err)
return
}
upt.AddData(fmt.Sprintf("dmreport_%d", t.Year()), rpt)
}
if err = upt.Do(c); err != nil {
log.Error("update.Do() error(%v)", err)
}
return
}
// SearchDM 搜索弹幕
func (d *Dao) SearchDM(c context.Context, p *model.SearchDMParams) (data *model.SearchDMData, err error) {
var (
order = "ctime"
sort = "desc"
req *elastic.Request
)
req = d.esCli.NewRequest("dm").Index(fmt.Sprintf("dm_%03d", p.Oid%_indexSharding)).Fields("id").Ps(int(p.Size)).Pn(int(p.Page))
req.WhereEq("oid", p.Oid)
if p.Mid != model.CondIntNil {
req.WhereEq("mid", p.Mid)
}
if p.State != "" {
if states, err1 := xstr.SplitInts(p.State); err1 == nil {
req.WhereIn("state", states)
}
}
if p.Pool != "" {
if pools, err1 := xstr.SplitInts(p.Pool); err1 == nil {
req.WhereIn("pool", pools)
}
}
if p.Attrs != "" {
if attrs, err1 := xstr.SplitInts(p.Attrs); err1 == nil {
req.WhereIn("attr_format", attrs)
}
}
if p.IP != "" {
req.WhereEq("ip_format", p.IP)
}
switch {
case p.ProgressFrom != model.CondIntNil && p.ProgressTo != model.CondIntNil:
req.WhereRange("progress", p.ProgressFrom, p.ProgressTo, elastic.RangeScopeLcRc)
case p.ProgressFrom != model.CondIntNil:
req.WhereRange("progress", p.ProgressFrom, nil, elastic.RangeScopeLcRc)
case p.ProgressTo != model.CondIntNil:
req.WhereRange("progress", nil, p.ProgressTo, elastic.RangeScopeLcRc)
}
switch {
case p.CtimeFrom != model.CondIntNil && p.CtimeTo != model.CondIntNil:
req.WhereRange("ctime", time.Unix(p.CtimeFrom, 0).Format("2006-01-02 15:04:05"), time.Unix(p.CtimeTo, 0).Format("2006-01-02 15:04:05"), elastic.RangeScopeLcRc)
case p.CtimeFrom != model.CondIntNil:
req.WhereRange("ctime", time.Unix(p.CtimeFrom, 0).Format("2006-01-02 15:04:05"), nil, elastic.RangeScopeLcRc)
case p.CtimeTo != model.CondIntNil:
req.WhereRange("ctime", nil, time.Unix(p.CtimeTo, 0).Format("2006-01-02 15:04:05"), elastic.RangeScopeLcRc)
}
if p.Keyword != "" {
req.WhereLike([]string{"kwmsg"}, []string{p.Keyword}, false, elastic.LikeLevelHigh)
}
if p.Order != "" {
order = p.Order
}
if p.Sort == "asc" {
sort = p.Sort
}
req.Order(order, sort)
if err = req.Scan(c, &data); err != nil {
log.Error("SearchDM:Scan params(%s) error(%v)", req.Params(), err)
return
}
if data == nil || data.Page == nil {
err = fmt.Errorf("data or data.Page nil")
log.Error("SearchDM params(%s) error(%v)", req.Params(), err)
return
}
return
}
// SearchProtectCount get protected dm count.
func (d *Dao) SearchProtectCount(c context.Context, tp int32, oid int64) (count int64, err error) {
var res struct {
Result map[string][]struct {
Key string `json:"key"`
Count int64 `json:"doc_count"`
} `json:"result"`
}
order := []map[string]string{{"attr": "desc"}}
req := d.esCli.NewRequest("dm").Fields("attr").Index(fmt.Sprintf("dm_%03d", d.hitIndex(oid)))
req.WhereEq("oid", oid).WhereIn("attr_format", "1").GroupBy(elastic.EnhancedModeGroupBy, "attr", order)
req.Pn(1).Ps(10)
if err = req.Scan(c, &res); err != nil {
log.Error("req.Scan() error(%v)", err)
return
}
if values, ok := res.Result["group_by_attr"]; ok {
for _, v := range values {
count = count + v.Count
}
}
return
}
// UpSearchDMState 通知搜索服务更新弹幕状态
func (d *Dao) UpSearchDMState(c context.Context, tp int32, state int32, dmidM map[int64][]int64) (err error) {
upt := d.esCli.NewUpdate("dm")
for oid, dmids := range dmidM {
for _, dmid := range dmids {
data := &model.UptSearchDMState{
ID: dmid,
Oid: oid,
State: state,
Type: tp,
Mtime: time.Now().Format("2006-01-02 15:04:05"),
}
upt.AddData(fmt.Sprintf("dm_%03d", oid%_indexSharding), data)
}
}
if err = upt.Do(c); err != nil {
log.Error("update.Do() params(%s) error(%v)", upt.Params(), err)
}
return
}
// UpSearchDMPool 通知搜索服务更新弹幕池
func (d *Dao) UpSearchDMPool(c context.Context, tp int32, oid int64, pool int32, dmids []int64) (err error) {
upt := d.esCli.NewUpdate("dm")
for _, dmid := range dmids {
data := &model.UptSearchDMPool{
ID: dmid,
Oid: oid,
Pool: pool,
Type: tp,
Mtime: time.Now().Format("2006-01-02 15:04:05"),
}
upt.AddData(fmt.Sprintf("dm_%03d", oid%_indexSharding), data)
}
if err = upt.Do(c); err != nil {
log.Error("update.Do() params(%s) error(%v)", upt.Params(), err)
}
return
}
// UpSearchDMAttr 通知搜索服务更新弹幕属性
func (d *Dao) UpSearchDMAttr(c context.Context, tp int32, oid int64, attr int32, dmids []int64) (err error) {
var bits []int64
for k, v := range strconv.FormatInt(int64(attr), 2) {
if v == 49 {
bits = append(bits, int64(k+1))
}
}
upt := d.esCli.NewUpdate("dm")
for _, dmid := range dmids {
data := &model.UptSearchDMAttr{
ID: dmid,
Oid: oid,
Attr: attr,
AttrFormat: bits,
Type: tp,
Mtime: time.Now().Format("2006-01-02 15:04:05"),
}
upt.AddData(fmt.Sprintf("dm_%03d", oid%_indexSharding), data)
}
if err = upt.Do(c); err != nil {
log.Error("update.Do() params(%s) error(%v)", upt.Params(), err)
}
return
}
// SearchSubjectLog get subject log
func (d *Dao) SearchSubjectLog(c context.Context, tp int32, oid int64) (data []*model.SubjectLog, err error) {
req := d.esCli.NewRequest("log_audit").Index("log_audit_31_all").Fields("uid", "uname", "oid", "ctime", "action", "extra_data").WhereEq("oid", oid).WhereEq("type", tp)
req.Ps(20).Order("ctime", "desc")
res := &model.SearchSubjectLog{}
if err = req.Scan(c, &res); err != nil || res == nil {
log.Error("SearchSubcetLog:Scan params(%s) error(%v)", req.Params(), err)
return
}
data = make([]*model.SubjectLog, 0)
s := new(struct {
Comment string `json:"comment"`
})
for _, v := range res.Result {
if err = json.Unmarshal([]byte(v.ExtraData), s); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", v.ExtraData, err)
return
}
log := &model.SubjectLog{
UID: v.UID,
Uname: v.Uname,
Oid: v.Oid,
Action: v.Action,
Comment: s.Comment,
Ctime: v.Ctime,
}
data = append(data, log)
}
return
}
// UpSearchRecentDMState .
func (d *Dao) UpSearchRecentDMState(c context.Context, tp int32, state int32, dmidM map[int64][]int64) (err error) {
upt := d.esCli.NewUpdate("dm_home")
year, month, _ := time.Now().Date()
yearPre, monthPre, _ := time.Now().AddDate(0, -1, 0).Date()
for oid, dmids := range dmidM {
for _, dmid := range dmids {
data := &model.UptSearchDMState{
ID: dmid,
Oid: oid,
State: state,
Type: tp,
Mtime: time.Now().Format("2006-01-02 15:04:05"),
}
upt.AddData(fmt.Sprintf("dm_home_%v",
fmt.Sprintf("%d_%02d", yearPre, int(monthPre)),
), data)
upt.AddData(fmt.Sprintf("dm_home_%v",
fmt.Sprintf("%d_%02d", year, int(month)),
), data)
}
}
if err = upt.Do(c); err != nil {
log.Error("update.Do() params(%s) error(%v)", upt.Params(), err)
}
return
}
// UpSearchRecentDMPool .
func (d *Dao) UpSearchRecentDMPool(c context.Context, tp int32, oid int64, pool int32, dmids []int64) (err error) {
upt := d.esCli.NewUpdate("dm_home")
year, month, _ := time.Now().Date()
yearPre, monthPre, _ := time.Now().AddDate(0, -1, 0).Date()
for _, dmid := range dmids {
data := &model.UptSearchDMPool{
ID: dmid,
Oid: oid,
Pool: pool,
Type: tp,
Mtime: time.Now().Format("2006-01-02 15:04:05"),
}
upt.AddData(fmt.Sprintf("dm_home_%v",
fmt.Sprintf("%d_%02d", yearPre, int(monthPre)),
), data)
upt.AddData(fmt.Sprintf("dm_home_%v",
fmt.Sprintf("%d_%02d", year, int(month)),
), data)
}
if err = upt.Do(c); err != nil {
log.Error("update.Do() params(%s) error(%v)", upt.Params(), err)
}
return
}
// UpSearchRecentDMAttr .
func (d *Dao) UpSearchRecentDMAttr(c context.Context, tp int32, oid int64, attr int32, dmids []int64) (err error) {
var bits []int64
for k, v := range strconv.FormatInt(int64(attr), 2) {
if v == 49 {
bits = append(bits, int64(k+1))
}
}
upt := d.esCli.NewUpdate("dm_home")
year, month, _ := time.Now().Date()
yearPre, monthPre, _ := time.Now().AddDate(0, -1, 0).Date()
for _, dmid := range dmids {
data := &model.UptSearchDMAttr{
ID: dmid,
Oid: oid,
Attr: attr,
AttrFormat: bits,
Type: tp,
Mtime: time.Now().Format("2006-01-02 15:04:05"),
}
upt.AddData(fmt.Sprintf("dm_home_%v",
fmt.Sprintf("%d_%02d", yearPre, int(monthPre)),
), data)
upt.AddData(fmt.Sprintf("dm_home_%v",
fmt.Sprintf("%d_%02d", year, int(month)),
), data)
}
if err = upt.Do(c); err != nil {
log.Error("update.Do() params(%s) error(%v)", upt.Params(), err)
}
return
}
// SearchSubject get subject log list from search
func (d *Dao) SearchSubject(c context.Context, req *model.SearchSubjectReq) (data []int64, page *model.Page, err error) {
r := d.esCli.NewRequest("dm_monitor_list").Index("dm_monitoring").Fields("oid")
if len(req.Oids) > 0 {
r.WhereIn("oid", req.Oids)
}
if len(req.Mids) > 0 {
r.WhereIn("mid", req.Mids)
}
if len(req.Aids) > 0 {
r.WhereIn("pid", req.Aids)
}
if len(req.Attrs) > 0 {
r.WhereIn("attr_format", req.Attrs)
}
if req.State != model.CondIntNil {
r.WhereEq("state", req.State)
}
r.Ps(int(req.Ps)).Pn(int(req.Pn)).Order(req.Order, req.Sort)
res := &model.SearchSubjectResult{}
if err = r.Scan(c, &res); err != nil {
log.Error("SearchSubject:Scan params(%s) error(%v)", r.Params(), err)
return
}
if res == nil || res.Page == nil {
err = fmt.Errorf("data or data.Page nil")
log.Error("SearchSubject params(%s) error(%v)", r.Params(), err)
return
}
for _, v := range res.Result {
data = append(data, v.Oid)
}
page = res.Page
return
}

View File

@@ -0,0 +1,50 @@
package dao
import (
"context"
"go-common/app/admin/main/dm/model"
"go-common/library/database/elastic"
"go-common/library/log"
)
var (
_subtitleFields = []string{"oid", "id"}
)
// SearchSubtitle .
func (d *Dao) SearchSubtitle(c context.Context, arg *model.SubtitleSearchArg) (res *model.SearchSubtitleResult, err error) {
var (
req *elastic.Request
fields []string
)
fields = _subtitleFields
req = d.esCli.NewRequest("dm_subtitle").Index("subtitle").Fields(fields...).Pn(int(arg.Pn)).Ps(int(arg.Ps))
if arg.Aid > 0 {
req.WhereEq("aid", arg.Aid)
}
if arg.Mid > 0 {
req.WhereEq("mid", arg.Mid)
}
if arg.Oid > 0 {
req.WhereEq("oid", arg.Oid)
}
if arg.Mid > 0 {
req.WhereEq("mid", arg.Mid)
}
if arg.Status > 0 {
req.WhereEq("status", arg.Status)
}
if arg.UpperMid > 0 {
req.WhereEq("up_mid", arg.UpperMid)
}
if arg.Lan > 0 {
req.WhereEq("lan", arg.Lan)
}
req.Order("mtime", "desc")
if err = req.Scan(c, &res); err != nil {
log.Error("elastic search(%s) error(%v)", req.Params(), err)
return
}
return
}

View File

@@ -0,0 +1,27 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/dm/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestSearchSubtitle(t *testing.T) {
var (
arg = &model.SubtitleSearchArg{
Oid: int64(10131981),
}
)
Convey("search subtitles", t, func() {
res, err := testDao.SearchSubtitle(context.Background(), arg)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
t.Logf("res:%+v", res)
for _, rpt := range res.Result {
t.Logf("======%+v", rpt)
}
})
}

View File

@@ -0,0 +1,258 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/dm/model"
. "github.com/smartystreets/goconvey/convey"
)
func TestSearchMonitor(t *testing.T) {
var (
c = context.TODO()
aid, cid, mid, p, ps int64 = 0, 0, 0, 1, 50
kw, sort, order string = "", "", ""
attr = int32(0)
tp = int32(1)
)
Convey("get monitor list from search", t, func() {
res, err := testDao.SearchMonitor(c, tp, aid, cid, mid, attr, kw, sort, order, p, ps)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
t.Logf("res:%+v", res)
for _, rpt := range res.Result {
t.Logf("======%+v", rpt)
}
})
}
func TestSearchReports(t *testing.T) {
var (
c = context.TODO()
tid = []int64{}
rpID = []int64{1, 2}
upOp = []int64{0, 1, 2}
state = []int64{0, 1, 2}
rt = &model.Report{
Aid: -1,
UID: -1,
RpUID: -1,
RpType: -1,
Cid: -1,
}
)
Convey("", t, func() {
res, err := testDao.SearchReport(c, 1, 100, "", "", "rp_time", "desc", "", tid, rpID, state, upOp, rt)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
t.Logf("======%+v", res.Page)
for _, rpt := range res.Result {
t.Logf("======%+v", rpt)
}
})
}
func TestSearchReportByID(t *testing.T) {
var (
c = context.TODO()
dmids = []int64{719218372}
)
Convey("", t, func() {
res, err := testDao.SearchReportByID(c, dmids)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
t.Logf("===res:%v", res)
for _, rpt := range res.Result {
t.Logf("======%+v", rpt)
}
})
}
func TestSearchDM(t *testing.T) {
var (
c = context.TODO()
d = &model.SearchDMParams{
Type: 1,
Oid: 10131232,
Mid: model.CondIntNil,
ProgressFrom: model.CondIntNil,
ProgressTo: model.CondIntNil,
CtimeFrom: model.CondIntNil,
CtimeTo: model.CondIntNil,
State: "",
Pool: "",
Attrs: "1",
Page: 1,
Order: "id",
Sort: "asc",
}
)
Convey("", t, func() {
res, err := testDao.SearchDM(c, d)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
t.Logf("===page:%+v", res.Page)
for _, rpt := range res.Result {
t.Logf("======%+v", rpt)
}
})
}
func TestSendJudgement(t *testing.T) {
var (
c = context.TODO()
li = make([]*model.ReportJudge, 0)
)
i := &model.ReportJudge{
MID: 150781,
Operator: "zhang",
OperID: 121,
OContent: "test dm",
OTitle: "test archive",
OType: 2,
OURL: "https://www.bilibili.com",
ReasonType: 2,
AID: 11,
OID: 22,
RPID: 33,
Page: 1,
BTime: int64(1517824276),
}
li = append(li, i)
Convey("test send judgement", t, func() {
err := testDao.SendJudgement(c, li)
So(err, ShouldBeNil)
})
}
func TestUpSearchDMState(t *testing.T) {
var (
tp int32 = 1
state int32 = 2
dmids = map[int64][]int64{10131232: {1909860427366403, 1909932482887683}}
)
Convey("", t, func() {
err := testDao.UpSearchDMState(context.TODO(), tp, state, dmids)
So(err, ShouldBeNil)
})
}
func TestUpSearchDMAttr(t *testing.T) {
var (
tp int32 = 1
oid int64 = 10131232
attr int32 = 1
dmids = []int64{1909860427366403, 1909932482887683}
)
Convey("", t, func() {
err := testDao.UpSearchDMAttr(context.TODO(), tp, oid, attr, dmids)
So(err, ShouldBeNil)
})
}
func TestUpSearchDMPool(t *testing.T) {
var (
tp int32 = 1
oid int64 = 10131232
pool int32 = 1
dmids = []int64{1909860427366403, 1909932482887683}
)
Convey("", t, func() {
err := testDao.UpSearchDMPool(context.TODO(), tp, oid, pool, dmids)
So(err, ShouldBeNil)
})
}
func TestUptSearchReport(t *testing.T) {
var (
uptRpt = &model.UptSearchReport{
DMid: 719218991,
Ctime: "2018-04-27 11:06:46",
Mtime: "2018-06-07 11:06:46",
State: model.StatSecondIgnore,
}
uptRpts = []*model.UptSearchReport{uptRpt}
)
Convey("test update search report", t, func() {
err := testDao.UptSearchReport(context.TODO(), uptRpts)
So(err, ShouldBeNil)
})
}
func TestDaoSearchSubjectLog(t *testing.T) {
Convey("SearchSubjectLog", t, func() {
data, err := testDao.SearchSubjectLog(context.TODO(), 1, 1221)
So(err, ShouldBeNil)
So(data, ShouldNotBeNil)
for _, v := range data {
t.Logf("====%+v", v)
}
})
}
func TestDaoSearchSubject(t *testing.T) {
r := &model.SearchSubjectReq{
// Oids: []int64{10131821},
Mids: []int64{0},
Sort: "desc",
Order: "mtime",
Pn: 1,
Ps: 5,
State: int64(model.CondIntNil),
}
Convey("SearchSubject", t, func() {
data, page, err := testDao.SearchSubject(context.TODO(), r)
So(err, ShouldBeNil)
for _, v := range data {
t.Logf("====%+v", v)
}
t.Logf("====%+v", page)
})
}
func TestSearchProtectCount(t *testing.T) {
Convey("get protect dm count", t, func() {
count, err := testDao.SearchProtectCount(context.TODO(), 1, 1221)
So(err, ShouldBeNil)
t.Log(count)
})
}
func TestUpSearchRecemtDMState(t *testing.T) {
var (
tp int32 = 1
state int32 = 2
dmids = map[int64][]int64{10131232: {1909860427366403, 1909932482887683}}
)
Convey("", t, func() {
err := testDao.UpSearchRecentDMState(context.TODO(), tp, state, dmids)
So(err, ShouldBeNil)
})
}
func TestUpSearchRecentDMAttr(t *testing.T) {
var (
tp int32 = 1
oid int64 = 10131232
attr int32 = 1
dmids = []int64{1909860427366403, 1909932482887683}
)
Convey("", t, func() {
err := testDao.UpSearchRecentDMAttr(context.TODO(), tp, oid, attr, dmids)
So(err, ShouldBeNil)
})
}
func TestUpSearchRecentDMPool(t *testing.T) {
var (
tp int32 = 1
oid int64 = 10131232
pool int32 = 1
dmids = []int64{1909860427366403, 1909932482887683}
)
Convey("", t, func() {
err := testDao.UpSearchRecentDMPool(context.TODO(), tp, oid, pool, dmids)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,130 @@
package dao
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"net/http"
"net/url"
"sort"
"strings"
"time"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_selectQuery = "SELECT index.dmid,index.oid,index.mid,index.state,content.msg,b_long2ip(content.ip),content.ctime FROM ods.ods_dm_index AS index, ods.ods_dm_content AS content WHERE index.dmid=content.dmid AND index.state in (0,2,6) %s limit 1000000"
)
var (
signParams = []string{"appKey", "timestamp", "version"}
)
// SendTask send task to BI
func (d *Dao) SendTask(c context.Context, taskSQL []string) (statusURL string, err error) {
var (
sql string
res struct {
Code int64 `json:"code"`
StatusURL string `json:"jobStatusUrl"`
Message string `json:"msg"`
}
params = url.Values{}
)
if len(taskSQL) > 0 {
sql = fmt.Sprintf(" AND %s", strings.Join(taskSQL, " AND "))
} else {
err = ecode.RequestErr
return
}
log.Warn("send task sql(%s)", fmt.Sprintf(_selectQuery, sql))
params.Set("appKey", "672bc22888af701529e8b3052fd2c4a7")
params.Set("query", fmt.Sprintf(_selectQuery, sql))
params.Set("timestamp", time.Now().Format("2006-01-02 15:04:05"))
params.Set("version", "1.0")
params.Set("signMethod", "md5")
uri := d.berserkerURI + "?" + sign(params)
log.Warn("send task uri(%s)", uri)
req, err := http.NewRequest(http.MethodGet, uri, nil)
if err != nil {
log.Error("http.NewRequest(%s) error(%v)", uri, err)
return
}
for i := 0; i < 3; i++ {
if err = d.httpCli.Do(c, req, &res); err != nil {
log.Error("d.httpCli.Do error:%v", err)
time.Sleep(100 * time.Millisecond)
continue
}
if res.Code != 200 {
err = fmt.Errorf("uri:%s,code:%d", uri, res.Code)
log.Error("d.res.Code error:%v", err)
time.Sleep(100 * time.Millisecond)
continue
}
break
}
if err != nil {
log.Error("d.SendTask(uri:%s) error(%v)", uri, err)
}
return res.StatusURL, err
}
// Sign calculate appkey and appsecret sign.
func sign(params url.Values) (query string) {
tmp := params.Encode()
signTmp := encode(params)
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
var b bytes.Buffer
b.WriteString("bee5e4b744a22a59abbaecc7ade5de9c")
b.WriteString(signTmp)
b.WriteString("bee5e4b744a22a59abbaecc7ade5de9c")
mh := md5.Sum(b.Bytes())
// fmt.Println(b.String())
// query
var qb bytes.Buffer
qb.WriteString(tmp)
qb.WriteString("&sign=")
qb.WriteString(strings.ToUpper(hex.EncodeToString(mh[:])))
query = qb.String()
return
}
// Encode encodes the values into ``sign encoded'' form
// ("barbazfooquux") sorted by key.
func encode(v url.Values) string {
if v == nil {
return ""
}
var buf bytes.Buffer
keys := make([]string, 0, len(v))
for k := range v {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
found := false
for _, p := range signParams {
if p == k {
found = true
break
}
}
if !found {
continue
}
vs := v[k]
prefix := k
for _, v := range vs {
buf.WriteString(prefix)
buf.WriteString(v)
}
}
return buf.String()
}

View File

@@ -0,0 +1,49 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSendTask(t *testing.T) {
convey.Convey("SendTask", t, func(ctx convey.C) {
var (
c = context.Background()
taskSQL = []string{"index.mid=3458517", "content.log_date<=20181111"}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
statusURL, err := testDao.SendTask(c, taskSQL)
ctx.Convey("Then err should be nil.statusURL should not be nil.", func(ctx convey.C) {
// ctx.So(err, convey.ShouldBeNil)
// ctx.So(statusURL, convey.ShouldNotBeNil)
t.Logf("%v %s\n", err, statusURL)
})
})
})
}
// func TestBerserker(t *testing.T) {
// params := url.Values{}
// params.Set("appKey", "672bc22888af701529e8b3052fd2c4a7")
// params.Set("query", "select * from ods.ods_dm_index where dmid<1000 limit 10")
// params.Set("timestamp", time.Now().Format("2006-01-02 15:04:05"))
// params.Set("version", "1.0")
// params.Set("signMethod", "md5")
// s := _berserker + "?" + sign(params)
// fmt.Println(s)
// body, err := oget(s)
// if err != nil {
// t.Errorf("url(%s) error(%s)", s, err)
// t.FailNow()
// }
// fmt.Println(string(body))
// var out bytes.Buffer
// if err = json.Indent(&out, body, "", " "); err != nil {
// t.Fatal(err)
// t.FailNow()
// }
// fmt.Println(out.String())
// }

View File

@@ -0,0 +1,99 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/app/admin/main/dm/model"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_views = "/videoup/views"
_types = "/videoup/types"
_season = "/pgc/admin/season/dm/aids"
)
// TypeInfo TypeInfo
func (d *Dao) TypeInfo(c context.Context) (types map[int64]*model.ArchiveType, err error) {
var (
res struct {
Code int64 `json:"code"`
Data map[int64]*model.ArchiveType `json:"data"`
Message string `json:"message"`
}
)
v := make(url.Values)
if err = d.httpCli.Get(c, d.typesURI, "", v, &res); err != nil {
log.Error("d.httpCli.Get(%s) error(%v)", d.typesURI, err)
return
}
if res.Code != 0 {
err = fmt.Errorf("%v", res)
log.Error("d.httpClient.Get(%s) code(%d)", d.typesURI, res.Code)
}
types = res.Data
return
}
// ArchiveVideos return archive and video info.
func (d *Dao) ArchiveVideos(c context.Context, aids []int64) (avm map[int64]*model.ArcVideo, err error) {
var (
res struct {
Code int64 `json:"code"`
Data map[int64]*model.ArcVideo `json:"data"`
Message string `json:"message"`
}
v = make(url.Values)
)
v.Set("aids", xstr.JoinInts(aids))
if err = d.httpCli.Get(c, d.viewsURI, "", v, &res); err != nil {
log.Error("d.httpClient.Get(%s) error(%v)", d.viewsURI, err)
return
}
if res.Code != 0 {
err = fmt.Errorf("%v", res)
log.Error("d.httpClient.Get(%s) code(%d)", d.viewsURI, res.Code)
return
}
avm = res.Data
return
}
// SeasonInfos return season infos
func (d *Dao) SeasonInfos(c context.Context, IDType string, id int64) (aids, oids []int64, err error) {
var (
res struct {
Code int64 `json:"code"`
Message string `json:"message"`
Data []*model.SeasonInfo `json:"result"`
}
params = make(url.Values, 1)
)
switch IDType {
case "ep":
params.Set("epid", fmt.Sprint(id))
case "ss":
params.Set("season_id", fmt.Sprint(id))
default:
err = fmt.Errorf("season type(%s) error", IDType)
log.Error("d.SeasonInfos error(%v)", err)
return
}
if err = d.httpSearch.Get(c, d.seasonURI, "", params, &res); err != nil {
log.Error("d.httpSearch.Get(uri:%s,params:%s) error(%v)", d.seasonURI, params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("uri:%s,code:%d", d.seasonURI, res.Code)
log.Error("d.SeasonInfos error(%v)", err)
return
}
for _, v := range res.Data {
aids = append(aids, v.Aid)
oids = append(oids, v.Cid)
}
return
}

View File

@@ -0,0 +1,24 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestTypeInfo(t *testing.T) {
Convey("", t, func() {
types, err := testDao.TypeInfo(context.TODO())
So(types, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestArchiveVideos(t *testing.T) {
Convey("", t, func() {
avm, err := testDao.ArchiveVideos(context.TODO(), []int64{10110320, 123, 3})
So(avm, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,40 @@
package dao
import (
"context"
"net/url"
"strconv"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
)
const (
_workFlowAppealDelete = "/x/internal/workflow/appeal/v3/delete"
)
// WorkFlowAppealDelete .
func (d *Dao) WorkFlowAppealDelete(c context.Context, bid, oid, subtitleID int64) (err error) {
var (
res struct {
Code int `json:"code"`
Message string `json:"message"`
}
params = url.Values{}
ip = metadata.String(c, metadata.RemoteIP)
)
params.Set("bid", strconv.FormatInt(bid, 10))
params.Set("oid", strconv.FormatInt(oid, 10))
params.Set("eid", strconv.FormatInt(subtitleID, 10))
if err = d.httpCli.Post(c, d.workFlowURI, ip, params, &res); err != nil {
log.Error("WorkFlowTagList(params:%v),error(%v)", params, err)
return
}
if err = ecode.Int(res.Code); err != ecode.OK {
log.Error("WorkFlowTagList(params:%v),error(%v)", params, err)
return
}
err = nil
return
}

View File

@@ -0,0 +1,22 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoWorkFlowAppealDelete(t *testing.T) {
convey.Convey("WorkFlowAppealDelete", t, func(ctx convey.C) {
var (
c = context.Background()
bid = int64(0)
oid = int64(0)
subtitleID = int64(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
testDao.WorkFlowAppealDelete(c, bid, oid, subtitleID)
})
})
}