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,92 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"databus_test.go",
"exp_test.go",
"hbase_test.go",
"member_log_test.go",
"memcache_test.go",
"message_test.go",
"moral_test.go",
"mysql_test.go",
"property_review_test.go",
"realname_test.go",
"redis_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/model:go_default_library",
"//library/cache/memcache: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 = [
"dao.go",
"databus.go",
"exp.go",
"hbase.go",
"member_log.go",
"memcache.go",
"message.go",
"moral.go",
"mysql.go",
"property_review.go",
"realname.go",
"redis.go",
],
importpath = "go-common/app/service/main/member/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/main/member/dao/block: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/net/metadata:go_default_library",
"//library/queue/databus:go_default_library",
"//library/queue/databus/report:go_default_library",
"//library/sync/pipeline/fanout:go_default_library",
"//library/time: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/service/main/member/dao/block:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,67 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"http.go",
"mc.go",
"mysql.go",
],
importpath = "go-common/app/service/main/member/dao/block",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/member/conf:go_default_library",
"//app/service/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/log:go_default_library",
"//library/net/http/blademaster: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"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
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/service/main/member/conf:go_default_library",
"//app/service/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/smartystreets/goconvey/convey:go_default_library",
],
)

View File

@@ -0,0 +1,97 @@
package block
import (
"context"
"math"
"math/rand"
"time"
"go-common/app/service/main/member/conf"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
xtime "go-common/library/time"
"github.com/pkg/errors"
)
type notifyFunc func(context.Context, int64, string) error
// Dao is
type Dao struct {
*cacheTTL
c *conf.Config
mc *memcache.Pool
db *sql.DB
client *bm.Client
NotifyPurgeCache notifyFunc
}
type cacheTTL struct {
UserTTL int32
UserMaxRate float64
UserT float64
}
// New is
func New(conf *conf.Config, db *sql.DB, mc *memcache.Pool, client *bm.Client, notifyFunc notifyFunc) *Dao {
d := &Dao{
c: conf,
mc: mc,
db: db,
client: client,
NotifyPurgeCache: notifyFunc,
}
d.cacheTTL = newCacheTTL(conf.BlockCacheTTL)
return d
}
// BeginTran is
func (d *Dao) BeginTran(c context.Context) (tx *sql.Tx, err error) {
if tx, err = d.db.Begin(c); err != nil {
err = errors.WithStack(err)
}
return
}
func durationToSeconds(expire xtime.Duration) int32 {
return int32(time.Duration(expire) / time.Second)
}
func newCacheTTL(c *conf.BlockCacheTTL) *cacheTTL {
return &cacheTTL{
UserTTL: durationToSeconds(c.UserTTL),
UserMaxRate: c.UserMaxRate,
UserT: c.UserT,
}
}
func (ttl *cacheTTL) mcUserExpire(key string) (sec int32) {
if ttl.UserT == 0.0 {
return ttl.UserTTL
}
// rate = -log(1-x)/t
rate := -math.Log(1-rand.Float64()) / ttl.UserT
if rate <= 1.0 {
return ttl.UserTTL
}
if rate > ttl.UserMaxRate {
rate = ttl.UserMaxRate
}
sec = int32(rate * float64(ttl.UserTTL))
if rate >= 5.0 {
log.Info("mc hotkey : %s, expire rate : %.2f , time : %d", key, rate, sec)
}
return
}
// Close close the resource.
func (d *Dao) Close() {
if d.mc != nil {
d.mc.Close()
}
if d.db != nil {
d.db.Close()
}
}

View File

@@ -0,0 +1,43 @@
package block
import (
"flag"
"os"
"testing"
"go-common/app/service/main/member/conf"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.member-service")
flag.Set("conf_token", "ef70dbff7ee115ce242c67e633b21c29")
flag.Set("tree_id", "2137")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
c := conf.Conf
d = New(c,
sql.NewMySQL(c.BlockMySQL),
memcache.NewPool(c.BlockMemcache),
bm.NewClient(c.HTTPClient),
nil,
)
m.Run()
os.Exit(0)
}

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.client.Post(c, d.c.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,41 @@
package block
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSendSysMsg(t *testing.T) {
convey.Convey("SendSysMsg", t, func(ctx convey.C) {
var (
c = context.Background()
mids = []int64{1, 2, 3}
content = "账号违规处理通知-test-content"
remoteIP = "127.0.0.1"
code = "2_3_2"
title = "账号违规处理通知-test"
)
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.SendSysMsg(c, code, mids, title, content, remoteIP)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaomidsToParam(t *testing.T) {
convey.Convey("midsToParam", t, func(ctx convey.C) {
var (
mids = []int64{46333, 35858}
)
ctx.Convey("When everything right", func(ctx convey.C) {
str := midsToParam(mids)
ctx.Convey("Then str should equal mids[0],mids[1],....", func(ctx convey.C) {
ctx.So(str, convey.ShouldEqual, "46333,35858")
})
})
})
}

View File

@@ -0,0 +1,171 @@
package block
import (
"context"
"fmt"
model "go-common/app/service/main/member/model/block"
"go-common/library/cache/memcache"
"go-common/library/log"
"github.com/pkg/errors"
)
func userKey(mid int64) (key string) {
key = fmt.Sprintf("u_%d", mid)
return
}
func userDetailKey(mid int64) (key string) {
key = fmt.Sprintf("ud_%d", mid)
return
}
// UsersCache get block info by mids
func (d *Dao) UsersCache(c context.Context, mids []int64) (res map[int64]*model.MCBlockInfo, err error) {
res = make(map[int64]*model.MCBlockInfo, len(mids))
if len(mids) == 0 {
return
}
var (
keys = make([]string, 0, len(mids))
keyMap = make(map[string]int64, len(mids))
key string
conn = d.mc.Get(c)
rs map[string]*memcache.Item
)
defer conn.Close()
for _, mid := range mids {
key = userKey(mid)
if _, ok := keyMap[key]; !ok {
keyMap[key] = mid
keys = append(keys, key)
}
}
if rs, err = conn.GetMulti(keys); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "keys : %+v", keys)
return
}
for k, r := range rs {
info := &model.MCBlockInfo{}
if err = conn.Scan(r, info); err != nil {
err = errors.Wrapf(err, "key : %s", k)
log.Error("%+v", err)
err = nil
continue
}
res[keyMap[k]] = info
}
return
}
// SetUserCache set user block info to cache
func (d *Dao) SetUserCache(c context.Context, mid int64, status model.BlockStatus, startTime, endTime int64) (err error) {
var (
key = userKey(mid)
conn = d.mc.Get(c)
info = &model.MCBlockInfo{
BlockStatus: status,
StartTime: startTime,
EndTime: endTime,
}
)
log.Info("Set User Cache key (%s) obj (%+v)", key, info)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: key,
Object: info,
Expiration: d.mcUserExpire(key),
Flags: memcache.FlagJSON,
}); err != nil {
err = (err)
return
}
return
}
// DeleteUserCache delete user cache
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 = (err)
return
}
return
}
// SetUserDetailCache set user detail to cache
func (d *Dao) SetUserDetailCache(c context.Context, mid int64, detail *model.MCUserDetail) (err error) {
var (
key = userDetailKey(mid)
conn = d.mc.Get(c)
)
log.Info("Set User Detail Cache key (%s) obj (%+v)", key, detail)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: key,
Object: detail,
Expiration: d.mcUserExpire(key),
Flags: memcache.FlagJSON,
}); err != nil {
return
}
return
}
// DeleteUserDetailCache delete user detail cache
func (d *Dao) DeleteUserDetailCache(c context.Context, mid int64) (err error) {
var (
key = userDetailKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
err = conn.Delete(key)
return
}
// UserDetailsCache .
func (d *Dao) UserDetailsCache(c context.Context, mids []int64) (res map[int64]*model.MCUserDetail, err error) {
res = make(map[int64]*model.MCUserDetail)
if len(mids) == 0 {
return
}
var (
keys = make([]string, 0, len(mids))
keyMap = make(map[string]int64, len(mids))
key string
conn = d.mc.Get(c)
rs map[string]*memcache.Item
)
defer conn.Close()
for _, mid := range mids {
key = userDetailKey(mid)
if _, ok := keyMap[key]; !ok {
keyMap[key] = mid
keys = append(keys, key)
}
}
if rs, err = conn.GetMulti(keys); err != nil {
err = errors.Wrapf(err, "keys : %+v", keys)
return
}
for k, r := range rs {
detail := &model.MCUserDetail{}
if err = conn.Scan(r, detail); err != nil {
err = errors.Wrapf(err, "key : %+v", k)
log.Error("%+v", err)
err = nil
continue
}
res[keyMap[k]] = detail
}
return
}

View File

@@ -0,0 +1,99 @@
package block
import (
"context"
"testing"
"time"
"go-common/app/service/main/member/conf"
model "go-common/app/service/main/member/model/block"
"github.com/smartystreets/goconvey/convey"
)
func TestDaouserKey(t *testing.T) {
convey.Convey("userKey", t, func(ctx convey.C) {
var (
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
key := userKey(mid)
ctx.Convey("Then key should equal u_mid.", func(ctx convey.C) {
ctx.So(key, convey.ShouldEqual, "u_46333")
})
})
})
}
func TestDaoSetUserCache(t *testing.T) {
convey.Convey("SetUserCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
status = model.BlockStatusForever
startTime = time.Now().Unix()
endTime = time.Now().Add(time.Minute).Unix()
)
ctx.Convey("When SetUserCache", func(ctx convey.C) {
err := d.SetUserCache(c, mid, status, startTime, endTime)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.Convey("When get UsersCache", func(ctx convey.C) {
res, err := d.UsersCache(c, []int64{mid})
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
ctx.Convey("When delete UsersCache", func(ctx convey.C) {
err := d.DeleteUserCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
})
})
}
func TestDaomcUserExpire(t *testing.T) {
convey.Convey("mcUserExpire", t, func(ctx convey.C) {
ctx.Convey("When everything right", func(ctx convey.C) {
sec := d.mcUserExpire("ut_key")
ctx.Convey("Then sec should >=mcUserExpireBase and <=mcUserExpireBase*conf.Conf.Memcache.Expire.UserMaxRate .", func(ctx convey.C) {
ctx.So(d.UserTTL, convey.ShouldBeGreaterThan, 0)
ctx.So(conf.Conf.BlockCacheTTL.UserMaxRate, convey.ShouldBeGreaterThan, 0)
ctx.So(sec, convey.ShouldBeGreaterThanOrEqualTo, d.UserTTL)
ctx.So(sec, convey.ShouldBeLessThanOrEqualTo, int32(conf.Conf.BlockCacheTTL.UserMaxRate*float64(d.UserTTL)))
})
})
})
}
func TestDaoSetUserDetailCache(t *testing.T) {
convey.Convey("SetUserDetailCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
)
ctx.Convey("When SetUserDetailCache", func(ctx convey.C) {
err := d.SetUserDetailCache(c, mid, &model.MCUserDetail{BlockCount: 12})
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.Convey("When get UserDetailCache", func(ctx convey.C) {
res, err := d.UserDetailsCache(c, []int64{mid})
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
ctx.Convey("When delete UsersDetailCache", func(ctx convey.C) {
err := d.DeleteUserDetailCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
})
})
}

View File

@@ -0,0 +1,184 @@
package block
import (
"context"
"fmt"
model "go-common/app/service/main/member/model/block"
xsql "go-common/library/database/sql"
"go-common/library/xstr"
"github.com/pkg/errors"
)
const (
_user = `SELECT id,mid,status,ctime,mtime FROM block_user WHERE mid=? LIMIT 1`
_upsertUser = `INSERT INTO block_user (mid,status) VALUES (?,?) ON DUPLICATE KEY UPDATE status=?`
_userStatusList = `SELECT id,mid FROM block_user WHERE status=? AND id >= 0 LIMIT ?`
_userStatusListWithMIDs = `SELECT mid FROM block_user WHERE status=? AND mid IN (%s)`
_userLastHistory = `SELECT id,mid,action,start_time,duration FROM block_history_%d WHERE mid=? ORDER BY id DESC LIMIT 1`
_addAddBlockCount = `INSERT INTO block_user_detail (mid,block_count) VALUES (?,1) ON DUPLICATE KEY UPDATE block_count=block_count+1`
_insertHistory = `INSERT INTO block_history_%d (mid,admin_id,admin_name,source,area,reason,comment,action,start_time,duration,notify) VALUES (?,?,?,?,?,?,?,?,?,?,?)`
_userDetails = `SELECT id,mid,block_count,ctime,mtime FROM block_user_detail WHERE mid IN (%s)`
)
func historyIdx(mid int64) int64 {
return mid % 10
}
// User get block user from db
func (d *Dao) User(c context.Context, mid int64) (user *model.DBUser, err error) {
user = &model.DBUser{}
row := d.db.QueryRow(c, _user, mid)
if err = row.Scan(&user.ID, &user.MID, &user.Status, &user.CTime, &user.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
user = nil
return
}
err = errors.WithStack(err)
return
}
return
}
// UserLastHistory get lastest block history
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.Action, &his.StartTime, &his.Duration); err != nil {
if err == xsql.ErrNoRows {
err = nil
his = nil
return
}
err = errors.WithStack(err)
return
}
return
}
// UserStatusList get user status list
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
}
// UserStatusMapWithMIDs get user block status map by mids
func (d *Dao) UserStatusMapWithMIDs(c context.Context, status model.BlockStatus, mids []int64) (midMap map[int64]struct{}, err error) {
var (
rows *xsql.Rows
)
url := fmt.Sprintf(_userStatusListWithMIDs, xstr.JoinInts(mids))
if rows, err = d.db.Query(c, url, status); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
midMap = make(map[int64]struct{})
for rows.Next() {
var (
mid int64
)
if err = rows.Scan(&mid); err != nil {
err = errors.WithStack(err)
return
}
midMap[mid] = struct{}{}
}
if err = rows.Err(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// TxUpdateUser is
func (d *Dao) TxUpdateUser(c context.Context, tx *xsql.Tx, mid int64, status model.BlockStatus) (err error) {
if _, err = tx.Exec(_upsertUser, mid, status, status); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UpdateAddBlockCount is
func (d *Dao) UpdateAddBlockCount(c context.Context, mid int64) (err error) {
if _, err = d.db.Exec(c, _addAddBlockCount, mid); 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
}
// UserDetails .
func (d *Dao) UserDetails(c context.Context, mids []int64) (midMap map[int64]*model.DBUserDetail, err error) {
var (
rows *xsql.Rows
)
sql := fmt.Sprintf(_userDetails, xstr.JoinInts(mids))
if rows, err = d.db.Query(c, sql); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
midMap = make(map[int64]*model.DBUserDetail, len(mids))
for rows.Next() {
detail := &model.DBUserDetail{}
if err = rows.Scan(&detail.ID, &detail.MID, &detail.BlockCount, &detail.CTime, &detail.MTime); err != nil {
err = errors.WithStack(err)
return
}
midMap[detail.MID] = detail
}
if err = rows.Err(); err != nil {
err = errors.WithStack(err)
return
}
return
}

View File

@@ -0,0 +1,150 @@
package block
import (
"context"
"testing"
"time"
model "go-common/app/service/main/member/model/block"
"github.com/smartystreets/goconvey/convey"
)
func TestDaohistoryIdx(t *testing.T) {
convey.Convey("historyIdx", t, func(ctx convey.C) {
var (
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
shard := historyIdx(mid)
ctx.Convey("Then shard should equal mid % 10.", func(ctx convey.C) {
ctx.So(shard, convey.ShouldEqual, 3)
})
})
})
}
func TestDaoUser(t *testing.T) {
convey.Convey("User", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
user, err := d.User(c, mid)
ctx.Convey("Then err should be nil.user should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(user, convey.ShouldNotBeNil)
ctx.So(user.MID, convey.ShouldEqual, mid)
})
})
})
}
func TestDaoTxInsertHistory(t *testing.T) {
convey.Convey("TxInsertHistory", t, func(ctx convey.C) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
his = &model.DBHistory{
MID: 46333,
AdminID: 2333,
AdminName: "ut",
Source: model.BlockSourceBlackHouse,
Area: model.BlockAreaAlbum,
Reason: "ut reason",
Comment: "ut comment",
Action: model.BlockActionLimit,
StartTime: time.Now(),
Duration: 60,
Notify: false,
CTime: time.Now(),
MTime: time.Now(),
}
)
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.TxInsertHistory(c, tx, his)
ctx.So(err, convey.ShouldBeNil)
err = tx.Commit()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.Convey("When get UserLastHistory", func(ctx convey.C) {
his2, err := d.UserLastHistory(c, his.MID)
ctx.Convey("Then err should be nil.his2 should resemble his.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(his2.MID, convey.ShouldEqual, his.MID)
ctx.So(his2.Action, convey.ShouldEqual, his.Action)
ctx.So(his2.StartTime.Unix(), convey.ShouldEqual, his.StartTime.Unix())
ctx.So(his2.Duration, convey.ShouldEqual, his.Duration)
})
})
})
})
})
}
func TestDaoTxUpdateUser(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(46333)
status = model.BlockStatusFalse
)
convey.Convey("TxUpdateUser", t, func(ctx convey.C) {
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.TxUpdateUser(c, tx, mid, status)
ctx.So(err, convey.ShouldBeNil)
err = tx.Commit()
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoUserStatusMapWithMIDs(t *testing.T) {
convey.Convey("UserStatusMapWithMIDs", t, func(ctx convey.C) {
var (
c = context.Background()
status = model.BlockStatusFalse
mids = []int64{46333, 2, 35858}
)
ctx.Convey("When everything right", func(ctx convey.C) {
midMap, err := d.UserStatusMapWithMIDs(c, status, mids)
ctx.Convey("Then err should be nil.midMap should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(midMap, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpdateAddBlockCount(t *testing.T) {
convey.Convey("UpdateAddBlockCount", t, func(ctx convey.C) {
var (
c = context.TODO()
mid = int64(46333)
)
ctx.Convey("When everything right", func(ctx convey.C) {
err := d.UpdateAddBlockCount(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestUserDetails(t *testing.T) {
convey.Convey("get user details", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(46333)
)
ctx.Convey("When get user details from db", func(ctx convey.C) {
_, err := d.UserDetails(c, []int64{mid})
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,114 @@
package dao
import (
"context"
"time"
"go-common/app/service/main/member/conf"
"go-common/app/service/main/member/dao/block"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/queue/databus"
"go-common/library/sync/pipeline/fanout"
xtime "go-common/library/time"
)
const (
_searchLogURI = "/x/admin/search/log"
_deleteLogURI = "/x/admin/search/log/delete"
)
// Dao struct info of Dao.
type Dao struct {
*cacheTTL
accdb *sql.DB
db *sql.DB
mc *memcache.Pool
c *conf.Config
client *bm.Client
redis *redis.Pool
cache *fanout.Fanout
// databus
logDatabus *databus.Databus
accNotify *databus.Databus
block *block.Dao
}
type cacheTTL struct {
baseTTL int32
moralTTL int32
captureTimesTTL int32
captureCodeTTL int32
captureErrTimesTTL int32
applyInfoTTL int32
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
accdb: sql.NewMySQL(c.AccMysql),
db: sql.NewMySQL(c.Mysql),
mc: memcache.NewPool(c.Memcache),
client: bm.NewClient(c.HTTPClient),
redis: redis.NewPool(c.Redis),
cache: fanout.New("memberServiceCache", fanout.Worker(1), fanout.Buffer(10240)),
logDatabus: databus.New(c.Databus),
accNotify: databus.New(c.AccountNotify),
}
d.block = block.New(
c,
sql.NewMySQL(c.BlockMySQL),
memcache.NewPool(c.BlockMemcache),
d.client,
d.NotifyPurgeCache,
)
d.cacheTTL = newCacheTTL(c.CacheTTL)
return
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) error {
if err := d.db.Ping(c); err != nil {
log.Error("Failed to ping database: %+v", err)
return err
}
return d.pingMC(c)
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
if d.mc != nil {
d.mc.Close()
}
if d.db != nil {
d.db.Close()
}
if d.block != nil {
d.block.Close()
}
}
func durationToSeconds(expire xtime.Duration) int32 {
return int32(time.Duration(expire) / time.Second)
}
func newCacheTTL(c *conf.CacheTTL) *cacheTTL {
return &cacheTTL{
baseTTL: durationToSeconds(c.BaseTTL),
moralTTL: durationToSeconds(c.MoralTTL),
captureTimesTTL: durationToSeconds(c.CaptureErrTimesTTL),
captureCodeTTL: durationToSeconds(c.CaptureCodeTTL),
captureErrTimesTTL: durationToSeconds(c.CaptureErrTimesTTL),
applyInfoTTL: durationToSeconds(c.ApplyInfoTTL),
}
}
// BlockImpl is
func (d *Dao) BlockImpl() *block.Dao {
return d.block
}

View File

@@ -0,0 +1,40 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/service/main/member/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.member-service")
flag.Set("conf_token", "ef70dbff7ee115ce242c67e633b21c29")
flag.Set("tree_id", "2137")
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-service-example.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.client.SetTransport(gock.DefaultTransport)
m.Run()
os.Exit(0)
}

View File

@@ -0,0 +1,42 @@
package dao
import (
"context"
"fmt"
"strconv"
"time"
"go-common/app/service/main/member/model"
)
func notifyKey(mid int64) string {
return fmt.Sprintf("MemberService-AccountNotify-T%d", mid)
}
// AddExplog add exp log with databus
func (d *Dao) AddExplog(c context.Context, mid, exp, toExp int64, oper, reason, ip string) (err error) {
log := &model.UserLog{
Mid: mid,
IP: ip,
TS: time.Now().Unix(),
LogID: model.UUID4(),
Content: map[string]string{
"from_exp": strconv.FormatInt(exp, 10),
"to_exp": strconv.FormatInt(toExp, 10),
"operater": oper,
"reason": reason,
},
}
err = d.logDatabus.Send(c, strconv.FormatInt(mid, 10), log)
return
}
// 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,52 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaonotifyKey(t *testing.T) {
var (
mid = int64(4780461)
)
convey.Convey("notifyKey", t, func(ctx convey.C) {
p1 := notifyKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoAddExplog(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
exp = int64(0)
toExp = int64(0)
oper = ""
reason = ""
ip = ""
)
convey.Convey("AddExplog", t, func(ctx convey.C) {
err := d.AddExplog(c, mid, exp, toExp, oper, reason, ip)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoNotifyPurgeCache(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
action = ""
)
convey.Convey("NotifyPurgeCache", t, func(ctx convey.C) {
p1 := d.NotifyPurgeCache(c, mid, action)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,113 @@
package dao
import (
"context"
"encoding/json"
"net/url"
"strconv"
"time"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_expLogID = 11
)
// Exp get user exp from cache,if miss get from db.
func (d *Dao) Exp(c context.Context, mid int64) (exp int64, err error) {
if exp, err = d.expCache(c, mid); err == nil {
return
}
if err != nil && err != memcache.ErrNotFound {
return
}
if exp, err = d.ExpDB(c, mid); err != nil {
return
}
d.SetExpCache(c, mid, exp)
return
}
// Exps get exps by mids.
func (d *Dao) Exps(c context.Context, mids []int64) (exps map[int64]int64, err error) {
exps, miss, err := d.expsCache(c, mids)
if err != nil {
return
}
if len(miss) == 0 {
return
}
for _, mid := range miss {
mid := mid
exp, err := d.ExpDB(c, mid)
if err != nil {
log.Error("exp mid %d err %v", mid, err)
err = nil
continue
}
exps[mid] = exp
d.cache.Do(c, func(ctx context.Context) {
d.SetExpCache(ctx, mid, exp)
})
}
return
}
// ExpLog is
func (d *Dao) ExpLog(ctx context.Context, mid int64, ip string) ([]*model.UserLog, error) {
t := time.Now().Add(-time.Hour * 24 * 7)
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(_expLogID, 10))
params.Set("pn", "1")
params.Set("ps", "1000")
params.Set("ctime_from", t.Format("2006-01-02 00:00:00"))
params.Set("sort", "desc")
params.Set("order", "ctime")
res := &model.SearchResult{}
if err := d.client.Get(ctx, d.c.Host.Search+_searchLogURI, ip, params, res); err != nil {
return nil, err
}
if res.Code != 0 {
return nil, ecode.Int(res.Code)
}
logs := asExpLog(res)
return logs, nil
}
func asExpLog(res *model.SearchResult) []*model.UserLog {
logs := make([]*model.UserLog, 0, len(res.Data.Result))
for _, r := range res.Data.Result {
ts, err := time.ParseInLocation("2006-01-02 15:04:05", r.Ctime, time.Local)
if err != nil {
log.Warn("Failed to parse log ctime: ctime: %s: %+v", r.Ctime, err)
continue
}
content := map[string]string{
"from_exp": "",
"operater": "",
"reason": "",
"to_exp": "",
"log_id": "",
}
if err := json.Unmarshal([]byte(r.ExtraData), &content); err != nil {
log.Warn("Failed to parse extra data in exp log: mid: %d, extra_data: %s: %+v", r.Mid, r.ExtraData, err)
continue
}
l := &model.UserLog{
Mid: r.Mid,
IP: r.IP,
TS: ts.Unix(),
LogID: content["log_id"],
Content: content,
}
logs = append(logs, l)
}
return logs
}

View File

@@ -0,0 +1,78 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestDaoExp(t *testing.T) {
var (
c = context.TODO()
mid = int64(4780461)
)
convey.Convey("Exp", t, func(ctx convey.C) {
exp, err := d.Exp(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("exp should not be nil", func(ctx convey.C) {
t.Logf("exp:%+v", exp)
ctx.So(exp, convey.ShouldNotBeNil)
})
})
}
func TestDaoExps(t *testing.T) {
var (
c = context.TODO()
mids = []int64{4780461, 2}
)
convey.Convey("Exps", t, func(ctx convey.C) {
exps, err := d.Exps(c, mids)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("exps should not be nil", func(ctx convey.C) {
ctx.So(exps, convey.ShouldNotBeNil)
})
})
}
func TestDaoExpLog(t *testing.T) {
var (
c = context.TODO()
mid = int64(0)
ip = ""
searchLogUrl = "http://uat-bili-search.bilibili.co/x/admin/search/log"
)
convey.Convey("ExpLog", t, func(ctx convey.C) {
d.client.SetTransport(gock.DefaultTransport)
defer gock.OffAll()
httpMock("GET", searchLogUrl).Reply(200).JSON(`{"code":0,"message":"0"}`)
l, err := d.ExpLog(c, mid, ip)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(l, convey.ShouldNotBeNil)
})
})
}
func TestDaoasExpLog(t *testing.T) {
var (
res = &model.SearchResult{}
)
convey.Convey("asExpLog", t, func(ctx convey.C) {
p1 := asExpLog(res)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
t.Logf("log:%+v", p1)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,49 @@
package dao
var (
// tableMoralLog = "ugc:MoralLog"
// familyDetail = "detail"
// familyDetailB = []byte(familyDetail)
// columnIP = "ip"
// columnTs = "ts"
// columnMid = "mid"
// columnLogID = "log_id"
// _logDuration = int64(7 * 24 * 3600)
)
// func rowKey(mid, ts int64) string {
// return fmt.Sprintf("%d%d_%d", mid%10, mid, math.MaxInt64-ts)
// }
// func moralRowKey(mid, ts int64, tid uint64) string {
// return fmt.Sprintf("%d%d_%d_%d", mid%10, mid, math.MaxInt64-ts, tid)
// }
// AddMoralLog add moral modify log.
// func (d *Dao) AddMoralLog(c context.Context, mid, ts int64, content map[string][]byte) (err error) {
// var (
// mutate *hrpc.Mutate
// key = moralRowKey(mid, ts, genID())
// 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, tableMoralLog, key, values); err != nil {
// log.Error("hrpc.NewPutStr(%s, %s, %v) error(%v)", tableMoralLog, key, values, err)
// return
// }
// if _, err = d.hbase.Put(c, mutate); err != nil {
// log.Error("hbase.Put mid %d,error(%v) value(%v)", mid, err, values)
// return
// }
// log.Info("hbase.Put moral log success mid: %d,value(%v)", mid, values)
// return
// }
// func genID() uint64 {
// i := [16]byte(uuid.NewV1())
// return farm.Hash64(i[:]) % math.MaxInt64
// }

View File

@@ -0,0 +1,47 @@
package dao
//import (
// "context"
// "testing"
//
// "github.com/smartystreets/goconvey/convey"
//)
//
//func TestDaomoralRowKey(t *testing.T) {
// var (
// mid = int64(0)
// ts = int64(0)
// tid uint64
// )
// convey.Convey("moralRowKey", t, func(ctx convey.C) {
// p1 := moralRowKey(mid, ts, tid)
// ctx.Convey("p1 should not be nil", func(ctx convey.C) {
// ctx.So(p1, convey.ShouldNotBeNil)
// })
// })
//}
//
//func TestDaoAddMoralLog(t *testing.T) {
// var (
// c = context.Background()
// mid = int64(0)
// ts = int64(0)
// s = []byte("abcd")
// content = map[string][]byte{"ts": s}
// )
// convey.Convey("AddMoralLog", t, func(ctx convey.C) {
// err := d.AddMoralLog(c, mid, ts, content)
// ctx.Convey("Error should be nil", func(ctx convey.C) {
// ctx.So(err, convey.ShouldBeNil)
// })
// })
//}
//
//func TestDaogenID(t *testing.T) {
// convey.Convey("genID", t, func(ctx convey.C) {
// p1 := genID()
// ctx.Convey("p1 should not be nil", func(ctx convey.C) {
// ctx.So(p1, convey.ShouldNotBeNil)
// })
// })
//}

View File

@@ -0,0 +1,50 @@
package dao
import (
"context"
"go-common/app/service/main/member/model"
"go-common/library/log"
"go-common/library/queue/databus/report"
"go-common/library/time"
)
// consts
const (
MoralLogID = 12
)
// AddMoralLogReport is
func (d *Dao) AddMoralLogReport(ctx context.Context, ul *model.UserLog) {
d.addLogReport(ctx, MoralLogID, "log_moral_change", ul)
}
// addLogReport is
func (d *Dao) addLogReport(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,38 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAddMoralLogReport(t *testing.T) {
var (
c = context.Background()
ul = &model.UserLog{
Mid: 4780461,
}
)
convey.Convey("AddMoralLogReport", t, func(ctx convey.C) {
d.AddMoralLogReport(c, ul)
t.Logf("log:%+v", ul)
})
}
func TestDaoaddLogReport(t *testing.T) {
var (
c = context.Background()
business = int(0)
action = ""
ul = &model.UserLog{
Mid: 4780461,
}
)
convey.Convey("addLogReport", t, func(ctx convey.C) {
d.addLogReport(c, business, action, ul)
t.Logf("log:%+v", ul)
})
}

View File

@@ -0,0 +1,498 @@
package dao
import (
"context"
"fmt"
"strconv"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"go-common/library/log"
"github.com/pkg/errors"
)
const (
_expPrefix = "exp_%d"
_moralPrefix = "moral_%d"
_expExpire = 86400
)
func expKey(mid int64) string {
return fmt.Sprintf(_expPrefix, mid)
}
func moralKey(mid int64) string {
return fmt.Sprintf(_moralPrefix, mid)
}
// pingMC ping memcache.
func (d *Dao) pingMC(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: "ping",
Value: []byte{1},
Expiration: 86400,
}); err != nil {
log.Error("conn.Set(ping, 1) error(%v)", err)
}
return
}
// -------- base --------- //
// BaseInfoCache get base info from mc.
func (d *Dao) BaseInfoCache(c context.Context, mid int64) (info *model.BaseInfo, err error) {
key := fmt.Sprintf(model.CacheKeyBase, mid)
conn := d.mc.Get(c)
defer conn.Close()
item, err := conn.Get(key)
if err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("conn.Get(%s) error(%v)", key, err)
return
}
info = &model.BaseInfo{}
if err = conn.Scan(item, info); err != nil {
log.Error("conn.Scan(%s) error(%v)", string(item.Value), err)
}
return
}
// BatchBaseInfoCache get batch base info from mc.
func (d *Dao) BatchBaseInfoCache(c context.Context, mids []int64) (cached map[int64]*model.BaseInfo, missed []int64, err error) {
cached = make(map[int64]*model.BaseInfo, len(mids))
if len(mids) == 0 {
return
}
keys := make([]string, 0, len(mids))
midmap := make(map[string]int64, len(mids))
for _, mid := range mids {
k := fmt.Sprintf(model.CacheKeyBase, mid)
keys = append(keys, k)
midmap[k] = mid
}
conn := d.mc.Get(c)
defer conn.Close()
bases, err := conn.GetMulti(keys)
if err != nil {
log.Error("conn.Gets(%v) error(%v)", keys, err)
return
}
for _, base := range bases {
b := &model.BaseInfo{}
if err = conn.Scan(base, b); err != nil {
log.Error("json.Unmarshal(%v) error(%v)", base.Value, err)
return
}
cached[midmap[base.Key]] = b
delete(midmap, base.Key)
}
missed = make([]int64, 0, len(midmap))
for _, bid := range midmap {
missed = append(missed, bid)
}
return
}
// SetBatchBaseInfoCache set batch base info to mc.
func (d *Dao) SetBatchBaseInfoCache(c context.Context, bs []*model.BaseInfo) (err error) {
for _, info := range bs {
d.SetBaseInfoCache(c, info.Mid, info)
}
return
}
// SetBaseInfoCache set base info to mc
func (d *Dao) SetBaseInfoCache(c context.Context, mid int64, info *model.BaseInfo) (err error) {
key := fmt.Sprintf(model.CacheKeyBase, mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{
Key: key,
Object: info,
Flags: memcache.FlagProtobuf,
Expiration: d.baseTTL,
}); err != nil {
log.Error("conn.Set(%s, %v) error(%v)", key, info, err)
}
return
}
// DelBaseInfoCache delete baseInfo cache.
func (d *Dao) DelBaseInfoCache(c context.Context, mid int64) (err error) {
key := fmt.Sprintf(model.CacheKeyBase, 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
}
// -------- base --------- //
// ----- exp ------ //
// Exp get user exp from cache,if miss get from db.
func (d *Dao) expCache(c context.Context, mid int64) (exp int64, err error) {
key := expKey(mid)
conn := d.mc.Get(c)
res, err := conn.Get(key)
defer conn.Close()
if err != nil {
return
}
exp, _ = strconv.ParseInt(string(res.Value), 10, 64)
return
}
// ExpsCache get users exp cache.
func (d *Dao) expsCache(c context.Context, mids []int64) (exps map[int64]int64, miss []int64, err error) {
var keys []string
for _, mid := range mids {
keys = append(keys, expKey(mid))
}
conn := d.mc.Get(c)
defer conn.Close()
its, err := conn.GetMulti(keys)
if err != nil {
return
}
exps = make(map[int64]int64)
for _, mid := range mids {
if it, ok := its[expKey(mid)]; ok {
exp, _ := strconv.ParseInt(string(it.Value), 10, 64)
exps[mid] = exp
} else {
miss = append(miss, mid)
}
}
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 {
err = errors.WithStack(err)
return
}
return
}
// moralCache get moral from cache.
func (d *Dao) moralCache(c context.Context, mid int64) (moral *model.Moral, err error) {
key := moralKey(mid)
conn := d.mc.Get(c)
item, err := conn.Get(key)
defer conn.Close()
if err != nil {
return
}
moral = &model.Moral{}
if err = conn.Scan(item, moral); err != nil {
log.Error("conn.Scan(%s) error(%v)", string(item.Value), err)
}
return
}
// SetMoralCache set moral to mc
func (d *Dao) SetMoralCache(c context.Context, mid int64, moral *model.Moral) (err error) {
key := moralKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if conn.Set(&memcache.Item{
Key: key,
Object: moral,
Flags: memcache.FlagProtobuf,
Expiration: d.moralTTL,
}); err != nil {
log.Error("conn.Set(%s, %v) error(%v)", key, moral, err)
}
return
}
// DelMoralCache delete moral cache.
func (d *Dao) DelMoralCache(c context.Context, mid int64) (err error) {
key := 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("DelMoralCache conn.Delete(%s) error(%v)", key, err)
}
return
}
// ------realname------
func realnameInfoKey(mid int64) string {
return fmt.Sprintf("realname_info_%d", mid)
}
func realnameCaptureTimesKey(mid int64) string {
return fmt.Sprintf("realname_cap_times_%d", mid)
}
func realnameCaptureCodeKey(mid int64) string {
return fmt.Sprintf("realname_cap_code_%d", mid)
}
func realnameCaptureErrTimesKey(mid int64) string {
return fmt.Sprintf("realname_cap_err_times%d", mid)
}
// RealnameCaptureTimesCache is
func (d *Dao) RealnameCaptureTimesCache(c context.Context, mid int64) (times int, err error) {
var (
key = realnameCaptureTimesKey(mid)
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
times = -1
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
if err = conn.Scan(item, &times); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// IncreaseRealnameCaptureTimes is
func (d *Dao) IncreaseRealnameCaptureTimes(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if _, err = conn.Increment(key, 1); err != nil {
err = errors.Wrapf(err, "conn.Increment(%s,1)", key)
return
}
return
}
// SetRealnameCaptureTimes is
func (d *Dao) SetRealnameCaptureTimes(c context.Context, mid int64, times int) (err error) {
var (
key = realnameCaptureTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: times, Flags: memcache.FlagJSON, Expiration: d.captureTimesTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, times)
return
}
return
}
// RealnameCaptureCodeCache .
// return code : -1 , if code not found
// RealnameCaptureCodeCache is
func (d *Dao) RealnameCaptureCodeCache(c context.Context, mid int64) (code int, err error) {
var (
key = realnameCaptureCodeKey(mid)
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
code = -1
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
if err = conn.Scan(item, &code); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// RealnameInfoCache is.
func (d *Dao) RealnameInfoCache(c context.Context, mid int64) (info *model.RealnameCacheInfo, err error) {
var (
key = realnameInfoKey(mid)
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
info = nil
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
info = &model.RealnameCacheInfo{}
if err = conn.Scan(item, &info); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// SetRealnameInfo is.
func (d *Dao) SetRealnameInfo(c context.Context, mid int64, info *model.RealnameCacheInfo) (err error) {
var (
key = realnameInfoKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: info, Flags: memcache.FlagJSON, Expiration: d.applyInfoTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, info)
return
}
return
}
// SetRealnameCaptureCode is
func (d *Dao) SetRealnameCaptureCode(c context.Context, mid int64, code int) (err error) {
var (
key = realnameCaptureCodeKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: code, Flags: memcache.FlagJSON, Expiration: d.captureCodeTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, code)
return
}
return
}
// DeleteRealnameCaptureCode is
func (d *Dao) DeleteRealnameCaptureCode(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureCodeKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "conn.Delete(%s)", key)
return
}
return
}
// DeleteRealnameInfo is
func (d *Dao) DeleteRealnameInfo(c context.Context, mid int64) (err error) {
var (
key = realnameInfoKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
err = errors.Wrapf(err, "conn.Delete(%s)", key)
return
}
return
}
// RealnameCaptureErrTimesCache is
func (d *Dao) RealnameCaptureErrTimesCache(c context.Context, mid int64) (times int, err error) {
var (
key = realnameCaptureErrTimesKey(mid)
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
times = -1
return
}
err = errors.Wrapf(err, "conn.Get(%s)", key)
return
}
if err = conn.Scan(item, &times); err != nil {
err = errors.Wrapf(err, "conn.Scan(%+v)", item)
return
}
return
}
// SetRealnameCaptureErrTimes is
func (d *Dao) SetRealnameCaptureErrTimes(c context.Context, mid int64, times int) (err error) {
var (
key = realnameCaptureErrTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: times, Flags: memcache.FlagJSON, Expiration: d.captureErrTimesTTL}); err != nil {
err = errors.Wrapf(err, "conn.Set(%s,%+v)", key, times)
return
}
return
}
// IncreaseRealnameCaptureErrTimes is
func (d *Dao) IncreaseRealnameCaptureErrTimes(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureErrTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if _, err = conn.Increment(key, 1); err != nil {
err = errors.Wrapf(err, "conn.Increment(%s,1)", key)
return
}
return
}
// DeleteRealnameCaptureErrTimes is
func (d *Dao) DeleteRealnameCaptureErrTimes(c context.Context, mid int64) (err error) {
var (
key = realnameCaptureErrTimesKey(mid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
err = nil
return
}
err = errors.Wrapf(err, "conn.Delete(%s)", key)
return
}
return
}

View File

@@ -0,0 +1,475 @@
package dao
import (
"context"
"reflect"
"testing"
"github.com/bouk/monkey"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoexpKey(t *testing.T) {
var (
mid = int64(111001740)
)
convey.Convey("expKey", t, func(ctx convey.C) {
p1 := expKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaomoralKey(t *testing.T) {
var (
mid = int64(111001740)
)
convey.Convey("moralKey", t, func(ctx convey.C) {
p1 := moralKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaopingMC(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("pingMC", t, func(ctx convey.C) {
err := d.pingMC(c)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetBaseInfoCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
info = &model.BaseInfo{
Mid: 19476037,
Name: "lala",
Sign: "We are the world!",
}
)
convey.Convey("SetBaseInfoCache", t, func(ctx convey.C) {
err := d.SetBaseInfoCache(c, mid, info)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoBaseInfoCache(t *testing.T) {
convey.Convey("BaseInfoCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(19476037)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
info, err := d.BaseInfoCache(c, mid)
ctx.Convey("Error should be nil. info should not be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(info, convey.ShouldNotBeNil)
})
})
ctx.Convey("When conn.Get gets error", func(ctx convey.C) {
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool,
_ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrItemObject)
})
defer guard.Unpatch()
_, err := d.BaseInfoCache(c, mid)
ctx.Convey("Error should be equal to memcache.ErrItemObject", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, memcache.ErrItemObject)
})
})
})
}
func TestDaoSetBatchBaseInfoCache(t *testing.T) {
var (
c = context.Background()
bi1 = &model.BaseInfo{
Mid: 19476037,
Name: "lala",
Sign: "We are the world!",
}
bi2 = &model.BaseInfo{
Mid: 4780461,
Name: "lala",
Sign: "We are the world!",
}
bs = []*model.BaseInfo{bi1, bi2}
)
convey.Convey("SetBatchBaseInfoCache", t, func(ctx convey.C) {
err := d.SetBatchBaseInfoCache(c, bs)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoBatchBaseInfoCache(t *testing.T) {
var (
c = context.Background()
mids = []int64{19476037, 1}
)
convey.Convey("BatchBaseInfoCache", t, func(ctx convey.C) {
cached, missed, err := d.BatchBaseInfoCache(c, mids)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("missed should not be nil", func(ctx convey.C) {
ctx.So(missed, convey.ShouldNotBeNil)
})
ctx.Convey("cached should not be nil", func(ctx convey.C) {
ctx.So(cached, convey.ShouldNotBeNil)
})
})
}
func TestDaoDelBaseInfoCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DelBaseInfoCache", t, func(ctx convey.C) {
err := d.DelBaseInfoCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetExpCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
exp = int64(10)
)
convey.Convey("SetExpCache", t, func(ctx convey.C) {
err := d.SetExpCache(c, mid, exp)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoexpCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("expCache", t, func(ctx convey.C) {
exp, err := d.expCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("exp should not be nil", func(ctx convey.C) {
ctx.So(exp, convey.ShouldNotBeNil)
})
})
}
func TestDaoexpsCache(t *testing.T) {
var (
c = context.Background()
mids = []int64{19476037, 4780461}
)
convey.Convey("expsCache", t, func(ctx convey.C) {
exps, miss, err := d.expsCache(c, mids)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("miss should not be nil", func(ctx convey.C) {
ctx.So(miss, convey.ShouldBeNil)
})
ctx.Convey("exps should not be nil", func(ctx convey.C) {
ctx.So(exps, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetMoralCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
moral = &model.Moral{}
)
convey.Convey("SetMoralCache", t, func(ctx convey.C) {
err := d.SetMoralCache(c, mid, moral)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaomoralCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("moralCache", t, func(ctx convey.C) {
moral, err := d.moralCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}
func TestDaoDelMoralCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DelMoralCache", t, func(ctx convey.C) {
err := d.DelMoralCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaorealnameInfoKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameApplyKey", t, func(ctx convey.C) {
key := realnameInfoKey(mid)
ctx.Convey("p1 should equal realname_info_<mid>", func(ctx convey.C) {
ctx.So(key, convey.ShouldEqual, "realname_info_19476037")
})
})
}
func TestDaorealnameCaptureTimesKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameCaptureTimesKey", t, func(ctx convey.C) {
p1 := realnameCaptureTimesKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaorealnameCaptureCodeKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameCaptureCodeKey", t, func(ctx convey.C) {
p1 := realnameCaptureCodeKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaorealnameCaptureErrTimesKey(t *testing.T) {
var (
mid = int64(19476037)
)
convey.Convey("realnameCaptureErrTimesKey", t, func(ctx convey.C) {
p1 := realnameCaptureErrTimesKey(mid)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetRealnameCaptureTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
times = int(0)
)
convey.Convey("SetRealnameCaptureTimes", t, func(ctx convey.C) {
err := d.SetRealnameCaptureTimes(c, mid, times)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameCaptureTimesCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameCaptureTimesCache", t, func(ctx convey.C) {
times, err := d.RealnameCaptureTimesCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("times should not be nil", func(ctx convey.C) {
ctx.So(times, convey.ShouldNotBeNil)
})
})
}
func TestDaoIncreaseRealnameCaptureTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("IncreaseRealnameCaptureTimes", t, func(ctx convey.C) {
err := d.IncreaseRealnameCaptureTimes(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameCaptureCodeCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameCaptureCodeCache", t, func(ctx convey.C) {
code, err := d.RealnameCaptureCodeCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("code should not be nil", func(ctx convey.C) {
ctx.So(code, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetRealnameInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
info = &model.RealnameCacheInfo{}
)
convey.Convey("SetRealnameApplyInfo", t, func(ctx convey.C) {
err := d.SetRealnameInfo(c, mid, info)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameInfoCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameApplyInfoCache", t, func(ctx convey.C) {
info, err := d.RealnameInfoCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("info should not be nil", func(ctx convey.C) {
ctx.So(info, convey.ShouldNotBeNil)
})
})
}
func TestDaoDeleteRealnameInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DeleteRealnameApplyInfo", t, func(ctx convey.C) {
err := d.DeleteRealnameInfo(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetRealnameCaptureCode(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
code = int(0)
)
convey.Convey("SetRealnameCaptureCode", t, func(ctx convey.C) {
err := d.SetRealnameCaptureCode(c, mid, code)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoDeleteRealnameCaptureCode(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DeleteRealnameCaptureCode", t, func(ctx convey.C) {
err := d.DeleteRealnameCaptureCode(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetRealnameCaptureErrTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
times = int(0)
)
convey.Convey("SetRealnameCaptureErrTimes", t, func(ctx convey.C) {
err := d.SetRealnameCaptureErrTimes(c, mid, times)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoRealnameCaptureErrTimesCache(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("RealnameCaptureErrTimesCache", t, func(ctx convey.C) {
times, err := d.RealnameCaptureErrTimesCache(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("times should not be nil", func(ctx convey.C) {
ctx.So(times, convey.ShouldNotBeNil)
})
})
}
func TestDaoIncreaseRealnameCaptureErrTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("IncreaseRealnameCaptureErrTimes", t, func(ctx convey.C) {
err := d.IncreaseRealnameCaptureErrTimes(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoDeleteRealnameCaptureErrTimes(t *testing.T) {
var (
c = context.Background()
mid = int64(19476037)
)
convey.Convey("DeleteRealnameCaptureErrTimes", t, func(ctx convey.C) {
err := d.DeleteRealnameCaptureErrTimes(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,43 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/library/ecode"
"go-common/library/log"
)
// consts
const (
notifyURL = "http://message.bilibili.co/api/notify/send.user.notify.do"
dataType = "4"
source = "2"
)
// SendMessage is
func (d *Dao) SendMessage(c context.Context, mid int64, title, msg, mc string) (err error) {
var (
params = url.Values{}
)
params.Set("mid_list", fmt.Sprintf("%d", mid))
params.Set("mc", mc)
params.Set("data_type", dataType)
params.Set("source", source)
params.Set("context", msg)
params.Set("title", title)
var resp struct {
Code int `json:"code"`
}
log.Info("SendMessage() params(%v)", params)
if err = d.client.Post(c, notifyURL, "", params, &resp); err != nil {
log.Error("d.client.Post(%s,%+v) error(%v)", notifyURL, params, err)
return
}
if resp.Code != 0 {
err = ecode.Int(resp.Code)
log.Error("d.client.Post(%s,%+v) resp.Code(%d)", notifyURL, params, resp.Code)
}
return
}

View File

@@ -0,0 +1,34 @@
package dao
import (
"context"
"strings"
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}
func TestDaoSendMessage(t *testing.T) {
var (
c = context.Background()
mid = int64(123)
title = "test"
msg = "test"
mc = "test"
)
convey.Convey("SendMessage", t, func(ctx convey.C) {
d.client.SetTransport(gock.DefaultTransport)
defer gock.OffAll()
httpMock("POST", notifyURL).Reply(200).JSON(`{"code":0,"message":"0"}`)
err := d.SendMessage(c, mid, title, msg, mc)
ctx.So(err, convey.ShouldBeNil)
})
}

View File

@@ -0,0 +1,157 @@
package dao
import (
"context"
"encoding/json"
"net/url"
"strconv"
"time"
"go-common/app/service/main/member/model"
"go-common/library/cache/memcache"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"github.com/pkg/errors"
)
const (
_moralLogID = 12
)
// Moral get user moral from cache,if miss get from db.
func (d *Dao) Moral(c context.Context, mid int64) (moral *model.Moral, err error) {
if moral, err = d.moralCache(c, mid); err == nil {
return
}
if err != nil && err != memcache.ErrNotFound {
log.Error("Failed to get moral from cache, mid: %d, error:%v", mid, err)
return
}
if moral, err = d.MoralDB(c, mid); err != nil {
return
}
if moral == nil {
moral = &model.Moral{Mid: mid, Moral: model.DefaultMoral}
}
d.SetMoralCache(c, mid, moral)
return
}
// MoralLog is
func (d *Dao) MoralLog(ctx context.Context, mid int64) ([]*model.UserLog, error) {
ip := metadata.String(ctx, metadata.RemoteIP)
t := time.Now().Add(-time.Hour * 24 * 7)
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(_moralLogID, 10))
params.Set("pn", "1")
params.Set("ps", "1000")
params.Set("ctime_from", t.Format("2006-01-02 00:00:00"))
params.Set("sort", "desc")
params.Set("order", "ctime")
res := &model.SearchResult{}
if err := d.client.Get(ctx, d.c.Host.Search+_searchLogURI, ip, params, res); err != nil {
return nil, err
}
if res.Code != 0 {
return nil, ecode.Int(res.Code)
}
logs := asMoralLog(res)
return logs, nil
}
// MoralLogByID get distinct log by log id
func (d *Dao) MoralLogByID(ctx context.Context, logID string) (*model.UserLog, error) {
ip := metadata.String(ctx, metadata.RemoteIP)
params := url.Values{}
params.Set("str_0", logID)
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(_moralLogID, 10))
params.Set("pn", "1")
params.Set("ps", "1")
params.Set("sort", "desc")
params.Set("order", "ctime")
res := &model.SearchResult{}
if err := d.client.Get(ctx, d.c.Host.Search+_searchLogURI, ip, params, res); err != nil {
return nil, err
}
if res.Code != 0 {
return nil, ecode.Int(res.Code)
}
logs := asMoralLog(res)
if len(logs) == 0 {
return nil, ecode.NothingFound
}
return logs[0], nil
}
// DeleteMoralLog is
func (d *Dao) DeleteMoralLog(ctx context.Context, logID string) error {
ip := metadata.String(ctx, metadata.RemoteIP)
return d.deleteLogReport(ctx, _moralLogID, logID, ip)
}
// DeleteLogReport is
func (d *Dao) deleteLogReport(ctx context.Context, business int, logID string, ip string) error {
if logID == "" {
return errors.New("Failed to delete log with empty logID")
}
params := url.Values{}
params.Set("str_0", logID)
params.Set("appid", "log_user_action")
params.Set("business", strconv.FormatInt(int64(business), 10))
res := &model.SearchResult{}
if err := d.client.Post(ctx, d.c.Host.Search+_deleteLogURI, ip, params, res); err != nil {
return err
}
if res.Code != 0 {
return ecode.Int(res.Code)
}
return nil
}
func asMoralLog(res *model.SearchResult) []*model.UserLog {
logs := make([]*model.UserLog, 0, len(res.Data.Result))
for _, r := range res.Data.Result {
ts, err := time.ParseInLocation("2006-01-02 15:04:05", r.Ctime, time.Local)
if err != nil {
log.Warn("Failed to parse log ctime: ctime: %s: %+v", r.Ctime, err)
continue
}
content := map[string]string{
"from_moral": "",
"log_id": "",
"mid": "",
"operater": "",
"origin": "",
"reason": "",
"remark": "",
"status": "",
"to_moral": "",
}
if err := json.Unmarshal([]byte(r.ExtraData), &content); err != nil {
log.Warn("Failed to parse extra data in moral log: mid: %d, extra_data: %s: %+v", r.Mid, r.ExtraData, err)
continue
}
if content["mid"] == "" {
content["mid"] = strconv.FormatInt(r.Mid, 10)
}
l := &model.UserLog{
Mid: r.Mid,
IP: r.IP,
TS: ts.Unix(),
LogID: content["log_id"],
Content: content,
}
logs = append(logs, l)
}
return logs
}

View File

@@ -0,0 +1,100 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoMoralLog(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
// ip = ""
)
convey.Convey("MoralLog", t, func(ctx convey.C) {
p1, p2 := d.MoralLog(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoMoralLogByID(t *testing.T) {
var (
c = context.Background()
logID = "test"
// ip = ""
)
convey.Convey("MoralLogByID", t, func(ctx convey.C) {
p1, p2 := d.MoralLogByID(c, logID)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldEqual, -404)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoDeleteMoralLog(t *testing.T) {
var (
c = context.Background()
logID = "test"
// ip = ""
)
convey.Convey("DeleteMoralLog", t, func(ctx convey.C) {
p1 := d.DeleteMoralLog(c, logID)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaodeleteLogReport(t *testing.T) {
var (
c = context.Background()
business = int(0)
logID = "test"
ip = ""
)
convey.Convey("deleteLogReport", t, func(ctx convey.C) {
p1 := d.deleteLogReport(c, business, logID, ip)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoasMoralLog(t *testing.T) {
var (
res = &model.SearchResult{}
)
convey.Convey("asMoralLog", t, func(ctx convey.C) {
p1 := asMoralLog(res)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoMoral(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("Moral", t, func(ctx convey.C) {
moral, err := d.Moral(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,544 @@
package dao
import (
"context"
"database/sql"
"fmt"
"strings"
"go-common/app/service/main/member/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/time"
"github.com/pkg/errors"
)
const (
_shard = 100
// base
_selBaseInfo = "SELECT mid,name,sex,face,sign,rank,birthday FROM user_base_%02d WHERE mid=? "
_setSex = "INSERT INTO user_base_%02d(mid,sex) VALUES (?,?) ON DUPLICATE KEY UPDATE sex=?"
_setName = "INSERT INTO user_base_%02d(mid,name) VALUES (?,?) ON DUPLICATE KEY UPDATE name=?"
_setRank = "INSERT INTO user_base_%02d(mid,rank) VALUES (?,?) ON DUPLICATE KEY UPDATE rank=?"
_setSign = "INSERT INTO user_base_%02d(mid,sign) VALUES (?,?) ON DUPLICATE KEY UPDATE sign=?"
_setBirthday = "INSERT INTO user_base_%02d(mid,birthday) VALUES (?,?) ON DUPLICATE KEY UPDATE birthday=?"
_setFace = "INSERT INTO user_base_%02d(mid,face) VALUES (?,?) ON DUPLICATE KEY UPDATE face=?"
_setBase = `INSERT INTO user_base_%02d(mid,name,sex,face,sign,rank,birthday) VALUES (?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE name=?,sex=?,face=?,sign=?,rank=?,birthday=?`
// _exp
_setExp = "INSERT INTO user_exp_%02d (mid,exp) VALUES(?,?) ON DUPLICATE KEY UPDATE exp=VALUES(exp)"
_updateExp = "UPDATE user_exp_%02d SET exp=exp+? WHERE mid=?"
_selExp = "SELECT exp FROM user_exp_%02d where mid=?"
//user_flag
_selUserAttr = "SELECT flag FROM user_flag where mid =? and flag & ?= ?"
_updateUserAttr = "INSERT INTO user_flag(mid,flag) VALUES(?,?) ON DUPLICATE KEY UPDATE flag=flag|?"
// user_official
_selOfficials = "SELECT mid,role,title,description FROM user_official WHERE role>0"
// moral
_selMoral = "SELECT moral,added,deducted,last_recover_date from user_moral where mid=?"
_initMoral = `INSERT IGNORE INTO user_moral (mid,moral,added,deducted,last_recover_date) VALUES(?,?,?,?,?)`
_updateMoral = `update user_moral set moral=moral+?,added=added+?, deducted=deducted + ? where mid = ?`
_updateMoralRecoverDate = `update user_moral set last_recover_date = ? where mid = ?`
// official
_setOfficialDoc = `INSERT INTO user_official_doc (mid,name,state,role,title,description,extra,submit_source,submit_time) VALUES (?,?,?,?,?,?,?,?,?)
ON DUPLICATE KEY UPDATE name=VALUES(name), state=VALUES(state), role=VALUES(role), title=VALUES(title), description=VALUES(description), extra=VALUES(extra), submit_source=VALUES(submit_source), submit_time=VALUES(submit_time)`
_selOfficialDoc = "SELECT mid,name,state,role,title,description,reject_reason,extra FROM user_official_doc WHERE mid=?"
_selOfficial = "SELECT role,title,description FROM user_official WHERE mid=? AND role>0"
//official addit
_setOfficialDocAddit = `INSERT INTO user_official_doc_addit (mid,property,vstring) VALUES (?,?,?) ON DUPLICATE KEY UPDATE vstring=VALUES(vstring)`
// realname
_selRealnameInfo = `SELECT id,mid,channel,realname,country,card_type,card,card_md5,status,reason,ctime,mtime FROM realname_info WHERE mid = ? LIMIT 1`
_selRealnameInfoByCard = `SELECT id,mid,channel,realname,country,card_type,card,card_md5,status,reason,ctime,mtime FROM realname_info WHERE card_md5=? AND status in (0,1) LIMIT 1`
_selRealnameInfoMidByCards = `SELECT mid,card_md5 FROM realname_info WHERE card_md5 IN (%s) AND status in (0,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=?`
_updateRealnameInfo = `UPDATE realname_info SET status=?,reason=? WHERE mid=?`
_selRealnameApply = "SELECT 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 FROM realname_apply WHERE mid = ? ORDER BY ID DESC LIMIT 1"
_insertRealnameApply = `INSERT INTO realname_apply (mid,realname,country,card_type,card_num,card_md5,hand_img,front_img,back_img,status) VALUES (?,?,?,?,?,?,?,?,?,?)`
_selRealnameApplyImg = "SELECT id,img_data,ctime,mtime FROM realname_apply_img WHERE id = ? LIMIT 1"
_insertRealnameApplyImg = `INSERT INTO realname_apply_img (img_data) VALUES (?)`
// alipay
_selRealnameAlipayApply = "SELECT id,mid,realname,card,img,status,reason,bizno,ctime,mtime FROM realname_alipay_apply WHERE mid = ? ORDER BY ID DESC LIMIT 1"
_insertRealnameAlipayApply = `INSERT INTO realname_alipay_apply (mid,realname,card,img,status,reason,bizno) VALUES (?,?,?,?,?,?,?)`
_updateRealnameAlipayApply = `UPDATE realname_alipay_apply SET status=?,reason=? WHERE id=?`
// realname old
_insertOldRealnameApply = `INSERT INTO dede_identification_card_apply (mid,realname,type,card_data,card_for_search,front_img,front_img2,back_img,apply_time,status) VALUES (?,?,?,?,?,?,?,?,?,?)`
_insertOldRealnameApplyImg = `INSERT INTO dede_identification_card_apply_img (img_data,add_time) VALUES (?,?)`
)
func hit(id int64) int64 {
return id % _shard
}
// BeginTran begin transcation.
func (d *Dao) BeginTran(c context.Context) (tx *xsql.Tx, err error) {
return d.db.Begin(c)
}
// BaseInfo base info of user.
func (d *Dao) BaseInfo(c context.Context, mid int64) (r *model.BaseInfo, err error) {
r = &model.BaseInfo{}
row := d.db.Master().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); err != nil {
if err == xsql.ErrNoRows {
r = nil
err = nil
return
}
err = errors.Wrapf(err, "dao base mid(%d)", mid)
}
r.RandFaceURL()
return
}
// SetBase set base.
func (d *Dao) SetBase(c context.Context, base *model.BaseInfo) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setBase, hit(base.Mid)), base.Mid, base.Name, base.Sex, base.Face, base.Sign,
base.Rank, base.Birthday, base.Name, base.Sex, base.Face, base.Sign, base.Rank, base.Birthday); err != nil {
err = errors.Wrapf(err, "dao set base(%v)", base)
}
return
}
// SetSign set user 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 {
err = errors.Wrapf(err, "dao set sign mid(%d)", mid)
}
return
}
// SetName set user name.
func (d *Dao) SetName(c context.Context, mid int64, name string) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setName, hit(mid)), mid, name, name); err != nil {
err = errors.Wrapf(err, "dao set name mid(%d) name(%s)", mid, name)
}
return
}
// SetRank set user rank.
func (d *Dao) SetRank(c context.Context, mid, rank int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setRank, hit(mid)), mid, rank, rank); err != nil {
err = errors.Wrapf(err, "dao set rank mid(%d) rank(%d)", mid, rank)
}
return
}
// SetSex set sex.
func (d *Dao) SetSex(c context.Context, mid, sex int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setSex, hit(mid)), mid, sex, sex); err != nil {
err = errors.Wrapf(err, "dao set sex mid(%d) sex(%d)", mid, sex)
}
return
}
// SetBirthday set birthday.
func (d *Dao) SetBirthday(c context.Context, mid int64, birthday time.Time) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_setBirthday, hit(mid)), mid, birthday, birthday); err != nil {
err = errors.Wrapf(err, "dao set birthday mid(%d) birthday(%d)", mid, birthday)
}
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)), mid, face, face); err != nil {
err = errors.Wrapf(err, "dao set face mid(%d) face(%v)", mid, face)
}
return
}
// ExpDB get user exp from db.
func (d *Dao) ExpDB(c context.Context, mid int64) (count int64, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_selExp, hit(mid)), mid)
if err = row.Scan(&count); err != nil {
if err == xsql.ErrNoRows {
err = nil
return
}
err = errors.Wrapf(err, "dao exp mid(%d)", mid)
}
return
}
// SetExp set user exp to count.
func (d *Dao) SetExp(c context.Context, mid, count int64) (affect int64, err error) {
row, err := d.db.Exec(c, fmt.Sprintf(_setExp, hit(mid)), mid, count)
if err != nil {
err = errors.Wrapf(err, "dao set exp mid(%d) exp(%d)", mid, count)
return
}
return row.RowsAffected()
}
// UpdateExp incr user exp by delta.
func (d *Dao) UpdateExp(c context.Context, mid, delta int64) (affect int64, err error) {
row, err := d.db.Exec(c, fmt.Sprintf(_updateExp, hit(mid)), delta, mid)
if err != nil {
err = errors.Wrapf(err, "dao update exp mid(%d) exp(%d)", mid, delta)
return
}
return row.RowsAffected()
}
// ------------- exp ---------------- //
// UserAttrDB get attr.
func (d *Dao) UserAttrDB(c context.Context, mid int64, attr uint) (hasAttr bool, err error) {
var flag int8
row := d.db.QueryRow(c, _selUserAttr, mid, attr, attr)
if err = row.Scan(&flag); err != nil {
if err == xsql.ErrNoRows {
err = nil
return
}
err = errors.Wrapf(err, "dao attr mid(%d) attr(%d)", mid, attr)
}
hasAttr = true
return
}
// SetUserAttr update attr .
func (d *Dao) SetUserAttr(c context.Context, mid int64, attr uint) (err error) {
if _, err = d.db.Exec(c, _updateUserAttr, mid, attr, attr); err != nil {
err = errors.Wrapf(err, "dao attr mid(%d) attr(%d)", mid, attr)
return
}
return
}
// Officials all officials info of user.
func (d *Dao) Officials(c context.Context) (om map[int64]*model.OfficialInfo, err error) {
om = make(map[int64]*model.OfficialInfo)
rows, err := d.db.Query(c, _selOfficials)
if err != nil {
err = errors.Wrap(err, "dao officials")
return
}
defer rows.Close()
for rows.Next() {
var mid int64
o := &model.OfficialInfo{}
if err = rows.Scan(&mid, &o.Role, &o.Title, &o.Desc); err != nil {
err = errors.Wrap(err, "dao officials scan")
return
}
om[mid] = o
}
return
}
// Official is.
func (d *Dao) Official(c context.Context, mid int64) (*model.OfficialInfo, error) {
row := d.db.QueryRow(c, _selOfficial, mid)
o := &model.OfficialInfo{}
if err := row.Scan(&o.Role, &o.Title, &o.Desc); err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, errors.Wrap(err, "dao official scan")
}
return o, nil
}
// MoralDB get user moral from db.
func (d *Dao) MoralDB(c context.Context, mid int64) (moral *model.Moral, err error) {
moral = &model.Moral{}
row := d.db.QueryRow(c, _selMoral, mid)
if err = row.Scan(&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)
err = errors.Wrapf(err, "dao moral mid(%d)", mid)
return
}
return
}
// TxMoralDB get user moral from db.
func (d *Dao) TxMoralDB(tx *xsql.Tx, mid int64) (moral *model.Moral, err error) {
moral = &model.Moral{}
row := tx.QueryRow(_selMoral, mid)
if err = row.Scan(&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)
err = errors.Wrapf(err, "dao moral mid(%d)", mid)
return
}
return
}
// TxUpdateMoral set user moral.
func (d *Dao) TxUpdateMoral(tx *xsql.Tx, mid, moral, added, deducted int64) (err error) {
if _, err = tx.Exec(_updateMoral, moral, added, deducted, mid); err != nil {
err = errors.Wrapf(err, "TxUpdateMoral mid(%d) moralAdded(%v)", mid, moral)
return
}
return
}
// TxUpdateMoralRecoverDate update moral recover date.
func (d *Dao) TxUpdateMoralRecoverDate(tx *xsql.Tx, mid int64, recoverDate time.Time) (err error) {
if _, err = tx.Exec(_updateMoralRecoverDate, recoverDate, mid); err != nil {
err = errors.Wrapf(err, "TxUpdateMoralRecoverDate mid(%d) recoverDate(%v)", mid, recoverDate)
return
}
return
}
// TxInitMoral set user moral.
func (d *Dao) TxInitMoral(tx *xsql.Tx, mid, moral, added, deducted int64, lastRecoverDate time.Time) (err error) {
if _, err = tx.Exec(_initMoral, mid, moral, added, deducted, lastRecoverDate); err != nil {
err = errors.Wrapf(err, "TxInitMoral mid(%d) moral(%v)", mid, moral)
return
}
return
}
// SetOfficialDoc add official doc.
func (d *Dao) SetOfficialDoc(c context.Context, od *model.OfficialDoc) (err error) {
_, err = d.db.Exec(c, _setOfficialDoc, od.Mid, od.Name, model.OfficialStateWait, od.Role,
od.Title, od.Desc, od.OfficialExtra.String(), od.SubmitSource, od.SubmitTime)
if err != nil {
err = errors.Wrapf(err, "dao add official doc")
return
}
return
}
// SetOfficialDocAddit add official doc addit.
func (d *Dao) SetOfficialDocAddit(c context.Context, mid int64, property, vstring string) error {
_, err := d.db.Exec(c, _setOfficialDocAddit, mid, property, vstring)
if err != nil {
err = errors.Wrapf(err, "dao add official doc addit")
return err
}
return nil
}
// OfficialDoc get official doc.
func (d *Dao) OfficialDoc(c context.Context, mid int64) (*model.OfficialDoc, error) {
od := new(model.OfficialDoc)
row := d.db.QueryRow(c, _selOfficialDoc, mid)
if err := row.Scan(&od.Mid, &od.Name, &od.State, &od.Role, &od.Title, &od.Desc, &od.RejectReason, &od.Extra); err != nil {
err = errors.Wrapf(err, "official doc")
return nil, err
}
od.ParseExtra()
return od, nil
}
// Realname
// 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
}
// RealnameInfoByCard is.
func (d *Dao) RealnameInfoByCard(c context.Context, cardMD5 string) (info *model.RealnameInfo, err error) {
row := d.db.QueryRow(c, _selRealnameInfoByCard, cardMD5)
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 cardMD5(%s)", cardMD5)
return
}
return
}
// UpsertTxRealnameInfo is.
func (d *Dao) UpsertTxRealnameInfo(c context.Context, tx *xsql.Tx, info *model.RealnameInfo) (err error) {
if _, err = tx.Exec(_upsertRealnameInfo, info.MID, info.Channel, info.Realname, info.Country, info.CardType, info.Card, info.CardMD5, info.Status, info.Reason, info.Channel, info.Realname, info.Country, info.CardType, info.Card, info.CardMD5, info.Status, info.Reason); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UpdateTxRealnameInfo is.
func (d *Dao) UpdateTxRealnameInfo(c context.Context, tx *xsql.Tx, mid int64, status model.RealnameApplyStatus, reason string) (err error) {
if _, err = tx.Exec(_updateRealnameInfo, status, reason, mid); err != nil {
err = errors.WithStack(err)
return
}
return
}
// RealnameApply realname
func (d *Dao) RealnameApply(c context.Context, mid int64) (apply *model.RealnameApply, err error) {
row := d.db.Master().QueryRow(c, _selRealnameApply, mid)
apply = &model.RealnameApply{}
if err = row.Scan(&apply.ID, &apply.MID, &apply.Realname, &apply.Country, &apply.CardType, &apply.CardNum, &apply.CardMD5, &apply.HandIMG, &apply.FrontIMG, &apply.BackIMG, &apply.Status, &apply.Operator, &apply.OperatorID, &apply.OperatorTime, &apply.Remark, &apply.RemarkStatus, &apply.CTime, &apply.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
apply = nil
return
}
err = errors.Wrapf(err, "dao RealnameApply mid(%d)", mid)
return
}
return
}
// InsertRealnameApply is
func (d *Dao) InsertRealnameApply(c context.Context, data *model.RealnameApply) (err error) {
if _, err = d.db.Exec(c, _insertRealnameApply, data.MID, data.Realname, data.Country, data.CardType, data.CardNum, data.CardMD5, data.HandIMG, data.FrontIMG, data.BackIMG, data.Status); err != nil {
err = errors.WithStack(err)
return
}
return
}
// RealnameApplyIMG is
func (d *Dao) RealnameApplyIMG(c context.Context, id int) (img *model.RealnameApplyImage, err error) {
row := d.db.Master().QueryRow(c, _selRealnameApplyImg, id)
img = &model.RealnameApplyImage{}
if err = row.Scan(&img.ID, &img.IMGData, &img.CTime, &img.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
img = nil
return
}
err = errors.Wrapf(err, "dao RealnameApplyIMG mid(%d)", id)
return
}
return
}
// InsertRealnameApplyImg is
func (d *Dao) InsertRealnameApplyImg(c context.Context, data *model.RealnameApplyImage) (id int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _insertRealnameApplyImg, data.IMGData); err != nil {
err = errors.WithStack(err)
return
}
if id, err = res.LastInsertId(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// InsertOldRealnameApply is
func (d *Dao) InsertOldRealnameApply(c context.Context, data *model.RealnameApply) (id int64, err error) {
var (
res sql.Result
cardType = int16(data.CardType)
)
if data.Country > 0 {
cardType = data.Country
}
if res, err = d.accdb.Exec(c, _insertOldRealnameApply, data.MID, data.Realname, cardType, data.CardNum, data.CardMD5, data.FrontIMG, data.HandIMG, data.BackIMG, data.CTime.Unix(), data.Status); err != nil {
err = errors.WithStack(err)
return
}
if id, err = res.LastInsertId(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// InsertOldRealnameApplyImg is
func (d *Dao) InsertOldRealnameApplyImg(c context.Context, data *model.RealnameApplyImage) (id int64, err error) {
var res sql.Result
if res, err = d.accdb.Exec(c, _insertOldRealnameApplyImg, data.IMGData, data.CTime); err != nil {
err = errors.WithStack(err)
return
}
if id, err = res.LastInsertId(); err != nil {
err = errors.WithStack(err)
return
}
return
}
// InsertTxRealnameAlipayApply .
func (d *Dao) InsertTxRealnameAlipayApply(c context.Context, tx *xsql.Tx, data *model.RealnameAlipayApply) (err error) {
if _, err = tx.Exec(_insertRealnameAlipayApply, data.MID, data.Realname, data.Card, data.IMG, data.Status, data.Reason, data.Bizno); err != nil {
err = errors.WithStack(err)
return
}
return
}
// UpdateTxRealnameAlipayApply is.
func (d *Dao) UpdateTxRealnameAlipayApply(c context.Context, tx *xsql.Tx, id int64, status model.RealnameApplyStatus, reason string) (err error) {
if _, err = tx.Exec(_updateRealnameAlipayApply, status, reason, id); err != nil {
err = errors.WithStack(err)
return
}
return
}
// RealnameAlipayApply .
func (d *Dao) RealnameAlipayApply(c context.Context, mid int64) (apply *model.RealnameAlipayApply, err error) {
row := d.db.QueryRow(c, _selRealnameAlipayApply, mid)
apply = &model.RealnameAlipayApply{}
if err = row.Scan(&apply.ID, &apply.MID, &apply.Realname, &apply.Card, &apply.IMG, &apply.Status, &apply.Reason, &apply.Bizno, &apply.CTime, &apply.MTime); err != nil {
if err == xsql.ErrNoRows {
err = nil
apply = nil
return
}
err = errors.Wrapf(err, "dao RealnameAlipayApply mid(%d)", mid)
return
}
return
}
func prepareStringArray(in []string) string {
surrounded := make([]string, 0, len(in))
for _, s := range in {
surrounded = append(surrounded, fmt.Sprintf(`'%s'`, s))
}
return strings.Join(surrounded, ",")
}
// MidByRealnameCards is
func (d *Dao) MidByRealnameCards(ctx context.Context, cardMD5s []string) (map[string]int64, error) {
rows, err := d.db.Query(ctx, fmt.Sprintf(_selRealnameInfoMidByCards, prepareStringArray(cardMD5s)))
if err != nil {
return nil, err
}
defer rows.Close()
result := make(map[string]int64, len(cardMD5s))
for rows.Next() {
mid, cardMD5 := int64(0), ""
if err := rows.Scan(&mid, &cardMD5); err != nil {
log.Warn("Failed to scan realname info: %+v", err)
continue
}
result[cardMD5] = mid
}
return result, nil
}

View File

@@ -0,0 +1,521 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"go-common/library/time"
"github.com/smartystreets/goconvey/convey"
)
func TestDaohit(t *testing.T) {
var (
id = int64(0)
)
convey.Convey("hit", t, func(ctx convey.C) {
p1 := hit(id)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoBeginTran(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("BeginTran", t, func(ctx convey.C) {
tx, err := d.BeginTran(c)
defer tx.Commit()
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("tx should not be nil", func(ctx convey.C) {
ctx.So(tx, convey.ShouldNotBeNil)
})
})
}
func TestDaoBaseInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("BaseInfo", t, func(ctx convey.C) {
r, err := d.BaseInfo(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("r should not be nil", func(ctx convey.C) {
ctx.So(r, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetBase(t *testing.T) {
var (
c = context.Background()
base = &model.BaseInfo{
Mid: 0,
}
)
convey.Convey("SetBase", t, func(ctx convey.C) {
err := d.SetBase(c, base)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetSign(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
sign = "test"
)
convey.Convey("SetSign", t, func(ctx convey.C) {
err := d.SetSign(c, mid, sign)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetName(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
name = "test"
)
convey.Convey("SetName", t, func(ctx convey.C) {
err := d.SetName(c, mid, name)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetRank(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
rank = int64(100)
)
convey.Convey("SetRank", t, func(ctx convey.C) {
err := d.SetRank(c, mid, rank)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetSex(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
sex = int64(1)
)
convey.Convey("SetSex", t, func(ctx convey.C) {
err := d.SetSex(c, mid, sex)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetBirthday(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
birthday = time.Time(946656000)
)
convey.Convey("SetBirthday", t, func(ctx convey.C) {
err := d.SetBirthday(c, mid, birthday)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetFace(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
face = "test"
)
convey.Convey("SetFace", t, func(ctx convey.C) {
err := d.SetFace(c, mid, face)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoExpDB(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
)
convey.Convey("ExpDB", t, func(ctx convey.C) {
count, err := d.ExpDB(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("count should not be nil", func(ctx convey.C) {
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetExp(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
count = int64(10)
)
convey.Convey("SetExp", t, func(ctx convey.C) {
affect, err := d.SetExp(c, mid, count)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("affect should not be nil", func(ctx convey.C) {
ctx.So(affect, convey.ShouldNotBeNil)
})
})
}
func TestDaoUpdateExp(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
delta = int64(6)
)
convey.Convey("UpdateExp", t, func(ctx convey.C) {
affect, err := d.UpdateExp(c, mid, delta)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("affect should not be nil", func(ctx convey.C) {
ctx.So(affect, convey.ShouldNotBeNil)
})
})
}
func TestDaoUserAttrDB(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
attr uint
)
convey.Convey("UserAttrDB", t, func(ctx convey.C) {
hasAttr, err := d.UserAttrDB(c, mid, attr)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("hasAttr should not be nil", func(ctx convey.C) {
ctx.So(hasAttr, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetUserAttr(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
attr uint
)
convey.Convey("SetUserAttr", t, func(ctx convey.C) {
err := d.SetUserAttr(c, mid, attr)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoOfficials(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("Officials", t, func(ctx convey.C) {
om, err := d.Officials(c)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("om should not be nil", func(ctx convey.C) {
ctx.So(om, convey.ShouldNotBeNil)
})
})
}
func TestDaoOfficial(t *testing.T) {
var (
c = context.Background()
mid = int64(1)
)
convey.Convey("Official", t, func(ctx convey.C) {
p1, p2 := d.Official(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoMoralDB(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("MoralDB", t, func(ctx convey.C) {
moral, err := d.MoralDB(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}
func TestDaoTxMoralDB(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(8)
)
defer tx.Commit()
convey.Convey("TxMoralDB", t, func(ctx convey.C) {
moral, err := d.TxMoralDB(tx, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("moral should not be nil", func(ctx convey.C) {
ctx.So(moral, convey.ShouldNotBeNil)
})
})
}
func TestDaoTxUpdateMoral(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(0)
moral = int64(0)
added = int64(0)
deducted = int64(0)
)
defer tx.Commit()
convey.Convey("TxUpdateMoral", t, func(ctx convey.C) {
err := d.TxUpdateMoral(tx, mid, moral, added, deducted)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoTxUpdateMoralRecoverDate(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(0)
recoverDate = time.Time(946656000)
)
defer tx.Commit()
convey.Convey("TxUpdateMoralRecoverDate", t, func(ctx convey.C) {
err := d.TxUpdateMoralRecoverDate(tx, mid, recoverDate)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoTxInitMoral(t *testing.T) {
var (
c = context.Background()
tx, _ = d.db.Begin(c)
mid = int64(10)
moral = int64(0)
added = int64(0)
deducted = int64(0)
lastRecoverDate = time.Time(946656000)
)
defer tx.Commit()
convey.Convey("TxInitMoral", t, func(ctx convey.C) {
err := d.TxInitMoral(tx, mid, moral, added, deducted, lastRecoverDate)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetOfficialDoc(t *testing.T) {
var (
c = context.Background()
od = &model.OfficialDoc{
Mid: 4780461,
}
)
convey.Convey("SetOfficialDoc", t, func(ctx convey.C) {
err := d.SetOfficialDoc(c, od)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoOfficialDoc(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("OfficialDoc", t, func(ctx convey.C) {
p1, p2 := d.OfficialDoc(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameInfo(t *testing.T) {
var (
c = context.Background()
mid = int64(46333)
)
convey.Convey("TestDaoRealnameInfo", t, func(ctx convey.C) {
info, err := d.RealnameInfo(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("info should not be nil", func(ctx convey.C) {
t.Logf("info:%+v", info)
ctx.So(info, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameInfoByCard(t *testing.T) {
var (
c = context.Background()
cardMD5 = "0088bdb8af58d25c1d9864e568a3cfb8"
)
convey.Convey("TestDaoRealnameInfoByCard", t, func(ctx convey.C) {
info, err := d.RealnameInfoByCard(c, cardMD5)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("info should not be nil", func(ctx convey.C) {
t.Logf("info:%+v", info)
ctx.So(info, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameApply(t *testing.T) {
var (
c = context.Background()
mid = int64(4780461)
)
convey.Convey("RealnameApply", t, func(ctx convey.C) {
apply, err := d.RealnameApply(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("apply should not be nil", func(ctx convey.C) {
ctx.So(apply, convey.ShouldNotBeNil)
})
})
}
func TestDaoInsertRealnameApply(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApply{
MID: 4780461,
}
)
convey.Convey("InsertRealnameApply", t, func(ctx convey.C) {
err := d.InsertRealnameApply(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoInsertRealnameApplyImg(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApplyImage{
ID: 1,
IMGData: "1234",
}
)
convey.Convey("InsertRealnameApplyImg", t, func(ctx convey.C) {
id, err := d.InsertRealnameApplyImg(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("id should not be nil", func(ctx convey.C) {
ctx.So(id, convey.ShouldNotBeNil)
})
})
}
func TestDaoRealnameApplyIMG(t *testing.T) {
var (
c = context.Background()
id = int(1)
)
convey.Convey("RealnameApplyIMG", t, func(ctx convey.C) {
img, err := d.RealnameApplyIMG(c, id)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("img should not be nil", func(ctx convey.C) {
ctx.So(img, convey.ShouldNotBeNil)
})
})
}
func TestDaoInsertOldRealnameApply(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApply{
ID: 1,
}
)
convey.Convey("InsertOldRealnameApply", t, func(ctx convey.C) {
id, err := d.InsertOldRealnameApply(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("id should not be nil", func(ctx convey.C) {
ctx.So(id, convey.ShouldNotBeNil)
})
})
}
func TestDaoInsertOldRealnameApplyImg(t *testing.T) {
var (
c = context.Background()
data = &model.RealnameApplyImage{
ID: 1,
IMGData: "1234",
}
)
convey.Convey("InsertOldRealnameApplyImg", t, func(ctx convey.C) {
id, err := d.InsertOldRealnameApplyImg(c, data)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("id should not be nil", func(ctx convey.C) {
ctx.So(id, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,50 @@
package dao
import (
"context"
"go-common/app/service/main/member/model"
"github.com/pkg/errors"
)
const (
_addUserMonitor = "INSERT INTO user_monitor(mid, operator, remark) VALUES(?,?,?) ON DUPLICATE KEY UPDATE operator=VALUES(operator), remark=VALUES(remark), is_deleted=0"
_isInUserMonitor = "SELECT count(1) FROM user_monitor WHERE mid=? and is_deleted=0"
_addPropertyReview = "INSERT INTO user_property_review(mid, old, new, state, property, is_monitor, extra) VALUES (?,?,?,?,?,?,?)"
_archivePropertyReview = "UPDATE user_property_review SET state=?, operator=?, remark=? WHERE mid=? AND property=? AND state=0"
)
// AddUserMonitor is.
func (d *Dao) AddUserMonitor(ctx context.Context, mid int64, operator, remark string) error {
if _, err := d.db.Exec(ctx, _addUserMonitor, mid, operator, remark); err != nil {
return errors.Wrapf(err, "dao add user monitor")
}
return nil
}
// IsInUserMonitor is.
func (d *Dao) IsInUserMonitor(ctx context.Context, mid int64) (bool, error) {
row := d.db.QueryRow(ctx, _isInUserMonitor, mid)
inMonitor := false
if err := row.Scan(&inMonitor); err != nil {
return false, errors.Wrapf(err, "dao is in user monitor")
}
return inMonitor, nil
}
// AddPropertyReview is.
func (d *Dao) AddPropertyReview(ctx context.Context, r *model.UserPropertyReview) error {
if _, err := d.db.Exec(ctx, _addPropertyReview, r.Mid, r.Old, r.New, r.State, r.Property, r.IsMonitor, r.Extra); err != nil {
return errors.Wrapf(err, "dao add user property review")
}
return nil
}
// ArchivePropertyReview is.
func (d *Dao) ArchivePropertyReview(ctx context.Context, mid int64, property int8) error {
if _, err := d.db.Exec(ctx, _archivePropertyReview, model.ReviewStateArchived, "system", "已存在待审核单,本条归档处理", mid, property); err != nil {
return errors.Wrapf(err, "dao archive property review")
}
return nil
}

View File

@@ -0,0 +1,76 @@
package dao
import (
"context"
"testing"
"go-common/app/service/main/member/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoAddUserMonitor(t *testing.T) {
var (
c = context.TODO()
mid = int64(1)
operator = "zhoujiahui"
remark = "test"
)
convey.Convey("AddUserMonitor", t, func(ctx convey.C) {
p1 := d.AddUserMonitor(c, mid, operator, remark)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoIsInUserMonitor(t *testing.T) {
var (
c = context.TODO()
mid = int64(1)
)
convey.Convey("IsInUserMonitor", t, func(ctx convey.C) {
p1, p2 := d.IsInUserMonitor(c, mid)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p2, convey.ShouldBeNil)
})
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoAddPropertyReview(t *testing.T) {
var (
c = context.TODO()
r = &model.UserPropertyReview{
Mid: 2231365,
Old: "hahhah",
New: "dangerou",
State: model.ReviewStateWait,
Property: model.ReviewPropertySign,
IsMonitor: true,
Extra: "{}",
}
)
convey.Convey("AddPropertyReview", t, func(ctx convey.C) {
p1 := d.AddPropertyReview(c, r)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}
func TestDaoArchivePropertyReview(t *testing.T) {
var (
c = context.TODO()
mid = int64(3)
property = int8(1)
)
convey.Convey("ArchivePropertyReview", t, func(ctx convey.C) {
p1 := d.ArchivePropertyReview(c, mid, property)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,40 @@
package dao
import (
"context"
"fmt"
"net/url"
"go-common/library/ecode"
"go-common/library/log"
)
// http client
const (
smsURL = "http://api.bilibili.co/x/internal/sms/send"
)
// SendCapture is
func (d *Dao) SendCapture(c context.Context, mid int64, code int) (err error) {
var (
params = url.Values{}
)
params.Set("mid", fmt.Sprintf("%d", mid))
params.Set("tcode", "acc_01")
params.Set("tparam", fmt.Sprintf(`{"identify_code":"%d"}`, code))
var resp struct {
Code int `json:"code"`
}
for i := 0; i < 3; i++ {
err = d.client.Post(c, smsURL, "", params, &resp)
if err != nil || resp.Code != 0 {
log.Error("d.client.Post(%s,%+v) resp.Code(%d)", smsURL, params, resp.Code)
err = ecode.RealnameCaptureErr
} else {
break
}
}
return
}

View File

@@ -0,0 +1,22 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSendCapture(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
code = int(0)
)
convey.Convey("SendCapture", t, func(ctx convey.C) {
err := d.SendCapture(c, mid, code)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, 74001)
})
})
}

View File

@@ -0,0 +1,64 @@
package dao
import (
"context"
"fmt"
"go-common/app/service/main/member/model"
"go-common/library/cache/redis"
)
const (
_expShard = 10000
_expAddedPrefix = "ea_%s_%d_%d"
_expCoinPrefix = "ecoin_%d_%d"
)
const (
_share = "shareClick"
_view = "watch"
_login = "login"
)
func expCoinKey(mid, day int64) string {
return fmt.Sprintf(_expCoinPrefix, day, mid)
}
func expAddedKey(tp string, mid, day int64) string {
return fmt.Sprintf(_expAddedPrefix, tp, day, mid/_expShard)
}
// StatCache get exp stat cache.
func (d *Dao) StatCache(c context.Context, mid, day int64) (st *model.ExpStat, err error) {
conn := d.redis.Get(c)
defer conn.Close()
conn.Send("GETBIT", expAddedKey(_login, mid, day), mid%_expShard)
conn.Send("GETBIT", expAddedKey(_view, mid, day), mid%_expShard)
conn.Send("GETBIT", expAddedKey(_share, mid, day), mid%_expShard)
conn.Send("GET", expCoinKey(mid, day))
err = conn.Flush()
if err != nil {
return
}
st = new(model.ExpStat)
st.Login, err = redis.Bool(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
st.Watch, err = redis.Bool(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
st.Share, err = redis.Bool(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
st.Coin, err = redis.Int64(conn.Receive())
if err != nil && err != redis.ErrNil {
return
}
if err == redis.ErrNil {
err = nil
}
return
}

View File

@@ -0,0 +1,52 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoexpCoinKey(t *testing.T) {
var (
mid = int64(0)
day = int64(0)
)
convey.Convey("expCoinKey", t, func(ctx convey.C) {
p1 := expCoinKey(mid, day)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoexpAddedKey(t *testing.T) {
var (
tp = ""
mid = int64(0)
day = int64(0)
)
convey.Convey("expAddedKey", t, func(ctx convey.C) {
p1 := expAddedKey(tp, mid, day)
ctx.Convey("p1 should not be nil", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoStatCache(t *testing.T) {
var (
c = context.Background()
mid = int64(0)
day = int64(0)
)
convey.Convey("StatCache", t, func(ctx convey.C) {
st, err := d.StatCache(c, mid, day)
ctx.Convey("Error should be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
ctx.Convey("st should not be nil", func(ctx convey.C) {
ctx.So(st, convey.ShouldNotBeNil)
})
})
}