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

View File

@ -0,0 +1,95 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"business_test.go",
"callback_test.go",
"challenge_test.go",
"dao_test.go",
"event_test.go",
"extra_test.go",
"group_test.go",
"memcache_test.go",
"message_test.go",
"redis_test.go",
"search2_test.go",
"tag_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/admin/main/workflow/model:go_default_library",
"//app/admin/main/workflow/model/param:go_default_library",
"//app/admin/main/workflow/model/search:go_default_library",
"//library/conf/paladin:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/jinzhu/gorm:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"business.go",
"callback.go",
"challenge.go",
"dao.go",
"event.go",
"extra.go",
"group.go",
"memcache.go",
"message.go",
"redis.go",
"search2.go",
"tag.go",
],
importpath = "go-common/app/admin/main/workflow/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/workflow/model:go_default_library",
"//app/admin/main/workflow/model/manager:go_default_library",
"//app/admin/main/workflow/model/param:go_default_library",
"//app/admin/main/workflow/model/search:go_default_library",
"//app/interface/main/credit/model:go_default_library",
"//app/job/main/member/model/block:go_default_library",
"//app/service/main/account/api:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/member/model/block:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/conf/paladin:go_default_library",
"//library/database/elastic:go_default_library",
"//library/database/orm:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/rpc/warden:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/jinzhu/gorm: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,303 @@
package dao
import (
"context"
"encoding/json"
"go-common/app/admin/main/workflow/model"
"go-common/app/admin/main/workflow/model/manager"
"go-common/library/ecode"
"go-common/library/log"
"github.com/pkg/errors"
)
const _businessRoleURI = "http://manager.bilibili.co/x/admin/manager/internal/business/role"
var metas map[int8]*model.Meta
func init() {
metas = make(map[int8]*model.Meta)
data := `[
{
"business": 1,
"name": "稿件投诉",
"item_type": "group",
"rounds": [
{
"id": 1,
"name": "一审"
},
{
"id": 2,
"name": "回查"
}
]
},
{
"business": 2,
"name": "稿件申诉",
"item_type": "challenge",
"rounds": [
{
"id": 1,
"name": "一审"
},
{
"id": 2,
"name": "回查"
},
{
"id": 3,
"name": "三查"
},
{
"id": 11,
"name": "客服"
}
]
},
{
"business": 3,
"name": "短点评投诉",
"item_type": "group",
"rounds": [
{
"id": 1,
"name": "一审"
},
{
"id": 2,
"name": "回查"
}
]
},
{
"business": 4,
"name": "长点评投诉",
"item_type": "group",
"rounds": [
{
"id": 1,
"name": "一审"
},
{
"id": 2,
"name": "回查"
}
]
},
{
"business": 5,
"name": "小黑屋",
"item_type": "challenge",
"rounds": [
{
"id": 1,
"name": "评论"
},
{
"id": 2,
"name": "弹幕"
},
{
"id": 3,
"name": "私信"
},
{
"id": 4,
"name": "标签"
},
{
"id": 5,
"name": "个人资料"
},
{
"id": 6,
"name": "投稿"
},
{
"id": 7,
"name": "音频"
},
{
"id": 8,
"name": "专栏"
},
{
"id": 9,
"name": "空间头图"
}
]
},
{
"business": 6,
"name": "稿件审核",
"item_type": "challenge",
"rounds": [
{
"id": 1,
"name": "一审"
}
]
},
{
"business": 7,
"name": "任务质检",
"item_type": "challenge",
"rounds": [
{
"id": 1,
"name": "一审"
}
]
},
{
"business": 8,
"name": "频道举报",
"item_type": "group",
"rounds": [
{
"id": 1,
"name": "一审"
}
]
}
]`
ml := make([]*model.Meta, 0)
err := json.Unmarshal([]byte(data), &ml)
if err != nil {
panic(err)
}
for _, m := range ml {
metas[m.Business] = m
}
}
// BatchLastBusRecIDs will retrive the last business record ids by serveral conditions
func (d *Dao) BatchLastBusRecIDs(c context.Context, oids []int64, business int8) (bids []int64, err error) {
bids = make([]int64, 0, len(oids))
if len(oids) <= 0 {
return
}
rows, err := d.ReadORM.Table("workflow_business").Select("max(id)").
Where("oid IN (?) AND business=?", oids, business).
Group("oid,business").Rows()
if err != nil {
err = errors.Wrapf(err, "Query(%v, %d)", oids, business)
return
}
defer rows.Close()
for rows.Next() {
var bid int64
if err = rows.Scan(&bid); err != nil {
err = errors.WithStack(err)
return
}
bids = append(bids, bid)
}
return
}
// BusinessRecs will retrive the business record by ids
func (d *Dao) BusinessRecs(c context.Context, bids []int64) (bs map[int32]*model.Business, err error) {
bs = make(map[int32]*model.Business, len(bids))
if len(bids) <= 0 {
return
}
blist := make([]*model.Business, 0, len(bids))
err = d.ReadORM.Table("workflow_business").Where("id IN (?)", bids).Find(&blist).Error
if err != nil {
err = errors.Wrapf(err, "Query(%v)", bids)
return
}
for _, b := range blist {
bs[b.Bid] = b
}
return
}
// LastBusRec will retrive last business record by business oid
func (d *Dao) LastBusRec(c context.Context, business int8, oid int64) (bs *model.Business, err error) {
bs = new(model.Business)
err = d.ReadORM.Table("workflow_business").Where("oid=? AND business=?", oid, business).Last(bs).Error
if err != nil || bs.Bid == 0 {
err = errors.Wrapf(err, "Query(%d, %d)", business, oid)
bs = nil
return
}
return
}
// BatchBusRecByCids will retrive businesses by cids
func (d *Dao) BatchBusRecByCids(c context.Context, cids []int64) (cidToBus map[int64]*model.Business, err error) {
cidToBus = make(map[int64]*model.Business)
if len(cids) <= 0 {
return
}
blist := make([]*model.Business, 0, len(cids))
err = d.ReadORM.Table("workflow_business").Where("cid IN (?)", cids).Find(&blist).Error
if err != nil {
err = errors.Wrapf(err, "Query(%v)", cids)
return
}
for _, b := range blist {
cidToBus[b.Cid] = b
}
return
}
// BusObjectByGids will retrive businesses by gids
func (d *Dao) BusObjectByGids(c context.Context, gids []int64) (gidToBus map[int64]*model.Business, err error) {
gidToBus = make(map[int64]*model.Business, len(gids))
if len(gids) <= 0 {
return
}
blist := make([]*model.Business, 0, len(gids))
if err = d.ReadORM.Table("workflow_business").Where("gid IN (?)", gids).Find(&blist).Error; err != nil {
err = errors.Wrapf(err, "Query(%v)", gids)
return
}
for _, b := range blist {
gidToBus[b.Gid] = b
}
return
}
// AllMetas will retrive business meta infomation from pre-configured
func (d *Dao) AllMetas(c context.Context) map[int8]*model.Meta {
return metas
}
// LoadRole .
func (d *Dao) LoadRole(c context.Context) (role map[int8]map[int8]string, err error) {
var (
resp *manager.RoleResponse
ok bool
uri = _businessRoleURI
)
role = make(map[int8]map[int8]string)
if err = d.httpRead.Get(c, uri, "", nil, &resp); err != nil {
log.Error("failed call %s error(%v)", uri, err)
return
}
if resp.Code != ecode.OK.Code() {
err = ecode.Int(resp.Code)
log.Error("call %s error response code(%d) message(%s)", uri, resp.Code, resp.Message)
return
}
for _, r := range resp.Data {
if _, ok = role[r.Bid]; !ok {
role[r.Bid] = make(map[int8]string)
}
role[r.Bid][r.Rid] = r.Name
}
return
}

View File

@ -0,0 +1,128 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoinit(t *testing.T) {
convey.Convey("init", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestDaoBatchLastBusRecIDs(t *testing.T) {
convey.Convey("BatchLastBusRecIDs", t, func(ctx convey.C) {
var (
c = context.Background()
oids = []int64{1}
business = int8(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
bids, err := d.BatchLastBusRecIDs(c, oids, business)
ctx.Convey("Then err should be nil.bids should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(bids, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBusinessRecs(t *testing.T) {
convey.Convey("BusinessRecs", t, func(ctx convey.C) {
var (
c = context.Background()
bids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
bs, err := d.BusinessRecs(c, bids)
ctx.Convey("Then err should be nil.bs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(bs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoLastBusRec(t *testing.T) {
convey.Convey("LastBusRec", t, func(ctx convey.C) {
var (
c = context.Background()
business = int8(1)
oid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
bs, err := d.LastBusRec(c, business, oid)
ctx.Convey("Then err should be nil.bs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(bs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBatchBusRecByCids(t *testing.T) {
convey.Convey("BatchBusRecByCids", t, func(ctx convey.C) {
var (
c = context.Background()
cids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cidToBus, err := d.BatchBusRecByCids(c, cids)
ctx.Convey("Then err should be nil.cidToBus should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(cidToBus, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBusObjectByGids(t *testing.T) {
convey.Convey("BusObjectByGids", t, func(ctx convey.C) {
var (
c = context.Background()
gids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
gidToBus, err := d.BusObjectByGids(c, gids)
ctx.Convey("Then err should be nil.gidToBus should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(gidToBus, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAllMetas(t *testing.T) {
convey.Convey("AllMetas", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := d.AllMetas(c)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoLoadRole(t *testing.T) {
convey.Convey("LoadRole", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
role, err := d.LoadRole(c)
ctx.Convey("Then err should be nil.role should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(role, convey.ShouldNotBeNil)
})
})
})
}

View File

@ -0,0 +1,85 @@
package dao
import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"go-common/app/admin/main/workflow/model"
"go-common/library/ecode"
"go-common/library/log"
"github.com/pkg/errors"
)
// AllCallbacks return all callbacks in database
func (d *Dao) AllCallbacks(c context.Context) (cbs map[int32]*model.Callback, err error) {
cbs = make(map[int32]*model.Callback)
cblist := make([]*model.Callback, 0)
err = d.ReadORM.Table("workflow_callback").Find(&cblist).Error
if err != nil {
err = errors.WithStack(err)
return
}
for _, cb := range cblist {
cbs[cb.CbID] = cb
}
return
}
// SendCallback send callback to pre configured server
func (d *Dao) SendCallback(c context.Context, cb *model.Callback, payload *model.Payload) (err error) {
var (
req *http.Request
pdata []byte
)
if pdata, err = json.Marshal(payload); err != nil {
return
}
// TODO:(zhoujiahui): with sign?
uv := url.Values{}
ts := strconv.FormatInt(time.Now().Unix(), 10)
uv.Set("ts", ts)
uv.Set("appkey", d.writeConf.Key)
sign := sign(uv, d.writeConf.Key, d.writeConf.Secret, true)
if req, err = http.NewRequest(http.MethodPost, cb.URL+"?ts="+ts+"&appkey="+d.writeConf.Key+"&sign="+sign, bytes.NewReader(pdata)); err != nil {
return
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
res := &model.CommonResponse{}
if err = d.httpWrite.Do(c, req, &res); err != nil {
log.Error("d.httpWrite.Do(%+v) error(%v)", req, err)
return
}
if res.Code != ecode.OK.Code() {
log.Error("callback occur code error url(%s) body(%s) error code(%v)", req.URL, string(pdata), ecode.Int(res.Code))
return
}
log.Info("send callback ok, req(%+v) body(%s) callback(%+v) ", req, string(pdata), cb)
return
}
// sign is used to sign form params by given condition.
func sign(params url.Values, appkey string, secret string, lower bool) (hexdigest string) {
data := params.Encode()
if strings.IndexByte(data, '+') > -1 {
data = strings.Replace(data, "+", "%20", -1)
}
if lower {
data = strings.ToLower(data)
}
digest := md5.Sum([]byte(data + secret))
hexdigest = hex.EncodeToString(digest[:])
return
}

View File

@ -0,0 +1,61 @@
package dao
import (
"context"
"net/url"
"testing"
"go-common/app/admin/main/workflow/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAllCallbacks(t *testing.T) {
convey.Convey("AllCallbacks", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cbs, err := d.AllCallbacks(c)
ctx.Convey("Then err should be nil.cbs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(cbs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSendCallback(t *testing.T) {
convey.Convey("SendCallback", t, func(ctx convey.C) {
var (
c = context.Background()
cb = &model.Callback{
URL: "http://uat-manager.bilibili.co/x/admin/reply/internal/callback/del",
}
payload = &model.Payload{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SendCallback(c, cb, payload)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaosign(t *testing.T) {
convey.Convey("sign", t, func(ctx convey.C) {
var (
params url.Values
appkey = ""
secret = ""
lower bool
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
hexdigest := sign(params, appkey, secret, lower)
ctx.Convey("Then hexdigest should not be nil.", func(ctx convey.C) {
ctx.So(hexdigest, convey.ShouldNotBeNil)
})
})
})
}

View File

@ -0,0 +1,326 @@
package dao
import (
"context"
"database/sql"
"encoding/json"
"time"
"go-common/app/admin/main/workflow/model"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
// Chall will retrive challenge by cid
func (d *Dao) Chall(c context.Context, cid int64) (chall *model.Chall, err error) {
chall = &model.Chall{}
if db := d.ReadORM.Table("workflow_chall").Where("id=?", cid).First(chall); db.Error != nil {
err = db.Error
if db.RecordNotFound() {
chall = nil
err = nil
} else {
err = errors.Wrapf(err, "chall(%d)", cid)
}
}
return
}
// Challs will select challenges by ids
func (d *Dao) Challs(c context.Context, cids []int64) (challs map[int64]*model.Chall, err error) {
challs = make(map[int64]*model.Chall, len(cids))
if len(cids) <= 0 {
return
}
chlist := make([]*model.Chall, 0)
err = d.ReadORM.Table("workflow_chall").Where("id IN (?)", cids).Find(&chlist).Error
if err != nil {
err = errors.WithStack(err)
return
}
for _, c := range chlist {
challs[c.Cid] = c
}
return
}
// StateChalls will select a set of groups by challenge ids and state
func (d *Dao) StateChalls(c context.Context, cids []int64, state int8) (challs map[int64]*model.Chall, err error) {
challs = make(map[int64]*model.Chall, len(cids))
challSlice := make([]*model.Chall, 0, len(cids))
if len(cids) <= 0 {
return
}
if err = d.ORM.Table("workflow_chall").Where("id IN (?)", cids).Find(&challSlice).Error; err != nil {
err = errors.WithStack(err)
return
}
for _, chall := range challSlice {
chall.FromState()
if chall.State != state {
continue
}
challs[chall.Cid] = chall
}
return
}
// LastChallIDsByGids will select last chall ids by given gids
func (d *Dao) LastChallIDsByGids(c context.Context, gids []int64) (cids []int64, err error) {
if len(gids) <= 0 {
return
}
var rows *sql.Rows
if rows, err = d.ReadORM.Table("workflow_chall").Select("max(id)").Where("gid IN (?)", gids).Group("gid").Rows(); err != nil {
return
}
defer rows.Close()
for rows.Next() {
var maxID int64
if err = rows.Scan(&maxID); err != nil {
return
}
cids = append(cids, maxID)
}
return
}
// TxUpChall will update state of a challenge
// Deprecated
func (d *Dao) TxUpChall(tx *gorm.DB, chall *model.Chall) (rows int64, err error) {
// write old field
chall.FromState()
db := tx.Table("workflow_chall").Where("id=?", chall.Cid).
Update("dispatch_state", chall.DispatchState)
if db.Error != nil {
err = errors.WithStack(db.Error)
return
}
rows = db.RowsAffected
return
}
// TxBatchUpChallByIDs will update state of challenges by cids
func (d *Dao) TxBatchUpChallByIDs(tx *gorm.DB, cids []int64, state int8) (err error) {
challSlice := make([]*model.Chall, 0, len(cids))
if len(cids) <= 0 {
return
}
if err = tx.Table("workflow_chall").Where("id IN (?)", cids).Find(&challSlice).Error; err != nil {
err = errors.WithStack(err)
return
}
for _, chall := range challSlice {
chall.SetState(uint32(state), uint8(0))
if err = tx.Table("workflow_chall").Where("id=?", chall.Cid).
Update("dispatch_state", chall.DispatchState).Error; err != nil {
err = errors.WithStack(err)
return
}
}
return
}
// AttPathsByCids will select a set of attachments paths by challenge ids
func (d *Dao) AttPathsByCids(c context.Context, cids []int64) (paths map[int64][]string, err error) {
var pathSlice []*struct {
Cid int64
Path string
}
paths = make(map[int64][]string, len(cids))
if len(cids) <= 0 {
return
}
if err = d.ReadORM.Table("workflow_attachment").Where("cid IN (?)", cids).Select("cid,path").Find(&pathSlice).Error; err != nil {
return
}
for _, cp := range pathSlice {
if _, ok := paths[cp.Cid]; !ok {
paths[cp.Cid] = make([]string, 0, 1)
}
paths[cp.Cid] = append(paths[cp.Cid], cp.Path)
}
return
}
// AttPathsByCid will select a set of attachments paths by challenge id
// Deprecated
func (d *Dao) AttPathsByCid(c context.Context, cid int64) (paths []string, err error) {
paths = make([]string, 0)
rows, err := d.ReadORM.Table("workflow_attachment").Select("cid,path").Where("cid=?", cid).Rows()
if err != nil {
err = errors.Wrapf(err, "cid(%d)", cid)
return
}
defer rows.Close()
for rows.Next() {
var cp struct {
cid int32
path string
}
if err = rows.Scan(&cp.cid, &cp.path); err != nil {
err = errors.WithStack(err)
return
}
paths = append(paths, cp.path)
}
return
}
// UpChallBusState will update specified business_state by conditions
// Deprecated
func (d *Dao) UpChallBusState(c context.Context, cid int64, busState int8, assigneeAdminid int64) (err error) {
var chall *model.Chall
if chall, err = d.Chall(c, cid); err != nil {
return
}
if chall == nil {
err = errors.Wrapf(err, "can not find challenge cid(%d)", cid)
return
}
// double write to new field
chall.SetState(uint32(busState), uint8(1))
if err = d.ORM.Table("workflow_chall").Where("id=?", cid).
Update("dispatch_state", chall.DispatchState).
Update("assignee_adminid", assigneeAdminid).
Error; err != nil {
err = errors.WithStack(err)
}
return
}
// BatchUpChallBusState will update specified business_state by conditions
func (d *Dao) BatchUpChallBusState(c context.Context, cids []int64, busState int8, assigneeAdminid int64) (err error) {
var challs map[int64]*model.Chall
challs, err = d.Challs(c, cids)
if err != nil {
return
}
for cid := range challs {
challs[cid].SetState(uint32(busState), uint8(1))
if err = d.ORM.Table("workflow_chall").Where("id=?", cid).
Update("dispatch_state", challs[cid].DispatchState).
Update("assignee_adminid", assigneeAdminid).Error; err != nil {
err = errors.WithStack(err)
return
}
}
return
}
// TxChallsByBusStates select cids by business and oid
func (d *Dao) TxChallsByBusStates(tx *gorm.DB, business int8, oid int64, busStates []int8) (cids []int64, err error) {
cids = make([]int64, 0)
rows, err := tx.Table("workflow_chall").Where("business=? AND oid=? ",
business, oid).Select("id,dispatch_state").Rows()
if err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
c := &model.Chall{}
if err = rows.Scan(&c.Cid, &c.DispatchState); err != nil {
return
}
for _, busState := range busStates {
c.FromState()
if c.BusinessState == busState {
cids = append(cids, int64(c.Cid))
}
}
}
return
}
// TxUpChallsBusStateByIDs will update specified business_state by conditions
func (d *Dao) TxUpChallsBusStateByIDs(tx *gorm.DB, cids []int64, busState int8, assigneeAdminid int64) (err error) {
challSlice := make([]*model.Chall, 0)
if err = tx.Table("workflow_chall").Where("id IN (?)", cids).
Select("id,gid,mid,dispatch_state").Find(&challSlice).Error; err != nil {
err = errors.WithStack(err)
return
}
for _, chall := range challSlice {
chall.SetState(uint32(busState), uint8(1))
if err = tx.Table("workflow_chall").Where("id=?", chall.Cid).
Update("dispatch_state", chall.DispatchState).Update("assignee_adminid", assigneeAdminid).Error; err != nil {
err = errors.WithStack(err)
return
}
}
return
}
// TxUpChallExtraV2 will update Extra data by business oid
func (d *Dao) TxUpChallExtraV2(tx *gorm.DB, business int8, oid, adminid int64, extra map[string]interface{}) (rows int64, err error) {
exData, err := json.Marshal(extra)
if err != nil {
err = errors.Wrapf(err, "business(%d) oid(%d), extra(%s)", business, oid, extra)
return
}
if err = tx.Table("workflow_business").Where("business=? AND oid=?", business, oid).Update("extra", exData).Error; err != nil {
err = errors.Wrapf(err, "business(%d), oid(%d), extra(%s)", business, oid, exData)
}
return
}
// UpExtraV3 will update Extra data by gids
func (d *Dao) UpExtraV3(gids []int64, adminid int64, extra string) error {
return d.ORM.Table("workflow_business").Where("gid IN (?)", gids).Update("extra", extra).Error
}
// TxUpChallTag will update tid by cid
func (d *Dao) TxUpChallTag(tx *gorm.DB, cid int64, tid int64) (err error) {
if err = tx.Table("workflow_chall").Where("id=?", cid).Update("tid", tid).Error; err != nil {
err = errors.Wrapf(err, "cid(%d), tid(%d)", cid, tid)
}
return
}
// BatchUpChallByIDs update dispatch_state field of cids
func (d *Dao) BatchUpChallByIDs(cids []int64, dispatchState uint32, adminid int64) (err error) {
if len(cids) <= 0 {
return
}
if err = d.ORM.Table("workflow_chall").Where("id IN (?)", cids).
Update("dispatch_state", dispatchState).Update("adminid", adminid).Error; err != nil {
err = errors.WithStack(err)
}
return
}
// BatchResetAssigneeAdminID reset assignee_adminid by cids
func (d *Dao) BatchResetAssigneeAdminID(cids []int64) (err error) {
if len(cids) <= 0 {
return
}
if err = d.ORM.Table("workflow_chall").Where("id IN (?)", cids).
Update("assignee_adminid", 0).Error; err != nil {
err = errors.WithStack(err)
}
return
}
// TxUpChallAssignee update assignee_adminid and dispatch_time when admin start a mission
func (d *Dao) TxUpChallAssignee(tx *gorm.DB, cids []int64) error {
return tx.Table("workflow_chall").Where("id IN (?)", cids).
Update("dispatch_time", time.Now().Format("2006-01-02 15:04:05")).Error
}

View File

@ -0,0 +1,353 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/workflow/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoChall(t *testing.T) {
convey.Convey("Chall", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
chall, err := d.Chall(c, cid)
ctx.Convey("Then err should be nil.chall should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(chall, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoChalls(t *testing.T) {
convey.Convey("Challs", t, func(ctx convey.C) {
var (
c = context.Background()
cids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
challs, err := d.Challs(c, cids)
ctx.Convey("Then err should be nil.challs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(challs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoStateChalls(t *testing.T) {
convey.Convey("StateChalls", t, func(ctx convey.C) {
var (
c = context.Background()
cids = []int64{1}
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
challs, err := d.StateChalls(c, cids, state)
ctx.Convey("Then err should be nil.challs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(challs, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoLastChallIDsByGids(t *testing.T) {
convey.Convey("LastChallIDsByGids", t, func(ctx convey.C) {
var (
c = context.Background()
gids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cids, err := d.LastChallIDsByGids(c, gids)
ctx.Convey("Then err should be nil.cids should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(cids, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxUpChall(t *testing.T) {
convey.Convey("TxUpChall", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
chall = &model.Chall{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
rows, err := d.TxUpChall(tx, chall)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxBatchUpChallByIDs(t *testing.T) {
convey.Convey("TxBatchUpChallByIDs", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
cids = []int64{1}
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxBatchUpChallByIDs(tx, cids, state)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoAttPathsByCids(t *testing.T) {
convey.Convey("AttPathsByCids", t, func(ctx convey.C) {
var (
c = context.Background()
cids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
paths, err := d.AttPathsByCids(c, cids)
ctx.Convey("Then err should be nil.paths should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(paths, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAttPathsByCid(t *testing.T) {
convey.Convey("AttPathsByCid", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
paths, err := d.AttPathsByCid(c, cid)
ctx.Convey("Then err should be nil.paths should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(paths, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpChallBusState(t *testing.T) {
convey.Convey("UpChallBusState", t, func(ctx convey.C) {
var (
c = context.Background()
cid = int64(1)
busState = int8(1)
assigneeAdminid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpChallBusState(c, cid, busState, assigneeAdminid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoBatchUpChallBusState(t *testing.T) {
convey.Convey("BatchUpChallBusState", t, func(ctx convey.C) {
var (
c = context.Background()
cids = []int64{1}
busState = int8(1)
assigneeAdminid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.BatchUpChallBusState(c, cids, busState, assigneeAdminid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxChallsByBusStates(t *testing.T) {
convey.Convey("TxChallsByBusStates", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
business = int8(1)
oid = int64(1)
busStates = []int8{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cids, err := d.TxChallsByBusStates(tx, business, oid, busStates)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.cids should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
ctx.So(cids, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxUpChallsBusStateByIDs(t *testing.T) {
convey.Convey("TxUpChallsBusStateByIDs", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
cids = []int64{1}
busState = int8(1)
assigneeAdminid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxUpChallsBusStateByIDs(tx, cids, busState, assigneeAdminid)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxUpChallExtraV2(t *testing.T) {
convey.Convey("TxUpChallExtraV2", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
business = int8(1)
oid = int64(1)
adminid = int64(1)
extra map[string]interface{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
rows, err := d.TxUpChallExtraV2(tx, business, oid, adminid, extra)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpExtraV3(t *testing.T) {
convey.Convey("UpExtraV3", t, func(ctx convey.C) {
var (
gids = []int64{1}
adminid = int64(1)
extra = "test extra"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpExtraV3(gids, adminid, extra)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxUpChallTag(t *testing.T) {
convey.Convey("TxUpChallTag", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
cid = int64(1)
tid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxUpChallTag(tx, cid, tid)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoBatchUpChallByIDs(t *testing.T) {
convey.Convey("BatchUpChallByIDs", t, func(ctx convey.C) {
var (
cids = []int64{1}
dispatchState = uint32(1)
adminid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.BatchUpChallByIDs(cids, dispatchState, adminid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoBatchResetAssigneeAdminID(t *testing.T) {
convey.Convey("BatchResetAssigneeAdminID", t, func(ctx convey.C) {
var (
cids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.BatchResetAssigneeAdminID(cids)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxUpChallAssignee(t *testing.T) {
convey.Convey("TxUpChallAssignee", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
cids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxUpChallAssignee(tx, cids)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}

View File

@ -0,0 +1,139 @@
package dao
import (
"context"
account "go-common/app/service/main/account/api"
archive "go-common/app/service/main/archive/api"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/conf/paladin"
"go-common/library/database/elastic"
"go-common/library/database/orm"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/rpc/warden"
"github.com/jinzhu/gorm"
)
// Dao is the appeal database access object
type Dao struct {
ReadORM *gorm.DB
ORM *gorm.DB
// search
httpRead *bm.Client
httpWrite *bm.Client
// memcache
mc *memcache.Pool
// redis
redis *redis.Pool
// es
es *elastic.Elastic
// account-service rpc
accRPC account.AccountClient
// archive-service rpc
arcRPC archive.ArchiveClient
c *paladin.Map // application.toml can reload
writeConf *bm.ClientConfig
}
// New will create a new appeal Dao instance
func New() (d *Dao) {
var (
db struct {
ReadORM *orm.Config
ORM *orm.Config
}
http struct {
HTTPClientRead *bm.ClientConfig
HTTPClient *bm.ClientConfig
Elastic *elastic.Config
}
grpc struct {
Account *warden.ClientConfig
Archive *warden.ClientConfig
}
mc struct {
Workflow *memcache.Config
}
rds struct {
Workflow *redis.Config
}
ac = new(paladin.TOML)
)
checkErr(paladin.Watch("application.toml", ac))
checkErr(paladin.Get("mysql.toml").UnmarshalTOML(&db))
checkErr(paladin.Get("http.toml").UnmarshalTOML(&http))
checkErr(paladin.Get("memcache.toml").UnmarshalTOML(&mc))
checkErr(paladin.Get("redis.toml").UnmarshalTOML(&rds))
checkErr(paladin.Get("grpc.toml").UnmarshalTOML(&grpc))
d = &Dao{
c: ac,
ReadORM: orm.NewMySQL(db.ReadORM),
ORM: orm.NewMySQL(db.ORM),
httpRead: bm.NewClient(http.HTTPClientRead),
httpWrite: bm.NewClient(http.HTTPClient),
// memcache
mc: memcache.NewPool(mc.Workflow),
// redis
redis: redis.NewPool(rds.Workflow),
// es
//es: elastic.NewElastic(nil),
es: elastic.NewElastic(http.Elastic),
writeConf: http.HTTPClient,
}
// account-service rpc
var err error
if d.accRPC, err = account.NewClient(grpc.Account); err != nil {
panic(err)
}
// archive-service rpc
if d.arcRPC, err = archive.NewClient(grpc.Archive); err != nil {
panic(err)
}
d.initORM()
return
}
func (d *Dao) initORM() {
d.ORM.LogMode(true)
d.ReadORM.LogMode(true)
}
// Close close dao.
func (d *Dao) Close() {
if d.ORM != nil {
d.ORM.Close()
}
if d.ReadORM != nil {
d.ReadORM.Close()
}
}
// Ping ping cpdb
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.ORM.DB().PingContext(c); err != nil {
return
}
if err = d.ReadORM.DB().PingContext(c); err != nil {
return
}
if err = d.pingMC(c); err != nil {
return
}
return d.pingRedis(c)
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}

View File

@ -0,0 +1,52 @@
package dao
import (
"context"
"flag"
"os"
"testing"
"go-common/library/conf/paladin"
"github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") == "uat" {
flag.Set("app_id", "main.manager.workflow-admin")
flag.Set("conf_token", "daebcaa3b1886d74e1b8f0361b34b04c")
flag.Set("tree_id", "6812")
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")
} else {
flag.Set("region", "sh")
flag.Set("zone", "sh001")
flag.Set("app_id", "main.manager.workflow-admin")
flag.Set("deploy.env", "dev")
flag.Set("conf_token", "1de17252107b89394b5e72e07bfbc8de")
flag.Set("conf_path", "/tmp")
flag.Set("conf_version", "docker-1")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("tree_id", "6812")
}
flag.Parse()
if err := paladin.Init(); err != nil {
panic(err)
}
d = New()
os.Exit(m.Run())
}
func TestPing(t *testing.T) {
convey.Convey("Ping", t, func() {
d.Ping(context.TODO())
})
}

View File

@ -0,0 +1,80 @@
package dao
import (
"context"
"go-common/app/admin/main/workflow/model"
"github.com/pkg/errors"
)
// EventsByCid will select events by cid
func (d *Dao) EventsByCid(c context.Context, cid int64) (events map[int64]*model.Event, err error) {
events = make(map[int64]*model.Event)
elist := make([]*model.Event, 0)
if err = d.ReadORM.Table("workflow_event").Where("cid=?", cid).Find(&elist).Error; err != nil {
err = errors.WithStack(err)
return
}
for _, e := range elist {
e.FixAttachments()
events[e.Eid] = e
}
return
}
// EventsByIDs will select events by eids
func (d *Dao) EventsByIDs(c context.Context, eids []int64) (events map[int64]*model.Event, err error) {
if len(eids) == 0 {
return
}
events = make(map[int64]*model.Event, len(eids))
elist := make([]*model.Event, 0)
if err = d.ReadORM.Table("workflow_event").Where("id IN (?)", eids).Find(&elist).Error; err != nil {
err = errors.WithStack(err)
return
}
for _, e := range elist {
e.FixAttachments()
events[e.Eid] = e
}
return
}
// LastEventByCid will retrive last event by cid
func (d *Dao) LastEventByCid(c context.Context, cid int64) (event *model.Event, err error) {
event = new(model.Event)
err = d.ReadORM.Table("workflow_event").Where("cid=?", cid).Order("id").Last(&event).Error
if err != nil {
err = errors.WithStack(err)
return
}
return
}
// BatchLastEventIDs will retrive the last event ids by serveral conditions
func (d *Dao) BatchLastEventIDs(c context.Context, cids []int64) (eids []int64, err error) {
eids = make([]int64, 0, len(cids))
if len(cids) <= 0 {
return
}
rows, err := d.ReadORM.Table("workflow_event").Select("max(id)").Where("cid IN (?)", cids).Group("cid").Rows()
if err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
var eid int64
if err = rows.Scan(&eid); err != nil {
err = errors.WithStack(err)
return
}
eids = append(eids, eid)
}
return
}

View File

@ -0,0 +1,44 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoEventsByCid(t *testing.T) {
var c = context.TODO()
convey.Convey("events by cid", t, func() {
events, err := d.EventsByCid(c, 1)
convey.So(err, convey.ShouldBeNil)
convey.So(events, convey.ShouldNotBeNil)
})
}
func TestDaoEventsByIDs(t *testing.T) {
var c = context.TODO()
convey.Convey("events by multi event ids", t, func() {
events, err := d.EventsByIDs(c, []int64{1})
convey.So(err, convey.ShouldBeNil)
convey.So(events, convey.ShouldNotBeNil)
})
}
func TestDaoLastEventByCid(t *testing.T) {
var c = context.TODO()
convey.Convey("last event by eids", t, func() {
events, err := d.EventsByIDs(c, []int64{1})
convey.So(err, convey.ShouldBeNil)
convey.So(events, convey.ShouldNotBeNil)
})
}
func TestDaoBatchLastEventIDs(t *testing.T) {
var c = context.TODO()
convey.Convey("batch last event by multi cids", t, func() {
events, err := d.BatchLastEventIDs(c, []int64{1})
convey.So(err, convey.ShouldBeNil)
convey.So(events, convey.ShouldNotBeNil)
})
}

View File

@ -0,0 +1,369 @@
package dao
import (
"context"
"fmt"
"net/url"
"strconv"
"sync"
"time"
"go-common/app/admin/main/workflow/model"
"go-common/app/admin/main/workflow/model/param"
credit "go-common/app/interface/main/credit/model"
"go-common/app/job/main/member/model/block"
acc "go-common/app/service/main/account/api"
arc "go-common/app/service/main/archive/api"
member "go-common/app/service/main/member/model/block"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
"go-common/library/xstr"
"github.com/pkg/errors"
)
const (
_upergroupURI = "http://api.bilibili.co/x/internal/uper/special/get"
_tagListURI = "http://manager.bilibili.co/x/admin/manager/internal/tag/list"
_blockURI = "http://api.bilibili.co/x/internal/block/batch/block"
_creditBlockedURI = "http://api.bilibili.co/x/internal/credit/blocked/info/add"
_blockInfoURI = "http://api.bilibili.co/x/internal/block/info"
_blockNumURI = "http://api.bilibili.co/x/internal/credit/blocked/user/num"
_blockCaseAddURI = "http://api.bilibili.co/x/internal/credit/blocked/case/add"
)
// BatchUperSpecial .
// http://info.bilibili.co/pages/viewpage.action?pageId=8479274
func (d *Dao) BatchUperSpecial(c context.Context, mids []int64) (UperTagMap map[int64][]*model.SpecialTag, err error) {
uri := _upergroupURI
uperSpecialResp := new(model.UperSpecial)
UperTagMap = make(map[int64][]*model.SpecialTag)
uv := url.Values{}
uv.Set("group_id", "0")
uv.Set("mids", xstr.JoinInts(mids))
uv.Set("pn", "1")
uv.Set("ps", "1000")
if err = d.httpRead.Get(c, uri, "", uv, uperSpecialResp); err != nil {
err = errors.Wrap(err, fmt.Sprintf("search uper special tag failed mids(%v)", uv.Get("mids")))
return
}
if uperSpecialResp.Code != ecode.OK.Code() {
log.Error("call %s result error code(%d), message(%s)", uri, uperSpecialResp.Code, uperSpecialResp.Message)
err = ecode.Int(uperSpecialResp.Code)
return
}
for _, special := range uperSpecialResp.Data.Items {
UperTagMap[special.MID] = append(UperTagMap[special.MID], special)
}
return
}
// ArchiveRPC .
func (d *Dao) ArchiveRPC(c context.Context, oids []int64) (archives map[int64]*model.Archive, err error) {
if len(oids) == 0 {
return
}
archives = make(map[int64]*model.Archive, len(oids))
var res *arc.ArcsReply
arg := &arc.ArcsRequest{
Aids: oids,
}
if res, err = d.arcRPC.Arcs(c, arg); err != nil {
log.Error("d.arcRPC.Archives3(%+v) error(%v)", arg, err)
return
}
for oid, arc := range res.Arcs {
tmplArc := &model.Archive{
Author: arc.Author.Name,
State: arc.State,
Mid: arc.Author.Mid,
TypeID: arc.TypeID,
Type: arc.TypeName,
Title: arc.Title,
}
archives[oid] = tmplArc
}
return
}
// TagList .
// http://info.bilibili.co/pages/viewpage.action?pageId=9831467
// tags map[bid][tagid]
func (d *Dao) TagList(c context.Context) (tags map[int8]map[int64]*model.TagMeta, err error) {
uri := _tagListURI
uv := url.Values{}
uv.Set("ps", "1000")
uv.Set("pn", "1")
result := new(model.TagListResult)
tags = make(map[int8]map[int64]*model.TagMeta)
if err = d.httpRead.Get(c, uri, "", uv, result); err != nil {
return
}
if result.Code != ecode.OK.Code() {
log.Error("tag list failed: %s?%s, error code(%d), message(%s)", uri, uv.Encode(), result.Code, result.Message)
err = ecode.Int(result.Code)
return
}
for _, tm := range result.Data.Tags {
if _, ok := tags[tm.Bid]; !ok {
tags[tm.Bid] = make(map[int64]*model.TagMeta)
}
tags[tm.Bid][tm.TagID] = tm
}
return
}
// CommonExtraInfo return common external info
func (d *Dao) CommonExtraInfo(c context.Context, bid int8, uri string, ids, oids, eids []int64) (data map[string]interface{}, err error) {
log.Info("start call common extra info bid(%d) gids(%v) oids(%v) eids(%v)", bid, ids, oids, eids)
data = make(map[string]interface{})
uv := url.Values{}
uv.Set("bid", strconv.FormatInt(int64(bid), 10))
uv.Set("ids", xstr.JoinInts(ids))
uv.Set("oids", xstr.JoinInts(oids))
uv.Set("eids", xstr.JoinInts(eids))
res := &model.CommonExtraDataResponse{}
if err = d.httpRead.Get(c, uri, "", uv, &res); err != nil {
return data, err
}
if res.Code != ecode.OK.Code() {
log.Error("get extra info failed: url(%s), code(%d), message(%s), bid(%d)", uri+"?"+uv.Encode(), res.Code, res.Message, bid)
err = ecode.Int(res.Code)
return
}
log.Info("success extra info (%+v) req url(%s)", res, uri+"?"+uv.Encode())
data = res.Data
return
}
// AccountInfoRPC .
func (d *Dao) AccountInfoRPC(c context.Context, mids []int64) (authors map[int64]*model.Account) {
g := &errgroup.Group{}
mutex := sync.RWMutex{}
authors = make(map[int64]*model.Account)
if len(mids) == 0 {
return
}
// distinct mid
mMap := make(map[int64]bool)
dMids := make([]int64, 0)
for _, m := range mids {
if _, ok := mMap[m]; !ok {
mMap[m] = false
dMids = append(dMids, m)
continue
}
}
for _, mid := range dMids {
gMid := mid
g.Go(func() (err error) {
var res *acc.ProfileStatReply
start := time.Now()
arg := &acc.MidReq{Mid: gMid}
if res, err = d.accRPC.ProfileWithStat3(c, arg); err != nil {
log.Error("d.accRPC.ProfileWithStat3(%v) error(%v)", arg, err)
err = nil
return
}
mutex.Lock()
acc := &model.Account{
Mid: res.Profile.Mid,
Name: res.Profile.Name,
Rank: res.Profile.Rank,
Follower: res.Follower,
Official: &model.Official{Role: res.Profile.Official.Role},
}
authors[res.Profile.Mid] = acc
log.Info("mid(%d) data(%+v) wrap success", res.Profile.Mid, acc)
mutex.Unlock()
log.Info("account rpc request gmid(%d) time %s", gMid, time.Since(start).String())
return
})
}
g.Wait()
return
}
// AddMoral 扣节操
func (d *Dao) AddMoral(c context.Context, mids []int64, gssp *param.GroupStateSetParam) (err error) {
var errFlag bool
for _, mid := range mids {
arg := &acc.MoralReq{
Mid: mid,
Moral: float64(gssp.DecreaseMoral),
Oper: gssp.AdminName,
Reason: gssp.Reason,
Remark: "workflow",
}
if _, err = d.accRPC.AddMoral3(c, arg); err != nil {
log.Error("failed decrease moral arg(%+v) error(%v)", arg, err)
errFlag = true
}
}
if !errFlag {
log.Info("add moral success mids(%v) param(%+v)", mids, gssp)
}
return
}
// AddBlock 发起账号封禁
// http://info.bilibili.co/pages/viewpage.action?pageId=7559616
func (d *Dao) AddBlock(c context.Context, mids []int64, gssp *param.GroupStateSetParam) (err error) {
uri := _blockURI
uv := url.Values{}
uv.Set("mids", xstr.JoinInts(mids))
source := strconv.Itoa(int(member.BlockSourceBlackHouse))
uv.Set("source", source) //来源: 后台相关
if gssp.Business == model.CommentComplain {
area := strconv.Itoa(int(member.BlockAreaReply))
uv.Set("area", area) //违规业务
}
if gssp.BlockDay > 0 { //限时封禁
action := strconv.Itoa(int(block.BlockActionLimit))
uv.Set("action", action)
uv.Set("duration", strconv.FormatInt(gssp.BlockDay*86400, 10))
} else { //永久封禁
action := strconv.Itoa(int(block.BlockActionForever))
uv.Set("action", action)
}
uv.Set("start_time", strconv.FormatInt(time.Now().Unix(), 10))
uv.Set("op_id", strconv.FormatInt(gssp.AdminID, 10))
uv.Set("operator", gssp.AdminName)
reason := model.BlockReason[gssp.BlockReason]
uv.Set("reason", reason)
uv.Set("notify", "1")
resp := &model.CommonResponse{}
if err = d.httpWrite.Post(c, uri, "", uv, resp); err != nil {
log.Error("add block url(%s) param(%s) error(%v)", uri, uv.Encode(), err)
return
}
if resp.Code != ecode.OK.Code() {
err = ecode.Int(resp.Code)
log.Error("call add block url(%s) param(%s) error res code(%d)", uri, uv.Encode(), resp.Code)
return
}
log.Info("add block success mids(%v) param(%+v)", mids, gssp)
return
}
// AddCreditBlockInfo 上报封禁信息到小黑屋
// http://info.bilibili.co/pages/viewpage.action?pageId=5417571
func (d *Dao) AddCreditBlockInfo(c context.Context, bus map[int64]*model.Business, gssp *param.GroupStateSetParam) (err error) {
// 请求小黑屋
uri := _creditBlockedURI
for _, b := range bus {
uv := url.Values{}
uv.Set("mid", strconv.FormatInt(b.Mid, 10))
uv.Set("oper_id", strconv.FormatInt(gssp.AdminID, 10))
uv.Set("origin_content", b.Title)
if gssp.Business == model.CommentComplain {
uv.Set("origin_type", strconv.Itoa(int(member.BlockAreaReply))) //违规业务
}
if gssp.BlockDay > 0 { //限时封禁
uv.Set("blocked_days", strconv.FormatInt(gssp.BlockDay, 10))
uv.Set("blocked_forever", strconv.Itoa(int(credit.NotInBlockedForever)))
uv.Set("punish_type", strconv.Itoa(int(credit.PunishTypeBlock)))
} else { //永久封禁
uv.Set("blocked_forever", strconv.Itoa(int(credit.InBlockedForever)))
uv.Set("punish_type", strconv.Itoa(int(credit.PunishTypeForever)))
}
uv.Set("punish_time", strconv.FormatInt(time.Now().Unix(), 10))
uv.Set("reason_type", strconv.Itoa(int(gssp.BlockReason)))
uv.Set("operator_name", gssp.AdminName)
resp := &model.CommonResponse{}
if err = d.httpWrite.Post(c, uri, "", uv, resp); err != nil {
log.Error("add credit block info url(%s) param(%s) error(%v)", uri, uv.Encode(), err)
continue
}
if resp.Code != ecode.OK.Code() {
err = ecode.Int(resp.Code)
log.Error("call add credit block info url(%s) param(%s) error res code(%d)", uri, uv.Encode(), resp.Code)
continue
}
log.Info("add credit block info success mid(%v) param(%+v)", b.Mid, gssp)
}
return
}
// AddCreditCase 请求风纪委众裁
func (d *Dao) AddCreditCase(c context.Context, uv url.Values) (err error) {
uri := _blockCaseAddURI
var res model.CommonResponse
if err = d.httpWrite.Post(c, uri, "", uv, &res); err != nil {
log.Error("d.httpWrite.Post(%s) body(%s) error(%v)", uri, uv.Encode(), err)
err = ecode.WkfSetPublicRefereeFailed
return
}
if res.Code != ecode.OK.Code() {
log.Error("call url(%s) body(%s) error code(%d)", uri, uv.Encode(), res.Code)
err = ecode.WkfSetPublicRefereeFailed
return
}
log.Info("call block add case success url(%s) body(%s)", uri, uv.Encode())
return
}
// BlockNum 查询封禁次数
func (d *Dao) BlockNum(c context.Context, mid int64) (sum int64, err error) {
uri := _blockNumURI
uv := url.Values{}
uv.Set("mid", strconv.FormatInt(mid, 10))
var numResp model.BlockNumResp
if err = d.httpRead.Get(c, uri, "", uv, &numResp); err != nil {
log.Error("d.httpRead.Get() error(%v) url(%s?%s)", err, uri, uv.Encode())
err = ecode.WkfGetBlockInfoFailed
return
}
if numResp.Code != ecode.OK.Code() {
log.Error("call url(%s?%s) response code (%d) error", uri, uv.Encode(), numResp.Code)
err = ecode.WkfGetBlockInfoFailed
return
}
sum = numResp.Data.BlockedSum
log.Info("url(%s) mid(%d) block num (%d)", uri, mid, sum)
return
}
// BlockInfo 查询封禁信息
func (d *Dao) BlockInfo(c context.Context, mid int64) (resp model.BlockInfoResp, err error) {
uri := _blockInfoURI
uv := url.Values{}
uv.Set("mid", strconv.FormatInt(mid, 10))
if err = d.httpRead.Get(c, uri, "", uv, &resp); err != nil {
log.Error("d.httpRead.Get() error(%v) url(%s?%s)", err, uri, uv.Encode())
err = ecode.WkfGetBlockInfoFailed
return
}
if resp.Code != ecode.OK.Code() {
log.Error("call url(%s?%s) response code (%d) error", uri, uv.Encode(), resp.Code)
err = ecode.WkfGetBlockInfoFailed
return
}
log.Info("url(%s) mid(%d) block info resp(%+v)", uri, mid, resp)
return
}
// SourceInfo 返回业务来源
func (d *Dao) SourceInfo(c context.Context, uri string) (data map[string]interface{}, err error) {
log.Info("start call SourceInfo uri(%s)", uri)
res := &model.SourceQueryResponse{}
if err = d.httpRead.Get(c, uri, "", nil, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
log.Error("get SourceInfo failed: url(%s), code(%d), message(%s)", uri, res.Code, res.Message)
err = ecode.Int(res.Code)
return
}
log.Info("success SourceInfo (%+v)", res.Data)
return res.Data, nil
}

View File

@ -0,0 +1,190 @@
package dao
import (
"context"
"net/url"
"testing"
"go-common/app/admin/main/workflow/model"
"go-common/app/admin/main/workflow/model/param"
"go-common/library/ecode"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoBatchUperSpecial(t *testing.T) {
convey.Convey("BatchUperSpecial", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{27515256}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
UperTagMap, err := d.BatchUperSpecial(c, mids)
ctx.Convey("Then err should be nil.UperTagMap should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(UperTagMap, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoArchiveRPC(t *testing.T) {
convey.Convey("ArchiveRPC", t, func(ctx convey.C) {
var (
c = context.Background()
oids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
archives, err := d.ArchiveRPC(c, oids)
ctx.Convey("Then err should be nil.archives should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(archives, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTagList(t *testing.T) {
convey.Convey("TagList", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
tags, err := d.TagList(c)
ctx.Convey("Then err should be nil.tags should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(tags, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoCommonExtraInfo(t *testing.T) {
convey.Convey("CommonExtraInfo", t, func(ctx convey.C) {
var (
c = context.Background()
bid = int8(13)
uri = "http://uat-manager.bilibili.co/x/admin/reply/internal/reply"
ids = []int64{1}
oids = []int64{1}
eids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
data, err := d.CommonExtraInfo(c, bid, uri, ids, oids, eids)
ctx.Convey("Then err should be nil.data should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(data, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAccountInfoRPC(t *testing.T) {
convey.Convey("AccountInfoRPC", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
authors := d.AccountInfoRPC(c, mids)
ctx.Convey("Then authors should not be nil.", func(ctx convey.C) {
ctx.So(authors, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddMoral(t *testing.T) {
convey.Convey("AddMoral", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1}
gssp = &param.GroupStateSetParam{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddMoral(c, mids, gssp)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err.Error(), convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddBlock(t *testing.T) {
convey.Convey("AddBlock", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1}
gssp = &param.GroupStateSetParam{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddBlock(c, mids, gssp)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAddCreditBlockInfo(t *testing.T) {
convey.Convey("AddCreditBlockInfo", t, func(ctx convey.C) {
var (
c = context.Background()
bus map[int64]*model.Business
gssp = &param.GroupStateSetParam{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddCreditBlockInfo(c, bus, gssp)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAddCreditCase(t *testing.T) {
convey.Convey("AddCreditCase", t, func(ctx convey.C) {
var (
c = context.Background()
uv url.Values
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddCreditCase(c, uv)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, ecode.Int(56504))
})
})
})
}
func TestDaoBlockNum(t *testing.T) {
convey.Convey("BlockNum", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
sum, err := d.BlockNum(c, mid)
ctx.Convey("Then err should be nil.sum should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(sum, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoBlockInfo(t *testing.T) {
convey.Convey("BlockInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
resp, err := d.BlockInfo(c, mid)
ctx.Convey("Then err should be nil.resp should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(resp, convey.ShouldNotBeNil)
})
})
})
}

View File

@ -0,0 +1,155 @@
package dao
import (
"context"
"go-common/app/admin/main/workflow/model"
"go-common/app/admin/main/workflow/model/param"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
// GroupByID will select a group by group id
func (d *Dao) GroupByID(c context.Context, gid int64) (g *model.Group, err error) {
g = &model.Group{}
if db := d.ReadORM.Table("workflow_group").Where("id=?", gid).First(g); db.Error != nil {
err = db.Error
if db.RecordNotFound() {
g = nil
err = nil
} else {
err = errors.Wrapf(err, "group(%d)", gid)
}
}
return
}
// GroupByOid will select a group by oid and business
func (d *Dao) GroupByOid(c context.Context, oid int64, business int8) (g *model.Group, err error) {
g = &model.Group{}
err = d.ReadORM.Table("workflow_group").Where("oid=? AND business=?", oid, business).Find(g).Error
return
}
// TxGroupsByOidsStates will select a set of groups by oids, business and states
func (d *Dao) TxGroupsByOidsStates(tx *gorm.DB, oids []int64, business, state int8) (groups map[int64]*model.Group, err error) {
var groupSlice []*model.Group
groups = make(map[int64]*model.Group, len(oids))
if len(oids) <= 0 {
return
}
if err = tx.Table("workflow_group").Where("oid IN (?) AND business=?", oids, business).Find(&groupSlice).Error; err != nil {
return
}
for _, g := range groupSlice {
groups[g.ID] = g
}
return
}
// Groups will select a set of groups by group ids
func (d *Dao) Groups(c context.Context, gids []int64) (groups map[int64]*model.Group, err error) {
var groupSlice []*model.Group
groups = make(map[int64]*model.Group, len(gids))
if len(gids) <= 0 {
return
}
if err = d.ReadORM.Table("workflow_group").Where("id IN (?)", gids).Find(&groupSlice).Error; err != nil {
return
}
for _, g := range groupSlice {
groups[g.ID] = g
}
return
}
// TxGroups .
func (d *Dao) TxGroups(tx *gorm.DB, gids []int64) (groups map[int64]*model.Group, err error) {
var groupSlice []*model.Group
groups = make(map[int64]*model.Group, len(gids))
if len(gids) <= 0 {
return
}
if err = tx.Set("gorm:query_option", "FOR UPDATE").Table("workflow_group").Where("id IN (?)", gids).Find(&groupSlice).Error; err != nil {
return
}
for _, g := range groupSlice {
groups[g.ID] = g
}
return
}
// TxUpGroup will update a group
func (d *Dao) TxUpGroup(tx *gorm.DB, oid int64, business int8, tid int64, note string, rid int8) (err error) {
err = tx.Table("workflow_group").Where("oid=? AND business=?", oid, business).UpdateColumn(map[string]interface{}{
"tid": tid,
"note": note,
"rid": rid,
}).Error
return
}
// UpGroupRole update tid note rid of groups
func (d *Dao) UpGroupRole(c context.Context, grsp *param.GroupRoleSetParam) (err error) {
err = d.ORM.Table("workflow_group").Where("id IN (?)", grsp.GID).UpdateColumn(map[string]interface{}{
"tid": grsp.TID,
"note": grsp.Note,
"rid": grsp.RID,
}).Error
return
}
// TxUpGroupState will update a group state
func (d *Dao) TxUpGroupState(tx *gorm.DB, gid int64, state int8) (err error) {
err = tx.Table("workflow_group").Where("id=? AND state=0", gid).Update("state", state).Error
return
}
// TxUpGroupHandling will use gorm update a group handling stat field
func (d *Dao) TxUpGroupHandling(tx *gorm.DB, gid int64, handling int32) (err error) {
err = tx.Table("workflow_group").Where("id=?", gid).Update("handling", handling).Error
return
}
// TxBatchUpGroupHandling will update a set of groups handling stat field
func (d *Dao) TxBatchUpGroupHandling(tx *gorm.DB, gids []int64, handling int32) (err error) {
if len(gids) <= 0 {
return
}
return tx.Table("workflow_group").Where("id IN (?)", gids).Update("handling", handling).Error
}
// TxBatchUpGroupState will update a group state
func (d *Dao) TxBatchUpGroupState(tx *gorm.DB, gids []int64, state int8) (err error) {
if len(gids) <= 0 {
return
}
return tx.Table("workflow_group").Where("id IN (?) AND state=0", gids).Update("state", state).Error
}
// TxSetGroupStateTid set group state,tid,rid
func (d *Dao) TxSetGroupStateTid(tx *gorm.DB, gids []int64, state, rid int8, tid int64) (err error) {
if len(gids) <= 0 {
return
}
return tx.Table("workflow_group").Where("id IN (?)", gids).UpdateColumn(map[string]interface{}{
"state": state,
"tid": tid,
"rid": rid,
}).Error
}
// TxSimpleSetGroupState only set group state
func (d *Dao) TxSimpleSetGroupState(tx *gorm.DB, gids []int64, state int8) (err error) {
if len(gids) <= 0 {
return
}
return tx.Table("workflow_group").Where("id IN (?)", gids).Update("state", state).Error
}

View File

@ -0,0 +1,290 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/workflow/model/param"
"github.com/jinzhu/gorm"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoGroupByID(t *testing.T) {
convey.Convey("GroupByID", t, func(ctx convey.C) {
var (
c = context.Background()
gid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
g, err := d.GroupByID(c, gid)
ctx.Convey("Then err should be nil.g should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(g, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGroupByOid(t *testing.T) {
convey.Convey("GroupByOid", t, func(ctx convey.C) {
var (
c = context.Background()
oid = int64(1)
business = int8(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
g, err := d.GroupByOid(c, oid, business)
ctx.Convey("Then err should be nil.g should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(g, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxGroupsByOidsStates(t *testing.T) {
convey.Convey("TxGroupsByOidsStates", t, func(ctx convey.C) {
var (
tx = &gorm.DB{}
oids = []int64{}
business = int8(0)
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
groups, err := d.TxGroupsByOidsStates(tx, oids, business, state)
ctx.Convey("Then err should be nil.groups should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(groups, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoGroups(t *testing.T) {
convey.Convey("Groups", t, func(ctx convey.C) {
var (
c = context.Background()
gids = []int64{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
groups, err := d.Groups(c, gids)
ctx.Convey("Then err should be nil.groups should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(groups, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxGroups(t *testing.T) {
convey.Convey("TxGroups", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
gids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
groups, err := d.TxGroups(tx, gids)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.groups should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
ctx.So(groups, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxUpGroup(t *testing.T) {
convey.Convey("TxUpGroup", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
oid = int64(1)
business = int8(1)
tid = int64(0)
note = "test note"
rid = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxUpGroup(tx, oid, business, tid, note, rid)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpGroupRole(t *testing.T) {
convey.Convey("UpGroupRole", t, func(ctx convey.C) {
var (
c = context.Background()
grsp = &param.GroupRoleSetParam{
GID: []int64{1},
AdminID: 1,
AdminName: "anonymous",
BID: 1,
RID: 1,
TID: 1,
Note: "test note",
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpGroupRole(c, grsp)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxUpGroupState(t *testing.T) {
convey.Convey("TxUpGroupState", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
gid = int64(1)
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxUpGroupState(tx, gid, state)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxUpGroupHandling(t *testing.T) {
convey.Convey("TxUpGroupHandling", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
gid = int64(1)
handling = int32(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxUpGroupHandling(tx, gid, handling)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxBatchUpGroupHandling(t *testing.T) {
convey.Convey("TxBatchUpGroupHandling", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
gids = []int64{1, 2}
handling = int32(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxBatchUpGroupHandling(tx, gids, handling)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxBatchUpGroupState(t *testing.T) {
convey.Convey("TxBatchUpGroupState", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
gids = []int64{1, 2}
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxBatchUpGroupState(tx, gids, state)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxSetGroupStateTid(t *testing.T) {
convey.Convey("TxSetGroupStateTid", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
gids = []int64{1, 2}
state = int8(0)
tid = int64(0)
rid = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxSetGroupStateTid(tx, gids, state, rid, tid)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}
func TestDaoTxSimpleSetGroupState(t *testing.T) {
convey.Convey("TxSimpleSetGroupState", t, func(ctx convey.C) {
var (
tx = d.ORM.Begin()
gids = []int64{1, 2}
state = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.TxSimpleSetGroupState(tx, gids, state)
err1 := tx.Commit().Error
defer func() {
if err != nil {
tx.Rollback()
}
}()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(err1, convey.ShouldBeNil)
})
})
})
}

View File

@ -0,0 +1,70 @@
package dao
import (
"context"
"encoding/json"
"go-common/library/conf/paladin"
"time"
"go-common/app/admin/main/workflow/model/search"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_prefixChallPendingCount = "wkf_cpc_uid_%d"
)
// pingMC ping memcache.
func (d *Dao) pingMC(c context.Context) (err error) {
conn := d.mc.Get(c)
//if err = conn.Store("set", "ping", []byte{1}, 0, d.mcExpire, 0); err != nil {
if err = conn.Set(&memcache.Item{Key: "ping", Value: []byte{1}, Expiration: 0}); err != nil {
log.Error("conn.Store(set, ping, 1) error(%v)", err)
}
conn.Close()
return
}
// ChallCountCache read pending chall count by uid from memcache
func (d *Dao) ChallCountCache(c context.Context, uid int64) (challCount *search.ChallCount, err error) {
var (
conn memcache.Conn
item *memcache.Item
key string
)
conn = d.mc.Get(c)
defer conn.Close()
key = d.keyChallCount(uid)
if item, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
return
}
err = json.Unmarshal(item.Value, &challCount)
return
}
// UpChallCountCache will write chall count to cache
func (d *Dao) UpChallCountCache(c context.Context, challCount *search.ChallCount, uid int64) (err error) {
var (
conn memcache.Conn
item *memcache.Item
jsonChallCount []byte
)
jsonChallCount, err = json.Marshal(challCount)
if err != nil {
return
}
conn = d.mc.Get(c)
defer conn.Close()
item = &memcache.Item{
Key: d.keyChallCount(uid),
Value: jsonChallCount,
Expiration: int32(paladin.Duration(d.c.Get("expireCount"), time.Duration(10*time.Second)) / time.Second),
}
err = conn.Set(item)
return
}

View File

@ -0,0 +1,55 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/workflow/model/search"
"github.com/smartystreets/goconvey/convey"
)
func TestDaopingMC(t *testing.T) {
convey.Convey("pingMC", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.pingMC(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoChallCountCache(t *testing.T) {
convey.Convey("ChallCountCache", t, func(ctx convey.C) {
var (
c = context.Background()
uid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.ChallCountCache(c, uid)
ctx.Convey("Then err should be nil.challCount should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpChallCountCache(t *testing.T) {
convey.Convey("UpChallCountCache", t, func(ctx convey.C) {
var (
c = context.Background()
challCount = &search.ChallCount{}
uid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UpChallCountCache(c, challCount, uid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@ -0,0 +1,27 @@
package dao
import (
"context"
"go-common/app/admin/main/workflow/model/param"
"go-common/library/ecode"
)
const _userNotifyURI = "http://message.bilibili.co/api/notify/send.user.notify.do"
// SendMessage send message to upper.
func (d *Dao) SendMessage(c context.Context, msg *param.MessageParam) (err error) {
uri := _userNotifyURI
params := msg.Query()
var res struct {
Code int `json:"code"`
}
if err = d.httpWrite.Post(c, uri, "", params, &res); err != nil {
return
}
if res.Code != 0 {
err = ecode.Int(res.Code)
return
}
return
}

View File

@ -0,0 +1,34 @@
package dao
import (
"context"
"testing"
"go-common/app/admin/main/workflow/model"
"go-common/app/admin/main/workflow/model/param"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSendMessage(t *testing.T) {
convey.Convey("SendMessage", t, func(ctx convey.C) {
var (
c = context.Background()
msg = &param.MessageParam{
Type: "json",
Source: 1,
DataType: 4,
MC: model.WkfNotifyMC,
Title: "test title",
Context: "test context",
MidList: []int64{1},
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SendMessage(c, msg)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err.Error(), convey.ShouldEqual, "-6")
})
})
})
}

View File

@ -0,0 +1,130 @@
package dao
import (
"context"
"fmt"
"go-common/app/admin/main/workflow/model"
"go-common/library/cache/redis"
"go-common/library/log"
)
const (
_listKeyFormat = "wf_%d_%d"
_fbRound = 11
_auditFlowDealType = 0
_feedbackFlowDealType = 1
_adminOnlineHash = "wkf_online_hash"
_prefixAdminOnlineField = "wkf_online_uid_%d"
)
func (d *Dao) pingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
_, err = conn.Do("SET", "PING", "PONG")
conn.Close()
return
}
// redis list key wf_business_dealtype like wf_2_1
// dealtype=0 audit dealtype=1 feedback
// RedisRPOPCids returns cids from a list
func (d *Dao) RedisRPOPCids(c context.Context, business int8, round int64, num int8) (cids []int64, err error) {
var (
key string
conn = d.redis.Get(c)
flow int
cid int64
chall *model.Chall
)
defer conn.Close()
cids = make([]int64, 0)
if round == _fbRound {
flow = _feedbackFlowDealType
} else {
flow = _auditFlowDealType
}
key = fmt.Sprintf(_listKeyFormat, business, flow)
for {
exist := false
if exist, err = redis.Bool(conn.Do("EXISTS", key)); err != nil {
log.Error("redis.Bool key(%s) err(%v)", key, err)
return
}
if !exist {
log.Warn("key(%s) not exist", key)
return
}
if cid, err = redis.Int64(conn.Do("RPOP", key)); err != nil {
log.Error("conn.Do(RPOP,%s) error(%v)", key, err)
return
}
// judge if business_state is queue state
if chall, err = d.Chall(c, cid); err != nil {
return
}
chall.FromState()
if chall.BusinessState == model.QueueState {
cids = append(cids, cid)
}
if len(cids) >= int(num) {
break
}
}
return
}
// IsOnline judge if admin is online
func (d *Dao) IsOnline(c context.Context, assigneeAdminID int64) (online bool, err error) {
conn := d.redis.Get(c)
defer conn.Close()
key := _adminOnlineHash
field := d.fieldOnlineList(assigneeAdminID)
return redis.Bool(conn.Do("HEXISTS", key, field))
}
// AddOnline checkin if start subscribe mission in platform, set key
func (d *Dao) AddOnline(c context.Context, assigneeAdminID int64) (err error) {
conn := d.redis.Get(c)
defer conn.Close()
key := _adminOnlineHash
field := d.fieldOnlineList(assigneeAdminID)
_, err = conn.Do("HSET", key, field, assigneeAdminID)
return
}
// DelOnline checkout if exit subscribe mission in platform, delete key
func (d *Dao) DelOnline(c context.Context, assigneeAdminID int64) (err error) {
conn := d.redis.Get(c)
defer conn.Close()
key := _adminOnlineHash
field := d.fieldOnlineList(assigneeAdminID)
_, err = conn.Do("HDEL", key, field)
return
}
// ListOnline list online admin
func (d *Dao) ListOnline(c context.Context) (ids []int64, err error) {
conn := d.redis.Get(c)
defer conn.Close()
key := _adminOnlineHash
return redis.Int64s(conn.Do("HVALS", key))
}
// LogInOutTime show last online or offline time
func (d *Dao) LogInOutTime(c context.Context, uids []int64) {
}
// uid field in key wkf_online_hash
func (d *Dao) fieldOnlineList(assigneeAdminID int64) string {
return fmt.Sprintf(_prefixAdminOnlineField, assigneeAdminID)
}
func (d *Dao) keyChallCount(assigneeAdminID int64) string {
return fmt.Sprintf(_prefixChallPendingCount, assigneeAdminID)
}

View File

@ -0,0 +1,142 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaopingRedis(t *testing.T) {
convey.Convey("pingRedis", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.pingRedis(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoRedisRPOPCids(t *testing.T) {
convey.Convey("RedisRPOPCids", t, func(ctx convey.C) {
var (
c = context.Background()
business = int8(0)
round = int64(0)
num = int8(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
cids, err := d.RedisRPOPCids(c, business, round, num)
ctx.Convey("Then err should be nil.cids should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(cids, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoIsOnline(t *testing.T) {
convey.Convey("IsOnline", t, func(ctx convey.C) {
var (
c = context.Background()
assigneeAdminID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
online, err := d.IsOnline(c, assigneeAdminID)
ctx.Convey("Then err should be nil.online should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(online, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAddOnline(t *testing.T) {
convey.Convey("AddOnline", t, func(ctx convey.C) {
var (
c = context.Background()
assigneeAdminID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddOnline(c, assigneeAdminID)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoDelOnline(t *testing.T) {
convey.Convey("DelOnline", t, func(ctx convey.C) {
var (
c = context.Background()
assigneeAdminID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelOnline(c, assigneeAdminID)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoListOnline(t *testing.T) {
convey.Convey("ListOnline", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
_, err := d.ListOnline(c)
ctx.Convey("Then err should be nil.ids should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoLogInOutTime(t *testing.T) {
convey.Convey("LogInOutTime", t, func(ctx convey.C) {
var (
c = context.Background()
uids = []int64{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.LogInOutTime(c, uids)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestDaofieldOnlineList(t *testing.T) {
convey.Convey("fieldOnlineList", t, func(ctx convey.C) {
var (
assigneeAdminID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := d.fieldOnlineList(assigneeAdminID)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyChallCount(t *testing.T) {
convey.Convey("keyChallCount", t, func(ctx convey.C) {
var (
assigneeAdminID = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := d.keyChallCount(assigneeAdminID)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}

View File

@ -0,0 +1,233 @@
package dao
import (
"context"
"net/url"
"strconv"
"time"
"go-common/app/admin/main/workflow/model/manager"
"go-common/app/admin/main/workflow/model/search"
"go-common/library/database/elastic"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_unameURI = "http://manager.bilibili.co/x/admin/manager/users/unames"
_srhAuditLogURI = "http://bili-search.bilibili.co/x/admin/search/log"
)
// SearchGroup will search group by given conditions
func (d *Dao) SearchGroup(c context.Context, cond *search.GroupSearchCommonCond) (resp *search.GroupSearchCommonResp, err error) {
start := time.Now()
var r *elastic.Request
defer func() {
log.Info("SearchGroup params(%s) group search ts %s err_or(%v)", r.Params(), time.Since(start).String(), err)
}()
r = d.es.NewRequest(search.GroupSrhComID).Index(search.GroupSrhComID).Fields(cond.Fields...).
WhereEq("business", cond.Business).WhereIn("round", cond.Rounds).WhereIn("tid", cond.Tids).
WhereIn("state", cond.States).WhereIn("mid", cond.Mids).WhereIn("oid", cond.Oids).WhereIn("typeid", cond.TypeIDs).
WhereIn("fid", cond.FID).WhereIn("rid", cond.RID).WhereIn("eid", cond.EID).
WhereIn("report_mid", cond.ReportMID).WhereIn("first_user_tid", cond.FirstUserTid).
Order(cond.Order, cond.Sort).
Pn(int(cond.PN)).Ps(int(cond.PS))
// 是否关键字匹配优先
if cond.KWPriority == true {
r.OrderScoreFirst(true)
} else {
r.OrderScoreFirst(false)
}
if len(cond.KWFields) > 0 && len(cond.KWFields) == len(cond.KW) {
r.WhereLike(cond.KWFields, cond.KW, true, elastic.LikeLevelMiddle)
}
r.WhereRange("ctime", cond.CTimeFrom, cond.CTimeTo, elastic.RangeScopeLcRc)
if err = r.Scan(c, &resp); err != nil {
log.Error("r.Scan(%+v) error(%v) params(%s)", resp, err, r.Params())
}
return
}
// SearchGroupMultiPage .
func (d *Dao) SearchGroupMultiPage(c context.Context, cond *search.GroupSearchCommonCond) (result []*search.GroupSearchCommonData, err error) {
var resp *search.GroupSearchCommonResp
cond.PS = 1000
cond.PN = 1
result = make([]*search.GroupSearchCommonData, 0, len(cond.IDs))
for {
if resp, err = d.SearchGroup(c, cond); err != nil {
return
}
result = append(result, resp.Result...)
if len(resp.Result) < resp.Page.Size {
break
}
cond.PN++
}
return
}
// SearchChallenge will search challenge by given conditions
func (d *Dao) SearchChallenge(c context.Context, cond *search.ChallSearchCommonCond) (resp *search.ChallSearchCommonResp, err error) {
start := time.Now()
var r *elastic.Request
defer func() {
log.Info("SearchChallenge params(%s) challenge search ts %s err_or(%v)", r.Params(), time.Since(start).String(), err)
}()
r = d.es.NewRequest(search.ChallSrhComID).Fields(cond.Fields...).
WhereIn("id", cond.IDs).WhereIn("round", cond.Rounds).WhereIn("tid", cond.Tids).WhereIn("state", cond.States).
WhereIn("business_state", cond.BusinessStates).WhereIn("mid", cond.Mids).WhereIn("oid", cond.Oids).WhereIn("typeid", cond.TypeIDs).
WhereIn("gid", cond.Gids).WhereIn("assignee_adminid", cond.AssigneeAdminIDs).WhereIn("adminid", cond.AdminIDs)
if cond.Business > 0 {
r.WhereEq("business", cond.Business)
}
if len(cond.KWFields) > 0 && len(cond.KWFields) == len(cond.KW) {
r.WhereLike(cond.KWFields, cond.KW, true, elastic.LikeLevelLow)
}
if cond.Order == "" {
cond.Order = "id"
}
if cond.Sort == "" {
cond.Sort = "desc"
}
r.Order(cond.Order, cond.Sort)
r.WhereRange("ctime", cond.CTimeFrom, cond.CTimeTo, elastic.RangeScopeLcRc)
if len(cond.Distinct) > 0 {
for _, g := range cond.Distinct {
r.GroupBy("distinct", g, nil)
}
}
r.Index(search.ChallSrhComID)
r.Pn(1)
r.Ps(50)
if cond.PN != 0 {
r.Pn(int(cond.PN))
}
if cond.PS != 0 {
r.Ps(int(cond.PS))
}
if err = r.Scan(c, &resp); err != nil {
log.Error("r.Scan(%+v) error(%v) params(%s)", resp, err, r.Params())
}
return
}
// SearchChallengeMultiPage .
func (d *Dao) SearchChallengeMultiPage(c context.Context, cond *search.ChallSearchCommonCond) (result []*search.ChallSearchCommonData, err error) {
var resp *search.ChallSearchCommonResp
cond.PS = 1000
cond.PN = 1
result = make([]*search.ChallSearchCommonData, 0, len(cond.IDs))
for {
if resp, err = d.SearchChallenge(c, cond); err != nil {
return
}
result = append(result, resp.Result...)
if len(resp.Result) < resp.Page.Size {
break
}
cond.PN++
// return if result too long
if cond.PN > 10 {
log.Warn("cond(%+v) result is too long to degrade", cond)
return
}
}
return
}
// BatchUNameByUID will search unames by uids
func (d *Dao) BatchUNameByUID(c context.Context, uids []int64) (UNames map[int64]string, err error) {
//todo: local cache uname
uri := _unameURI
uv := url.Values{}
UNames = make(map[int64]string)
if len(uids) == 0 {
return
}
uv.Set("uids", xstr.JoinInts(uids))
unameSchRes := new(manager.UNameSearchResult)
if err = d.httpRead.Get(c, uri, "", uv, unameSchRes); err != nil {
return
}
if unameSchRes.Code != ecode.OK.Code() {
log.Error("search uname failed: %s?%s, error code(%d)", uri, uv.Get("uids"), unameSchRes.Code)
err = ecode.Int(unameSchRes.Code)
return
}
UNames = unameSchRes.Data
return
}
// SearchAuditLogGroup search archive audit log from log platform
func (d *Dao) SearchAuditLogGroup(c context.Context, cond *search.AuditLogGroupSearchCond) (auditLogSchRes *search.AuditLogSearchResult, err error) {
uri := _srhAuditLogURI
uv := cond.Query()
auditLogSchRes = new(search.AuditLogSearchResult)
if err = d.httpRead.Get(c, uri, "", uv, auditLogSchRes); err != nil {
log.Error("call search audit log %s error(%v)", uri, err)
return
}
if auditLogSchRes.Code != ecode.OK.Code() {
log.Error("call search audit log %s result error code(%d), message(%s)", uri, auditLogSchRes.Code, auditLogSchRes.Message)
err = ecode.Int(auditLogSchRes.Code)
}
return
}
// SearchAuditReportLog .
func (d *Dao) SearchAuditReportLog(c context.Context, cond *search.AuditReportSearchCond) (resp *search.AuditLogSearchCommonResult, err error) {
if len(cond.Fields) == 0 {
return
}
r := d.es.NewRequest(search.LogAuditAction).Fields(cond.Fields...).WhereIn("uid", cond.UID).WhereIn("oid", cond.Oid).
WhereEq("business", cond.Business).WhereIn("type", cond.Type).Order(cond.Order, cond.Sort).Pn(1).Ps(1000)
indexPrefix := search.LogAuditAction + "_" + strconv.Itoa(cond.Business)
if cond.IndexTimeType != "" {
switch cond.IndexTimeType {
case "year":
r.IndexByTime(indexPrefix, elastic.IndexTypeYear, cond.IndexTimeFrom, cond.IndexTimeEnd)
case "month":
r.IndexByTime(indexPrefix, elastic.IndexTypeMonth, cond.IndexTimeFrom, cond.IndexTimeEnd)
case "week":
r.IndexByTime(indexPrefix, elastic.IndexTypeWeek, cond.IndexTimeFrom, cond.IndexTimeEnd)
case "day":
r.IndexByTime(indexPrefix, elastic.IndexTypeDay, cond.IndexTimeFrom, cond.IndexTimeEnd)
default:
r.Index(indexPrefix + "_all")
}
} else {
r.Index(indexPrefix + "_all")
}
r.WhereIn("int_0", cond.Int0).WhereIn("int_1", cond.Int1).WhereIn("int_2", cond.Int2)
if cond.Str0 != "" {
r.WhereEq("str_0", cond.Str0)
}
if cond.Str1 != "" {
r.WhereEq("str_1", cond.Str1)
}
if cond.Str2 != "" {
r.WhereEq("str_2", cond.Str2)
}
if cond.Group != "" {
r.GroupBy(elastic.EnhancedModeGroupBy, cond.Group, []map[string]string{{"ctime": "desc"}})
}
if cond.Distinct != "" {
r.GroupBy(elastic.EnhancedModeDistinct, cond.Distinct, []map[string]string{{"ctime": "desc"}})
}
if err = r.Scan(c, &resp); err != nil {
log.Error("r.Scan(%+v) error(%v) params(%s)", resp, err, r.Params())
}
log.Info("SearchAuditReportLog end param(%v) err(%v)", r.Params(), err)
return
}

View File

@ -0,0 +1,108 @@
package dao
import (
"context"
"fmt"
"math"
"strconv"
"testing"
"time"
"go-common/app/admin/main/workflow/model"
"go-common/app/admin/main/workflow/model/search"
"github.com/smartystreets/goconvey/convey"
)
func TestSearchAuditLogGroup(t *testing.T) {
convey.Convey("SearchAuditLogGroup", t, func() {
cond := &search.AuditLogGroupSearchCond{
Group: []string{"oid"},
Businesses: []int64{3},
Order: "ctime",
PS: 1000,
PN: 1,
Sort: "desc",
//Oids: []int64{24648472, 24694284, 24706061, 24583668, 24703363},
Oids: []int64{10110151},
}
result, err := d.SearchAuditLogGroup(context.TODO(), cond)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldNotBeEmpty)
fmt.Println(len(result.Data.Result))
fmt.Println(result.Data.Result)
})
}
func TestSearchChallengeMultiPage(t *testing.T) {
convey.Convey("SearchChallengeMultiPage", t, func() {
cond := &search.ChallSearchCommonCond{
Fields: []string{"id", "gid", "mid", "state", "ctime"},
//IDs: []int64{1869, 1872},
IDs: []int64{1967, 1966, 1960},
}
result, err := d.SearchChallengeMultiPage(context.TODO(), cond)
convey.So(err, convey.ShouldBeNil)
fmt.Println("len", len(result))
for _, c := range result {
tc := &model.TinyChall{
Cid: c.ID,
Gid: c.Gid,
Mid: c.Mid,
}
var t time.Time
if t, err = time.Parse("2006-01-02 15:04:05", c.CTime); err != nil {
fmt.Printf("time.Parse() error(%v)\n", err)
}
if err = tc.CTime.Scan(t); err != nil {
fmt.Printf("xtime.Scan() error(%v)\n", err)
}
if str, ok := c.State.(string); ok {
st, _ := strconv.Atoi(str)
tc.State = int8(st)
}
if f, ok := c.State.(float64); ok {
tc.State = int8(math.Floor(f))
}
fmt.Printf("%+v\n", tc)
}
})
}
func TestSearchWorkflowReportLog(t *testing.T) {
convey.Convey("SearchWkf", t, func() {
cond := &search.AuditReportSearchCond{
AppID: search.LogAuditAction,
Fields: []string{"uname", "extra_data"},
Business: 11,
Order: "ctime",
Sort: "desc",
UID: []int64{6},
}
result, err := d.SearchAuditReportLog(context.TODO(), cond)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldNotBeEmpty)
fmt.Println(len(result.Result))
fmt.Printf("%+v\n", result.Result[0])
})
}
func TestSearchArchiveReportLog(t *testing.T) {
convey.Convey("SearchArc", t, func() {
cond := &search.AuditReportSearchCond{
AppID: search.LogAuditAction,
Fields: []string{"oid", "ctime"},
IndexTimeType: "month",
IndexTimeFrom: time.Now().AddDate(0, -6, 0),
IndexTimeEnd: time.Now(),
Business: 3,
Order: "ctime",
Sort: "desc",
Oid: []int64{1},
Distinct: "oid",
}
result, err := d.SearchAuditReportLog(context.TODO(), cond)
convey.So(err, convey.ShouldBeNil)
convey.So(result, convey.ShouldNotBeEmpty)
})
}

View File

@ -0,0 +1,64 @@
package dao
import (
"context"
"go-common/app/admin/main/workflow/model"
"go-common/app/admin/main/workflow/model/search"
"go-common/library/log"
)
// ChallTagsCount will retrive challenge tags count from group ids and group by tag id
// group id to challenge id to tag count
func (d *Dao) ChallTagsCount(c context.Context, gids []int64) (counts map[int64]map[int64]int64, err error) {
counts = make(map[int64]map[int64]int64, len(gids))
if len(gids) <= 0 {
return
}
rows, err := d.ReadORM.Table("workflow_chall").Where("gid IN (?)", gids).Select("gid,tid,count(tid)").
Group("gid,tid").Rows()
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
var gtc struct {
Gid int64
Tid int64
Count int64
}
if err = rows.Scan(&gtc.Gid, &gtc.Tid, &gtc.Count); err != nil {
return
}
if _, ok := counts[gtc.Gid]; !ok {
counts[gtc.Gid] = make(map[int64]int64)
}
counts[gtc.Gid][gtc.Tid] = gtc.Count
}
return
}
// ChallTagsCountV3 .
func (d *Dao) ChallTagsCountV3(c context.Context, gids []int64) (counts map[int64]map[int64]int64, err error) {
var result []*search.ChallSearchCommonData
counts = make(map[int64]map[int64]int64, len(gids))
cond := &search.ChallSearchCommonCond{
Fields: []string{"gid", "tid"},
Gids: gids,
States: []int64{int64(model.Pending)},
}
if result, err = d.SearchChallengeMultiPage(c, cond); err != nil {
log.Error("s.dao.SearchChallengeMultiPage(%+v) error(%v)", cond, err)
return
}
for _, r := range result {
if _, ok := counts[r.Gid]; !ok {
counts[r.Gid] = make(map[int64]int64)
}
counts[r.Gid][r.Tid]++
}
return
}

View File

@ -0,0 +1,40 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoChallTagsCount(t *testing.T) {
convey.Convey("ChallTagsCount", t, func(ctx convey.C) {
var (
c = context.Background()
gids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
counts, err := d.ChallTagsCount(c, gids)
ctx.Convey("Then err should be nil.counts should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(counts, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoChallTagsCountV3(t *testing.T) {
convey.Convey("ChallTagsCountV3", t, func(ctx convey.C) {
var (
c = context.Background()
gids = []int64{1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
counts, err := d.ChallTagsCountV3(c, gids)
ctx.Convey("Then err should be nil.counts should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(counts, convey.ShouldNotBeNil)
})
})
})
}