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,63 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"acc_test.go",
"dao_test.go",
"mysql_test.go",
"redis_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/usersuit/conf:go_default_library",
"//app/service/main/usersuit/model:go_default_library",
"//vendor/github.com/satori/go.uuid: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 = [
"acc.go",
"dao.go",
"mysql.go",
"redis.go",
],
importpath = "go-common/app/service/main/usersuit/dao/invite",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/usersuit/conf:go_default_library",
"//app/service/main/usersuit/model: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",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,42 @@
package dao
import (
"context"
"net/url"
"strconv"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_accErrWasFormal = -659
)
// BeFormal be formal member.
func (d *Dao) BeFormal(c context.Context, mid int64, cookie, ip string) (err error) {
params := url.Values{}
params.Set("Cookie", cookie)
params.Set("mid", strconv.FormatInt(mid, 10))
// request
req, err := d.httpClient.NewRequest("POST", d.beFormalURI, ip, params)
if err != nil {
log.Error("account beformal uri(%s) error(%v)", d.beFormalURI+params.Encode(), err)
return
}
req.Header.Set("Cookie", cookie)
var res struct {
Code int `json:"code"`
}
if err = d.httpClient.Do(c, req, &res); err != nil {
return
}
if res.Code != 0 {
if res.Code == _accErrWasFormal {
return
}
err = ecode.Int(res.Code)
log.Error("account beformal uri(%s) error(%v)", d.beFormalURI+params.Encode(), err)
}
return
}

View File

@@ -0,0 +1,26 @@
package dao
import (
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestDaoBeFormal(t *testing.T) {
convey.Convey("BeFormal", t, func(ctx convey.C) {
var (
mid = int64(88888970)
cookie = "fts=1532412723; buvid3=9FE379B1-4742-4414-83BC-070DC6D5C30128620infoc; rpdid=oxlilxsoqdoskipoimqw; UM_distinctid=164cb9399eb124-053863286996f2-163b6952-1fa400-164cb9399ec15e; LIVE_BUVID=dfbc64db5d227b750394fc08dc27ad5e; LIVE_BUVID__ckMd5=612509d11892d4bd; im_notify_type_27956255=0; sid=66taifil; im_local_unread_27956255=0; im_seqno_27956255=4; CNZZDATA2724999=cnzz_eid%3D937547062-1534212022-%26ntime%3D1534212022; pgv_pvi=1353490432; finger=14bc3c4e; DedeUserID=27956255; DedeUserID__ckMd5=2dfe07340adf4bc9; SESSDATA=3f325bec%2C1538121389%2Cb8e04f4a; bili_jct=008e9de4d371cf91f089a66b77e1d8d7; PHPSESSID=3btocfs7f8mo3u8cpkhfv155e0; bp_t_offset_27956255=157578003585063279; _dfcaptcha=aa24be76e8c462474766bc1f4db916a0"
ip = "127.0.0.1"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer gock.OffAll()
httpMock("POST", d.beFormalURI).Reply(0).JSON(`{"code":0}`)
err := d.BeFormal(c, mid, cookie, ip)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,58 @@
package dao
import (
"context"
"time"
"go-common/app/service/main/usersuit/conf"
"go-common/library/cache/redis"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
const (
_beFormal = "/api/member/beFormal"
)
// Dao struct answer history of Dao
type Dao struct {
db *sql.DB
redis *redis.Pool
//http
httpClient *bm.Client
c *conf.Config
beFormalURI string
inviteExpire int32
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.MySQL),
redis: redis.NewPool(c.Redis.Config),
inviteExpire: int32(time.Duration(c.Redis.InviteExpire) / time.Second),
httpClient: bm.NewClient(c.HTTPClient),
beFormalURI: c.AccountIntranetURI + _beFormal,
}
return
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
d.db.Close()
d.redis.Close()
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
log.Error("dao.db.Ping() error(%v)", err)
return
}
if err = d.pingRedis(c); err != nil {
log.Error("dao.pingRedis() error(%v)", err)
}
return
}

View File

@@ -0,0 +1,47 @@
package dao
import (
"context"
"flag"
"os"
"strings"
"testing"
"go-common/app/service/main/usersuit/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
c = context.Background()
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.usersuit-service")
flag.Set("conf_token", "BVWgBtBvS2pkTBbmxAl0frX6KRA14d5P")
flag.Set("tree_id", "6813")
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/convey-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,88 @@
package dao
import (
"context"
"database/sql"
"time"
"go-common/app/service/main/usersuit/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
)
const (
_addInviteSQL = "INSERT INTO invite_code(mid,code,buy_ip,buy_ip_ng,expires,ctime) VALUES(?,?,?,?,?,?)"
_updateInviteSQL = "UPDATE invite_code SET imid=?,used_at=? WHERE code=?"
_getInviteSQL = "SELECT mid,imid,code,expires,used_at,ctime FROM invite_code WHERE code=?"
_getInvitesSQL = "SELECT mid,imid,code,expires,used_at,ctime FROM invite_code WHERE mid=?"
_getCurrentCountSQL = "SELECT count(1) FROM invite_code WHERE mid=? AND ctime>=? AND ctime<=?"
)
// Begin begin transaction
func (d *Dao) Begin(c context.Context) (tx *xsql.Tx, err error) {
return d.db.Begin(c)
}
// TxAddInvite transaction invite
func (d *Dao) TxAddInvite(c context.Context, tx *xsql.Tx, inv *model.Invite) (affected int64, err error) {
var res sql.Result
if res, err = tx.Exec(_addInviteSQL, inv.Mid, inv.Code, inv.IP, inv.IPng, inv.Expires, inv.Ctime); err != nil {
log.Error("add invite, dao.db.Exec(%d, %s, %d, %v, %d, %v) error(%v)", inv.Mid, inv.Code, inv.IP, inv.IPng, inv.Expires, inv.Ctime, err)
return
}
return res.RowsAffected()
}
// UpdateInvite update invite
func (d *Dao) UpdateInvite(c context.Context, imid int64, usedAt int64, code string) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateInviteSQL, imid, usedAt, code); err != nil {
log.Error("update invite, dao.db.Exec(%d, %d, %s) error(%v)", imid, usedAt, code, err)
return
}
return res.RowsAffected()
}
// Invite invite info
func (d *Dao) Invite(c context.Context, code string) (res *model.Invite, err error) {
row := d.db.QueryRow(c, _getInviteSQL, code)
res = new(model.Invite)
if err = row.Scan(&res.Mid, &res.Imid, &res.Code, &res.Expires, &res.UsedAt, &res.Ctime); err != nil {
if err == sql.ErrNoRows {
res = nil
err = nil
} else {
log.Error("get invite, row.Scan() error(%v)", err)
}
}
return
}
// Invites invite list
func (d *Dao) Invites(c context.Context, mid int64) (res []*model.Invite, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, _getInvitesSQL, mid); err != nil {
log.Error("get invites, dao.db.Query(%d) error(%v)", mid, err)
return
}
defer rows.Close()
for rows.Next() {
inv := new(model.Invite)
if err = rows.Scan(&inv.Mid, &inv.Imid, &inv.Code, &inv.Expires, &inv.UsedAt, &inv.Ctime); err != nil {
log.Error("row.Scan() error(%v)", err)
return
}
res = append(res, inv)
}
err = rows.Err()
return
}
// CurrentCount current count
func (d *Dao) CurrentCount(c context.Context, mid int64, start, end time.Time) (res int64, err error) {
row := d.db.QueryRow(c, _getCurrentCountSQL, mid, start, end)
if err = row.Scan(&res); err != nil {
log.Error("get current count, mid: %d, start: %d, end: %d, row.Scan() error(%v)", mid, start, end, err)
}
return
}

View File

@@ -0,0 +1,107 @@
package dao
import (
"testing"
"time"
"go-common/app/service/main/usersuit/model"
"github.com/satori/go.uuid"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoBegin(t *testing.T) {
convey.Convey("Begin", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
tx, err := d.Begin(c)
ctx.Convey("Then err should be nil.tx should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(tx, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoTxAddInvite(t *testing.T) {
convey.Convey("TxAddInvite", t, func(ctx convey.C) {
var (
tx, _ = d.Begin(c)
inv = &model.Invite{
Mid: 1,
IPng: []byte{1, 1, 1, 1},
Code: uuid.NewV4().String(),
}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affected, err := d.TxAddInvite(c, tx, inv)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoUpdateInvite(t *testing.T) {
convey.Convey("UpdateInvite", t, func(ctx convey.C) {
var (
imid = int64(0)
usedAt = int64(0)
code = "2bbf90926c984a53"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
affected, err := d.UpdateInvite(c, imid, usedAt, code)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoInvite(t *testing.T) {
convey.Convey("Invite", t, func(ctx convey.C) {
var (
code = "2bbf90926c984a53"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Invite(c, code)
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)
})
})
})
}
func TestDaoInvites(t *testing.T) {
convey.Convey("Invites", t, func(ctx convey.C) {
var (
mid = int64(88888970)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Invites(c, 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)
})
})
})
}
func TestDaoCurrentCount(t *testing.T) {
convey.Convey("CurrentCount", t, func(ctx convey.C) {
var (
mid = int64(0)
start = time.Now()
end = time.Now()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.CurrentCount(c, mid, start, end)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,86 @@
package dao
import (
"context"
"strconv"
"go-common/library/cache/redis"
"go-common/library/log"
)
const (
_prefixBuyFlag = "b_"
_prefixApplyFlag = "a_"
)
func keyBuyFlag(mid int64) string {
return _prefixBuyFlag + strconv.FormatInt(mid, 10)
}
func keyApplyFlag(code string) string {
return _prefixApplyFlag + code
}
// pingRedis ping redis.
func (d *Dao) pingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
defer conn.Close()
if _, err = redis.String(conn.Do("PING")); err != nil {
log.Error("redis.String(conn.Do(PING)) error(%v)", err)
}
return
}
// SetBuyFlagCache set buy flag cache
func (d *Dao) SetBuyFlagCache(c context.Context, mid int64, f string) (ok bool, err error) {
key := keyBuyFlag(mid)
conn := d.redis.Get(c)
defer conn.Close()
var res interface{}
if res, err = conn.Do("SET", key, f, "EX", d.inviteExpire, "NX"); err != nil {
log.Error("conn.Do(SET, %s, %s, EX, %d, NX)", key, f)
return
}
if res != nil {
ok = true
}
return
}
// DelBuyFlagCache del buy flag cache
func (d *Dao) DelBuyFlagCache(c context.Context, mid int64) (err error) {
key := keyBuyFlag(mid)
conn := d.redis.Get(c)
defer conn.Close()
if _, err = conn.Do("DEL", key); err != nil {
log.Error("conn.Do(DEL, %s)", key)
}
return
}
// SetApplyFlagCache set apply flag cache
func (d *Dao) SetApplyFlagCache(c context.Context, code, f string) (ok bool, err error) {
key := keyApplyFlag(code)
conn := d.redis.Get(c)
defer conn.Close()
var res interface{}
if res, err = conn.Do("SET", key, f, "EX", d.inviteExpire, "NX"); err != nil {
log.Error("conn.Do(SET, %s, %s, EX, %d, NX)", key, f, d.inviteExpire)
return
}
if res != nil {
ok = true
}
return
}
// DelApplyFlagCache del apply Flag Cache
func (d *Dao) DelApplyFlagCache(c context.Context, code string) (err error) {
key := keyApplyFlag(code)
conn := d.redis.Get(c)
defer conn.Close()
if _, err = conn.Do("DEL", key); err != nil {
log.Error("conn.Do(DEL, %s)", key)
}
return
}

View File

@@ -0,0 +1,106 @@
package dao
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaokeyBuyFlag(t *testing.T) {
convey.Convey("keyBuyFlag", t, func(ctx convey.C) {
var (
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyBuyFlag(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaokeyApplyFlag(t *testing.T) {
convey.Convey("keyApplyFlag", t, func(ctx convey.C) {
var (
code = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyApplyFlag(code)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestDaopingRedis(t *testing.T) {
convey.Convey("pingRedis", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.pingRedis(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetBuyFlagCache(t *testing.T) {
convey.Convey("SetBuyFlagCache", t, func(ctx convey.C) {
var (
mid = int64(0)
f = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
ok, err := d.SetBuyFlagCache(c, mid, f)
ctx.Convey("Then err should be nil.ok should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ok, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDelBuyFlagCache(t *testing.T) {
convey.Convey("DelBuyFlagCache", t, func(ctx convey.C) {
var (
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelBuyFlagCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoSetApplyFlagCache(t *testing.T) {
convey.Convey("SetApplyFlagCache", t, func(ctx convey.C) {
var (
code = ""
f = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
ok, err := d.SetApplyFlagCache(c, code, f)
ctx.Convey("Then err should be nil.ok should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ok, convey.ShouldNotBeNil)
})
})
})
}
func TestDaoDelApplyFlagCache(t *testing.T) {
convey.Convey("DelApplyFlagCache", t, func(ctx convey.C) {
var (
code = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelApplyFlagCache(c, code)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,67 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"depend_test.go",
"localcache_test.go",
"memcache_test.go",
"mysql_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/usersuit/conf:go_default_library",
"//app/service/main/usersuit/model: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",
"depend.go",
"localcache.go",
"memcache.go",
"mysql.go",
],
importmap = "go-common/app/service/main/usersuit/dao/medal",
importpath = "go-common/app/service/main/usersuit/dao/medal",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/usersuit/conf:go_default_library",
"//app/service/main/usersuit/model:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/stat/prom:go_default_library",
"//vendor/github.com/bluele/gcache:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,68 @@
package medal
import (
"context"
"time"
"go-common/app/service/main/usersuit/conf"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
"github.com/bluele/gcache"
)
const (
_sendMsgPath = "/api/notify/send.user.notify.do"
_getWaredFansMedalPath = "/fans_medal/v1/fans_medal/get_weared_medal"
)
// Dao struct info of Dao.
type Dao struct {
db *sql.DB
c *conf.Config
client *bm.Client
// memcache
mc *memcache.Pool
mcExpire int32
pointExpire int32
// send message URI.
sendMsgURI string
// get weared fans medal URI.
getWaredFansMedalURI string
// medalStore
medalStore gcache.Cache
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.MySQL),
client: bm.NewClient(c.HTTPClient),
// memcache
mc: memcache.NewPool(c.Memcache.Config),
mcExpire: int32(time.Duration(c.Memcache.MedalExpire) / time.Second),
pointExpire: int32(time.Duration(c.Memcache.PointExpire) / time.Second),
sendMsgURI: c.Host.MessageCo + _sendMsgPath,
getWaredFansMedalURI: c.Host.LiveAPICo + _getWaredFansMedalPath,
medalStore: gcache.New(c.MedalCache.Size).LFU().Build(),
}
return
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) (err error) {
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()
}
}

View File

@@ -0,0 +1,47 @@
package medal
import (
"context"
"flag"
"os"
"testing"
"go-common/app/service/main/usersuit/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
c = context.Background()
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.usersuit-service")
flag.Set("conf_token", "BVWgBtBvS2pkTBbmxAl0frX6KRA14d5P")
flag.Set("tree_id", "6813")
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/convey-test.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)
}
// func httpMock(method, url string) *gock.Request {
// r := gock.New(url)
// r.Method = strings.ToUpper(method)
// return r
// }

View File

@@ -0,0 +1,66 @@
package medal
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/library/log"
)
// SendMsg send message.
func (d *Dao) SendMsg(c context.Context, mid int64, title string, context string) (err error) {
params := url.Values{}
params.Set("mc", "2_1_13")
params.Set("title", title)
params.Set("data_type", "4")
params.Set("context", context)
params.Set("mid_list", fmt.Sprintf("%d", mid))
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.sendMsgURI, "", params, &res); err != nil {
log.Error("sendMsgURL(%s) error(%v)", d.sendMsgURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("sendMsgURL(%s) res(%d)", d.sendMsgURI+"?"+params.Encode(), res.Code)
}
log.Info("d.sendMsgURL url(%s) res(%d)", d.sendMsgURI+"?"+params.Encode(), res.Code)
return
}
// GetWearedfansMedal get weared fans medals from live.
func (d *Dao) GetWearedfansMedal(c context.Context, mid int64, source int8) (isLove bool, err error) {
params := url.Values{}
params.Set("uid", strconv.FormatInt(mid, 10))
params.Set("source", strconv.FormatInt(int64(source), 10))
var res struct {
Code int `json:"code"`
Data *struct {
Max int8 `json:"max"`
Cnt int8 `json:"cnt"`
MasterMax int8 `json:"master_max"`
} `json:"data"`
}
if err = d.client.Post(c, d.getWaredFansMedalURI, "", params, &res); err != nil {
log.Error("GetWearedfansMedal(%s) error(%v)", d.getWaredFansMedalURI+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("GetWearedfansMedal(%s) res(%d)", d.getWaredFansMedalURI+"?"+params.Encode(), res.Code)
}
log.Info("GetWearedfansMedal(%s) res(%+v)", d.getWaredFansMedalURI+"?"+params.Encode(), res)
if res.Code == 0 {
if res.Data.Cnt > 0 {
isLove = true
return
}
}
return
}

View File

@@ -0,0 +1,39 @@
package medal
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestMedalSendMsg(t *testing.T) {
convey.Convey("SendMsg", t, func(ctx convey.C) {
var (
mid = int64(88889017)
title = ""
context = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SendMsg(c, mid, title, context)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalGetWearedfansMedal(t *testing.T) {
convey.Convey("GetWearedfansMedal", t, func(ctx convey.C) {
var (
mid = int64(88889017)
source = int8(2)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
isLove, err := d.GetWearedfansMedal(c, mid, source)
ctx.Convey("Then err should be nil.isLove should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(isLove, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,84 @@
package medal
import (
"context"
"time"
"go-common/library/log"
"go-common/library/stat/prom"
"github.com/bluele/gcache"
"github.com/pkg/errors"
)
func (d *Dao) loadMedal(c context.Context, mid int64) (int64, bool, error) {
nid, nofound, err := d.medalActivatedCache(c, mid)
if err != nil {
return 0, nofound, err
}
d.storeMedal(mid, nid, nofound)
return nid, nofound, nil
}
func (d *Dao) storeMedal(mid int64, nid int64, nofound bool) {
if nofound {
return
}
d.medalStore.SetWithExpire(mid, nid, time.Duration(d.c.MedalCache.Expire))
}
func (d *Dao) localMedal(mid int64) (int64, error) {
prom.CacheHit.Incr("local_medal_cache")
item, err := d.medalStore.Get(mid)
if err != nil {
prom.CacheMiss.Incr("local_medal_cache")
return 0, err
}
nid, ok := item.(int64)
if !ok {
prom.CacheMiss.Incr("local_medal_cache")
return 0, errors.New("Not a medal")
}
return nid, nil
}
// MedalActivatedCache get medal cache.
func (d *Dao) MedalActivatedCache(c context.Context, mid int64) (int64, bool, error) {
nid, err := d.localMedal(mid)
if err != nil {
if err != gcache.KeyNotFoundError {
log.Error("Failed to get medal from local: mid: %d: %+v", mid, err)
}
return d.loadMedal(c, mid)
}
return nid, false, nil
}
// MedalsActivatedCache get multi medals cache.
func (d *Dao) MedalsActivatedCache(c context.Context, mids []int64) (map[int64]int64, []int64, error) {
nids := make(map[int64]int64, len(mids))
lcMissed := make([]int64, 0, len(mids))
for _, mid := range mids {
nid, err := d.localMedal(mid)
if err != nil {
if err != gcache.KeyNotFoundError {
log.Error("Failed to get medal from local: mid: %d: %+v", mid, err)
}
lcMissed = append(lcMissed, mid)
continue
}
nids[mid] = nid
}
if len(lcMissed) == 0 {
return nids, nil, nil
}
mcMedals, mcMissed, err := d.medalsActivatedCache(c, lcMissed)
if err != nil {
return nil, nil, err
}
for mid, nid := range mcMedals {
d.storeMedal(mid, nid, false)
nids[mid] = nid
}
return nids, mcMissed, nil
}

View File

@@ -0,0 +1,85 @@
package medal
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestMedalloadMedal(t *testing.T) {
convey.Convey("loadMedal", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, p2, err := d.loadMedal(c, mid)
ctx.Convey("Then err should be nil.p1,p2 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p2, convey.ShouldNotBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalstoreMedal(t *testing.T) {
convey.Convey("storeMedal", t, func(ctx convey.C) {
var (
mid = int64(88889017)
nid = int64(1)
nofound bool
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.storeMedal(mid, nid, nofound)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestMedallocalMedal(t *testing.T) {
convey.Convey("localMedal", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, err := d.localMedal(mid)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalMedalActivatedCache(t *testing.T) {
convey.Convey("MedalActivatedCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, p2, err := d.MedalActivatedCache(c, mid)
ctx.Convey("Then err should be nil.p1,p2 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p2, convey.ShouldNotBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalMedalsActivatedCache(t *testing.T) {
convey.Convey("MedalsActivatedCache", t, func(ctx convey.C) {
var (
mids = []int64{88889017, 1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, p2, err := d.MedalsActivatedCache(c, mids)
ctx.Convey("Then err should be nil.p1,p2 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
ctx.So(p2, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,273 @@
package medal
import (
"context"
"strconv"
"github.com/pkg/errors"
"go-common/app/service/main/usersuit/model"
gmc "go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_prefixActivatedNid = "usma:" // key of activated medal nid
_prefixOwners = "umos:" // key of owners info
_prefixRedPoint = "usrp:" // key of red point
_prefixPopup = "uspp:" // key of new medal popup
)
// medalactivated medal nid key.
func activatedNidKey(mid int64) string {
return _prefixActivatedNid + strconv.FormatInt(mid, 10)
}
// ownersKey medal_owner key.
func ownersKey(mid int64) string {
return _prefixOwners + strconv.FormatInt(mid, 10)
}
//RedPointKey new medal RedPoint key.
func RedPointKey(mid int64) string {
return _prefixRedPoint + strconv.FormatInt(mid, 10)
}
// PopupKey new medal popup key.
func PopupKey(mid int64) string {
return _prefixPopup + strconv.FormatInt(mid, 10)
}
func (d *Dao) pingMC(c context.Context) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&gmc.Item{Key: "ping", Value: []byte{1}, Expiration: d.mcExpire}); err != nil {
err = errors.WithStack(err)
}
return
}
// MedalOwnersCache get medal_owner cache.
func (d *Dao) MedalOwnersCache(c context.Context, mid int64) (res []*model.MedalOwner, notFound bool, err error) {
conn := d.mc.Get(c)
defer conn.Close()
item, err := conn.Get(ownersKey(mid))
if err != nil {
if err == gmc.ErrNotFound {
res = nil
err = nil
notFound = true
return
}
err = errors.WithStack(err)
return
}
res = make([]*model.MedalOwner, 0)
if err = conn.Scan(item, &res); err != nil {
err = errors.WithStack(err)
}
return
}
// SetMedalOwnersache set medal_owner cache.
func (d *Dao) SetMedalOwnersache(c context.Context, mid int64, nos []*model.MedalOwner) (err error) {
key := ownersKey(mid)
item := &gmc.Item{Key: key, Object: nos, Expiration: d.mcExpire, Flags: gmc.FlagJSON}
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(item); err != nil {
err = errors.WithStack(err)
}
return
}
// DelMedalOwnersCache delete medal_owner cache.
func (d *Dao) DelMedalOwnersCache(c context.Context, mid int64) (err error) {
key := ownersKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == gmc.ErrNotFound {
err = nil
} else {
err = errors.WithStack(err)
}
}
return
}
// MedalsActivatedCache multi get user activated medal nid from memcache.
func (d *Dao) medalsActivatedCache(c context.Context, mids []int64) (nids map[int64]int64, missed []int64, err error) {
nids = make(map[int64]int64, len(mids))
keys := make([]string, len(mids))
mm := make(map[string]int64, len(mids))
for i, mid := range mids {
var key = activatedNidKey(mid)
keys[i] = key
mm[key] = mid
}
conn := d.mc.Get(c)
defer conn.Close()
items, err := conn.GetMulti(keys)
if err != nil {
if err == gmc.ErrNotFound {
err = nil
}
return
}
for _, item := range items {
var nid int64
if err = conn.Scan(item, &nid); err != nil {
log.Error("conn.Scan(%s) error(%v)", item.Value, err)
continue
}
nids[mm[item.Key]] = nid
delete(mm, item.Key)
}
missed = make([]int64, 0, len(mm))
for _, m := range mm {
missed = append(missed, m)
}
return
}
// MedalActivatedCache get user activated medal nid.
func (d *Dao) medalActivatedCache(c context.Context, mid int64) (nid int64, notFound bool, err error) {
conn := d.mc.Get(c)
defer conn.Close()
item, err := conn.Get(activatedNidKey(mid))
if err != nil {
if err == gmc.ErrNotFound {
nid = 0
err = nil
notFound = true
return
}
err = errors.WithStack(err)
return
}
if err = conn.Scan(item, &nid); err != nil {
err = errors.WithStack(err)
}
return
}
// SetMedalActivatedCache set activated medal cache.
func (d *Dao) SetMedalActivatedCache(c context.Context, mid, nid int64) (err error) {
key := activatedNidKey(mid)
item := &gmc.Item{Key: key, Object: nid, Expiration: d.mcExpire, Flags: gmc.FlagJSON}
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(item); err != nil {
err = errors.WithStack(err)
}
return
}
// DelMedalActivatedCache delete activated medal cache.
func (d *Dao) DelMedalActivatedCache(c context.Context, mid int64) (err error) {
key := activatedNidKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == gmc.ErrNotFound {
err = nil
} else {
err = errors.WithStack(err)
}
}
return
}
// PopupCache get new medal info popup cache.
func (d *Dao) PopupCache(c context.Context, mid int64) (nid int64, err error) {
conn := d.mc.Get(c)
defer conn.Close()
item, err := conn.Get(PopupKey(mid))
if err != nil {
if err == gmc.ErrNotFound {
nid = 0
err = nil
return
}
err = errors.WithStack(err)
return
}
if err = conn.Scan(item, &nid); err != nil {
err = errors.WithStack(err)
}
return
}
// SetPopupCache set popup cache.
func (d *Dao) SetPopupCache(c context.Context, mid, nid int64) (err error) {
key := PopupKey(mid)
item := &gmc.Item{Key: key, Object: nid, Expiration: d.pointExpire, Flags: gmc.FlagJSON}
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(item); err != nil {
err = errors.WithStack(err)
}
return
}
// DelPopupCache delete new medal info popup cache.
func (d *Dao) DelPopupCache(c context.Context, mid int64) (err error) {
key := PopupKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == gmc.ErrNotFound {
err = nil
} else {
err = errors.WithStack(err)
}
}
return
}
// RedPointCache get new medal info red point cache.
func (d *Dao) RedPointCache(c context.Context, mid int64) (nid int64, err error) {
conn := d.mc.Get(c)
defer conn.Close()
item, err := conn.Get(RedPointKey(mid))
if err != nil {
if err == gmc.ErrNotFound {
err = nil
return
}
err = errors.WithStack(err)
return
}
if err = conn.Scan(item, &nid); err != nil {
err = errors.WithStack(err)
}
return
}
// SetRedPointCache set red point cache.
func (d *Dao) SetRedPointCache(c context.Context, mid, nid int64) (err error) {
key := RedPointKey(mid)
item := &gmc.Item{Key: key, Object: nid, Expiration: d.pointExpire, Flags: gmc.FlagJSON}
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(item); err != nil {
err = errors.WithStack(err)
}
return
}
// DelRedPointCache delete new medal info red point cache.
func (d *Dao) DelRedPointCache(c context.Context, mid int64) (err error) {
key := RedPointKey(mid)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(key); err != nil {
if err == gmc.ErrNotFound {
err = nil
} else {
err = errors.WithStack(err)
}
}
return
}

View File

@@ -0,0 +1,271 @@
package medal
import (
"go-common/app/service/main/usersuit/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestMedalactivatedNidKey(t *testing.T) {
convey.Convey("activatedNidKey", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := activatedNidKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalownersKey(t *testing.T) {
convey.Convey("ownersKey", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := ownersKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalRedPointKey(t *testing.T) {
convey.Convey("RedPointKey", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := RedPointKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalPopupKey(t *testing.T) {
convey.Convey("PopupKey", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := PopupKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalpingMC(t *testing.T) {
convey.Convey("pingMC", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.pingMC(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalSetMedalOwnersache(t *testing.T) {
convey.Convey("SetMedalOwnersache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
nos = []*model.MedalOwner{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetMedalOwnersache(c, mid, nos)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalMedalOwnersCache(t *testing.T) {
convey.Convey("MedalOwnersCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
nos = []*model.MedalOwner{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.SetMedalOwnersache(c, mid, nos)
res, notFound, err := d.MedalOwnersCache(c, mid)
ctx.Convey("Then err should be nil.res,notFound should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(notFound, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalDelMedalOwnersCache(t *testing.T) {
convey.Convey("DelMedalOwnersCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelMedalOwnersCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalmedalsActivatedCache(t *testing.T) {
convey.Convey("medalsActivatedCache", t, func(ctx convey.C) {
var (
mids = []int64{88889017}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
nids, missed, err := d.medalsActivatedCache(c, mids)
ctx.Convey("Then err should be nil.nids,missed should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(missed, convey.ShouldNotBeNil)
ctx.So(nids, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalSetMedalActivatedCache(t *testing.T) {
convey.Convey("SetMedalActivatedCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
nid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetMedalActivatedCache(c, mid, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalmedalActivatedCache(t *testing.T) {
convey.Convey("medalActivatedCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
nid, notFound, err := d.medalActivatedCache(c, mid)
ctx.Convey("Then err should be nil.nid,notFound should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(notFound, convey.ShouldNotBeNil)
ctx.So(nid, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalDelMedalActivatedCache(t *testing.T) {
convey.Convey("DelMedalActivatedCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelMedalActivatedCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalPopupCache(t *testing.T) {
convey.Convey("PopupCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
nid, err := d.PopupCache(c, mid)
ctx.Convey("Then err should be nil.nid should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(nid, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalSetPopupCache(t *testing.T) {
convey.Convey("SetPopupCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
nid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetPopupCache(c, mid, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalDelPopupCache(t *testing.T) {
convey.Convey("DelPopupCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelPopupCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalRedPointCache(t *testing.T) {
convey.Convey("RedPointCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
nid, err := d.RedPointCache(c, mid)
ctx.Convey("Then err should be nil.nid should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(nid, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalSetRedPointCache(t *testing.T) {
convey.Convey("SetRedPointCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
nid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetRedPointCache(c, mid, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalDelRedPointCache(t *testing.T) {
convey.Convey("DelRedPointCache", t, func(ctx convey.C) {
var (
mid = int64(88889017)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelRedPointCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,181 @@
package medal
import (
"context"
"fmt"
"go-common/app/service/main/usersuit/model"
"go-common/library/database/sql"
"github.com/pkg/errors"
)
const (
_sharding = 10
_insOwnerSQL = "INSERT INTO medal_owner_%s(mid,nid) VALUES (?,?)"
_updateOwnerSQL = "UPDATE medal_owner_%s SET is_activated=? WHERE mid=? AND nid=?"
_updateOwnerUnallSQL = "UPDATE medal_owner_%s SET is_activated=0 WHERE mid=? AND nid!=?"
_selInfoAllSQL = "SELECT id,name,description,image,image_small,cond,gid,level,level_rank,sort FROM medal_info ORDER BY sort ASC,gid ASC,level ASC"
_selOwnerByMidSQL = "SELECT id,mid,nid,is_activated,ctime,mtime FROM medal_owner_%s WHERE mid=? AND is_del=0 ORDER BY ctime DESC"
_selInfoByNidSQL = "SELECT name FROM medal_info WHERE id=? AND is_online=1"
_selInstalledOwnerBYMidSQL = "SELECT nid FROM medal_owner_%s WHERE mid=? AND is_activated=1 AND is_del=0 LIMIT 1"
_countOwnerBYNidMidSQL = "SELECT COUNT(*) FROM medal_owner_%s WHERE mid=? AND nid=?"
_OwnerBYNidMidSQL = "SELECT id,mid,nid,is_activated,ctime,mtime FROM medal_owner_%s WHERE mid=? AND nid=?"
_selGroupAllSQL = "SELECT id,name,pid,rank FROM medal_group WHERE is_online=1 ORDER BY pid ASC,rank ASC"
)
func (d *Dao) hit(id int64) string {
return fmt.Sprintf("%d", id%_sharding)
}
// AddMedalOwner insert into medal_owner.
func (d *Dao) AddMedalOwner(c context.Context, mid, nid int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_insOwnerSQL, d.hit(mid)), mid, nid); err != nil {
err = errors.WithStack(err)
}
return
}
// InstallMedalOwner update medal_owner set is_activated=1.
func (d *Dao) InstallMedalOwner(c context.Context, mid, nid int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_updateOwnerSQL, d.hit(mid)), model.OwnerInstall, mid, nid); err != nil {
err = errors.WithStack(err)
}
return
}
// UninstallMedalOwner update medal_owner set is_activated=0.
func (d *Dao) UninstallMedalOwner(c context.Context, mid, nid int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_updateOwnerSQL, d.hit(mid)), model.OwnerUninstall, mid, nid); err != nil {
err = errors.WithStack(err)
}
return
}
// UninstallAllMedalOwner uninst all medal_owner set is_activated=0.
func (d *Dao) UninstallAllMedalOwner(c context.Context, mid, nid int64) (err error) {
if _, err = d.db.Exec(c, fmt.Sprintf(_updateOwnerUnallSQL, d.hit(mid)), mid, nid); err != nil {
err = errors.WithStack(err)
}
return
}
// MedalInfoAll retun all medal_info where is_online=1.
func (d *Dao) MedalInfoAll(c context.Context) (res map[int64]*model.MedalInfo, err error) {
res = make(map[int64]*model.MedalInfo)
rows, err := d.db.Query(c, _selInfoAllSQL)
if err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
info := new(model.MedalInfo)
if err = rows.Scan(&info.ID, &info.Name, &info.Description, &info.Image, &info.ImageSmall, &info.Condition, &info.GID, &info.Level, &info.LevelRank, &info.Sort); err != nil {
err = errors.WithStack(err)
return
}
info.Build()
res[info.ID] = info
}
err = rows.Err()
return
}
// MedalOwnerByMid return medal_owner by mid.
func (d *Dao) MedalOwnerByMid(c context.Context, mid int64) (res []*model.MedalOwner, err error) {
res = make([]*model.MedalOwner, 0)
rows, err := d.db.Query(c, fmt.Sprintf(_selOwnerByMidSQL, d.hit(mid)), mid)
if err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.MedalOwner)
if err = rows.Scan(&r.ID, &r.MID, &r.NID, &r.IsActivated, &r.CTime, &r.MTime); err != nil {
err = errors.WithStack(err)
return
}
res = append(res, r)
}
err = rows.Err()
return
}
// MedalInfoByNid return medal_info by nid.
func (d *Dao) MedalInfoByNid(c context.Context, nid int64) (res *model.MedalInfo, err error) {
res = &model.MedalInfo{}
rows := d.db.QueryRow(c, _selInfoByNidSQL, nid)
if err = rows.Scan(&res.Name); err != nil {
if err != sql.ErrNoRows {
err = errors.Wrap(err, "InstalledOwnerBYMid")
return
}
err = nil
}
return
}
// ActivatedOwnerByMid retun nid of medal_owner by mid where is_activated=1.
func (d *Dao) ActivatedOwnerByMid(c context.Context, mid int64) (nid int64, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_selInstalledOwnerBYMidSQL, d.hit(mid)), mid)
if err = row.Scan(&nid); err != nil {
if err != sql.ErrNoRows {
err = errors.Wrap(err, "InstalledOwnerBYMid")
return
}
err = nil
}
return
}
// CountOwnerBYNidMid retun number of medal_owner by mid and nid.
func (d *Dao) CountOwnerBYNidMid(c context.Context, mid, nid int64) (count int64, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_countOwnerBYNidMidSQL, d.hit(mid)), mid, nid)
if err = row.Scan(&count); err != nil {
if err != sql.ErrNoRows {
err = errors.Wrap(err, "CountOwnerBYNidMid")
return
}
count = 0
err = nil
}
return
}
// OwnerBYNidMid retun medal_owner by mid and nid.
func (d *Dao) OwnerBYNidMid(c context.Context, mid, nid int64) (res *model.MedalOwner, err error) {
res = &model.MedalOwner{}
row := d.db.QueryRow(c, fmt.Sprintf(_OwnerBYNidMidSQL, d.hit(mid)), mid, nid)
if err = row.Scan(&res.ID, &res.MID, &res.NID, &res.IsActivated, &res.CTime, &res.MTime); err != nil {
if err != sql.ErrNoRows {
err = errors.Wrap(err, "OwnerBYNidMid")
return
}
res = nil
err = nil
}
return
}
// MedalGroupAll retun all medal_group where is_online=1.
func (d *Dao) MedalGroupAll(c context.Context) (res []*model.MedalGroup, err error) {
rows, err := d.db.Query(c, _selGroupAllSQL)
if err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
info := new(model.MedalGroup)
if err = rows.Scan(&info.ID, &info.Name, &info.PID, &info.Rank); err != nil {
err = errors.WithStack(err)
return
}
res = append(res, info)
}
err = rows.Err()
return
}

View File

@@ -0,0 +1,183 @@
package medal
import (
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestMedalhit(t *testing.T) {
convey.Convey("hit", t, func(ctx convey.C) {
var (
id = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := d.hit(id)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalAddMedalOwner(t *testing.T) {
convey.Convey("AddMedalOwner", t, func(ctx convey.C) {
var (
mid = time.Now().Unix()
nid = int64(5)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddMedalOwner(c, mid, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalInstallMedalOwner(t *testing.T) {
convey.Convey("InstallMedalOwner", t, func(ctx convey.C) {
var (
mid = int64(0)
nid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.InstallMedalOwner(c, mid, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalUninstallMedalOwner(t *testing.T) {
convey.Convey("UninstallMedalOwner", t, func(ctx convey.C) {
var (
mid = int64(0)
nid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UninstallMedalOwner(c, mid, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalUninstallAllMedalOwner(t *testing.T) {
convey.Convey("UninstallAllMedalOwner", t, func(ctx convey.C) {
var (
mid = int64(0)
nid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.UninstallAllMedalOwner(c, mid, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestMedalMedalInfoAll(t *testing.T) {
convey.Convey("MedalInfoAll", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.MedalInfoAll(c)
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)
})
})
})
}
func TestMedalMedalOwnerByMid(t *testing.T) {
convey.Convey("MedalOwnerByMid", t, func(ctx convey.C) {
var (
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.MedalOwnerByMid(c, 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)
})
})
})
}
func TestMedalMedalInfoByNid(t *testing.T) {
convey.Convey("MedalInfoByNid", t, func(ctx convey.C) {
var (
nid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.MedalInfoByNid(c, nid)
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)
})
})
})
}
func TestMedalActivatedOwnerByMid(t *testing.T) {
convey.Convey("ActivatedOwnerByMid", t, func(ctx convey.C) {
var (
mid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
nid, err := d.ActivatedOwnerByMid(c, mid)
ctx.Convey("Then err should be nil.nid should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(nid, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalCountOwnerBYNidMid(t *testing.T) {
convey.Convey("CountOwnerBYNidMid", t, func(ctx convey.C) {
var (
mid = int64(0)
nid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
count, err := d.CountOwnerBYNidMid(c, mid, nid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
})
}
func TestMedalOwnerBYNidMid(t *testing.T) {
convey.Convey("OwnerBYNidMid", t, func(ctx convey.C) {
var (
mid = int64(32141)
nid = int64(1)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.OwnerBYNidMid(c, mid, nid)
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)
})
})
})
}
func TestMedalMedalGroupAll(t *testing.T) {
convey.Convey("MedalGroupAll", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.MedalGroupAll(c)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,73 @@
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",
"local_equip_test.go",
"memcache_test.go",
"mysql_test.go",
"pay_test.go",
"redis_test.go",
"vip_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/usersuit/conf:go_default_library",
"//app/service/main/usersuit/model: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",
"local_equip.go",
"memcache.go",
"mysql.go",
"pay.go",
"redis.go",
"vip.go",
],
importpath = "go-common/app/service/main/usersuit/dao/pendant",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/usersuit/conf:go_default_library",
"//app/service/main/usersuit/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/stat/prom:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/bluele/gcache:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,79 @@
package pendant
import (
"context"
"time"
"go-common/app/service/main/usersuit/conf"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
"github.com/bluele/gcache"
)
const (
_info = "/internal/v1/user/"
)
// Dao struct info of Dao.
type Dao struct {
db *sql.DB
c *conf.Config
client *bm.Client
// redis
redis *redis.Pool
pendantExpire int32
// memcache
mc *memcache.Pool
pointExpire int32
vipInfoURL string
payURL string
notifyURL string
// equipStore
equipStore gcache.Cache
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.MySQL),
client: bm.NewClient(c.HTTPClient),
// redis
redis: redis.NewPool(c.Redis.Config),
pendantExpire: int32(time.Duration(c.Redis.PendantExpire) / time.Second),
// memcache
mc: memcache.NewPool(c.Memcache.Config),
pointExpire: int32(time.Duration(c.Memcache.PointExpire) / time.Second),
vipInfoURL: c.VipURI + _info,
payURL: c.PayURL,
notifyURL: c.NotifyURL,
equipStore: gcache.New(c.EquipCache.Size).LFU().Build(),
}
return
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) (err error) {
return d.pingRedis(c)
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
if d.redis != nil {
d.redis.Close()
}
if d.db != nil {
d.db.Close()
}
}
func (d *Dao) pingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
_, err = conn.Do("SET", "PING", "PONG")
conn.Close()
return
}

View File

@@ -0,0 +1,48 @@
package pendant
import (
"context"
"flag"
"os"
"strings"
"testing"
"go-common/app/service/main/usersuit/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
c = context.Background()
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.usersuit-service")
flag.Set("conf_token", "BVWgBtBvS2pkTBbmxAl0frX6KRA14d5P")
flag.Set("tree_id", "6813")
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/convey-test.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)
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,85 @@
package pendant
import (
"context"
"time"
"go-common/app/service/main/usersuit/model"
"go-common/library/log"
"go-common/library/stat/prom"
"github.com/bluele/gcache"
"github.com/pkg/errors"
)
func (d *Dao) loadEquip(c context.Context, mid int64) (*model.PendantEquip, error) {
equip, err := d.equipCache(c, mid)
if err != nil {
return nil, err
}
d.storeEquip(mid, equip)
return equip, nil
}
func (d *Dao) storeEquip(mid int64, equip *model.PendantEquip) {
if equip == nil {
return
}
d.equipStore.SetWithExpire(mid, equip, time.Duration(d.c.EquipCache.Expire))
}
func (d *Dao) localEquip(mid int64) (*model.PendantEquip, error) {
prom.CacheHit.Incr("local_equip_cache")
item, err := d.equipStore.Get(mid)
if err != nil {
prom.CacheMiss.Incr("local_equip_cache")
return nil, err
}
equip, ok := item.(*model.PendantEquip)
if !ok {
prom.CacheMiss.Incr("local_equip_cache")
return nil, errors.New("Not a equip")
}
return equip, nil
}
// EquipCache get equip cache.
func (d *Dao) EquipCache(c context.Context, mid int64) (*model.PendantEquip, error) {
equip, err := d.localEquip(mid)
if err != nil {
if err != gcache.KeyNotFoundError {
log.Error("Failed to get equip from local: mid: %d: %+v", mid, err)
}
return d.loadEquip(c, mid)
}
return equip, nil
}
// EquipsCache get multi equip cache.
func (d *Dao) EquipsCache(c context.Context, mids []int64) (map[int64]*model.PendantEquip, []int64, error) {
equips := make(map[int64]*model.PendantEquip, len(mids))
lcMissed := make([]int64, 0, len(mids))
for _, mid := range mids {
equip, err := d.localEquip(mid)
if err != nil {
if err != gcache.KeyNotFoundError {
log.Error("Failed to get equip from local: mid: %d: %+v", mid, err)
}
lcMissed = append(lcMissed, mid)
continue
}
equips[equip.Mid] = equip
}
if len(lcMissed) == 0 {
return equips, nil, nil
}
rdsEquips, rdsMissed, err := d.equipsCache(c, lcMissed)
if err != nil {
return nil, nil, err
}
for _, equip := range rdsEquips {
d.storeEquip(equip.Mid, equip)
equips[equip.Mid] = equip
}
return equips, rdsMissed, nil
}

View File

@@ -0,0 +1,88 @@
package pendant
import (
"go-common/app/service/main/usersuit/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestPendantloadEquip(t *testing.T) {
convey.Convey("loadEquip", t, func(ctx convey.C) {
var (
mid = int64(650454)
info = &model.PendantEquip{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.AddEquipCache(c, mid, info)
p1, err := d.loadEquip(c, mid)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantstoreEquip(t *testing.T) {
convey.Convey("storeEquip", t, func(ctx convey.C) {
var (
mid = int64(650454)
equip = &model.PendantEquip{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.storeEquip(mid, equip)
ctx.Convey("No return values", func(ctx convey.C) {
})
})
})
}
func TestPendantlocalEquip(t *testing.T) {
convey.Convey("localEquip", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, err := d.localEquip(mid)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantEquipCache(t *testing.T) {
convey.Convey("EquipCache", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, err := d.EquipCache(c, mid)
ctx.Convey("Then err should be nil.p1 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantEquipsCache(t *testing.T) {
convey.Convey("EquipsCache", t, func(ctx convey.C) {
var (
mids = []int64{650454, 1}
info = &model.PendantEquip{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
d.AddEquipCache(c, int64(650454), info)
d.AddEquipCache(c, int64(1), info)
p1, p2, err := d.EquipsCache(c, mids)
ctx.Convey("Then err should be nil.p1,p2 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p2, convey.ShouldNotBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,54 @@
package pendant
import (
"context"
"fmt"
gmc "go-common/library/cache/memcache"
)
const (
_prefixRedPointFlag = "r_p_f_%d"
)
func redPointFlagKey(mid int64) string {
return fmt.Sprintf(_prefixRedPointFlag, mid)
}
// RedPointCache get new pendant info red point cache.
func (d *Dao) RedPointCache(c context.Context, mid int64) (pid int64, err error) {
conn := d.mc.Get(c)
defer conn.Close()
item, err := conn.Get(redPointFlagKey(mid))
if err != nil {
if err == gmc.ErrNotFound {
err = nil
}
return
}
err = conn.Scan(item, &pid)
return
}
// SetRedPointCache set red point cache.
func (d *Dao) SetRedPointCache(c context.Context, mid, pid int64) (err error) {
var (
item = &gmc.Item{Key: redPointFlagKey(mid), Object: pid, Expiration: d.pointExpire, Flags: gmc.FlagJSON}
conn = d.mc.Get(c)
)
defer conn.Close()
err = conn.Set(item)
return
}
// DelRedPointCache delete new pendant info red point cache.
func (d *Dao) DelRedPointCache(c context.Context, mid int64) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(redPointFlagKey(mid)); err != nil {
if err == gmc.ErrNotFound {
err = nil
}
}
return
}

View File

@@ -0,0 +1,69 @@
package pendant
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestPendantredPointFlagKey(t *testing.T) {
convey.Convey("redPointFlagKey", t, func(ctx convey.C) {
var (
mid = int64(123)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := redPointFlagKey(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantRedPointCache(t *testing.T) {
convey.Convey("RedPointCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(123)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
pid, err := d.RedPointCache(c, mid)
ctx.Convey("Then err should be nil.pid should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(pid, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantSetRedPointCache(t *testing.T) {
convey.Convey("SetRedPointCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(123)
pid = int64(10)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.SetRedPointCache(c, mid, pid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestPendantDelRedPointCache(t *testing.T) {
convey.Convey("DelRedPointCache", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(123)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelRedPointCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,515 @@
package pendant
import (
"bytes"
"context"
"database/sql"
"fmt"
"time"
"go-common/app/service/main/usersuit/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
"github.com/pkg/errors"
)
const (
_getGroupOnlineSQL = "SELECT id,name,rank,status,image,image_model,frequency_limit,time_limit FROM pendant_group WHERE status = 1 or id in (30,31) ORDER BY rank"
_getGroupByIDSQL = "SELECT id,name,rank,status,image,image_model,frequency_limit,time_limit FROM pendant_group where id = ?"
_selGIDRefPIDSQL = "SELECT gid,pid FROM pendant_group_ref"
_getPendantInfoSQL = "SELECT id,name,image,image_model,status FROM pendant_info"
_getPendantInfoByIDSQL = "SELECT id,name,image,image_model,status FROM pendant_info where id = ? limit 1"
_getPendantInfosSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info ORDER BY rank"
_getPendantPriceSQL = "SELECT pid,type,price FROM pendant_price where pid = ? "
_getOrderHistorySQL = "SELECT mid,order_id,pay_id,appid,status,pid,time_length,cost,buy_time,is_callback,callback_time,pay_type FROM user_pendant_order WHERE %s"
_getUserPackageSQL = "SELECT mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? AND pid = ? "
_getUserPackageByMidSQL = "SELECT mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? AND expires >= ? AND status > 0 ORDER BY mtime DESC"
_countOrderHistorySQL = "SELECT count(1) FROM user_pendant_order WHERE %s"
_getPendantEquipByMidSQL = "SELECT mid,pid,expires FROM user_pendant_equip WHERE mid = ? and expires >= ?"
_getPendantEquipByMidsSQL = "SELECT mid,pid,expires FROM user_pendant_equip WHERE mid IN (%s) and expires >= ?"
_insertPendantPackageSQL = "INSERT INTO user_pendant_pkg(mid,pid,expires,type,status,is_vip) VALUES (?,?,?,?,?,?)"
_insertOrderHistory = "INSERT INTO user_pendant_order(mid,order_id,pay_id,appid,status,pid,time_length,cost,buy_time,is_callback,callback_time,pay_type) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)"
_insertOperationSQL = "INSERT INTO pendant_grant_history(mid,pid,source_type,operator_name,operator_action) VALUES (?,?,?,?,?)"
_insertEquipSQL = "INSERT INTO user_pendant_equip(mid,pid,expires) VALUES (?,?,?) ON DUPLICATE KEY UPDATE pid=VALUES(pid),expires=VALUES(expires)"
_updatePackageSQL = "UPDATE user_pendant_pkg %s WHERE mid=? AND pid=?"
_updatePackageExpireSQL = "UPDATE user_pendant_pkg SET status=0 WHERE mid=? AND expires<?"
_updateOrderInfoSQL = "UPDATE user_pendant_order SET status=?,pay_id=?,is_callback=?,callback_time=? WHERE order_id=?"
_updateEquipMIDSQL = "UPDATE user_pendant_equip SET pid=0,expires=0 WHERE mid=?"
)
//PendantGroupInfo return all group info
func (d *Dao) PendantGroupInfo(c context.Context) (res []*model.PendantGroupInfo, err error) {
var row *xsql.Rows
res = make([]*model.PendantGroupInfo, 0)
if row, err = d.db.Query(c, _getGroupOnlineSQL); err != nil {
log.Error("PendantGroupInfo query error %v", err)
return
}
defer row.Close()
for row.Next() {
info := new(model.PendantGroupInfo)
if err = row.Scan(&info.ID, &info.Name, &info.Rank, &info.Status, &info.Image, &info.ImageModel, &info.FrequencyLimit, &info.TimeLimit); err != nil {
log.Error("PendantGroupInfo scan error %v", err)
return
}
res = append(res, info)
}
return
}
// GroupByID return group info by id
func (d *Dao) GroupByID(c context.Context, gid int64) (res *model.PendantGroupInfo, err error) {
var row *xsql.Row
res = new(model.PendantGroupInfo)
row = d.db.QueryRow(c, _getGroupByIDSQL, gid)
if err = row.Scan(&res.ID, &res.Name, &res.Rank, &res.Status, &res.Image, &res.ImageModel, &res.FrequencyLimit, &res.TimeLimit); err != nil {
if err == xsql.ErrNoRows {
res = nil
err = nil
return
}
log.Error("PendantGroupInfo scan error %v", err)
return
}
return
}
// GIDRefPID gid relation of pid .
func (d *Dao) GIDRefPID(c context.Context) (gidMap map[int64][]int64, pidMap map[int64]int64, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, _selGIDRefPIDSQL); err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
gidMap = make(map[int64][]int64)
pidMap = make(map[int64]int64)
for rows.Next() {
var gid, pid int64
if err = rows.Scan(&gid, &pid); err != nil {
if err == xsql.ErrNoRows {
gidMap = nil
pidMap = nil
err = nil
return
}
err = errors.WithStack(err)
return
}
pidMap[pid] = gid
gidMap[gid] = append(gidMap[gid], pid)
}
return
}
// PendantList return pendant info
func (d *Dao) PendantList(c context.Context) (res []*model.Pendant, err error) {
var (
row *xsql.Rows
)
res = make([]*model.Pendant, 0)
if row, err = d.db.Query(c, _getPendantInfosSQL); err != nil {
log.Error("PendantInfo query error %v", err)
return
}
defer row.Close()
for row.Next() {
info := new(model.Pendant)
if err = row.Scan(&info.ID, &info.Name, &info.Image, &info.ImageModel, &info.Status, &info.Rank); err != nil {
log.Error("PendantInfo scan error %v", err)
return
}
res = append(res, info)
}
return
}
// Pendants return pendant info by ids
func (d *Dao) Pendants(c context.Context, pids []int64) (res []*model.Pendant, err error) {
var (
row *xsql.Rows
bf bytes.Buffer
)
res = make([]*model.Pendant, 0)
bf.WriteString(_getPendantInfoSQL)
bf.WriteString(" where id in(")
bf.WriteString(xstr.JoinInts(pids))
bf.WriteString(") and status = 1 ORDER BY rank")
if row, err = d.db.Query(c, bf.String()); err != nil {
log.Error("Pendants query error %v", err)
return
}
defer row.Close()
for row.Next() {
info := new(model.Pendant)
if err = row.Scan(&info.ID, &info.Name, &info.Image, &info.ImageModel, &info.Status); err != nil {
log.Error("Pendants scan error %v", err)
return
}
res = append(res, info)
}
return
}
// PendantInfo return pendant info by id
func (d *Dao) PendantInfo(c context.Context, pid int64) (res *model.Pendant, err error) {
var (
row *xsql.Row
)
res = new(model.Pendant)
row = d.db.QueryRow(c, _getPendantInfoByIDSQL, pid)
if err = row.Scan(&res.ID, &res.Name, &res.Image, &res.ImageModel, &res.Status); err != nil {
if err == xsql.ErrNoRows {
res = nil
err = nil
return
}
log.Error("Pendant scan error %v", err)
return
}
return
}
// PendantPrice return pendant price
func (d *Dao) PendantPrice(c context.Context, pid int64) (res map[int64]*model.PendantPrice, err error) {
var row *xsql.Rows
res = make(map[int64]*model.PendantPrice)
if row, err = d.db.Query(c, _getPendantPriceSQL, pid); err != nil {
log.Error("PendantPrice query error %v", err)
return
}
defer row.Close()
for row.Next() {
info := new(model.PendantPrice)
if err = row.Scan(&info.Pid, &info.Type, &info.Price); err != nil {
log.Error("PendantPrice scan error %v", err)
return
}
res[info.Type] = info
}
return
}
// getOrderInfoSQL return a sql string
func (d *Dao) getOrderInfoSQL(c context.Context, arg *model.ArgOrderHistory, tp string) (sql string, values []interface{}) {
values = make([]interface{}, 0, 5)
var cond bytes.Buffer
cond.WriteString("mid = ?")
values = append(values, arg.Mid)
if arg.OrderID != "" {
cond.WriteString(" AND order_id = ?")
values = append(values, arg.OrderID)
}
if arg.Pid != 0 {
cond.WriteString(" AND pid = ?")
values = append(values, arg.Pid)
}
if arg.Status != 0 {
cond.WriteString(" AND status = ?")
values = append(values, arg.Status)
}
if arg.PayType != 0 {
cond.WriteString(" AND pay_type = ?")
values = append(values, arg.PayType)
}
if arg.PayID != "" {
cond.WriteString(" AND pay_id = ?")
values = append(values, arg.PayID)
}
if arg.StartTime != 0 {
cond.WriteString(" AND buy_time >= ?")
values = append(values, arg.StartTime)
}
if arg.EndTime != 0 {
cond.WriteString(" AND buy_time <= ?")
values = append(values, arg.EndTime)
}
if tp == "info" {
cond.WriteString(" order by buy_time DESC LIMIT ?,20")
values = append(values, (arg.Page-1)*20)
sql = fmt.Sprintf(_getOrderHistorySQL, cond.String())
} else if tp == "count" {
sql = fmt.Sprintf(_countOrderHistorySQL, cond.String())
}
return
}
// OrderInfo return order info
func (d *Dao) OrderInfo(c context.Context, arg *model.ArgOrderHistory) (res []*model.PendantOrderInfo, count int64, err error) {
sqlstr, values := d.getOrderInfoSQL(c, arg, "info")
var (
row *xsql.Rows
r *xsql.Row
)
res = make([]*model.PendantOrderInfo, 0)
if row, err = d.db.Query(c, sqlstr, values...); err != nil {
log.Error("PendantOrderInfo query error %v", err)
return
}
defer row.Close()
cstr, values2 := d.getOrderInfoSQL(c, arg, "count")
r = d.db.QueryRow(c, cstr, values2...)
for row.Next() {
info := new(model.PendantOrderInfo)
if err = row.Scan(&info.Mid, &info.OrderID, &info.PayID, &info.AppID, &info.Stauts, &info.Pid, &info.TimeLength, &info.Cost, &info.BuyTime, &info.IsCallback, &info.CallbackTime, &info.PayType); err != nil {
log.Error("PendantOrderInfo scan error %v", err)
return
}
if info.PayType == 3 {
info.PayPrice = info.PayPrice / 100
}
res = append(res, info)
}
err = r.Scan(&count)
if err == xsql.ErrNoRows {
res = nil
err = nil
return
}
return
}
// OrderInfoByID return order info by order id
func (d *Dao) OrderInfoByID(c context.Context, orderID string) (res *model.PendantOrderInfo, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_getOrderHistorySQL, "order_id=?"), orderID)
res = new(model.PendantOrderInfo)
if err = row.Scan(&res.Mid, &res.OrderID, &res.PayID, &res.AppID, &res.Stauts, &res.Pid, &res.TimeLength, &res.Cost, &res.BuyTime, &res.IsCallback, &res.CallbackTime, &res.PayType); err != nil {
if err == xsql.ErrNoRows {
res = nil
err = nil
return
}
log.Error("OrderInfoByID scan error %v", err)
return
}
return
}
// AddOrderInfo add order log
func (d *Dao) AddOrderInfo(c context.Context, arg *model.PendantOrderInfo) (id int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _insertOrderHistory, arg.Mid, arg.OrderID, arg.PayID, arg.AppID, arg.Stauts, arg.Pid, arg.TimeLength, arg.Cost, arg.BuyTime, arg.IsCallback, arg.CallbackTime, arg.PayType); err != nil {
log.Error("AddOrderInfo insert error %v", err)
return
}
return res.LastInsertId()
}
// TxAddOrderInfo add order log
func (d *Dao) TxAddOrderInfo(c context.Context, arg *model.PendantOrderInfo, tx *xsql.Tx) (id int64, err error) {
var res sql.Result
if res, err = tx.Exec(_insertOrderHistory, arg.Mid, arg.OrderID, arg.PayID, arg.AppID, arg.Stauts, arg.Pid, arg.TimeLength, arg.Cost, arg.BuyTime, arg.IsCallback, arg.CallbackTime, arg.PayType); err != nil {
log.Error("TxAddOrderInfo insert error %v", err)
return
}
return res.LastInsertId()
}
// UpdateOrderInfo update order info
func (d *Dao) UpdateOrderInfo(c context.Context, arg *model.PendantOrderInfo) (id int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateOrderInfoSQL, arg.Stauts, arg.PayID, arg.IsCallback, arg.CallbackTime, arg.OrderID); err != nil {
log.Error("UpdateOrderInfo update error %v", err)
return
}
return res.LastInsertId()
}
// TxUpdateOrderInfo update order info
func (d *Dao) TxUpdateOrderInfo(c context.Context, arg *model.PendantOrderInfo, tx *xsql.Tx) (id int64, err error) {
var res sql.Result
if res, err = tx.Exec(_updateOrderInfoSQL, arg.Stauts, arg.PayID, arg.IsCallback, arg.CallbackTime, arg.OrderID); err != nil {
log.Error("UpdateOrderInfo update error %v", err)
return
}
return res.LastInsertId()
}
// PackageByMid get pendant in user's package
func (d *Dao) PackageByMid(c context.Context, mid int64) (res []*model.PendantPackage, err error) {
var (
row *xsql.Rows
t = time.Now().Unix()
)
res = make([]*model.PendantPackage, 0)
if row, err = d.db.Query(c, _getUserPackageByMidSQL, mid, t); err != nil {
log.Error("Package query error %v", err)
return
}
defer row.Close()
for row.Next() {
info := new(model.PendantPackage)
if err = row.Scan(&info.Mid, &info.Pid, &info.Expires, &info.Type, &info.Status, &info.IsVIP); err != nil {
log.Error("Package scan error %v", err)
return
}
res = append(res, info)
}
return
}
// PackageByID get pendant in user's package
func (d *Dao) PackageByID(c context.Context, mid, pid int64) (res *model.PendantPackage, err error) {
var row *xsql.Row
res = new(model.PendantPackage)
row = d.db.QueryRow(c, _getUserPackageSQL, mid, pid)
if err = row.Scan(&res.Mid, &res.Pid, &res.Expires, &res.Type, &res.Status, &res.IsVIP); err != nil {
if err == xsql.ErrNoRows {
res = nil
err = nil
return
}
log.Error("Package scan error %v", err)
return
}
return
}
// EquipByMid obtain pendant equiped
func (d *Dao) EquipByMid(c context.Context, mid, t int64) (res *model.PendantEquip, noRow bool, err error) {
var row *xsql.Row
res = new(model.PendantEquip)
row = d.db.QueryRow(c, _getPendantEquipByMidSQL, mid, t)
if err = row.Scan(&res.Mid, &res.Pid, &res.Expires); err != nil {
if err == xsql.ErrNoRows {
noRow = true
res = nil
err = nil
return
}
err = errors.WithStack(err)
}
return
}
// EquipByMids obtain equipss by mids .
func (d *Dao) EquipByMids(c context.Context, mids []int64, t int64) (res map[int64]*model.PendantEquip, err error) {
res = make(map[int64]*model.PendantEquip)
rows, err := d.db.Query(c, fmt.Sprintf(_getPendantEquipByMidsSQL, xstr.JoinInts(mids)), t)
if err != nil {
err = errors.WithStack(err)
return
}
defer rows.Close()
for rows.Next() {
pe := &model.PendantEquip{}
if err = rows.Scan(&pe.Mid, &pe.Pid, &pe.Expires); err != nil {
if err == xsql.ErrNoRows {
err = nil
return
}
err = errors.WithStack(err)
}
if _, ok := res[pe.Mid]; !ok {
res[pe.Mid] = pe
}
}
err = rows.Err()
return
}
// AddEquip add equip
func (d *Dao) AddEquip(c context.Context, arg *model.PendantEquip) (n int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _insertEquipSQL, arg.Mid, arg.Pid, arg.Expires); err != nil {
return 0, err
}
return res.RowsAffected()
}
// UpEquipMID uninstall user pid by mid.
func (d *Dao) UpEquipMID(c context.Context, mid int64) (n int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateEquipMIDSQL, mid); err != nil {
return 0, err
}
return res.RowsAffected()
}
// TxUpdatePackageInfo update package info
func (d *Dao) TxUpdatePackageInfo(c context.Context, arg *model.PendantPackage, tx *xsql.Tx) (n int64, err error) {
var (
bf bytes.Buffer
values = make([]interface{}, 0, 4)
res sql.Result
)
if arg.Status != 0 && arg.Expires != 0 {
bf.WriteString("SET status=?,expires=?,type=?")
values = append(values, arg.Status)
values = append(values, arg.Expires)
values = append(values, arg.Type)
} else if arg.Status != 0 {
bf.WriteString("SET status=?,type=?")
values = append(values, arg.Status)
values = append(values, arg.Type)
} else if arg.Expires != 0 {
bf.WriteString("SET expires=?,type=?")
values = append(values, arg.Expires)
values = append(values, arg.Type)
}
values = append(values, arg.Mid)
values = append(values, arg.Pid)
if res, err = tx.Exec(fmt.Sprintf(_updatePackageSQL, bf.String()), values...); err != nil {
log.Error("TxUpdatePackageInfo update error %v", err)
return
}
return res.RowsAffected()
}
// CheckPackageExpire check expire items and update
func (d *Dao) CheckPackageExpire(c context.Context, mid, expires int64) (rows int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updatePackageExpireSQL, mid, expires); err != nil {
log.Error("CheckPackageExpire error %v", err)
return
}
return res.RowsAffected()
}
// BeginTran begin a tx.
func (d *Dao) BeginTran(c context.Context) (res *xsql.Tx, err error) {
if res, err = d.db.Begin(c); err != nil || res == nil {
log.Error("BeginTran error %v", err)
return
}
return
}
// TxAddPackage add a pendant in package
func (d *Dao) TxAddPackage(c context.Context, arg *model.PendantPackage, tx *xsql.Tx) (id int64, err error) {
var res sql.Result
if res, err = tx.Exec(_insertPendantPackageSQL, arg.Mid, arg.Pid, arg.Expires, arg.Type, arg.Status, arg.IsVIP); err != nil {
log.Error("TxAddPackage insert error %v", err)
return
}
return res.LastInsertId()
}
// TxAddHistory add a history of operation
func (d *Dao) TxAddHistory(c context.Context, arg *model.PendantHistory, tx *xsql.Tx) (id int64, err error) {
var res sql.Result
if res, err = tx.Exec(_insertOperationSQL, arg.Mid, arg.Pid, arg.SourceType, arg.OperatorName, arg.OperatorAction); err != nil {
log.Error("TxAddHistory insert error %v", err)
return
}
return res.LastInsertId()
}

View File

@@ -0,0 +1,372 @@
package pendant
import (
"strconv"
"testing"
"time"
"go-common/app/service/main/usersuit/model"
"github.com/smartystreets/goconvey/convey"
)
func TestPendantPendantGroupInfo(t *testing.T) {
convey.Convey("PendantGroupInfo", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PendantGroupInfo(c)
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)
})
})
})
}
func TestPendantGroupByID(t *testing.T) {
convey.Convey("GroupByID", t, func(ctx convey.C) {
var (
gid = int64(4)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.GroupByID(c, gid)
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)
})
})
})
}
func TestPendantGIDRefPID(t *testing.T) {
convey.Convey("GIDRefPID", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
gidMap, pidMap, err := d.GIDRefPID(c)
ctx.Convey("Then err should be nil.gidMap,pidMap should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(pidMap, convey.ShouldNotBeNil)
ctx.So(gidMap, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantPendantList(t *testing.T) {
convey.Convey("PendantList", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PendantList(c)
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)
})
})
})
}
func TestPendantPendants(t *testing.T) {
convey.Convey("Pendants", t, func(ctx convey.C) {
var (
pids = []int64{4}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.Pendants(c, pids)
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)
})
})
})
}
func TestPendantPendantInfo(t *testing.T) {
convey.Convey("PendantInfo", t, func(ctx convey.C) {
var (
pid = int64(4)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PendantInfo(c, pid)
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)
})
})
})
}
func TestPendantPendantPrice(t *testing.T) {
convey.Convey("PendantPrice", t, func(ctx convey.C) {
var (
pid = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PendantPrice(c, pid)
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)
})
})
})
}
func TestPendantgetOrderInfoSQL(t *testing.T) {
convey.Convey("getOrderInfoSQL", t, func(ctx convey.C) {
var (
arg = &model.ArgOrderHistory{}
tp = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
sql, values := d.getOrderInfoSQL(c, arg, tp)
ctx.Convey("Then sql,values should not be nil.", func(ctx convey.C) {
ctx.So(values, convey.ShouldNotBeNil)
ctx.So(sql, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantOrderInfo(t *testing.T) {
convey.Convey("OrderInfo", t, func(ctx convey.C) {
var (
arg = &model.ArgOrderHistory{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, count, err := d.OrderInfo(c, arg)
ctx.Convey("Then err should be nil.res,count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantOrderInfoByID(t *testing.T) {
convey.Convey("OrderInfoByID", t, func(ctx convey.C) {
var (
orderID = ""
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.OrderInfoByID(c, orderID)
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)
})
})
})
}
func TestPendantAddOrderInfo(t *testing.T) {
convey.Convey("AddOrderInfo", t, func(ctx convey.C) {
var (
arg = &model.PendantOrderInfo{Mid: 650454, OrderID: strconv.FormatInt(time.Now().Unix(), 10)}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
id, err := d.AddOrderInfo(c, arg)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantTxAddOrderInfo(t *testing.T) {
convey.Convey("TxAddOrderInfo", t, func(ctx convey.C) {
var (
arg = &model.PendantOrderInfo{Mid: 650454, OrderID: strconv.FormatInt(time.Now().UnixNano(), 10)}
tx, _ = d.BeginTran(c)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
id, err := d.TxAddOrderInfo(c, arg, tx)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantUpdateOrderInfo(t *testing.T) {
convey.Convey("UpdateOrderInfo", t, func(ctx convey.C) {
var (
arg = &model.PendantOrderInfo{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
id, err := d.UpdateOrderInfo(c, arg)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantTxUpdateOrderInfo(t *testing.T) {
convey.Convey("TxUpdateOrderInfo", t, func(ctx convey.C) {
var (
arg = &model.PendantOrderInfo{}
tx, _ = d.BeginTran(c)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
id, err := d.TxUpdateOrderInfo(c, arg, tx)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantPackageByMid(t *testing.T) {
convey.Convey("PackageByMid", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PackageByMid(c, 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)
})
})
})
}
func TestPendantPackageByID(t *testing.T) {
convey.Convey("PackageByID", t, func(ctx convey.C) {
var (
mid = int64(650454)
pid = int64(21)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.PackageByID(c, mid, pid)
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)
})
})
})
}
func TestPendantEquipByMid(t *testing.T) {
convey.Convey("EquipByMid", t, func(ctx convey.C) {
var (
mid = int64(88888929)
no = int64(44)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, noRow, err := d.EquipByMid(c, mid, no)
ctx.Convey("Then err should be nil.res,noRow should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(noRow, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantEquipByMids(t *testing.T) {
convey.Convey("EquipByMids", t, func(ctx convey.C) {
var (
mids = []int64{650454}
no = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.EquipByMids(c, mids, no)
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)
})
})
})
}
func TestPendantAddEquip(t *testing.T) {
convey.Convey("AddEquip", t, func(ctx convey.C) {
var (
arg = &model.PendantEquip{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
n, err := d.AddEquip(c, arg)
ctx.Convey("Then err should be nil.n should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(n, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantTxUpdatePackageInfo(t *testing.T) {
convey.Convey("TxUpdatePackageInfo", t, func(ctx convey.C) {
var (
arg = &model.PendantPackage{Mid: 88888929, Pid: 2, Status: 1}
tx, _ = d.BeginTran(c)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
n, err := d.TxUpdatePackageInfo(c, arg, tx)
ctx.Convey("Then err should be nil.n should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(n, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantCheckPackageExpire(t *testing.T) {
convey.Convey("CheckPackageExpire", t, func(ctx convey.C) {
var (
mid = int64(650454)
expires = int64(2147483647)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
rows, err := d.CheckPackageExpire(c, mid, expires)
ctx.Convey("Then err should be nil.rows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(rows, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantBeginTran(t *testing.T) {
convey.Convey("BeginTran", t, func(ctx convey.C) {
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.BeginTran(c)
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)
})
})
})
}
func TestPendantTxAddPackage(t *testing.T) {
convey.Convey("TxAddPackage", t, func(ctx convey.C) {
var (
arg = &model.PendantPackage{Mid: time.Now().Unix(), Pid: 4}
tx, _ = d.BeginTran(c)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
id, err := d.TxAddPackage(c, arg, tx)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantTxAddHistory(t *testing.T) {
convey.Convey("TxAddHistory", t, func(ctx convey.C) {
var (
arg = &model.PendantHistory{}
tx, _ = d.BeginTran(c)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
id, err := d.TxAddHistory(c, arg, tx)
ctx.Convey("Then err should be nil.id should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(id, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,31 @@
package pendant
import (
"context"
"net/url"
"go-common/library/ecode"
"go-common/library/log"
)
// PayBcoin pay coin
func (d *Dao) PayBcoin(c context.Context, params url.Values, ip string) (orderNo, casherURL string, err error) {
var res struct {
Code int `json:"code"`
Ts string `json:"ts"`
OrderNum string `json:"order_no"`
CasherURL string `json:"cashier_url"`
}
if err = d.client.Post(c, d.payURL, ip, params, &res); err != nil {
log.Error("dao.client.Post(%s) error(%v)", d.payURL, err)
return
}
if res.Code != 0 {
log.Error("dao.client.Post(%s) error(%v)", d.payURL, res)
err = ecode.Int(res.Code)
return
}
orderNo = res.OrderNum
casherURL = res.CasherURL
return
}

View File

@@ -0,0 +1,41 @@
package pendant
import (
"fmt"
"net/url"
"strconv"
"testing"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
func TestPendantPayBcoin(t *testing.T) {
convey.Convey("PayBcoin", t, func(ctx convey.C) {
var (
params = url.Values{}
ip = ""
_subject = "头像挂件"
)
params.Set("mid", "109228")
params.Set("out_trade_no", "2016050614625209018624230766")
params.Set("money", strconv.FormatFloat(2, 'f', 2, 64))
params.Set("subject", _subject)
params.Set("remark", fmt.Sprintf(_subject+" - %s%s个月", strconv.FormatInt(4, 10), strconv.FormatInt(1234, 10)))
params.Set("merchant_id", d.c.PayInfo.MerchantID)
params.Set("merchant_product_id", d.c.PayInfo.MerchantProductID)
params.Set("platform_type", "3")
params.Set("iap_pay_type", "0")
params.Set("notify_url", d.c.PayInfo.CallBackURL)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
defer gock.OffAll()
httpMock("Post", d.payURL).Reply(0).JSON(`{"code":0}`)
orderNo, casherURL, err := d.PayBcoin(c, params, ip)
ctx.Convey("Then err should be nil.orderNo,casherURL should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(casherURL, convey.ShouldNotBeNil)
ctx.So(orderNo, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,286 @@
package pendant
import (
"context"
"strconv"
"encoding/json"
"go-common/app/service/main/usersuit/model"
"go-common/library/cache/redis"
"go-common/library/log"
"github.com/pkg/errors"
)
const (
_pendantPKG = "pkg_" // key of
_pendantEquip = "pe_"
)
func keyEquip(mid int64) string {
return _pendantEquip + strconv.FormatInt(mid, 10)
}
// encode
func (d *Dao) encode(mid, pid, expires, tp int64, status, isVIP int32, pendant *model.Pendant) (res []byte, err error) {
ft := &model.PendantPackage{Mid: mid, Pid: pid, Expires: expires, Type: tp, Status: status, IsVIP: isVIP, Pendant: pendant}
return json.Marshal(ft)
}
// decode
func (d *Dao) decode(src []byte, v *model.PendantPackage) (err error) {
return json.Unmarshal(src, v)
}
// AddPKGCache set package cache.
func (d *Dao) AddPKGCache(c context.Context, mid int64, info []*model.PendantPackage) (err error) {
var (
key = _pendantPKG + strconv.FormatInt(mid, 10)
args = redis.Args{}.Add(key)
)
for i := 0; i < len(info); i++ {
var ef []byte
if ef, err = d.encode(info[i].Mid, info[i].Pid, info[i].Expires, info[i].Type, info[i].Status, info[i].IsVIP, info[i].Pendant); err != nil {
return
}
args = args.Add(i, ef)
}
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("DEL", key); err != nil {
log.Error("conn.Send(DEL, %s) error(%v)", key, err)
return
}
if err = conn.Send("HMSET", args...); err != nil {
log.Error("conn.Send(HMSET, %s) error(%v)", key, err)
return
}
if err = conn.Send("EXPIRE", key, d.pendantExpire); err != nil {
log.Error("conn.Send(EXPIRE, %s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush() error(%v)", err)
return
}
for i := 0; i < 3; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() %d error(%v)", i+1, err)
break
}
}
return
}
// PKGCache get package cache.
func (d *Dao) PKGCache(c context.Context, mid int64) (info []*model.PendantPackage, err error) {
var (
key = _pendantPKG + strconv.FormatInt(mid, 10)
tmp = make(map[string]string, len(info))
)
conn := d.redis.Get(c)
defer conn.Close()
if tmp, err = redis.StringMap(conn.Do("HGETALL", key)); err != nil {
return
}
if err == nil && len(tmp) > 0 {
for i := 0; i < len(tmp); i++ {
s := strconv.FormatInt(int64(i), 10)
vf := &model.PendantPackage{}
vf.Pendant = &model.Pendant{}
if err = d.decode([]byte(tmp[s]), vf); err != nil {
return
}
info = append(info, &model.PendantPackage{
Mid: vf.Mid,
Pid: vf.Pid,
Expires: vf.Expires,
Type: vf.Type,
Status: vf.Status,
IsVIP: vf.IsVIP,
Pendant: vf.Pendant,
})
}
}
return
}
// DelPKGCache del package cache
func (d *Dao) DelPKGCache(c context.Context, mid int64) (err error) {
key := _pendantPKG + strconv.FormatInt(mid, 10)
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("DEL", key); err != nil {
log.Error("conn.Send(DEL, %s) error(%v)", key, err)
return
}
return
}
// equipCache return pendant info cache
func (d *Dao) equipCache(c context.Context, mid int64) (info *model.PendantEquip, err error) {
var (
item []byte
conn = d.redis.Get(c)
)
defer conn.Close()
if item, err = redis.Bytes(conn.Do("GET", keyEquip(mid))); err != nil {
if err == redis.ErrNil {
err = nil
}
return
}
if err = json.Unmarshal(item, &info); err != nil {
log.Error("json.Unmarshal(%v) err(%v)", item, err)
}
return
}
// equipsCache obtain equips from redis .
func (d *Dao) equipsCache(c context.Context, mids []int64) (map[int64]*model.PendantEquip, []int64, error) {
var (
err error
bss [][]byte
key string
args = redis.Args{}
conn = d.redis.Get(c)
)
for _, v := range mids {
key = keyEquip(v)
args = args.Add(key)
}
defer conn.Close()
if bss, err = redis.ByteSlices(conn.Do("MGET", args...)); err != nil {
if err == redis.ErrNil {
return nil, nil, nil
}
log.Error("Failed mget equip: keys: %+v: %+v", args, err)
return nil, nil, err
}
info := make(map[int64]*model.PendantEquip, len(mids))
for _, bs := range bss {
if bs == nil {
continue
}
pe := &model.PendantEquip{}
if err = json.Unmarshal(bs, pe); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(bs), err)
err = nil
continue
}
info[pe.Mid] = pe
}
missed := make([]int64, 0, len(mids))
for _, mid := range mids {
if _, ok := info[mid]; !ok {
missed = append(missed, mid)
}
}
return info, missed, nil
}
// AddEquipCache set pendant info cache
func (d *Dao) AddEquipCache(c context.Context, mid int64, info *model.PendantEquip) (err error) {
var (
key = keyEquip(mid)
values []byte
conn = d.redis.Get(c)
)
defer conn.Close()
if values, err = json.Marshal(info); err != nil {
return
}
if err = conn.Send("SET", keyEquip(mid), values); err != nil {
log.Error("conn.Send(SET, %s, %d) error(%v)", key, values, err)
return
}
if err = conn.Send("EXPIRE", key, d.pendantExpire); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", key, d.pendantExpire, err)
return
}
if err = conn.Flush(); err != nil {
err = errors.Wrap(err, "conn.Send Flush")
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
err = errors.Wrap(err, "conn.Send conn.Receive()")
return
}
}
return
}
// AddEquipsCache mset equips info to caache .
func (d *Dao) AddEquipsCache(c context.Context, equips map[int64]*model.PendantEquip) (err error) {
var (
bs []byte
key string
keys []string
argsMid = redis.Args{}
conn = d.redis.Get(c)
)
defer conn.Close()
for _, v := range equips {
if bs, err = json.Marshal(v); err != nil {
log.Error("json.Marshal err(%v)", err)
continue
}
key = keyEquip(v.Mid)
keys = append(keys, key)
argsMid = argsMid.Add(key).Add(string(bs))
}
if err = conn.Send("MSET", argsMid...); err != nil {
err = errors.Wrap(err, "conn.Send(MSET) error")
return
}
count := 1
for _, v := range keys {
count++
if err = conn.Send("EXPIRE", v, d.pendantExpire); err != nil {
err = errors.Wrap(err, "conn.Send error")
return
}
}
if err = conn.Flush(); err != nil {
err = errors.Wrap(err, "conn.Send Flush")
return
}
for i := 0; i < count; i++ {
if _, err = conn.Receive(); err != nil {
err = errors.Wrap(err, "conn.Send conn.Receive()")
return
}
}
return
}
// DelEquipCache set pendant info cache
func (d *Dao) DelEquipCache(c context.Context, mid int64) (err error) {
key := keyEquip(mid)
conn := d.redis.Get(c)
defer conn.Close()
if _, err = conn.Do("DEL", key); err != nil {
log.Error("conn.Do(DEL, %s) error(%v)", key, err)
}
return
}
// DelEquipsCache del batch equip cache .
func (d *Dao) DelEquipsCache(c context.Context, mids []int64) (err error) {
var (
args = redis.Args{}
conn = d.redis.Get(c)
)
defer conn.Close()
for _, v := range mids {
args = args.Add(keyEquip(v))
}
if _, err = conn.Do("DEL", args...); err != nil {
log.Error("conn.Do(DEL, %s) error(%v)", args, err)
}
return
}

View File

@@ -0,0 +1,180 @@
package pendant
import (
"fmt"
"go-common/app/service/main/usersuit/model"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestPendantkeyEquip(t *testing.T) {
convey.Convey("keyEquip", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1 := keyEquip(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantencode(t *testing.T) {
convey.Convey("encode", t, func(ctx convey.C) {
var (
mid = int64(650454)
pid = int64(1)
expires = int64(1535970125)
tp = int64(0)
status = int32(1)
isVIP = int32(1)
pendant = &model.Pendant{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.encode(mid, pid, expires, tp, status, isVIP, pendant)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
fmt.Println(string(res))
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantdecode(t *testing.T) {
convey.Convey("decode", t, func(ctx convey.C) {
var (
src = []byte("\u007b\u0022\u0069\u0064\u0022\u003a\u0030\u002c\u0022\u006d\u0069\u0064\u0022\u003a\u0036\u0035\u0030\u0034\u0035\u0034\u002c\u0022\u0070\u0069\u0064\u0022\u003a\u0031\u002c\u0022\u0065\u0078\u0070\u0069\u0072\u0065\u0022\u003a\u0031\u0035\u0033\u0035\u0039\u0037\u0030\u0031\u0032\u0035\u002c\u0022\u0074\u0079\u0070\u0065\u0022\u003a\u0030\u002c\u0022\u0073\u0074\u0061\u0074\u0075\u0073\u0022\u003a\u0031\u002c\u0022\u0069\u0073\u0056\u0049\u0050\u0022\u003a\u0031\u002c\u0022\u0070\u0065\u006e\u0064\u0061\u006e\u0074\u0022\u003a\u007b\u0022\u0070\u0069\u0064\u0022\u003a\u0030\u002c\u0022\u006e\u0061\u006d\u0065\u0022\u003a\u0022\u0022\u002c\u0022\u0069\u006d\u0061\u0067\u0065\u0022\u003a\u0022\u0022\u002c\u0022\u0069\u006d\u0061\u0067\u0065\u005f\u006d\u006f\u0064\u0065\u006c\u0022\u003a\u0022\u0022\u002c\u0022\u0073\u0074\u0061\u0074\u0075\u0073\u0022\u003a\u0030\u002c\u0022\u0063\u006f\u0069\u006e\u0022\u003a\u0030\u002c\u0022\u0070\u006f\u0069\u006e\u0074\u0022\u003a\u0030\u002c\u0022\u0062\u0063\u006f\u0069\u006e\u0022\u003a\u0030\u002c\u0022\u0065\u0078\u0070\u0069\u0072\u0065\u0022\u003a\u0030\u002c\u0022\u0067\u0069\u0064\u0022\u003a\u0030\u002c\u0022\u0072\u0061\u006e\u006b\u0022\u003a\u0030\u007d\u007d")
v = &model.PendantPackage{Mid: 650454, Pid: 1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.decode(src, v)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestPendantAddPKGCache(t *testing.T) {
convey.Convey("AddPKGCache", t, func(ctx convey.C) {
var (
mid = int64(650454)
info = []*model.PendantPackage{}
pp = &model.PendantPackage{Mid: mid, Pid: int64(1)}
)
info = append(info, pp)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddPKGCache(c, mid, info)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestPendantPKGCache(t *testing.T) {
convey.Convey("PKGCache", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
info, err := d.PKGCache(c, mid)
ctx.Convey("Then err should be nil.info should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(info, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantDelPKGCache(t *testing.T) {
convey.Convey("DelPKGCache", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelPKGCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestPendantAddEquipCache(t *testing.T) {
convey.Convey("AddEquipCache", t, func(ctx convey.C) {
var (
mid = int64(650454)
info = &model.PendantEquip{}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.AddEquipCache(c, mid, info)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestPendantequipCache(t *testing.T) {
convey.Convey("equipCache", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
info, err := d.equipCache(c, mid)
ctx.Convey("Then err should be nil.info should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(info, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantDelEquipCache(t *testing.T) {
convey.Convey("DelEquipCache", t, func(ctx convey.C) {
var (
mid = int64(650454)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelEquipCache(c, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestPendantequipsCache(t *testing.T) {
convey.Convey("equipsCache", t, func(ctx convey.C) {
var (
mids = []int64{650454}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
p1, p2, err := d.equipsCache(c, mids)
ctx.Convey("Then err should be nil.p1,p2 should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(p2, convey.ShouldNotBeNil)
ctx.So(p1, convey.ShouldNotBeNil)
})
})
})
}
func TestPendantDelEquipsCache(t *testing.T) {
convey.Convey("DelEquipsCache", t, func(ctx convey.C) {
var (
mids = []int64{650454, 1}
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
err := d.DelEquipsCache(c, mids)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,28 @@
package pendant
import (
"context"
"strconv"
"go-common/app/service/main/usersuit/model"
"go-common/library/ecode"
"github.com/pkg/errors"
)
// VipInfo get identify info by calling api.
func (d *Dao) VipInfo(c context.Context, mid int64, ip string) (idt *model.VipInfo, err error) {
var res struct {
Code int
Data *model.VipInfo
}
if err = d.client.Get(c, d.vipInfoURL+strconv.FormatInt(mid, 10), ip, nil, &res); err != nil {
return
}
if res.Code != 0 {
err = errors.WithStack(ecode.Int(res.Code))
return
}
idt = res.Data
return
}

View File

@@ -0,0 +1,23 @@
package pendant
import (
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestPendantVipInfo(t *testing.T) {
convey.Convey("VipInfo", t, func(ctx convey.C) {
var (
mid = int64(650454)
ip = "127.0.0.1"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
idt, err := d.VipInfo(c, mid, ip)
ctx.Convey("Then err should be nil.idt should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(idt, convey.ShouldNotBeNil)
})
})
})
}