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,91 @@
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_notify_test.go",
"dao_test.go",
"databus_test.go",
"exp_test.go",
"http_test.go",
"member_log_test.go",
"member_old_test.go",
"member_test.go",
"memcache_test.go",
"realname_test.go",
"redis_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/member/conf:go_default_library",
"//app/job/main/member/model:go_default_library",
"//library/database/sql:go_default_library",
"//library/queue/databus:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"account_notify.go",
"dao.go",
"databus.go",
"exp.go",
"hbase.go",
"http.go",
"member.go",
"member_log.go",
"member_old.go",
"memcache.go",
"realname.go",
"redis.go",
],
importpath = "go-common/app/job/main/member/dao",
tags = ["automanaged"],
deps = [
"//app/job/main/member/conf:go_default_library",
"//app/job/main/member/dao/block:go_default_library",
"//app/job/main/member/model:go_default_library",
"//app/service/main/member/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis: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/queue/databus:go_default_library",
"//library/queue/databus/report:go_default_library",
"//library/time:go_default_library",
"//library/xstr: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",
"//app/job/main/member/dao/block:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,22 @@
package dao
import (
"context"
"fmt"
"go-common/app/job/main/member/model"
)
func notifyKey(mid int64) string {
return fmt.Sprintf("MemberJob-AccountNotify-T%d", mid)
}
// NotifyPurgeCache is
func (d *Dao) NotifyPurgeCache(c context.Context, mid int64, action string) error {
msg := &model.NotifyInfo{
Mid: mid,
Action: action,
}
key := notifyKey(mid)
return d.accNotify.Send(c, key, msg)
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"github.com/smartystreets/goconvey/convey"
"testing"
)
func TestDaonotifyKey(t *testing.T) {
convey.Convey("notifyKey", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
p1 := notifyKey(mid)
convCtx.Convey("Then p1 should not be nil.", func(convCtx convey.C) {
convCtx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
//func TestDaoNotifyPurgeCache(t *testing.T) {
// convey.Convey("NotifyPurgeCache", t, func(convCtx convey.C) {
// var (
// c = context.Background()
// mid = int64(0)
// action = ""
// )
// convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
// err := d.NotifyPurgeCache(c, mid, action)
// convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
// convCtx.So(err, convey.ShouldBeNil)
// })
// })
// })
//}

View File

@@ -0,0 +1,67 @@
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",
"http_test.go",
"mc_test.go",
"mysql_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/member/conf:go_default_library",
"//app/job/main/member/model/block:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/bouk/monkey:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"http.go",
"mc.go",
"mysql.go",
"notify.go",
],
importpath = "go-common/app/job/main/member/dao/block",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/member/conf:go_default_library",
"//app/job/main/member/model/block:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode: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,67 @@
package block
import (
"context"
"go-common/app/job/main/member/conf"
"go-common/library/cache/memcache"
xsql "go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
"github.com/pkg/errors"
)
type notifyFunc func(context.Context, int64, string) error
// Dao dao
type Dao struct {
conf *conf.Config
mc *memcache.Pool
db *xsql.DB
httpClient *bm.Client
notifyFunc notifyFunc
}
// New init mysql db
func New(conf *conf.Config, mc *memcache.Pool, db *xsql.DB, client *bm.Client, notifyFunc notifyFunc) (dao *Dao) {
dao = &Dao{
conf: conf,
mc: mc,
db: db,
httpClient: client,
notifyFunc: notifyFunc,
}
return
}
// Close close the resource.
func (d *Dao) Close() {
d.mc.Close()
d.db.Close()
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
return
}
if err = d.pingMC(c); err != nil {
return
}
return
}
// pingMc ping
func (d *Dao) pingMC(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
return
}
// BeginTX is.
func (d *Dao) BeginTX(c context.Context) (tx *xsql.Tx, err error) {
if tx, err = d.db.Begin(c); err != nil {
err = errors.WithStack(err)
}
return
}

View File

@@ -0,0 +1,61 @@
package block
import (
"flag"
"os"
"strings"
"testing"
"go-common/app/job/main/member/conf"
"go-common/library/cache/memcache"
xsql "go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
. "github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestTool(t *testing.T) {
Convey("tool", t, func() {
var (
mids = []int64{1, 2, 3, 46333, 35858}
)
str := midsToParam(mids)
So(str, ShouldEqual, "1,2,3,46333,35858")
})
}
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.member-job")
flag.Set("conf_token", "VEc5eqZNZHGQi6fsx7J6lJTqOGR9SnEO")
flag.Set("tree_id", "2134")
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("conf", "../cmd/member-job-dev.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
config := conf.Conf
//d.New().BlockImpl()
d = New(conf.Conf, memcache.NewPool(config.Memcache.Config), xsql.NewMySQL(config.BlockDB), bm.NewClient(config.HTTPClient), nil)
d.httpClient.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,46 @@
package block
import (
"context"
"fmt"
"net/url"
"strings"
"go-common/library/ecode"
"github.com/pkg/errors"
)
// SendSysMsg send sys msg.
func (d *Dao) SendSysMsg(c context.Context, code string, mids []int64, title string, content string, remoteIP string) (err error) {
params := url.Values{}
params.Set("mc", code)
params.Set("title", title)
params.Set("data_type", "4")
params.Set("context", content)
params.Set("mid_list", midsToParam(mids))
var res struct {
Code int `json:"code"`
Data *struct {
Status int8 `json:"status"`
Remark string `json:"remark"`
} `json:"data"`
}
if err = d.httpClient.Post(c, d.conf.BlockProperty.MSGURL, remoteIP, params, &res); err != nil {
err = errors.WithStack(err)
return
}
if res.Code != 0 {
err = errors.WithStack(ecode.Int(res.Code))
return
}
return
}
func midsToParam(mids []int64) (str string) {
strs := make([]string, 0, len(mids))
for _, mid := range mids {
strs = append(strs, fmt.Sprintf("%d", mid))
}
return strings.Join(strs, ",")
}

View File

@@ -0,0 +1,55 @@
package block
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestBlockSendSysMsg(t *testing.T) {
convey.Convey("SendSysMsg", t, func(convCtx convey.C) {
var (
c = context.Background()
code = ""
mids = []int64{}
title = ""
content = ""
remoteIP = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
defer gock.OffAll()
httpMock("POST", d.conf.BlockProperty.MSGURL).Reply(200).JSON(`{"code":0,"data":{"status":1,"remark":"test"}}`)
err := d.SendSysMsg(c, code, mids, title, content, remoteIP)
//println("err==",err)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
convCtx.Convey("When everything goes negative", func(convCtx convey.C) {
defer gock.OffAll()
httpMock("POST", d.conf.BlockProperty.MSGURL).Reply(200).JSON(`{"code":500,"data":{"status":1,"remark":"test"}}`)
//d.httpClient.SetTransport(gock.DefaultTransport)
err := d.SendSysMsg(c, code, mids, title, content, remoteIP)
convCtx.Convey("Then err should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestBlockmidsToParam(t *testing.T) {
convey.Convey("midsToParam", t, func(convCtx convey.C) {
var (
mids = []int64{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
str := midsToParam(mids)
convCtx.Convey("Then str should not be nil.", func(convCtx convey.C) {
convCtx.So(str, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,70 @@
package block
import (
"context"
"fmt"
"go-common/library/cache/memcache"
"github.com/pkg/errors"
)
func userKey(mid int64) (key string) {
key = fmt.Sprintf("u_%d", mid)
return
}
func syncBlockTypeID() (key string) {
return "sync_bt_cur_id"
}
//SetSyncBlockTypeID is.
func (d *Dao) SetSyncBlockTypeID(c context.Context, id int64) (err error) {
var (
key = syncBlockTypeID()
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: id, Expiration: 3600 * 24, Flags: memcache.FlagJSON}); err != nil {
err = errors.WithStack(err)
return
}
return
}
//SyncBlockTypeID is.
func (d *Dao) SyncBlockTypeID(c context.Context) (id int64, err error) {
var (
key = syncBlockTypeID()
conn = d.mc.Get(c)
item *memcache.Item
)
defer conn.Close()
if item, err = conn.Get(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.WithStack(err)
return
}
if err = conn.Scan(item, &id); err != nil {
err = errors.WithStack(err)
return
}
return
}
// DeleteUserCache is.
func (d *Dao) DeleteUserCache(c context.Context, mid int64) (err error) {
var (
key = userKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
err = errors.WithStack(err)
return
}
return
}

View File

@@ -0,0 +1,86 @@
package block
import (
"context"
"reflect"
"testing"
"go-common/library/cache/memcache"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
func TestBlockuserKey(t *testing.T) {
convey.Convey("userKey", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
key := userKey(mid)
convCtx.Convey("Then key should not be nil.", func(convCtx convey.C) {
convCtx.So(key, convey.ShouldNotBeNil)
})
})
})
}
func TestBlocksyncBlockTypeID(t *testing.T) {
convey.Convey("syncBlockTypeID", t, func(convCtx convey.C) {
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
key := syncBlockTypeID()
convCtx.Convey("Then key should not be nil.", func(convCtx convey.C) {
convCtx.So(key, convey.ShouldNotBeNil)
})
})
})
}
func TestBlockSetSyncBlockTypeID(t *testing.T) {
convey.Convey("SetSyncBlockTypeID", t, func(convCtx convey.C) {
var (
c = context.Background()
id = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.SetSyncBlockTypeID(c, id)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestBlockSyncBlockTypeID(t *testing.T) {
convey.Convey("SyncBlockTypeID", t, func(convCtx convey.C) {
var (
c = context.Background()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
id, err := d.SyncBlockTypeID(c)
convCtx.Convey("Then err should be nil.id should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestBlockDeleteUserCache(t *testing.T) {
convey.Convey("DeleteUserCache", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convCtx.Convey("connect memcache failed", func(convCtx convey.C) {
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool, _ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrConnClosed)
})
defer guard.Unpatch()
err := d.DeleteUserCache(c, mid)
convCtx.Convey("Then err should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,143 @@
package block
import (
"context"
"fmt"
model "go-common/app/job/main/member/model/block"
xsql "go-common/library/database/sql"
"github.com/pkg/errors"
)
const (
_upsertUser = `INSERT INTO block_user (mid,status) VALUES (?,?) ON DUPLICATE KEY UPDATE status=?`
_userStatusList = `SELECT id,mid FROM block_user WHERE status=? AND id>? LIMIT ?`
_userExtra = `SELECT id,mid,credit_answer_flag,action_time FROM block_extra WHERE mid=? ORDER BY id DESC LIMIT 1`
_userLastHistory = `SELECT id,mid,source,area,action,start_time,duration FROM block_history_%d WHERE mid=? ORDER BY id DESC LIMIT 1`
_upsertAddBlockCount = `INSERT INTO block_user_detail (mid,block_count) VALUES (?,1) ON DUPLICATE KEY UPDATE block_count=block_count+1`
_upsertExtra = `INSERT INTO block_extra (mid,credit_answer_flag,action_time) VALUES (?,?,?) ON DUPLICATE KEY UPDATE credit_answer_flag=? , action_time=?`
_insertHistory = `INSERT INTO block_history_%d (mid,admin_id,admin_name,source,area,reason,comment,action,start_time,duration,notify) VALUES (?,?,?,?,?,?,?,?,?,?,?)`
)
func historyIdx(mid int64) int64 {
return mid % 10
}
// UserStatusList is.
func (d *Dao) UserStatusList(c context.Context, status model.BlockStatus, startID int64, limit int) (maxID int64, mids []int64, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _userStatusList, status, startID, limit); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
var (
id, mid int64
)
if err = rows.Scan(&id, &mid); err != nil {
err = errors.WithStack(err)
return
}
if maxID < id {
maxID = id
}
mids = append(mids, mid)
}
if err = rows.Err(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UserLastHistory is.
func (d *Dao) UserLastHistory(c context.Context, mid int64) (his *model.DBHistory, err error) {
var (
sql = fmt.Sprintf(_userLastHistory, historyIdx(mid))
)
row := d.db.QueryRow(c, sql, mid)
his = &model.DBHistory{}
if err = row.Scan(&his.ID, &his.MID, &his.Source, &his.Area, &his.Action, &his.StartTime, &his.Duration); err != nil {
if err == xsql.ErrNoRows {
err = nil
his = nil
return
}
err = errors.WithStack(err)
return
}
return
}
// UserExtra is.
func (d *Dao) UserExtra(c context.Context, mid int64) (ex *model.DBExtra, err error) {
row := d.db.QueryRow(c, _userExtra, mid)
ex = &model.DBExtra{}
if err = row.Scan(&ex.ID, &ex.MID, &ex.CreditAnswerFlag, &ex.ActionTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
ex = nil
return
}
err = errors.WithStack(err)
return
}
return
}
// TxUpsertUser is.
func (d *Dao) TxUpsertUser(c context.Context, tx *xsql.Tx, mid int64, status model.BlockStatus) (count int64, err error) {
rows, err := tx.Exec(_upsertUser, mid, status, status)
if err != nil {
err = errors.WithStack(err)
return
}
return rows.RowsAffected()
}
// InsertExtra is.
func (d *Dao) InsertExtra(c context.Context, ex *model.DBExtra) (err error) {
if _, err = d.db.Exec(c, _upsertExtra, ex.MID, ex.CreditAnswerFlag, ex.ActionTime, ex.CreditAnswerFlag, ex.ActionTime); err != nil {
err = errors.WithStack(err)
return
}
return
}
// TxUpsertExtra is.
func (d *Dao) TxUpsertExtra(c context.Context, tx *xsql.Tx, ex *model.DBExtra) (err error) {
if _, err = tx.Exec(_upsertExtra, ex.MID, ex.CreditAnswerFlag, ex.ActionTime, ex.CreditAnswerFlag, ex.ActionTime); err != nil {
err = errors.WithStack(err)
return
}
return
}
//TxInsertHistory is.
func (d *Dao) TxInsertHistory(c context.Context, tx *xsql.Tx, h *model.DBHistory) (err error) {
var (
sql = fmt.Sprintf(_insertHistory, historyIdx(h.MID))
)
if _, err = tx.Exec(sql, h.MID, h.AdminID, h.AdminName, h.Source, h.Area, h.Reason, h.Comment, h.Action, h.StartTime, h.Duration, h.Notify); err != nil {
err = errors.WithStack(err)
return
}
return
}
//UpsertAddBlockCount is.
func (d *Dao) UpsertAddBlockCount(c context.Context, mid int64) (err error) {
if _, err = d.db.Exec(c, _upsertAddBlockCount, mid); err != nil {
err = errors.WithStack(err)
return
}
return
}

View File

@@ -0,0 +1,277 @@
package block
import (
"context"
"database/sql"
"fmt"
"reflect"
"testing"
model "go-common/app/job/main/member/model/block"
xsql "go-common/library/database/sql"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
func TestBlockhistoryIdx(t *testing.T) {
convey.Convey("historyIdx", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
p1 := historyIdx(mid)
convCtx.Convey("Then p1 should not be nil.", func(convCtx convey.C) {
convCtx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestBlockUserStatusList(t *testing.T) {
convey.Convey("UserStatusList", t, func(convCtx convey.C) {
var (
c = context.Background()
status model.BlockStatus
startID = int64(0)
limit = int(10)
)
rows, _ := d.db.Query(c, _userStatusList, status, startID, limit)
convCtx.Convey("UserStatusList success", func(convCtx convey.C) {
guard := monkey.PatchInstanceMethod(reflect.TypeOf(rows), "Scan", func(_ *xsql.Rows, _ ...interface{}) error {
return nil
})
defer guard.Unpatch()
maxID, mids, err := d.UserStatusList(c, status, startID, limit)
convCtx.Convey("Then err should be nil.maxID,mids should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(mids, convey.ShouldNotBeNil)
convCtx.So(maxID, convey.ShouldNotBeNil)
})
})
})
}
func TestBlockUserLastHistory(t *testing.T) {
convey.Convey("UserLastHistory", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("UserLastHistory success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db.QueryRow(context.TODO(), fmt.Sprintf(_userLastHistory, historyIdx(mid)), 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return nil
})
defer monkey.UnpatchAll()
his, err := d.UserLastHistory(c, mid)
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(his, convey.ShouldNotBeNil)
})
convey.Convey("UserLastHistory err", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db.QueryRow(context.TODO(), fmt.Sprintf(_userLastHistory, historyIdx(mid)), 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return fmt.Errorf("row.Scan error")
})
defer monkey.UnpatchAll()
his, err := d.UserLastHistory(c, mid)
convCtx.So(err, convey.ShouldNotBeNil)
convCtx.So(his, convey.ShouldNotBeNil)
})
convey.Convey("UserLastHistory no record", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db.QueryRow(context.TODO(), fmt.Sprintf(_userLastHistory, historyIdx(mid)), 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return sql.ErrNoRows
})
defer monkey.UnpatchAll()
his, err := d.UserLastHistory(c, mid)
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(his, convey.ShouldBeNil)
})
})
}
func TestBlockUserExtra(t *testing.T) {
convey.Convey("UserExtra", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("UserExtra success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db.QueryRow(context.TODO(), _userExtra, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return nil
})
defer monkey.UnpatchAll()
ex, err := d.UserExtra(c, mid)
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(ex, convey.ShouldNotBeNil)
})
convey.Convey("UserExtra err", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db.QueryRow(context.TODO(), _userExtra, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return fmt.Errorf("row.Scan error")
})
defer monkey.UnpatchAll()
ex, err := d.UserExtra(c, mid)
convCtx.So(err, convey.ShouldNotBeNil)
convCtx.So(ex, convey.ShouldNotBeNil)
})
convey.Convey("UserExtra no record", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db.QueryRow(context.TODO(), _userExtra, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return sql.ErrNoRows
})
defer monkey.UnpatchAll()
ex, err := d.UserExtra(c, mid)
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(ex, convey.ShouldBeNil)
})
})
}
func TestBlockTxUpsertUser(t *testing.T) {
convey.Convey("TxUpsertUser", t, func(convCtx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTX(c)
mid = int64(0)
status model.BlockStatus
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
count, err := d.TxUpsertUser(c, tx, mid, status)
convCtx.Convey("Then err should be nil.count should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(count, convey.ShouldNotBeNil)
})
})
convCtx.Reset(func() {
tx.Commit()
})
})
}
func TestBlockInsertExtra(t *testing.T) {
convey.Convey("InsertExtra", t, func(convCtx convey.C) {
var (
c = context.Background()
ex = &model.DBExtra{}
)
convCtx.Convey("InsertExtra success", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.InsertExtra(c, ex)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
convCtx.Convey("InsertExtra err", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("insert err")
})
defer monkey.UnpatchAll()
err := d.InsertExtra(c, ex)
convCtx.Convey("Then err should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
})
})
})
}
func TestBlockTxUpsertExtra(t *testing.T) {
convey.Convey("TxUpsertExtra", t, func(convCtx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTX(c)
ex = &model.DBExtra{}
)
convCtx.Convey("TxUpsertExtra success", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(tx), "Exec", func(_ *xsql.Tx, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.TxUpsertExtra(c, tx, ex)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
convCtx.Convey("TxUpsertExtra err", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(tx), "Exec", func(_ *xsql.Tx, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("insert err")
})
defer monkey.UnpatchAll()
err := d.TxUpsertExtra(c, tx, ex)
convCtx.Convey("Then err should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
})
})
convCtx.Reset(func() {
tx.Commit()
})
})
}
func TestBlockTxInsertHistory(t *testing.T) {
convey.Convey("TxInsertHistory", t, func(convCtx convey.C) {
var (
c = context.Background()
tx, _ = d.BeginTX(c)
h = &model.DBHistory{}
)
convCtx.Convey("TxUpsertExtra success", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(tx), "Exec", func(_ *xsql.Tx, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.TxInsertHistory(c, tx, h)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
convCtx.Convey("TxUpsertExtra err", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(tx), "Exec", func(_ *xsql.Tx, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("insert err")
})
defer monkey.UnpatchAll()
err := d.TxInsertHistory(c, tx, h)
convCtx.Convey("Then err should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
})
})
convCtx.Reset(func() {
tx.Commit()
})
})
}
func TestBlockUpsertAddBlockCount(t *testing.T) {
convey.Convey("UpsertAddBlockCount", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convCtx.Convey("UpsertAddBlockCount success", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.UpsertAddBlockCount(c, mid)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
convCtx.Convey("InsertExtra err", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("insert err")
})
defer monkey.UnpatchAll()
err := d.UpsertAddBlockCount(c, mid)
convCtx.Convey("Then err should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,16 @@
package block
import (
"context"
"github.com/pkg/errors"
)
// AccountNotify is
func (d *Dao) AccountNotify(c context.Context, mid int64) (err error) {
action := "blockUser"
if err = d.notifyFunc(c, mid, action); err != nil {
err = errors.Errorf("mid(%d) s.accountNotify.Send(%+v) error(%+v)", mid, action, err)
}
return
}

View File

@@ -0,0 +1,79 @@
package dao
import (
"context"
"time"
"go-common/app/job/main/member/conf"
"go-common/app/job/main/member/dao/block"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
"go-common/library/queue/databus"
)
// Dao struct info of Dao.
type Dao struct {
c *conf.Config
block *block.Dao
db *sql.DB
accCheckDB *sql.DB
passLogDB *sql.DB
accdb *sql.DB
asodb *sql.DB
client *bm.Client
mc *memcache.Pool
mcExpire int32
redis *redis.Pool
plogDatabus *databus.Databus
accNotify *databus.Databus
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.Mysql),
accCheckDB: sql.NewMySQL(c.AccCheckMysql),
passLogDB: sql.NewMySQL(c.PasslogMysql),
accdb: sql.NewMySQL(c.AccMysql),
asodb: sql.NewMySQL(c.AsoMysql),
client: bm.NewClient(c.HTTPClient),
mc: memcache.NewPool(c.Memcache.Config),
mcExpire: int32(time.Duration(c.Memcache.Expire) / time.Second),
redis: redis.NewPool(c.Redis),
plogDatabus: databus.New(c.PLogDatabus),
accNotify: databus.New(c.AccountNotify),
}
d.block = block.New(c,
memcache.NewPool(c.BlockMemcache),
sql.NewMySQL(c.BlockDB),
d.client,
d.NotifyPurgeCache,
)
return
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
if d.mc != nil {
d.mc.Close()
}
if d.block != nil {
d.block.Close()
}
}
// Ping ping health of db.
func (d *Dao) Ping(c context.Context) (err error) {
return d.db.Ping(c)
}
// BlockImpl is.
func (d *Dao) BlockImpl() *block.Dao {
return d.block
}

View File

@@ -0,0 +1,45 @@
package dao
import (
"flag"
"os"
"strings"
"testing"
"go-common/app/job/main/member/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.member-job")
flag.Set("conf_token", "VEc5eqZNZHGQi6fsx7J6lJTqOGR9SnEO")
flag.Set("tree_id", "2134")
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("conf", "../cmd/member-job-dev.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.client.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,25 @@
package dao
import (
"context"
"strconv"
"go-common/app/job/main/member/model"
)
// DatabusAddLog add exp log messager to databus
func (d *Dao) DatabusAddLog(c context.Context, mid, exp, toExp, ts int64, oper, reason, ip string) (err error) {
log := &model.UserLog{
Mid: mid,
TS: ts,
IP: ip,
Content: map[string]string{
"from_exp": strconv.FormatInt(exp, 10),
"to_exp": strconv.FormatInt(toExp, 10),
"operater": oper,
"reason": reason,
},
}
err = d.plogDatabus.Send(c, strconv.FormatInt(mid, 10), log)
return
}

View File

@@ -0,0 +1,49 @@
package dao
import (
"context"
"fmt"
"reflect"
"testing"
"go-common/library/queue/databus"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoDatabusAddLog(t *testing.T) {
convey.Convey("DatabusAddLog", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
exp = int64(0)
toExp = int64(0)
ts = int64(0)
oper = ""
reason = ""
ip = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.plogDatabus), "Send", func(_ *databus.Databus, _ context.Context, _ string, _ interface{}) error {
return nil
})
defer monkey.UnpatchAll()
err := d.DatabusAddLog(c, mid, exp, toExp, ts, oper, reason, ip)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
convCtx.Convey("When everything goes negative", func(convCtx convey.C) {
monkey.PatchInstanceMethod(reflect.TypeOf(d.plogDatabus), "Send", func(_ *databus.Databus, _ context.Context, _ string, _ interface{}) error {
return fmt.Errorf("Failed send data err")
})
defer monkey.UnpatchAll()
err := d.DatabusAddLog(c, mid, exp, toExp, ts, oper, reason, ip)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,52 @@
package dao
import (
"context"
"fmt"
"go-common/app/job/main/member/model"
"go-common/library/database/sql"
"go-common/library/time"
)
const (
_initExp = "INSERT IGNORE INTO user_exp_%02d (mid) VALUES (?)"
_updateExpAped = `UPDATE user_exp_%02d SET exp=exp+?,flag=flag|? WHERE mid=? AND flag&?=0`
_updateExpFlag = `UPDATE user_exp_%02d SET addtime=?,flag=? WHERE mid=? AND addtime<?`
_SelExp = "SELECT mid,exp,flag,addtime,mtime FROM user_exp_%02d where mid=?"
)
// InitExp init user exp
func (d *Dao) InitExp(c context.Context, mid int64) (err error) {
_, err = d.db.Exec(c, fmt.Sprintf(_initExp, hit(mid)), mid)
return
}
// SelExp get new user exp by mid
func (d *Dao) SelExp(c context.Context, mid int64) (exp *model.NewExp, err error) {
exp = &model.NewExp{}
row := d.db.QueryRow(c, fmt.Sprintf(_SelExp, hit(mid)), mid)
if err = row.Scan(&exp.Mid, &exp.Exp, &exp.Flag, &exp.Addtime, &exp.Mtime); err != nil {
if err == sql.ErrNoRows {
err = nil
}
return
}
return
}
// UpdateExpAped update user exp append mode.
func (d *Dao) UpdateExpAped(c context.Context, mid, exp int64, flag int32) (rows int64, err error) {
res, err := d.db.Exec(c, fmt.Sprintf(_updateExpAped, hit(mid)), exp, flag, mid, flag)
if err != nil {
return
}
rows, _ = res.RowsAffected()
return
}
// UpdateExpFlag update user exp.
func (d *Dao) UpdateExpFlag(c context.Context, mid int64, flag int32, addtime time.Time) (err error) {
_, err = d.db.Exec(c, fmt.Sprintf(_updateExpFlag, hit(mid)), addtime, flag, mid, addtime)
return
}

View File

@@ -0,0 +1,43 @@
package dao
import (
"context"
"testing"
"time"
xtime "go-common/library/time"
. "github.com/smartystreets/goconvey/convey"
)
func Test_SelExp(t *testing.T) {
Convey("selExp", t, func() {
exp, err := d.SelExp(context.TODO(), 2233)
So(err, ShouldBeNil)
So(exp, ShouldNotBeEmpty)
})
}
func Test_UpdateExpAped(t *testing.T) {
Convey("updateExpAped", t, func() {
if _, err := d.UpdateExpAped(context.TODO(), 2233, 666, 1); err != nil {
So(err, ShouldBeNil)
}
})
}
func Test_InitExp(t *testing.T) {
Convey("InitExp", t, func() {
if err := d.InitExp(context.Background(), 1111); err != nil {
So(err, ShouldNotBeNil)
}
})
}
func Test_UpdateExpFlag(t *testing.T) {
Convey("UpdateExpFlag", t, func() {
if err := d.UpdateExpFlag(context.Background(), 1111, 123, xtime.Time(time.Now().Unix())); err != nil {
So(err, ShouldNotBeNil)
}
})
}

View File

@@ -0,0 +1,34 @@
package dao
// var (
// familyDetail = "detail"
// columnTs = "ts"
// )
// func rowKey(mid, ts int64, op string) string {
// return fmt.Sprintf("%d%d_%d_%s", mid%10, mid, math.MaxInt64-ts, op)
// }
// // AddLog coin modify log.
// func (d *Dao) AddLog(c context.Context, mid, ts int64, content map[string][]byte, table string) (err error) {
// var (
// mutate *hrpc.Mutate
// operator = string(content["operater"])
// key = rowKey(mid, ts, operator)
// tsB = make([]byte, 8)
// ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.WriteTimeout))
// )
// defer cancel()
// binary.BigEndian.PutUint64(tsB, uint64(ts))
// content[columnTs] = tsB
// values := map[string]map[string][]byte{familyDetail: content}
// if mutate, err = hrpc.NewPutStr(ctx, table, key, values); err != nil {
// log.Error("hrpc.NewPutStr(%s, %s, %v) error(%v)", table, key, values, err)
// return
// }
// if _, err = d.hbase.Put(c, mutate); err != nil {
// log.Error("hbase.Put mid %d,error(%v)", mid, err)
// return
// }
// return
// }

View File

@@ -0,0 +1,89 @@
package dao
import (
"context"
"net/url"
"strconv"
"go-common/app/job/main/member/model"
"go-common/library/ecode"
"go-common/library/log"
)
// AsoSt aso user status.
type AsoSt struct {
Code int64
Data struct {
Email string `json:"email"`
Telphone string `json:"telphone"`
SafeQs int8 `json:"safe_question"`
Spacesta int8 `json:"spacesta"`
} `json:"data"`
}
const (
_asoURI = "http://passport.bilibili.co/intranet/acc/queryByMid"
_identityURL = "http://account.bilibili.co/api/identify/info"
_updateFaceURL = "http://account.bilibili.co/api/internal/member/updateFace"
)
// AsoStatus get aso bind status.
func (d *Dao) AsoStatus(c context.Context, mid int64) (aso *model.MemberAso, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
res := new(struct {
Code int64 `json:"code"`
Data model.MemberAso `json:"data"`
})
if err = d.client.Get(c, _asoURI, "", params, res); err != nil {
log.Error("get aso err %v uri %s ", err, _asoURI+params.Encode())
return
}
if res.Code != 0 {
err = ecode.RequestErr
log.Error("asotatus err res %v", res)
return
}
aso = &res.Data
return
}
// IdentifyStaus identify status.
func (d *Dao) IdentifyStaus(c context.Context, mid int64) (b bool, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int64 `json:"code"`
Data struct {
Identify int8 `json:"identify"` // 0
} `json:"data"`
}
if err = d.client.Get(c, _identityURL, "", params, &res); err != nil {
log.Error("get aso err %v uri %s ", err, _asoURI+params.Encode())
return
}
if res.Code == 0 && res.Data.Identify == 0 {
b = true
}
return
}
// UpdateAccFace update acc face.
func (d *Dao) UpdateAccFace(c context.Context, mid int64, face string) (err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("face", face)
var res struct {
Code int `json:"code"`
}
if err = d.client.Post(c, _updateFaceURL, "", params, &res); err != nil {
log.Error("update account face err %v uri %s ", err, _updateFaceURL+params.Encode())
return
}
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("UpdateAccFace mid(%d) error(%v)", mid, err)
return
}
return
}

View File

@@ -0,0 +1,29 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestDao_UpdateAccFace(t *testing.T) {
Convey("UpdateAccFace", t, func() {
Convey("When everything goes positive", func() {
defer gock.OffAll()
httpMock("POST", _updateFaceURL).Reply(200).JSON(`{"code":0}`)
err := d.UpdateAccFace(context.TODO(), 1, "1456")
So(err, ShouldBeNil)
})
Convey("When everything goes negative", func() {
defer gock.OffAll()
httpMock("POST", _updateFaceURL).Reply(200).JSON(`{"code":500}`)
err := d.UpdateAccFace(context.TODO(), 1, "1456")
Convey("Then err should be nil.", func() {
So(err, ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,140 @@
package dao
import (
"context"
"database/sql"
"fmt"
"go-common/app/job/main/member/model"
smodel "go-common/app/service/main/member/model"
"go-common/library/log"
)
const (
_shard = 100
_SelBaseInfo = "SELECT mid,name,sex,face,sign,rank,birthday,ctime,mtime FROM user_base_%02d WHERE mid=?"
_SetOfficial = "INSERT INTO user_official (mid,role,title,description) values (?,?,?,?) ON DUPLICATE KEY UPDATE role=VALUES(role),title=VALUES(title),description=VALUES(description)"
_SetBaseInfo = "INSERT INTO user_base_%02d(mid,name,sex,face,sign,rank) VALUES (?,?,?,?,?,?) ON DUPLICATE KEY UPDATE name=?,sex=?,face=?,sign=?,rank=?"
_SetName = "INSERT INTO user_base_%02d(mid,name) VALUES (?,?) ON DUPLICATE KEY UPDATE name=?"
_SetSign = "INSERT INTO user_base_%02d(mid,sign) VALUES (?,?) ON DUPLICATE KEY UPDATE sign=?"
_InitBase = "INSERT IGNORE INTO user_base_%02d(mid) VALUES (?)"
_SetFace = "UPDATE user_base_%02d SET face=? WHERE mid=?"
_SelMoral = "SELECT mid,moral,added,deducted,last_recover_date from user_moral where mid = ?"
_recoverMoral = `update user_moral set moral=moral+?,added=added+?, last_recover_date=? where mid = ? and last_recover_date != ? and moral < 7000 `
_auditQueuingFace = `UPDATE user_property_review SET state=?, operator='system', remark=? WHERE property=1 AND state=10 AND is_monitor=0 AND new=?`
)
// hit get table suffix
func hit(id int64) int64 {
return id % _shard
}
// BaseInfo info of user.
//用于检查数据不需要拼url
func (d *Dao) BaseInfo(c context.Context, mid int64) (r *model.BaseInfo, err error) {
r = &model.BaseInfo{}
row := d.db.QueryRow(c, fmt.Sprintf(_SelBaseInfo, hit(mid)), mid)
if err = row.Scan(&r.Mid, &r.Name, &r.Sex, &r.Face, &r.Sign, &r.Rank, &r.Birthday, &r.CTime, &r.MTime); err != nil {
r = nil
if err == sql.ErrNoRows {
err = nil
return
}
log.Error("row.Scan() error(%v) mid(%v)", err, mid)
}
return
}
// SelMoral select moral by mid from db
func (d *Dao) SelMoral(c context.Context, mid int64) (moral *smodel.Moral, err error) {
moral = &smodel.Moral{}
row := d.db.QueryRow(c, _SelMoral, mid)
if err = row.Scan(&moral.Mid, &moral.Moral, &moral.Added, &moral.Deducted, &moral.LastRecoverDate); err != nil {
if err == sql.ErrNoRows {
moral = nil
err = nil
return
}
log.Error(" SelMoral row.Scan() error(%v) mid(%v)", err, mid)
}
return
}
// RecoverMoral set moral by mid from db
func (d *Dao) RecoverMoral(c context.Context, mid, delta, added int64, lastRecoverDate string) (rowsAffected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _recoverMoral, delta, added, lastRecoverDate, mid, lastRecoverDate); err != nil {
log.Error(" RecoverMoral d.db.Exec() error(%v) mid(%v)", err, mid)
return
}
return res.RowsAffected()
}
// SetSign set sign.
func (d *Dao) SetSign(c context.Context, mid int64, sign string) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_SetSign, hit(mid)), mid, sign, sign); err != nil {
log.Error("setSign: tx.Exec(%d, %v) error(%v)", mid, sign, err)
return
}
return
}
// SetOfficial set official.
func (d *Dao) SetOfficial(c context.Context, mid int64, role int8, title string, desc string) error {
if _, err := d.db.Exec(c, _SetOfficial, mid, role, title, desc); err != nil {
log.Error("_SetOfficial: tx.Exec(%d,%d,%s,%s) error(%v)", mid, role, title, desc, err)
return err
}
return nil
}
// SetName set name.
func (d *Dao) SetName(c context.Context, mid int64, name string) (err error) {
if len(name) <= 0 {
log.Error("SetName: mid(%d) len(name)<=0 ", mid)
return
}
if _, err = d.db.Exec(c, fmt.Sprintf(_SetName, hit(mid)), mid, name, name); err != nil {
log.Error("setName: tx.Exec(%d, %v) error(%v)", mid, name, err)
return
}
return
}
// SetBaseInfo set base info of user.
func (d *Dao) SetBaseInfo(c context.Context, r *model.BaseInfo) (err error) {
if len(r.Name) <= 0 {
log.Error("SetBaseInfo: mid(%d) len(r.Name)<=0 BaseInfo(%v)", r.Mid, r)
return
}
if _, err = d.db.Exec(c, fmt.Sprintf(_SetBaseInfo, hit(r.Mid)), r.Mid, r.Name, r.Sex, r.Face, r.Sign, r.Rank, r.Name, r.Sex, r.Face, r.Sign, r.Rank); err != nil {
log.Error("SetBaseInfo: db.Exec(%d, %v) error(%v)", r.Mid, r, err)
}
return
}
// SetFace set face.
func (d *Dao) SetFace(c context.Context, mid int64, face string) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_SetFace, hit(mid)), face, mid); err != nil {
log.Error("SetFace: tx.Exec(%v,%v) error(%v)", face, mid, err)
}
return
}
// InitBase init base info.
func (d *Dao) InitBase(c context.Context, mid int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_InitBase, hit(mid)), mid); err != nil {
log.Error("InitBase: tx.Exec(%d) error(%v)", mid, err)
}
return
}
// AuditQueuingFace auditQueuingFace.
func (d *Dao) AuditQueuingFace(c context.Context, face string, remark string, state int8) error {
_, err := d.db.Exec(c, _auditQueuingFace, state, remark, face)
if err != nil {
log.Error("Failed to audit queuing face: %s, remark: %s, state: %d: %+v", face, remark, state, err)
return err
}
return nil
}

View File

@@ -0,0 +1,56 @@
package dao
import (
"context"
"go-common/app/job/main/member/model"
"go-common/library/log"
"go-common/library/queue/databus/report"
"go-common/library/time"
)
// consts
const (
ExpLogID = 11
MoralLogID = 12
)
// AddExpLog is
func (d *Dao) AddExpLog(ctx context.Context, ul *model.UserLog) {
d.addLog(ctx, ExpLogID, "log_exp_change", ul)
}
// AddMoralLog is
func (d *Dao) AddMoralLog(ctx context.Context, ul *model.UserLog) {
d.addLog(ctx, MoralLogID, "log_moral_change", ul)
}
// AddExpLog is
func (d *Dao) addLog(ctx context.Context, business int, action string, ul *model.UserLog) {
t := time.Time(ul.TS)
content := make(map[string]interface{}, len(ul.Content))
for k, v := range ul.Content {
content[k] = v
}
if ul.LogID == "" {
ul.LogID = model.UUID4()
}
content["log_id"] = ul.LogID
ui := &report.UserInfo{
Mid: ul.Mid,
Platform: "",
Build: 0,
Buvid: "",
Business: business,
Type: 0,
Oid: 0,
Action: action,
Ctime: t.Time(),
IP: ul.IP,
// extra
Index: []interface{}{ul.LogID},
Content: content,
}
report.User(ui)
log.Info("add log to report: userlog: %+v userinfo: %+v", ul, ui)
}

View File

@@ -0,0 +1,53 @@
package dao
import (
"context"
"go-common/app/job/main/member/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAddExpLog(t *testing.T) {
convey.Convey("AddExpLog", t, func(convCtx convey.C) {
var (
ctx = context.Background()
ul = &model.UserLog{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
d.AddExpLog(ctx, ul)
convCtx.Convey("No return values", func(convCtx convey.C) {
})
})
})
}
func TestDaoAddMoralLog(t *testing.T) {
convey.Convey("AddMoralLog", t, func(convCtx convey.C) {
var (
ctx = context.Background()
ul = &model.UserLog{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
d.AddMoralLog(ctx, ul)
convCtx.Convey("No return values", func(convCtx convey.C) {
})
})
})
}
func TestDaoaddLog(t *testing.T) {
convey.Convey("addLog", t, func(convCtx convey.C) {
var (
ctx = context.Background()
business = int(0)
action = ""
ul = &model.UserLog{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
d.addLog(ctx, business, action, ul)
convCtx.Convey("No return values", func(convCtx convey.C) {
})
})
})
}

View File

@@ -0,0 +1,54 @@
package dao
import (
"context"
"fmt"
"go-common/app/job/main/member/model"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_SelAsos = "SELECT mid,uname from aso_account where mid in(%s)"
_SelAsoName = "SELECT uname from aso_account where mid=?"
)
// Accounts gets account info.
func (d *Dao) Accounts(c context.Context, mids []int64) (accs map[int64]*model.AccountInfo, errs map[int64]map[string]bool, err error) {
//moralLogTpl := mids[0] % _shardMoralLog
midsStr := xstr.JoinInts(mids)
accs = make(map[int64]*model.AccountInfo)
errs = make(map[int64]map[string]bool)
// name
rows, err := d.asodb.Query(c, fmt.Sprintf(_SelAsos, midsStr))
if err != nil {
log.Error("d.asodb.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
r := &model.AccountInfo{}
if err = rows.Scan(&r.Mid, &r.Name); err != nil {
log.Error("row.Scan() error(%v) mid(%v)", err, r.Mid)
err = nil
continue
}
accs[r.Mid] = r
errs[r.Mid] = make(map[string]bool)
errs[r.Mid]["asoOK"] = true
}
return
}
//Name name.
func (d *Dao) Name(c context.Context, mid int64) (name string, err error) {
arow := d.asodb.QueryRow(c, _SelAsoName, mid)
if err = arow.Scan(&name); err != nil {
log.Error("row.Scan() error(%v)", err)
return
}
return
}

View File

@@ -0,0 +1,56 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAccounts(t *testing.T) {
convey.Convey("Accounts", t, func(convCtx convey.C) {
var (
c = context.Background()
mids = []int64{1, 2}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
accs, errs, err := d.Accounts(c, mids)
if err != nil {
convCtx.Convey("When no rows int result", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
convCtx.So(errs, convey.ShouldNotBeNil)
convCtx.So(accs, convey.ShouldNotBeNil)
})
} else {
convCtx.Convey("When have rows int result", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(errs, convey.ShouldNotBeNil)
convCtx.So(accs, convey.ShouldNotBeNil)
})
}
})
})
}
func TestDaoName(t *testing.T) {
convey.Convey("Name", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(1)
)
convCtx.Convey("Name search two situation:", func(convCtx convey.C) {
name, err := d.Name(c, mid)
if err != nil {
convCtx.Convey("Name occur an error", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
convCtx.So(name, convey.ShouldNotBeNil)
})
} else {
convCtx.Convey("Name no err search", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(name, convey.ShouldNotBeNil)
})
}
})
})
}

View File

@@ -0,0 +1,305 @@
package dao
import (
"context"
"database/sql"
"fmt"
"reflect"
"testing"
"time"
"go-common/app/job/main/member/model"
xsql "go-common/library/database/sql"
"github.com/bouk/monkey"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_SetBaseInfo(t *testing.T) {
r := &model.BaseInfo{Mid: 100, Sex: 1, Name: "lgs", Face: "face", Sign: "sign", Rank: 3}
Convey("SetBaseInfo", t, func() {
Convey("SetBaseInfo success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.SetBaseInfo(context.TODO(), r)
So(err, ShouldBeNil)
})
Convey("SetBaseInfo failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.SetBaseInfo(context.TODO(), r)
So(err, ShouldNotBeNil)
})
})
}
func TestDao_UpdateSign(t *testing.T) {
Convey("SetSign", t, func() {
Convey("SetSign success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.SetSign(context.TODO(), 1, "my sign")
So(err, ShouldBeNil)
})
Convey("SetSign failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.SetSign(context.TODO(), 1, "my sign")
So(err, ShouldNotBeNil)
})
})
}
func TestDao_SetName(t *testing.T) {
Convey("SetName", t, func() {
Convey("SetName success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.SetName(context.TODO(), 1, "myname")
So(err, ShouldBeNil)
})
Convey("SetName failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.SetName(context.TODO(), 1, "myname")
So(err, ShouldNotBeNil)
})
})
}
func TestDao_UpdateFace(t *testing.T) {
Convey("SetFaceRank", t, func() {
Convey("SetFaceRank success", func() {
err := d.SetFace(context.TODO(), int64(1), "http://face")
So(err, ShouldBeNil)
})
Convey("SetFaceRank failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.SetFace(context.TODO(), int64(1), "http://face")
So(err, ShouldNotBeNil)
})
})
}
func TestDao_SelMoral(t *testing.T) {
Convey("SelMoral", t, func() {
Convey("SelMoral success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.accdb.QueryRow(context.TODO(), _SelMoral, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return nil
})
defer monkey.UnpatchAll()
moral, err := d.SelMoral(context.TODO(), int64(8))
So(err, ShouldBeNil)
So(moral, ShouldNotBeNil)
})
Convey("SelMoral error", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.accdb.QueryRow(context.TODO(), _SelMoral, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return fmt.Errorf("row.Scan error")
})
defer monkey.UnpatchAll()
moral, err := d.SelMoral(context.TODO(), int64(8))
So(err, ShouldNotBeNil)
So(moral, ShouldNotBeNil)
})
Convey("SelMoral no record", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.accdb.QueryRow(context.TODO(), _SelMoral, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return sql.ErrNoRows
})
defer monkey.UnpatchAll()
moral, err := d.SelMoral(context.TODO(), int64(8))
So(err, ShouldBeNil)
So(moral, ShouldBeNil)
})
})
}
func TestDao_IncrMoral(t *testing.T) {
Convey("IncrMoral", t, func() {
Convey("AuditQueuingFace success", func() {
_, err := d.RecoverMoral(context.TODO(), 2, 100, 1, time.Now().Format("2006-01-02"))
So(err, ShouldBeNil)
})
Convey("AuditQueuingFace failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
_, err := d.RecoverMoral(context.TODO(), 2, 100, 1, time.Now().Format("2006-01-02"))
So(err, ShouldNotBeNil)
})
})
}
func TestDao_AuditQueuingFace(t *testing.T) {
Convey("AuditQueuingFace", t, func() {
Convey("AuditQueuingFace success", func() {
err := d.AuditQueuingFace(context.TODO(), "/bfs/face/7e68723b9d3664ac3773c1f3c26d5e2bfabc0f22.jpg", "", 0)
So(err, ShouldBeNil)
})
Convey("AuditQueuingFace failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.AuditQueuingFace(context.TODO(), "/bfs/face/7e68723b9d3664ac3773c1f3c26d5e2bfabc0f22.jpg", "", 0)
So(err, ShouldNotBeNil)
})
})
}
func TestDao_BaseInfo(t *testing.T) {
Convey("BaseInfo", t, func() {
Convey("BaseInfo success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.accdb.QueryRow(context.TODO(), _SelBaseInfo, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return nil
})
defer monkey.UnpatchAll()
r, err := d.BaseInfo(context.TODO(), 100)
So(err, ShouldBeNil)
So(r, ShouldNotBeNil)
})
Convey("BaseInfo error", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.accdb.QueryRow(context.TODO(), _SelBaseInfo, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return fmt.Errorf("row.Scan error")
})
defer monkey.UnpatchAll()
r, err := d.BaseInfo(context.TODO(), 11)
So(err, ShouldNotBeNil)
So(r, ShouldBeNil)
})
Convey("BaseInfo no record", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.accdb.QueryRow(context.TODO(), _SelBaseInfo, 1)), "Scan", func(_ *xsql.Row, _ ...interface{}) error {
return sql.ErrNoRows
})
defer monkey.UnpatchAll()
r, err := d.BaseInfo(context.TODO(), 11)
So(err, ShouldBeNil)
So(r, ShouldBeNil)
})
})
}
// TestDao_RecoverMoral update
func TestDao_RecoverMoral(t *testing.T) {
Convey("RecoverMoral", t, func() {
Convey("RecoverMoral success", func() {
_, err := d.RecoverMoral(context.TODO(), 121, 1, 1, time.Now().Format("2006-01-02"))
So(err, ShouldBeNil)
})
Convey("RecoverMoral failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
r, err := d.RecoverMoral(context.TODO(), 121, 1, 1, time.Now().Format("2006-01-02"))
So(err, ShouldNotBeNil)
So(r, ShouldEqual, 0)
})
})
}
func TestDao_SetSign(t *testing.T) {
Convey("SetSign", t, func() {
Convey("SetSign success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.SetSign(context.TODO(), 100, fmt.Sprintf("sign%s", time.Minute.String()))
So(err, ShouldBeNil)
})
Convey("SetSign failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.SetSign(context.TODO(), 100, fmt.Sprintf("sign%s", time.Minute.String()))
So(err, ShouldNotBeNil)
})
})
}
func TestDao_SetOfficial(t *testing.T) {
Convey("SetOfficial", t, func() {
Convey("SetOfficial success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.SetOfficial(context.TODO(), 100, 1, fmt.Sprintf("title%s", time.Minute.String()), "it's a test")
So(err, ShouldBeNil)
})
Convey("SetOfficial failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.SetOfficial(context.TODO(), 100, 1, fmt.Sprintf("title%s", time.Minute.String()), "it's a test")
So(err, ShouldNotBeNil)
})
})
}
func TestDao_SetFace(t *testing.T) {
Convey("SetFace", t, func() {
err := d.SetFace(context.TODO(), 100, fmt.Sprintf("face%s", time.Minute.String()))
So(err, ShouldBeNil)
})
Convey("SetFace", t, func() {
Convey("SetFace success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.SetFace(context.TODO(), 100, fmt.Sprintf("face%s", time.Minute.String()))
So(err, ShouldBeNil)
})
Convey("SetFace failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.SetFace(context.TODO(), 100, fmt.Sprintf("face%s", time.Minute.String()))
So(err, ShouldNotBeNil)
})
})
}
func TestDao_InitBase(t *testing.T) {
Convey("InitBase", t, func() {
Convey("InitBase success", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, nil
})
defer monkey.UnpatchAll()
err := d.InitBase(context.TODO(), 1)
So(err, ShouldBeNil)
})
Convey("InitBase failed", func() {
monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Exec", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (sql.Result, error) {
return nil, fmt.Errorf("cannot connect database error")
})
defer monkey.UnpatchAll()
err := d.InitBase(context.TODO(), 1)
So(err, ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,123 @@
package dao
import (
"context"
"fmt"
"go-common/app/job/main/member/model"
"go-common/library/cache/memcache"
"go-common/library/log"
"strconv"
errors "github.com/pkg/errors"
)
const (
_expPrefix = "exp_%d"
_expExpire = 86400
)
func expKey(mid int64) string {
return fmt.Sprintf(_expPrefix, mid)
}
func (d *Dao) mcBaseKey(mid int64) (key string) {
return fmt.Sprintf(model.CacheKeyBase, mid)
}
func (d *Dao) moralKey(mid int64) (key string) {
return fmt.Sprintf(model.CacheKeyMoral, mid)
}
// SetStartCache set data import start
func (d *Dao) SetStartCache(c context.Context, mid int64, key string) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if conn.Set(&memcache.Item{
Key: key,
Object: mid,
Flags: memcache.FlagJSON,
Expiration: 0,
}); err != nil {
log.Error("conn.Set(%s, %d) error(%v)", key, mid, err)
}
return
}
// DelMoralCache delete moral cache.
func (d *Dao) DelMoralCache(c context.Context, mid int64) (err error) {
key := d.moralKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("conn.Delete(%s) error(%v)", key, err)
}
return
}
// DelBaseInfoCache delete baseInfo cache.
func (d *Dao) DelBaseInfoCache(c context.Context, mid int64) (err error) {
key := d.mcBaseKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("conn.Delete(%s) error(%v)", key, err)
}
return
}
// SetExpCache set user exp cache.
func (d *Dao) SetExpCache(c context.Context, mid, exp int64) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: expKey(mid),
Value: []byte(strconv.FormatInt(exp, 10)),
Expiration: _expExpire,
}); err != nil {
log.Error("setexpcache mid %d err %v ", mid, err)
}
return
}
func realnameInfoKey(mid int64) string {
return fmt.Sprintf("realname_info_%d", mid)
}
func realnameApplyStatusKey(mid int64) string {
return fmt.Sprintf("realname_apply_%d", mid)
}
// DeleteRealnameCache delete all realname cache
func (d *Dao) DeleteRealnameCache(c context.Context, mid int64) (err error) {
var (
key1 = realnameInfoKey(mid)
key2 = realnameApplyStatusKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key1); err != nil {
if err != memcache.ErrNotFound {
err = errors.Wrapf(err, "conn.Delete(%s)", key1)
return
}
err = nil
}
if err = conn.Delete(key2); err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
err = errors.Wrapf(err, "conn.Delete(%s)", key2)
}
return
}
return
}

View File

@@ -0,0 +1,155 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoexpKey(t *testing.T) {
convey.Convey("expKey", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
p1 := expKey(mid)
convCtx.Convey("Then p1 should not be nil.", func(convCtx convey.C) {
convCtx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaomcBaseKey(t *testing.T) {
convey.Convey("mcBaseKey", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
key := d.mcBaseKey(mid)
convCtx.Convey("Then key should not be nil.", func(convCtx convey.C) {
convCtx.So(key, convey.ShouldNotBeNil)
})
})
})
}
func TestDaomoralKey(t *testing.T) {
convey.Convey("moralKey", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
key := d.moralKey(mid)
convCtx.Convey("Then key should not be nil.", func(convCtx convey.C) {
convCtx.So(key, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetStartCache(t *testing.T) {
convey.Convey("SetStartCache", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
key = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.SetStartCache(c, mid, key)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoDelMoralCache(t *testing.T) {
convey.Convey("DelMoralCache", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.DelMoralCache(c, mid)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoDelBaseInfoCache(t *testing.T) {
convey.Convey("DelBaseInfoCache", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.DelBaseInfoCache(c, mid)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetExpCache(t *testing.T) {
convey.Convey("SetExpCache", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
exp = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.SetExpCache(c, mid, exp)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaorealnameInfoKey(t *testing.T) {
convey.Convey("realnameInfoKey", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
p1 := realnameInfoKey(mid)
convCtx.Convey("Then p1 should not be nil.", func(convCtx convey.C) {
convCtx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaorealnameApplyStatusKey(t *testing.T) {
convey.Convey("realnameApplyStatusKey", t, func(convCtx convey.C) {
var (
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
p1 := realnameApplyStatusKey(mid)
convCtx.Convey("Then p1 should not be nil.", func(convCtx convey.C) {
convCtx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDeleteRealnameCache(t *testing.T) {
convey.Convey("DeleteRealnameCache", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.DeleteRealnameCache(c, mid)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,166 @@
package dao
import (
"context"
"net/http"
"net/url"
"time"
"go-common/app/job/main/member/conf"
"go-common/app/job/main/member/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"github.com/pkg/errors"
)
var (
_selRealnameAlipayApplyList = "SELECT id,mid,realname,card,img,status,reason,bizno,ctime,mtime FROM realname_alipay_apply WHERE id>? AND status=? AND mtime>=? AND mtime<=? ORDER BY id ASC LIMIT ?"
_selRealnameInfo = `SELECT id,mid,channel,realname,country,card_type,card,card_md5,status,reason,ctime,mtime FROM realname_info WHERE mid = ? LIMIT 1`
_upsertRealnameInfo = `INSERT INTO realname_info (mid,channel,realname,country,card_type,card,card_md5,status,reason) VALUES (?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE channel=?,realname=?,country=?,card_type=?,card=?,card_md5=?,status=?,reason=?`
_upsertRealnameApply = `INSERT INTO realname_apply (id,mid,realname,country,card_type,card_num,card_md5,hand_img,front_img,back_img,status,operator,operator_id,operator_time,remark,remark_status,ctime,mtime) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE realname=?,country=?,card_type=?,card_num=?,card_md5=?,hand_img=?,front_img=?,back_img=?,status=?,operator=?,operator_time=?,remark=?,remark_status=?,mtime=?`
_upsertRealnameApplyIMG = `INSERT INTO realname_apply_img (id,img_data,ctime,mtime) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE img_data=?,mtime=?`
)
// UpdateRealnameFromMSG is
func (d *Dao) UpdateRealnameFromMSG(c context.Context, ms *model.RealnameApplyMessage) (err error) {
var (
tx *xsql.Tx
cardEncrpted = ms.CardData()
cardMD5 = ms.CardMD5()
)
if tx, err = d.db.Begin(c); err != nil {
return
}
if _, err = tx.Exec(_upsertRealnameApply, ms.ID, ms.MID, ms.Realname, ms.Country(), ms.CardType(), cardEncrpted, cardMD5, ms.FrontIMG, ms.FrontIMG2, ms.BackIMG, ms.Status, ms.Operater, 0, ms.OperaterTime(), ms.Remark, ms.RemarkStatus, ms.ApplyTime(), ms.ApplyTime(), ms.Realname, ms.Country(), ms.CardType(), cardEncrpted, cardMD5, ms.FrontIMG, ms.FrontIMG2, ms.BackIMG, ms.Status, ms.Operater, ms.OperaterTime(), ms.Remark, ms.RemarkStatus, time.Now()); err != nil {
err = errors.WithStack(err)
tx.Rollback()
return
}
if _, err = tx.Exec(_upsertRealnameInfo, ms.MID, 0, ms.Realname, ms.Country(), ms.CardType(), cardEncrpted, cardMD5, ms.Status, ms.Remark, 0, ms.Realname, ms.Country(), ms.CardType(), cardEncrpted, cardMD5, ms.Status, ms.Remark); err != nil {
err = errors.WithStack(err)
tx.Rollback()
return
}
if err = tx.Commit(); err != nil {
return
}
return
}
// RealnameInfo is.
func (d *Dao) RealnameInfo(c context.Context, mid int64) (info *model.RealnameInfo, err error) {
row := d.db.QueryRow(c, _selRealnameInfo, mid)
info = &model.RealnameInfo{}
if err = row.Scan(&info.ID, &info.MID, &info.Channel, &info.Realname, &info.Country, &info.CardType, &info.Card, &info.CardMD5, &info.Status, &info.Reason, &info.CTime, &info.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
info = nil
return
}
err = errors.Wrapf(err, "dao RealnameInfo mid(%d)", mid)
return
}
return
}
// UpsertRealnameInfo is
func (d *Dao) UpsertRealnameInfo(c context.Context, ms *model.RealnameInfo) (err error) {
if _, err = d.db.Exec(c, _upsertRealnameInfo, ms.MID, 0, ms.Realname, ms.Country, ms.CardType, ms.Card, ms.CardMD5, ms.Status, ms.Reason, 0, ms.Realname, ms.Country, ms.CardType, ms.Card, ms.CardMD5, ms.Status, ms.Reason); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UpsertRealnameApplyImg is
func (d *Dao) UpsertRealnameApplyImg(c context.Context, ms *model.RealnameApplyImgMessage) (err error) {
if _, err = d.db.Exec(c, _upsertRealnameApplyIMG, ms.ID, ms.IMGData, ms.AddTime(), ms.AddTime(), ms.IMGData, time.Now()); err != nil {
err = errors.WithStack(err)
return
}
return
}
// RealnameAlipayApplyList is
func (d *Dao) RealnameAlipayApplyList(c context.Context, startID int64, status model.RealnameApplyStatus, fromTime, toTime time.Time, limit int) (maxID int64, list []*model.RealnameAlipayApply, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _selRealnameAlipayApplyList, startID, status, fromTime, toTime, limit); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
var (
apply = &model.RealnameAlipayApply{}
)
if err = rows.Scan(&apply.ID, &apply.MID, &apply.Realname, &apply.Card, &apply.IMG, &apply.Status, &apply.Reason, &apply.Bizno, &apply.CTime, &apply.MTime); err != nil {
err = errors.WithStack(err)
return
}
if maxID < apply.ID {
maxID = apply.ID
}
list = append(list, apply)
}
if err = rows.Err(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// AlipayQuery .
func (d *Dao) AlipayQuery(c context.Context, param url.Values) (pass bool, reason string, err error) {
var (
req *http.Request
)
url := conf.Conf.Biz.RealnameAlipayGateway + "?" + param.Encode()
if req, err = http.NewRequest("GET", url, nil); err != nil {
err = errors.Wrapf(err, "http.NewRequest(GET,%s)", url)
return
}
var resp struct {
Resp struct {
respAlipay
Passed string `json:"passed"`
FailedReason string `json:"failed_reason"`
IdentityInfo string `json:"identity_info"`
AttributeInfo string `json:"attribute_info"`
ChannelStatuses string `json:"channel_statuses"`
} `json:"zhima_customer_certification_query_response"`
Sign string `json:"sign"`
}
if err = d.client.Do(c, req, &resp); err != nil {
return
}
log.Info("Realname alipay query \n\tparam : %+v \n\tresp : %+v", param, resp)
if err = resp.Resp.Error(); err != nil {
return
}
if resp.Resp.Passed == "true" {
pass = true
} else {
pass = false
}
reason = resp.Resp.FailedReason
return
}
type respAlipay struct {
Code string `json:"code"`
Msg string `json:"msg"`
SubCode string `json:"sub_code"`
SubMsg string `json:"sub_msg"`
}
func (r *respAlipay) Error() error {
if r.Code == "10000" {
return nil
}
return errors.Errorf("alipay response failed , code : %s, msg : %s, sub_code : %s, sub_msg : %s", r.Code, r.Msg, r.SubCode, r.SubMsg)
}

View File

@@ -0,0 +1,111 @@
package dao
import (
"context"
"go-common/app/job/main/member/model"
"net/url"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoUpdateRealnameFromMSG(t *testing.T) {
convey.Convey("UpdateRealnameFromMSG", t, func(convCtx convey.C) {
var (
c = context.Background()
ms = &model.RealnameApplyMessage{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.UpdateRealnameFromMSG(c, ms)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoRealnameInfo(t *testing.T) {
convey.Convey("RealnameInfo", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
info, err := d.RealnameInfo(c, mid)
convCtx.Convey("Then err should be nil.info should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(info, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpsertRealnameInfo(t *testing.T) {
convey.Convey("UpsertRealnameInfo", t, func(convCtx convey.C) {
var (
c = context.Background()
ms = &model.RealnameInfo{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.UpsertRealnameInfo(c, ms)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUpsertRealnameApplyImg(t *testing.T) {
convey.Convey("UpsertRealnameApplyImg", t, func(convCtx convey.C) {
var (
c = context.Background()
ms = &model.RealnameApplyImgMessage{}
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
err := d.UpsertRealnameApplyImg(c, ms)
convCtx.Convey("Then err should be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoRealnameAlipayApplyList(t *testing.T) {
convey.Convey("RealnameAlipayApplyList", t, func(convCtx convey.C) {
var (
c = context.Background()
startID = int64(0)
status model.RealnameApplyStatus
fromTime = time.Now().AddDate(-1, 0, 0)
toTime = time.Now()
limit = int(10)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
status = 2
maxID, list, err := d.RealnameAlipayApplyList(c, startID, status, fromTime, toTime, limit)
convCtx.Convey("Then err should be nil.maxID,list should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(list, convey.ShouldNotBeNil)
convCtx.So(maxID, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoAlipayQuery(t *testing.T) {
convey.Convey("AlipayQuery", t, func(convCtx convey.C) {
var (
c = context.Background()
param url.Values
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
pass, _, err := d.AlipayQuery(c, param)
convCtx.Convey("Then err should be nil.pass,reason should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldNotBeNil)
//convCtx.So(reason, convey.ShouldBeNil)
convCtx.So(pass, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,66 @@
package dao
import (
"context"
"fmt"
"os"
"time"
"go-common/library/cache/redis"
)
const (
_expShard = 10000
_expAddedPrefix = "ea_%s_%d_%d"
_expire = 86400
)
func expAddedKey(tp string, mid int64, day int) string {
return fmt.Sprintf(_expAddedPrefix, tp, day, mid/_expShard)
}
func leader() (key string, value string) {
value, _ = os.Hostname()
key = fmt.Sprintf("member-job:leader:%d", time.Now().Day())
return key, value
}
// SetExpAdded set user exp added of tp,
func (d *Dao) SetExpAdded(c context.Context, mid int64, day int, tp string) (b bool, err error) {
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("SETBIT", expAddedKey(tp, mid, day), mid%_expShard, 1); err != nil {
return
}
if err = conn.Send("EXPIRE", expAddedKey(tp, mid, day), _expire); err != nil {
return
}
if err = conn.Flush(); err != nil {
return
}
if b, err = redis.Bool(conn.Receive()); err != nil {
return
}
conn.Receive()
return
}
// ExpAdded check if user had add exp.
func (d *Dao) ExpAdded(c context.Context, mid int64, day int, tp string) (b bool, err error) {
conn := d.redis.Get(c)
b, err = redis.Bool(conn.Do("GETBIT", expAddedKey(tp, mid, day), mid%_expShard))
conn.Close()
return
}
// LeaderEleciton eleciton job leader.
func (d *Dao) LeaderEleciton(c context.Context) (elected bool) {
key, value := leader()
conn := d.redis.Get(c)
elected, _ = redis.Bool(conn.Do("SETNX", key, value))
if elected {
conn.Do("EXPIRE", key, 600)
}
conn.Close()
return
}

View File

@@ -0,0 +1,86 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoexpAddedKey(t *testing.T) {
convey.Convey("expAddedKey", t, func(convCtx convey.C) {
var (
tp = ""
mid = int64(0)
day = int(0)
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
p1 := expAddedKey(tp, mid, day)
convCtx.Convey("Then p1 should not be nil.", func(convCtx convey.C) {
convCtx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoleader(t *testing.T) {
convey.Convey("leader", t, func(convCtx convey.C) {
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
key, value := leader()
convCtx.Convey("Then key,value should not be nil.", func(convCtx convey.C) {
convCtx.So(value, convey.ShouldNotBeNil)
convCtx.So(key, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoSetExpAdded(t *testing.T) {
convey.Convey("SetExpAdded", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
day = int(0)
tp = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
b, err := d.SetExpAdded(c, mid, day, tp)
convCtx.Convey("Then err should be nil.b should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(b, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoExpAdded(t *testing.T) {
convey.Convey("ExpAdded", t, func(convCtx convey.C) {
var (
c = context.Background()
mid = int64(0)
day = int(0)
tp = ""
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
b, err := d.ExpAdded(c, mid, day, tp)
convCtx.Convey("Then err should be nil.b should not be nil.", func(convCtx convey.C) {
convCtx.So(err, convey.ShouldBeNil)
convCtx.So(b, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoLeaderEleciton(t *testing.T) {
convey.Convey("LeaderEleciton", t, func(convCtx convey.C) {
var (
c = context.Background()
)
convCtx.Convey("When everything goes positive", func(convCtx convey.C) {
elected := d.LeaderEleciton(c)
convCtx.Convey("Then elected should not be nil.", func(convCtx convey.C) {
convCtx.So(elected, convey.ShouldNotBeNil)
})
})
})
}