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,78 @@
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",
"invite_test.go",
"manager_test.go",
"medal_mc_test.go",
"medal_test.go",
"msg_test.go",
"pendant_redis_test.go",
"pendant_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/usersuit/conf:go_default_library",
"//app/admin/main/usersuit/model:go_default_library",
"//library/time: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 = [
"dao.go",
"invite.go",
"manager.go",
"medal.go",
"medal_mc.go",
"msg.go",
"pendant.go",
"pendant_mc.go",
"pendant_redis.go",
"upload.go",
],
importpath = "go-common/app/admin/main/usersuit/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/usersuit/conf:go_default_library",
"//app/admin/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/sync/errgroup:go_default_library",
"//library/xstr:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,82 @@
package dao
import (
"context"
"time"
"go-common/app/admin/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"
)
const (
_msgURL = "/api/notify/send.user.notify.do"
_managersURI = "/x/admin/manager/users"
_managerTotalURI = "/x/admin/manager/users/total"
)
// Dao struct answer history of Dao
type Dao struct {
db *sql.DB
c *conf.Config
// redis
redis *redis.Pool
// http
client *bm.Client
mc *memcache.Pool
mcExpire int32
pointExpire int32
msgURL string
managersURL string
managerTotalURL string
bucket string
key string
secret string
bfs string
}
// New new a Dao and return.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.DB.Usersuit),
// http client
client: bm.NewClient(c.HTTPClient),
// redis
redis: redis.NewPool(c.Redis),
mc: memcache.NewPool(c.Memcache.Config),
mcExpire: int32(time.Duration(c.Memcache.Expire) / time.Second),
pointExpire: int32(time.Duration(c.Memcache.PointExpire) / time.Second),
}
d.msgURL = c.Host.Msg + _msgURL
d.managersURL = c.Host.Manager + _managersURI
d.managerTotalURL = c.Host.Manager + _managerTotalURI
d.bucket = c.BFS.Bucket
d.key = c.BFS.Key
d.secret = c.BFS.Secret
d.bfs = c.Host.Bfs
return
}
// BeginTran begin tran.
func (d *Dao) BeginTran(c context.Context) (tx *sql.Tx, err error) {
tx, err = d.db.Begin(c)
return
}
// Close close connections of mc, redis, db.
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
if d.redis != nil {
d.redis.Close()
}
}
// Ping ping health.
func (d *Dao) Ping(c context.Context) (err error) {
return d.db.Ping(c)
}

View File

@@ -0,0 +1,46 @@
package dao
import (
"flag"
"go-common/app/admin/main/usersuit/conf"
"os"
"strings"
"testing"
gock "gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account.usersuit-admin")
flag.Set("conf_appid", "main.account.usersuit-admin")
flag.Set("conf_token", "DJOLMyoiZhqTIrk0r9zGrhewXiBMirIH")
flag.Set("tree_id", "6814")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_env", "10")
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/usersuit-admin-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.client.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,46 @@
package dao
import (
"context"
"database/sql"
"time"
"go-common/app/admin/main/usersuit/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
)
const (
_addIgnoreInviteSQL = "INSERT IGNORE INTO invite_code(mid,code,buy_ip,buy_ip_ng,expires,ctime) VALUES(?,?,?,?,?,?)"
_getRangeInvitesSQL = "SELECT mid,imid,code,buy_ip,buy_ip_ng,expires,used_at,ctime FROM invite_code WHERE mid=? AND ctime>=? AND ctime<=?"
)
// AddIgnoreInvite add ignore invite code.
func (d *Dao) AddIgnoreInvite(c context.Context, inv *model.Invite) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _addIgnoreInviteSQL, 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()
}
// RangeInvites range invites.
func (d *Dao) RangeInvites(c context.Context, mid int64, start, end time.Time) (res []*model.Invite, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, _getRangeInvitesSQL, mid, start, end); err != nil {
log.Error("get range invites, dao.db.Query(%v, %v, %v) error(%v)", mid, start, end, err)
return
}
defer rows.Close()
for rows.Next() {
inv := new(model.Invite)
if err = rows.Scan(&inv.Mid, &inv.Imid, &inv.Code, &inv.IP, &inv.IPng, &inv.Expires, &inv.UsedAt, &inv.Ctime); err != nil {
log.Error("row.Scan() error(%v)", err)
return
}
res = append(res, inv)
}
err = rows.Err()
return
}

View File

@@ -0,0 +1,49 @@
package dao
import (
"context"
"net"
"testing"
"time"
"github.com/satori/go.uuid"
"go-common/app/admin/main/usersuit/model"
xtime "go-common/library/time"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_RangeInvites(t *testing.T) {
mid := int64(2)
Convey("add invite", t, func() {
now := time.Now().Unix()
inv := &model.Invite{
Mid: mid,
Code: uuid.NewV4().String(),
IPng: net.ParseIP("127.0.0.1"),
Expires: now + int64(time.Hour*72/time.Second),
Ctime: xtime.Time(now),
}
affected, err := d.AddIgnoreInvite(context.Background(), inv)
So(err, ShouldBeNil)
So(affected, ShouldEqual, 1)
})
Convey("range a test account's current month invite codes", t, func() {
now := time.Now()
start, end := rangeMonth(now)
res, err := d.RangeInvites(context.Background(), mid, start, end)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func rangeMonth(now time.Time) (start, end time.Time) {
year := now.Year()
month := now.Month()
loc := now.Location()
start = time.Date(year, month, 1, 0, 0, 0, 0, loc)
end = time.Date(year, month+1, 0, 23, 59, 59, 0, loc)
return
}

View File

@@ -0,0 +1,101 @@
package dao
import (
"context"
"net/url"
"strconv"
"sync"
"go-common/app/admin/main/usersuit/model"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
// Managers get manager users info.
func (d *Dao) Managers(c context.Context) (manMap map[int64]string, err error) {
var (
count, page int64
g errgroup.Group
l sync.RWMutex
)
if count, err = d.ManagerTotal(c); err != nil {
log.Error("d.ManagerTotal error(%v)", err)
return
}
if count <= 0 {
return
}
manMap = make(map[int64]string, count)
ps := int64(500)
pageNum := count / ps
if count%ps != 0 {
pageNum++
}
for page = 1; page <= pageNum; page++ {
tmpPage := page
g.Go(func() (err error) {
mi, err := d.Manager(c, tmpPage, ps)
if err != nil {
log.Error("d.Manager(%d,%d) error(%v) ", tmpPage, ps, err)
err = nil
return
}
for _, v := range mi {
l.Lock()
manMap[v.OID] = v.Uname
l.Unlock()
}
return
})
}
g.Wait()
return
}
// Manager get manager users.
func (d *Dao) Manager(c context.Context, pn, ps int64) (mi []*model.MangerInfo, err error) {
params := url.Values{}
params.Set("pn", strconv.FormatInt(pn, 10))
params.Set("ps", strconv.FormatInt(ps, 10))
var res struct {
Code int `json:"code"`
Data *struct {
Items []*model.MangerInfo `json:"items"`
} `json:"data"`
}
if err = d.client.Get(c, d.managersURL, "", params, &res); err != nil {
log.Error("Manager(%s) error(%v)", d.managersURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Warn("Manager(%s) code(%d) data(%+v)", d.managersURL+"?"+params.Encode(), res.Code, res.Data)
return
}
if res.Data != nil {
mi = res.Data.Items
}
return
}
// ManagerTotal get manager user total.
func (d *Dao) ManagerTotal(c context.Context) (count int64, err error) {
params := url.Values{}
var res struct {
Code int `json:"code"`
Data *struct {
Total int64 `json:"total"`
} `json:"data"`
}
if err = d.client.Get(c, d.managerTotalURL, "", params, &res); err != nil {
log.Error("ManagerTotal(%s) error(%v)", d.managerTotalURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Warn("ManagerTotal(%s) code(%d) data(%+v)", d.managerTotalURL+"?"+params.Encode(), res.Code, res.Data)
return
}
if res.Data != nil {
count = res.Data.Total
}
return
}

View File

@@ -0,0 +1,32 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func Test_Managers(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.Managers(context.Background())
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func Test_Manager(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.Manager(context.Background(), 1, 2)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func Test_ManagerTotal(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.ManagerTotal(context.Background())
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,353 @@
package dao
import (
"context"
"database/sql"
"fmt"
"go-common/app/admin/main/usersuit/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"github.com/pkg/errors"
)
const (
_sharding = 10
_selMedal = "SELECT id,name,description,cond,gid,level,level_rank,sort,is_online FROM medal_info"
_selMedalByID = "SELECT id,name,description,image,image_small,cond,gid,level,level_rank,sort,is_online FROM medal_info WHERE id= ?"
_insertMedal = "INSERT INTO medal_info (name,description,cond,gid,level,sort,level_rank,is_online,image,image_small) VALUES(?,?,?,?,?,?,?,?,?,?)"
_updateMedal = "UPDATE medal_info SET name=?,description=?,cond=?,gid=?,level=?,sort=?,level_rank=?,is_online=?,image=?,image_small=? WHERE id=?"
_sellMedalGroup = "SELECT id,name,pid,rank,is_online FROM medal_group ORDER BY id ASC, rank ASC"
_sellMedalGroupInfo = "SELECT m1.id,m1.name,m1.pid,m1.rank,m1.is_online,ifnull(m2.name,'无') FROM medal_group m1 left join medal_group m2 on m1.pid=m2.id ORDER BY pid ASC, rank ASC"
_selMedalGroupParent = "SELECT id,name,pid,rank,is_online FROM medal_group WHERE pid=0"
_selMedalGroupByID = "SELECT id,name,pid,rank,is_online FROM medal_group WHERE id= ?"
_insertMedalGroup = "INSERT INTO medal_group (name,pid,rank,is_online) VALUES (?,?,?,?)"
_updateMedalGroupByID = "UPDATE medal_group SET name=?,pid=?,rank=?,is_online=? WHERE id =?"
_selMedalOwnerByMID = "SELECT o.id,o.nid,o.is_activated,o.is_del,i.name FROM medal_owner_%s o LEFT JOIN medal_info i ON o.nid=i.id WHERE o.mid=?"
_selMedalAddList = "SELECT id,name FROM medal_info WHERE id NOT IN (SELECT nid FROM medal_owner_%s WHERE mid=?)"
_countOwnerBYNidMidSQL = "SELECT COUNT(*) FROM medal_owner_%s WHERE mid=? AND nid=?"
_insertMedalOwner = "INSERT INTO medal_owner_%s (mid,nid) VALUES (?,?)"
_updatMedalOwnerActivated = "UPDATE medal_owner_%s SET is_activated=1 WHERE mid=? AND nid=?"
_updatMedalOwnerNoActivated = "UPDATE medal_owner_%s SET is_activated=0 WHERE mid=? AND nid!=?"
_updatMedalOwnerDel = "UPDATE medal_owner_%s SET is_del=? WHERE mid=? AND nid=?"
_insertMedalOperationLogSQL = "INSERT INTO medal_operation_log(oper_id,mid,medal_id,source_type,action) VALUES (?,?,?,?,?)"
_medalOperationLogTotalSQL = "SELECT COUNT(*) FROM medal_operation_log WHERE mid=?"
_medalOperationLogSQL = "SELECT oper_id,action,mid,medal_id,source_type,ctime,mtime FROM medal_operation_log WHERE mid=? ORDER BY mtime DESC LIMIT ?,?"
)
func (d *Dao) hit(id int64) string {
return fmt.Sprintf("%d", id%_sharding)
}
// Medal medal info .
func (d *Dao) Medal(c context.Context) (ms []*model.Medal, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, _selMedal); err != nil {
log.Error("Medal, d.db.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
m := &model.Medal{}
if err = rows.Scan(&m.ID, &m.Name, &m.Description, &m.Condition, &m.GID, &m.Level, &m.LevelRank, &m.Sort, &m.IsOnline); err != nil {
log.Error("Medal, rows.Scan(%+v) error(%v)", m, err)
return
}
ms = append(ms, m)
}
err = rows.Err()
return
}
// MedalByID medal info by id .
func (d *Dao) MedalByID(c context.Context, id int64) (m *model.Medal, err error) {
var row = d.db.QueryRow(c, _selMedalByID, id)
m = &model.Medal{}
if err = row.Scan(&m.ID, &m.Name, &m.Description, &m.Image, &m.ImageSmall, &m.Condition, &m.GID, &m.Level, &m.LevelRank, &m.Sort, &m.IsOnline); err != nil {
log.Error("MedalByID, rows.Scan(%+v) error(%v)", m, err)
}
return
}
// AddMedal add medal .
func (d *Dao) AddMedal(c context.Context, m *model.Medal) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _insertMedal, m.Name, m.Description, m.Condition, m.GID, m.Level, m.Sort, m.LevelRank, m.IsOnline, m.Image, m.ImageSmall); err != nil {
log.Error("AddMedal, rows.Exec(%+v) error(%v)", m, err)
return
}
return res.RowsAffected()
}
// UpMedal update nameplate .
func (d *Dao) UpMedal(c context.Context, id int64, m *model.Medal) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateMedal, m.Name, m.Description, m.Condition, m.GID, m.Level, m.Sort, m.LevelRank, m.IsOnline, m.Image, m.ImageSmall, id); err != nil {
log.Error("UpMedal, d.db.Exec(%+v,%d) error(%v)", m, id, err)
return
}
return res.RowsAffected()
}
// MedalGroup return medal group all .
func (d *Dao) MedalGroup(c context.Context) (res map[int64]*model.MedalGroup, err error) {
res = make(map[int64]*model.MedalGroup)
var rows *xsql.Rows
if rows, err = d.db.Query(c, _sellMedalGroup); err != nil {
log.Error("MedalGroup, d.db.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
re := &model.MedalGroup{}
if err = rows.Scan(&re.ID, &re.Name, &re.PID, &re.Rank, &re.IsOnline); err != nil {
log.Error("MedalGroup, rows.Scan(%+v) error(%v)", re, err)
return
}
res[re.ID] = re
}
err = rows.Err()
return
}
// MedalGroupInfo return medal group all info include parent group name .
func (d *Dao) MedalGroupInfo(c context.Context) (res []*model.MedalGroup, err error) {
res = make([]*model.MedalGroup, 0)
var rows *xsql.Rows
if rows, err = d.db.Query(c, _sellMedalGroupInfo); err != nil {
log.Error("MedalGroupInfo, d.db.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
re := &model.MedalGroup{}
if err = rows.Scan(&re.ID, &re.Name, &re.PID, &re.Rank, &re.IsOnline, &re.PName); err != nil {
log.Error("MedalGroupInfo, rows.Scan(%+v) error(%v)", re, err)
return
}
res = append(res, re)
}
err = rows.Err()
return
}
// MedalGroupParent return medal group parent info .
func (d *Dao) MedalGroupParent(c context.Context) (res []*model.MedalGroup, err error) {
res = make([]*model.MedalGroup, 0)
var rows *xsql.Rows
if rows, err = d.db.Query(c, _selMedalGroupParent); err != nil {
log.Error("MedalGroupInfo, d.db.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
re := &model.MedalGroup{}
if err = rows.Scan(&re.ID, &re.Name, &re.PID, &re.Rank, &re.IsOnline); err != nil {
log.Error("MedalGroupParent, rows.Scan(%+v) error(%v)", re, err)
return
}
res = append(res, re)
}
err = rows.Err()
return
}
// MedalGroupByID medal group by gid .
func (d *Dao) MedalGroupByID(c context.Context, id int64) (mg *model.MedalGroup, err error) {
var row = d.db.QueryRow(c, _selMedalGroupByID, id)
mg = &model.MedalGroup{}
if err = row.Scan(&mg.ID, &mg.Name, &mg.PID, &mg.Rank, &mg.IsOnline); err != nil {
log.Error("MedalGroupByID, rows.Scan(%+v) error(%v)", mg, err)
return
}
return
}
// MedalGroupAdd add medal group .
func (d *Dao) MedalGroupAdd(c context.Context, mg *model.MedalGroup) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _insertMedalGroup, mg.Name, mg.PID, mg.Rank, mg.IsOnline); err != nil {
log.Error("MedalGroupAdd, d.db.Exec(%+v) error(%v)", mg, err)
return
}
return res.RowsAffected()
}
// MedalGroupUp update name group .
func (d *Dao) MedalGroupUp(c context.Context, id int64, mg *model.MedalGroup) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _updateMedalGroupByID, mg.Name, mg.PID, mg.Rank, mg.IsOnline, id); err != nil {
log.Error("MedalGroupUp, d.db.Exec(%+v %d) error(%v)", mg, id, err)
return
}
return res.RowsAffected()
}
// MedalOwner medal owner .
func (d *Dao) MedalOwner(c context.Context, mid int64) (res []*model.MedalMemberMID, err error) {
var (
rows *xsql.Rows
sqlStr string
)
res = make([]*model.MedalMemberMID, 0)
sqlStr = fmt.Sprintf(_selMedalOwnerByMID, d.hit(mid))
if rows, err = d.db.Query(c, sqlStr, mid); err != nil {
log.Error("MedalOwner, d.db.Query(%s %d) error(%v)", sqlStr, mid, err)
return
}
defer rows.Close()
for rows.Next() {
re := &model.MedalMemberMID{}
if err = rows.Scan(&re.ID, &re.NID, &re.IsActivated, &re.IsDel, &re.MedalName); err != nil {
log.Error("MedalOwner, rows.Scan(%+v) error(%v)", re, err)
return
}
res = append(res, re)
}
err = rows.Err()
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
}
// MedalOwnerAdd add medal owner .
func (d *Dao) MedalOwnerAdd(c context.Context, mid, nid int64) (affected int64, err error) {
var (
res sql.Result
sqlStr string
)
sqlStr = fmt.Sprintf(_insertMedalOwner, d.hit(mid))
if res, err = d.db.Exec(c, sqlStr, mid, nid); err != nil {
log.Error("MedalOwnerAdd, d.db.Exec(%s %d %d) error(%v)", sqlStr, mid, nid, err)
return
}
return res.RowsAffected()
}
// MedalAddList .
func (d *Dao) MedalAddList(c context.Context, mid int64) (ms []*model.MedalMemberAddList, err error) {
var (
rows *xsql.Rows
sqlStr string
)
sqlStr = fmt.Sprintf(_selMedalAddList, d.hit(mid))
if rows, err = d.db.Query(c, sqlStr, mid); err != nil {
log.Error("MedalAddList, d.db.Query(%s %d) error(%v)", sqlStr, mid, err)
return
}
defer rows.Close()
for rows.Next() {
m := &model.MedalMemberAddList{}
if err = rows.Scan(&m.ID, &m.MedalName); err != nil {
log.Error("MedalAddList, rows.Scan(%+v) error(%v)", m, err)
return
}
ms = append(ms, m)
}
err = rows.Err()
return
}
// MedalOwnerUpActivated update medal owner is_activated=1.
func (d *Dao) MedalOwnerUpActivated(c context.Context, mid, nid int64) (affected int64, err error) {
var (
res sql.Result
sqlStr string
)
sqlStr = fmt.Sprintf(_updatMedalOwnerActivated, d.hit(mid))
if res, err = d.db.Exec(c, sqlStr, mid, nid); err != nil {
log.Error("MedalOwnerUpActivated, d.db.Exec(%s %d %d) error(%v)", sqlStr, mid, nid, err)
return
}
return res.RowsAffected()
}
// MedalOwnerUpNotActivated update medal owner is_activated=0.
func (d *Dao) MedalOwnerUpNotActivated(c context.Context, mid, nid int64) (affected int64, err error) {
var (
res sql.Result
sqlStr string
)
sqlStr = fmt.Sprintf(_updatMedalOwnerNoActivated, d.hit(mid))
if res, err = d.db.Exec(c, sqlStr, mid, nid); err != nil {
log.Error("MedalOwnerUpNotActivated, d.db.Exec(%s %d %d) error(%v)", sqlStr, mid, nid, err)
return
}
return res.RowsAffected()
}
// MedalOwnerDel update medal owner is_del=1.
func (d *Dao) MedalOwnerDel(c context.Context, mid, nid int64, isDel int8) (affected int64, err error) {
var (
res sql.Result
sqlStr string
)
sqlStr = fmt.Sprintf(_updatMedalOwnerDel, d.hit(mid))
if res, err = d.db.Exec(c, sqlStr, isDel, mid, nid); err != nil {
log.Error("MedalOwnerDel, d.db.Exec(%s %d %d %d) error(%v)", sqlStr, isDel, mid, nid, err)
return
}
return res.RowsAffected()
}
// AddMedalOperLog insert medal operation log.
func (d *Dao) AddMedalOperLog(c context.Context, oid int64, mid int64, medalID int64, action string) (affected int64, err error) {
var res sql.Result
// oper_id,mid,medal_id,source_type,action
if res, err = d.db.Exec(c, _insertMedalOperationLogSQL, oid, mid, medalID, model.MedalSourceTypeAdmin, action); err != nil {
log.Error("MedalGroupAdd, d.db.Exec() error(%v)", err)
return
}
return res.RowsAffected()
}
// MedalOperLog get medal operation log.
func (d *Dao) MedalOperLog(c context.Context, mid int64, pn, ps int) (opers []*model.MedalOperLog, uids []int64, err error) {
var (
rows *xsql.Rows
offset = (pn - 1) * ps
)
if rows, err = d.db.Query(c, _medalOperationLogSQL, mid, offset, ps); err != nil {
err = errors.Wrapf(err, "MedalOperLog d.db.Query(%d,%d,%d)", mid, offset, ps)
return
}
defer rows.Close()
for rows.Next() {
oper := new(model.MedalOperLog)
if err = rows.Scan(&oper.OID, &oper.Action, &oper.MID, &oper.MedalID, &oper.SourceType, &oper.CTime, &oper.MTime); err != nil {
err = errors.Wrap(err, "MedalOperLog row.Scan()")
return
}
opers = append(opers, oper)
uids = append(uids, oper.MID)
}
err = rows.Err()
return
}
// MedalOperationLogTotal medal operation log total.
func (d *Dao) MedalOperationLogTotal(c context.Context, mid int64) (count int64, err error) {
row := d.db.QueryRow(c, _medalOperationLogTotalSQL, mid)
if err = row.Scan(&count); err != nil {
err = errors.Wrap(err, "d.dao.MedalOperationLogTotal")
return
}
return
}

View File

@@ -0,0 +1,234 @@
package dao
import (
"context"
"strconv"
"go-common/app/admin/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 {
log.Error("conn.Store(set, ping, 1) error(%v)", err)
}
return
}
// MedalOwnersCache get medal_owner cache.
func (d *Dao) MedalOwnersCache(c context.Context, mid int64) (res []*model.MedalOwner, 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
return
}
log.Error("d.MedalOwnersCache err(%v)", err)
return
}
res = make([]*model.MedalOwner, 0)
if err = conn.Scan(item, &res); err != nil {
log.Error("d.MedalOwnersCache err(%v)", 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 {
log.Error("SetMedalOwnersache err(%v)", 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 {
log.Error("d.DelMedalOwnersCache(%s) error(%v)", key, err)
}
}
return
}
// MedalActivatedCache get user activated medal nid.
func (d *Dao) MedalActivatedCache(c context.Context, mid int64) (nid int64, 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
return
}
log.Error("d.MedalActivatedCache(mid:%d) err(%v)", mid, err)
return
}
if err = conn.Scan(item, &nid); err != nil {
log.Error("d.MedalActivatedCache(mid:%d) err(%v)", mid, 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 {
log.Error("SetMedalActivatedCache err(%v)", 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 {
log.Error("d.DelMedalActivatedCache(%s) error(%v)", key, 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
}
log.Error("d.PopupCache(mid:%d) err(%v)", mid, err)
return
}
if err = conn.Scan(item, &nid); err != nil {
log.Error("d.PopupCache(mid:%d) err(%v)", mid, 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 {
log.Error("SetMedalOwnersache err(%v)", 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 {
log.Error("d.DelPopupCache(%s) error(%v)", key, 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
}
log.Error("d.RedPointCache(mid:%d) err(%v)", mid, err)
return
}
if err = conn.Scan(item, &nid); err != nil {
log.Error("d.RedPointCache(mid:%d) err(%v)", mid, 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 {
log.Error("SetRedPointCache(%d %d) err(%v)", mid, nid, 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 {
log.Error("d.DelRedPointCache(%d) error(%v)", mid, err)
}
}
return
}

View File

@@ -0,0 +1,118 @@
package dao
import (
"context"
"fmt"
"testing"
"time"
"go-common/app/admin/main/usersuit/model"
xtime "go-common/library/time"
. "github.com/smartystreets/goconvey/convey"
)
// TestMcJury .
func Test_pingMC(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.pingMC(context.Background())
So(err, ShouldBeNil)
})
}
func Test_SetMedalOwnersache(t *testing.T) {
Convey("should return err be nil", t, func() {
nos := make([]*model.MedalOwner, 0)
no := &model.MedalOwner{}
no.ID = 1
no.MID = 1
no.NID = 2
no.CTime = xtime.Time(time.Now().Second())
no.MTime = xtime.Time(time.Now().Second())
nos = append(nos, no)
err := d.SetMedalOwnersache(context.Background(), 1, nos)
So(err, ShouldBeNil)
})
Convey("should return err be nil", t, func() {
res, err := d.MedalOwnersCache(context.Background(), 1)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func Test_DelMedalOwnersCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.DelMedalOwnersCache(context.Background(), 1)
So(err, ShouldBeNil)
})
}
func Test_MedalActivatedCache(t *testing.T) {
Convey("should return err be nil", t, func() {
nid, err := d.MedalActivatedCache(context.Background(), 1)
fmt.Printf("%+v\n", nid)
So(nid, ShouldNotBeNil)
So(err, ShouldBeNil)
})
}
func Test_SetMedalActivatedCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.SetMedalActivatedCache(context.Background(), 1, 22)
So(err, ShouldBeNil)
})
}
func Test_DelMedalActivatedCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.DelMedalActivatedCache(context.Background(), 1)
So(err, ShouldBeNil)
})
}
func Test_PopupCache(t *testing.T) {
Convey("should return err be nil", t, func() {
nid, err := d.PopupCache(context.Background(), 1)
fmt.Printf("%+v\n", nid)
So(nid, ShouldNotBeNil)
So(nid, ShouldBeGreaterThanOrEqualTo, 0)
So(err, ShouldBeNil)
})
}
func Test_SetPopupCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.SetPopupCache(context.Background(), 1, 3)
So(err, ShouldBeNil)
})
}
func Test_DelPopupCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.DelPopupCache(context.Background(), 1)
So(err, ShouldBeNil)
})
}
func Test_RedPointCache(t *testing.T) {
Convey("should return err be nil", t, func() {
nid, err := d.RedPointCache(context.Background(), 1)
fmt.Printf("%+v\n", nid)
So(nid, ShouldNotBeNil)
So(nid, ShouldBeGreaterThanOrEqualTo, 0)
So(err, ShouldBeNil)
})
}
func Test_SetRedPointCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.SetRedPointCache(context.Background(), 1, 3)
So(err, ShouldBeNil)
})
}
func Test_DelRedPointCache(t *testing.T) {
Convey("should return err be nil", t, func() {
err := d.DelRedPointCache(context.Background(), 1)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,177 @@
package dao
import (
"context"
"go-common/app/admin/main/usersuit/model"
"math/rand"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_hit(t *testing.T) {
Convey("return someting", t, func() {
re := d.hit(1)
So(re, ShouldEqual, "1")
})
}
func TestDao_Medal(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.Medal(context.Background())
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDao_MedalByID(t *testing.T) {
Convey("return someting", t, func() {
re, err := d.MedalByID(context.Background(), 1)
So(err, ShouldBeNil)
So(re, ShouldNotBeNil)
})
}
func TestDao_AddMedal(t *testing.T) {
Convey("return someting", t, func() {
pg := &model.Medal{
Name: "知名偶像",
Description: "红白出道,拯救高校",
Condition: "所有自制视频总播放数>=100万 ",
GID: 4,
Level: int8(3),
Sort: 3,
LevelRank: "100万",
IsOnline: 1,
Image: "/bfs/face/27a952195555e64508310e366b3e38bd4cd143fc.png",
ImageSmall: "/bfs/face/0497be49e08357bf05bca56e33a0637a273a7610.png",
}
id, err := d.AddMedal(context.Background(), pg)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
}
func TestDao_UpMedal(t *testing.T) {
Convey("return someting", t, func() {
pg := &model.Medal{
Name: "test",
Description: "Description",
Condition: "Condition",
GID: 1,
Level: int8(3),
Sort: 1,
LevelRank: "LevelRank",
IsOnline: 1,
Image: "Image",
ImageSmall: "ImageSmall",
}
id, err := d.UpMedal(context.Background(), 1, pg)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
}
func TestDao_MedalGroup(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.MedalGroup(context.Background())
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDao_MedalGroupInfo(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.MedalGroupInfo(context.Background())
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDao_MedalGroupParent(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.MedalGroupParent(context.Background())
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDao_MedalGroupByID(t *testing.T) {
Convey("return someting", t, func() {
re, err := d.MedalGroupByID(context.Background(), 2)
So(err, ShouldBeNil)
So(re, ShouldNotBeNil)
})
}
func TestDao_MedalGroupAdd(t *testing.T) {
Convey("return someting", t, func() {
pg := &model.MedalGroup{
Name: "test",
PID: 1,
Rank: int8(1),
IsOnline: int8(1),
}
id, err := d.MedalGroupAdd(context.Background(), pg)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
}
func TestDao_MedalGroupUp(t *testing.T) {
Convey("return someting", t, func() {
pg := &model.MedalGroup{
Name: "test111",
PID: 2,
Rank: 2,
IsOnline: 0,
}
id, err := d.MedalGroupUp(context.Background(), 37, pg)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
}
func Test_MedalOwnerAdd(t *testing.T) {
mid := int64(rand.Int31())
Convey("return someting", t, func() {
id, err := d.MedalOwnerAdd(context.Background(), mid, 1)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
Convey("return someting", t, func() {
_, err := d.MedalOwner(context.Background(), mid)
So(err, ShouldBeNil)
})
}
func TestDao_MedalAddList(t *testing.T) {
Convey("return someting", t, func() {
res, err := d.MedalAddList(context.Background(), 111)
So(err, ShouldBeNil)
So(res, ShouldNotBeNil)
})
}
func TestDao_MedalOwnerUpActivated(t *testing.T) {
Convey("return someting", t, func() {
id, err := d.MedalOwnerUpActivated(context.Background(), 1, 1)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
}
func TestDao_MedalOwnerUpNotActivated(t *testing.T) {
Convey("return someting", t, func() {
id, err := d.MedalOwnerUpNotActivated(context.Background(), 1, 1)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
}
func TestDao_MedalOwnerDel(t *testing.T) {
Convey("return someting", t, func() {
id, err := d.MedalOwnerDel(context.Background(), 1, 1, 1)
So(err, ShouldBeNil)
So(id, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,60 @@
package dao
import (
"context"
"net/url"
"go-common/library/ecode"
"go-common/library/xstr"
"github.com/pkg/errors"
)
// MutliSendSysMsg Mutli send sys msg.
func (d *Dao) MutliSendSysMsg(c context.Context, allUids []int64, title string, context string, ip string) (err error) {
var times int
ulen := len(allUids)
if ulen%100 == 0 {
times = ulen / 100
} else {
times = ulen/100 + 1
}
var uids []int64
for i := 0; i < times; i++ {
if i == times-1 {
uids = allUids[i*100:]
} else {
uids = allUids[i*100 : (i+1)*100]
}
if err = d.SendSysMsg(c, uids, title, context, ip); err != nil {
err = errors.Wrapf(err, "d.SendSysMsg(%+v,%s,%s,%s)", uids, title, context, ip)
continue
}
}
return
}
// SendSysMsg send sys msg.
func (d *Dao) SendSysMsg(c context.Context, uids []int64, title string, context string, ip 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", xstr.JoinInts(uids))
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.msgURL, ip, params, &res); err != nil {
err = errors.Wrapf(err, "SendSysMsg d.client.Post(%s)", d.msgURL+"?"+params.Encode())
return
}
if res.Code != 0 {
err = errors.Wrapf(ecode.Int(res.Code), "SendSysMsg d.client.Post(%s,%d)", d.msgURL+"?"+params.Encode(), res.Code)
}
return
}

View File

@@ -0,0 +1,27 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
func Test_MutliSendSysMsg(t *testing.T) {
Convey("return someting", t, func() {
defer gock.OffAll()
httpMock("POST", d.msgURL).Reply(200).JSON(`{"code":0}`)
err := d.MutliSendSysMsg(context.Background(), []int64{22, 11}, "dasda", "dsadasd", "127.0.0.1")
So(err, ShouldBeNil)
})
}
func Test_SendSysMsg(t *testing.T) {
Convey("return someting", t, func() {
defer gock.OffAll()
httpMock("POST", d.msgURL).Reply(200).JSON(`{"code":0}`)
err := d.SendSysMsg(context.Background(), []int64{22, 11}, "dasda", "dsadasd", "127.0.0.1")
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,761 @@
package dao
import (
"bytes"
"context"
"database/sql"
"fmt"
"reflect"
"strconv"
"strings"
"sync"
"time"
"go-common/app/admin/main/usersuit/model"
xsql "go-common/library/database/sql"
"go-common/library/xstr"
"github.com/pkg/errors"
)
const (
_inPdGroupSQL = "INSERT INTO pendant_group(name,rank,status) VALUES (?,?,?)"
_inPdGroupRefSQL = "INSERT INTO pendant_group_ref(gid,pid) VALUES (?,?)"
_inPdInfoSQL = "INSERT INTO pendant_info(name,image,image_model,status,rank) VALUES (?,?,?,?,?)"
_inPdPriceSQL = "INSERT INTO pendant_price(pid,type,price) VALUES (?,?,?) ON DUPLICATE KEY UPDATE pid=?,type=?,price=?"
_inPdPKGSQL = "INSERT INTO user_pendant_pkg(mid,pid,expires,type,status) VALUES (?,?,?,4,1) ON DUPLICATE KEY UPDATE expires = ?, type = 4, status = 1"
_inPdPKGsSQL = "INSERT INTO user_pendant_pkg(mid,pid,expires,type,status) VALUES %s"
_inPdEquipSQL = "INSERT INTO user_pendant_equip(mid,pid,expires) VALUES (?,?,?) ON DUPLICATE KEY UPDATE pid = ? ,expires = ?"
_inPdOperationLogSQL = "INSERT INTO pendant_operation_log(oper_id,mid,pid,source_type,action) VALUES %s"
_upPdGroupRefSQL = "UPDATE pendant_group_ref SET gid = ? WHERE pid = ?"
_upPdPKGsSQL = "UPDATE user_pendant_pkg SET expires = CASE id %s END, type = 4, status = 1 WHERE id IN (%s)"
_upPdGroupSQL = "UPDATE pendant_group SET name=?,rank=?,status=? WHERE id=?"
_upPdGroupStatusSQL = "UPDATE pendant_group SET status=? WHERE id=?"
_upPdInfoSQL = "UPDATE pendant_info SET name=?,image=?,image_model=?,status=?,rank=? WHERE id=?"
_upPdInfoStatusSQL = "UPDATE pendant_info SET status=? WHERE id=?"
_pdInfoAllSQL = `SELECT i.id,i.name,i.image,i.image_model,i.status,i.rank,g.id,g.name,g.rank FROM pendant_info AS i INNER JOIN pendant_group_ref AS r
ON i.id = r.pid LEFT JOIN pendant_group AS g ON g.id = r.gid ORDER BY g.rank ,i.rank ASC,i.id DESC LIMIT ?,?`
_pdGroupInfoTotalSQL = "SELECT COUNT(*) FROM pendant_info INNER JOIN pendant_group_ref ON pendant_info.id = pendant_group_ref.pid"
_pdGroupsTotalSQL = "SELECT COUNT(*) FROM pendant_group"
_pdGroupRefsTotalSQL = "SELECT COUNT(*) FROM pendant_group_ref"
_pdGroupRefsGidTotalSQL = "SELECT COUNT(*) FROM pendant_group_ref WHERE gid = ?"
_pdGroupsSQL = "SELECT id,name,rank,status FROM pendant_group ORDER BY rank ASC LIMIT ?,?"
_pdGroupAllSQL = "SELECT id,name,rank,status FROM pendant_group ORDER BY rank ASC"
_pdGroupIDsSQL = "SELECT id,name,rank,status FROM pendant_group WHERE id IN (%s)"
_pdGroupIDSQL = "SELECT id,name,rank,status FROM pendant_group WHERE id = ?"
_pdInfoIDsSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info WHERE id IN (%s) ORDER BY rank ASC"
_pdPriceIDsSQL = "SELECT pid,type,price FROM pendant_price WHERE pid IN (%s)"
_pdGroupRefRanksSQL = "SELECT pr.gid,pr.pid FROM pendant_group_ref AS pr INNER JOIN pendant_group AS pg WHERE pr.gid = pg.id ORDER BY pg.rank ASC LIMIT ?,?"
_pdGroupRefsSQL = "SELECT pid FROM pendant_group_ref WHERE gid = ? LIMIT ?,?"
_pdInfoIDSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info WHERE id = ?"
_pdInfoAllNoPageSQL = "SELECT id,name,image,image_model,status,rank FROM pendant_info"
_maxOrderHistorysSQL = "SELECT MAX(id) FROM user_pendant_order"
_countOrderHistorysSQL = "SELECT COUNT(*) FROM user_pendant_order %s"
_orderHistorysSQL = "SELECT mid,order_id,pay_id,appid,status,pid,time_length,cost,buy_time,pay_type FROM user_pendant_order %s"
_pdPKGsUIDSQL = "SELECT mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? ORDER BY mtime DESC"
_pdPKGUIDsSQL = "SELECT id,mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid IN (%s) AND pid = ?"
_pdPKGUIDSQL = "SELECT id,mid,pid,expires,type,status,is_vip FROM user_pendant_pkg WHERE mid = ? AND pid = ?"
_pdEquipUIDSQL = "SELECT pid,expires FROM user_pendant_equip WHERE mid = ? AND expires >= ?"
_pdOperationLogTotalSQL = "SELECT MAX(id) FROM pendant_operation_log"
_pdOperationLogSQL = "SELECT oper_id,action,mid,pid,source_type,ctime,mtime FROM pendant_operation_log ORDER BY mtime DESC LIMIT ?,?"
)
// AddPendantGroup insert pendant group .
func (d *Dao) AddPendantGroup(c context.Context, pg *model.PendantGroup) (gid int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _inPdGroupSQL, pg.Name, pg.Rank, pg.Status); err != nil {
err = errors.Wrapf(err, "AddPendantGroup d.db.Exec(%s,%d)", pg.Name, pg.Rank)
return
}
return res.LastInsertId()
}
// TxAddPendantGroupRef tx insert pendant group ref.
func (d *Dao) TxAddPendantGroupRef(tx *xsql.Tx, pr *model.PendantGroupRef) (affected int64, err error) {
var res sql.Result
if res, err = tx.Exec(_inPdGroupRefSQL, pr.GID, pr.PID); err != nil {
err = errors.Wrapf(err, "TxAddPendantGroupRef itx.Exec(%d,%d)", pr.GID, pr.PID)
return
}
return res.RowsAffected()
}
// TxAddPendantInfo insert pendant info.
func (d *Dao) TxAddPendantInfo(tx *xsql.Tx, pi *model.PendantInfo) (pid int64, err error) {
var res sql.Result
if res, err = tx.Exec(_inPdInfoSQL, pi.Name, pi.Image, pi.ImageModel, pi.Status, pi.Rank); err != nil {
err = errors.Wrapf(err, "TxAddPendantInfo tx.Exec(%s,%s,%s,%d)", pi.Name, pi.Image, pi.ImageModel, pi.Rank)
return
}
return res.LastInsertId()
}
// TxAddPendantPrices insert pendant prices.
func (d *Dao) TxAddPendantPrices(tx *xsql.Tx, pp *model.PendantPrice) (affected int64, err error) {
var res sql.Result
if res, err = tx.Exec(_inPdPriceSQL, pp.PID, pp.TP, pp.Price, pp.PID, pp.TP, pp.Price); err != nil {
err = errors.Wrapf(err, "TxAddPendantPrices tx.Exec(%d,%d,%d)", pp.PID, pp.TP, pp.Price)
return
}
return res.RowsAffected()
}
// AddPendantPKG insert pendant pkg.
func (d *Dao) AddPendantPKG(c context.Context, pkg *model.PendantPKG) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _inPdPKGSQL, pkg.UID, pkg.PID, pkg.Expires, pkg.Expires); err != nil {
err = errors.Wrapf(err, "AddPendantPKG d.db.Exec(%d,%d,%d)", pkg.UID, pkg.PID, pkg.Expires)
return
}
return res.RowsAffected()
}
// TxAddPendantPKGs multi insert pendant pkg.
func (d *Dao) TxAddPendantPKGs(tx *xsql.Tx, pkgs []*model.PendantPKG) (affected int64, err error) {
var (
uids []int64
pids map[int64]struct{}
)
l := len(pkgs)
valueStrings := make([]string, 0, l)
valueArgs := make([]interface{}, 0, l*3)
pids = make(map[int64]struct{})
for _, pkg := range pkgs {
valueStrings = append(valueStrings, "(?,?,?,4,1)")
valueArgs = append(valueArgs, strconv.FormatInt(pkg.UID, 10))
valueArgs = append(valueArgs, strconv.FormatInt(pkg.PID, 10))
valueArgs = append(valueArgs, strconv.FormatInt(pkg.Expires, 10))
uids = append(uids, pkg.UID)
pids[pkg.PID] = struct{}{}
}
stmt := fmt.Sprintf(_inPdPKGsSQL, strings.Join(valueStrings, ","))
_, err = tx.Exec(stmt, valueArgs...)
if err != nil {
err = errors.Wrapf(err, "TxAddPendantPKGs tx.Exec(%s,%+v)", xstr.JoinInts(uids), reflect.ValueOf(pids).MapKeys())
}
return
}
// AddPendantEquip insert pendant equip.
func (d *Dao) AddPendantEquip(c context.Context, pkg *model.PendantPKG) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _inPdEquipSQL, pkg.UID, pkg.PID, pkg.Expires, pkg.PID, pkg.Expires); err != nil {
err = errors.Wrapf(err, "AddPendantEquip d.db.Exec(%d,%d,%d)", pkg.UID, pkg.PID, pkg.Expires)
return
}
return res.RowsAffected()
}
// AddPendantOperLog insert pendant operation log.
func (d *Dao) AddPendantOperLog(c context.Context, oid int64, uids []int64, pid int64, action string) (affected int64, err error) {
var res sql.Result
l := len(uids)
valueStrings := make([]string, 0, l)
valueArgs := make([]interface{}, 0, l*5)
for _, uid := range uids {
valueStrings = append(valueStrings, "(?,?,?,?,?)")
valueArgs = append(valueArgs, strconv.FormatInt(oid, 10))
valueArgs = append(valueArgs, strconv.FormatInt(uid, 10))
valueArgs = append(valueArgs, strconv.FormatInt(pid, 10))
valueArgs = append(valueArgs, strconv.FormatInt(int64(model.PendantSourceTypeAdmin), 10))
valueArgs = append(valueArgs, action)
}
stmt := fmt.Sprintf(_inPdOperationLogSQL, strings.Join(valueStrings, ","))
res, err = d.db.Exec(c, stmt, valueArgs...)
if err != nil {
err = errors.Errorf("AddPendantOperLog tx.Exec(%s,%d,%s) error(%+v)", xstr.JoinInts(uids), pid, action, err)
return
}
return res.RowsAffected()
}
// TxUpPendantGroupRef update pendant group ref.
func (d *Dao) TxUpPendantGroupRef(tx *xsql.Tx, gid, pid int64) (affected int64, err error) {
var res sql.Result
if res, err = tx.Exec(_upPdGroupRefSQL, gid, pid); err != nil {
err = errors.Wrapf(err, "UpPendantGroupRef tx.Exec(%d,%d)", gid, pid)
return
}
return res.RowsAffected()
}
// TxUpPendantPKGs multi update pendant pkg.
func (d *Dao) TxUpPendantPKGs(tx *xsql.Tx, pkgs []*model.PendantPKG) (affected int64, err error) {
var ids []int64
l := len(pkgs)
valueStrings := make([]string, 0, l)
valueArgs := make([]interface{}, 0, l*2)
for _, pkg := range pkgs {
valueStrings = append(valueStrings, "WHEN ? THEN ? ")
valueArgs = append(valueArgs, strconv.FormatInt(pkg.ID, 10))
valueArgs = append(valueArgs, strconv.FormatInt(pkg.Expires, 10))
ids = append(ids, pkg.ID)
}
stmt := fmt.Sprintf(_upPdPKGsSQL, strings.Join(valueStrings, " "), xstr.JoinInts(ids))
_, err = tx.Exec(stmt, valueArgs...)
if err != nil {
err = errors.Wrapf(err, "TxUpPendantPKGs tx.Exec(%s)", xstr.JoinInts(ids))
}
return
}
// UpPendantGroup update pendant group.
func (d *Dao) UpPendantGroup(c context.Context, pg *model.PendantGroup) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _upPdGroupSQL, pg.Name, pg.Rank, pg.Status, pg.ID); err != nil {
err = errors.Wrapf(err, "UpPendantGroup tx.Exec(%s,%d,%d,%d)", pg.Name, pg.Rank, pg.Status, pg.ID)
return
}
return res.RowsAffected()
}
// UpPendantGroupStatus update pendant group status.
func (d *Dao) UpPendantGroupStatus(c context.Context, gid int64, status int8) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _upPdGroupStatusSQL, status, gid); err != nil {
err = errors.Wrapf(err, "UpPendantGroupStatus tx.Exec(%d,%d)", status, gid)
return
}
return res.RowsAffected()
}
// TxUpPendantInfo update pendant info.
func (d *Dao) TxUpPendantInfo(tx *xsql.Tx, pi *model.PendantInfo) (affected int64, err error) {
var res sql.Result
if res, err = tx.Exec(_upPdInfoSQL, pi.Name, pi.Image, pi.ImageModel, pi.Status, pi.Rank, pi.ID); err != nil {
err = errors.Wrapf(err, "TxAddPendantPrices tx.Exec(%s,%s,%s,%d,%d,%d)", pi.Name, pi.Image, pi.ImageModel, pi.Status, pi.Rank, pi.ID)
return
}
return res.RowsAffected()
}
// UpPendantInfoStatus update pendant info status.
func (d *Dao) UpPendantInfoStatus(c context.Context, pid int64, status int8) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _upPdInfoStatusSQL, status, pid); err != nil {
err = errors.Wrapf(err, "UpPendantGroupStatus tx.Exec(%d,%d)", status, pid)
return
}
return res.RowsAffected()
}
// PendantInfoAll pendant info all.
func (d *Dao) PendantInfoAll(c context.Context, pn, ps int) (pis []*model.PendantInfo, pids []int64, err error) {
var (
gid, groupRank sql.NullInt64
groupName sql.NullString
rows *xsql.Rows
offset = (pn - 1) * ps
)
if rows, err = d.db.Query(c, _pdInfoAllSQL, offset, ps); err != nil {
err = errors.Wrapf(err, "PendantInfoAll d.db.Query(%d,%d)", offset, ps)
return
}
defer rows.Close()
for rows.Next() {
pi := new(model.PendantInfo)
if err = rows.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank, &gid, &groupName, &groupRank); err != nil {
err = errors.Wrap(err, "PendantInfoAll row.Scan()")
return
}
pi.GID = gid.Int64
pi.GroupName = groupName.String
pi.GroupRank = int16(groupRank.Int64)
pids = append(pids, pi.ID)
pis = append(pis, pi)
}
err = rows.Err()
return
}
// PendantGroupInfoTotal pendant group info total.
func (d *Dao) PendantGroupInfoTotal(c context.Context) (count int64, err error) {
row := d.db.QueryRow(c, _pdGroupInfoTotalSQL)
if err = row.Scan(&count); err != nil {
err = errors.Wrap(err, "d.dao.PendantGroupInfoTotal")
}
return
}
// PendantGroupsTotal pendant group total.
func (d *Dao) PendantGroupsTotal(c context.Context) (count int64, err error) {
row := d.db.QueryRow(c, _pdGroupsTotalSQL)
if err = row.Scan(&count); err != nil {
err = errors.Wrap(err, "d.dao.PendantGroupsTotal")
}
return
}
// PendantGroupRefsTotal pendant group refs total.
func (d *Dao) PendantGroupRefsTotal(c context.Context) (count int64, err error) {
row := d.db.QueryRow(c, _pdGroupRefsTotalSQL)
if err = row.Scan(&count); err != nil {
err = errors.Wrap(err, "d.dao.PendantGroupRefsTotal")
}
return
}
// PendantGroupRefsGidTotal pendant group refs total by gid.
func (d *Dao) PendantGroupRefsGidTotal(c context.Context, gid int64) (count int64, err error) {
row := d.db.QueryRow(c, _pdGroupRefsGidTotalSQL, gid)
if err = row.Scan(&count); err != nil {
err = errors.Wrap(err, "d.dao.PendantGroupRefsGidTotal")
}
return
}
// PendantGroups pendant group pagesize.
func (d *Dao) PendantGroups(c context.Context, pn, ps int) (pgs []*model.PendantGroup, err error) {
var (
rows *xsql.Rows
offset = (pn - 1) * ps
)
if rows, err = d.db.Query(c, _pdGroupsSQL, offset, ps); err != nil {
err = errors.Wrapf(err, "PendantGroups d.db.Query(%d,%d)", offset, ps)
return
}
defer rows.Close()
for rows.Next() {
pg := new(model.PendantGroup)
if err = rows.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
err = errors.Wrap(err, "PendantGroups row.Scan()")
return
}
pgs = append(pgs, pg)
}
err = rows.Err()
return
}
// PendantGroupAll pendant all group .
func (d *Dao) PendantGroupAll(c context.Context) (pgs []*model.PendantGroup, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, _pdGroupAllSQL); err != nil {
err = errors.Wrap(err, "PendantGroupAll d.db.Query(%d,%d)")
return
}
defer rows.Close()
for rows.Next() {
pg := new(model.PendantGroup)
if err = rows.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
err = errors.Wrap(err, "PendantGroupAll row.Scan()")
return
}
pgs = append(pgs, pg)
}
err = rows.Err()
return
}
// PendantGroupIDs pendant group in ids.
func (d *Dao) PendantGroupIDs(c context.Context, ids []int64) (pgs []*model.PendantGroup, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, fmt.Sprintf(_pdGroupIDsSQL, xstr.JoinInts(ids))); err != nil {
err = errors.Wrapf(err, "PendantGroupIDs d.db.Query(%s)", xstr.JoinInts(ids))
return
}
defer rows.Close()
for rows.Next() {
pg := new(model.PendantGroup)
if err = rows.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
err = errors.Wrap(err, "PendantGroupIDs row.Scan()")
return
}
pgs = append(pgs, pg)
}
err = rows.Err()
return
}
// PendantGroupID pendant group by id.
func (d *Dao) PendantGroupID(c context.Context, id int64) (pg *model.PendantGroup, err error) {
row := d.db.QueryRow(c, _pdGroupIDSQL, id)
if err != nil {
err = errors.Wrapf(err, "PendantGroupID d.db.Query(%d)", id)
return
}
pg = &model.PendantGroup{}
if err = row.Scan(&pg.ID, &pg.Name, &pg.Rank, &pg.Status); err != nil {
if err == sql.ErrNoRows {
err = nil
pg = nil
return
}
err = errors.Wrap(err, "PendantGroupID row.Scan")
}
return
}
// PendantInfoIDs pendant info in ids.
func (d *Dao) PendantInfoIDs(c context.Context, ids []int64) (pis []*model.PendantInfo, pim map[int64]*model.PendantInfo, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, fmt.Sprintf(_pdInfoIDsSQL, xstr.JoinInts(ids))); err != nil {
err = errors.Wrapf(err, "PendantInfoIDs d.db.Query(%s)", xstr.JoinInts(ids))
return
}
defer rows.Close()
pim = make(map[int64]*model.PendantInfo, len(ids))
for rows.Next() {
pi := new(model.PendantInfo)
if err = rows.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank); err != nil {
err = errors.Wrap(err, "PendantInfoIDs row.Scan()")
return
}
pis = append(pis, pi)
pim[pi.ID] = pi
}
err = rows.Err()
return
}
// PendantPriceIDs pendant price in ids.
func (d *Dao) PendantPriceIDs(c context.Context, ids []int64) (ppm map[int64][]*model.PendantPrice, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, fmt.Sprintf(_pdPriceIDsSQL, xstr.JoinInts(ids))); err != nil {
err = errors.Wrapf(err, "PendantPriceIDs d.db.Query(%s)", xstr.JoinInts(ids))
return
}
defer rows.Close()
ppm = make(map[int64][]*model.PendantPrice, len(ids))
for rows.Next() {
pp := new(model.PendantPrice)
if err = rows.Scan(&pp.PID, &pp.TP, &pp.Price); err != nil {
err = errors.Wrap(err, "PendantPriceIDs row.Scan()")
return
}
ppm[pp.PID] = append(ppm[pp.PID], pp)
}
err = rows.Err()
return
}
// PendantGroupRefRanks pendant group ref pagesize by rank.
func (d *Dao) PendantGroupRefRanks(c context.Context, pn, ps int) (prs []*model.PendantGroupRef, err error) {
var (
rows *xsql.Rows
offset = (pn - 1) * ps
)
if rows, err = d.db.Query(c, _pdGroupRefRanksSQL, offset, ps); err != nil {
err = errors.Wrapf(err, "PendantGroupRefRanks d.db.Query(%d,%d)", offset, ps)
return
}
defer rows.Close()
for rows.Next() {
pr := new(model.PendantGroupRef)
if err = rows.Scan(&pr.GID, &pr.PID); err != nil {
err = errors.Wrap(err, "PendantGroupRefRanks row.Scan()")
return
}
prs = append(prs, pr)
}
err = rows.Err()
return
}
// PendantGroupPIDs pendant group ref pagesize.
func (d *Dao) PendantGroupPIDs(c context.Context, gid int64, pn, ps int) (pids []int64, err error) {
var (
rows *xsql.Rows
offset = (pn - 1) * ps
)
if rows, err = d.db.Query(c, _pdGroupRefsSQL, gid, offset, ps); err != nil {
err = errors.Wrapf(err, "PendantGroupPIDs d.db.Query(%d,%d,%d)", gid, offset, ps)
return
}
defer rows.Close()
var pid int64
for rows.Next() {
if err = rows.Scan(&pid); err != nil {
err = errors.Wrap(err, "PendantGroupPIDs row.Scan()")
return
}
pids = append(pids, pid)
}
err = rows.Err()
return
}
// PendantInfoID pendant info.
func (d *Dao) PendantInfoID(c context.Context, id int64) (pi *model.PendantInfo, err error) {
row := d.db.QueryRow(c, _pdInfoIDSQL, id)
if err != nil {
err = errors.Wrapf(err, "PendantInfoID d.db.QueryRow(%d)", id)
return
}
pi = &model.PendantInfo{}
if err = row.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank); err != nil {
if err == sql.ErrNoRows {
err = nil
pi = nil
return
}
err = errors.Wrap(err, "PendantInfoID row.Scan")
}
return
}
// PendantInfoAllNoPage pendant info no page.
func (d *Dao) PendantInfoAllNoPage(c context.Context) (pis []*model.PendantInfo, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, _pdInfoAllNoPageSQL); err != nil {
err = errors.Wrap(err, "PendantInfoAllOnSale d.db.Query()")
return
}
defer rows.Close()
for rows.Next() {
pi := new(model.PendantInfo)
if err = rows.Scan(&pi.ID, &pi.Name, &pi.Image, &pi.ImageModel, &pi.Status, &pi.Rank); err != nil {
err = errors.Wrap(err, "PendantInfoAllOnSale row.Scan()")
return
}
pis = append(pis, pi)
}
err = rows.Err()
return
}
// BuildOrderInfoSQL build a order sql string.
func (d *Dao) BuildOrderInfoSQL(c context.Context, arg *model.ArgPendantOrder, tp string) (sql string, values []interface{}) {
values = make([]interface{}, 0, 5)
var (
cond []string
condStr string
)
if arg.UID != 0 {
cond = append(cond, "mid = ?")
values = append(values, arg.UID)
}
if arg.PID != 0 {
cond = append(cond, "pid = ?")
values = append(values, arg.PID)
}
if arg.Status != 0 {
cond = append(cond, "status = ?")
values = append(values, arg.Status)
}
if arg.PayID != "" {
cond = append(cond, "pay_id = ?")
values = append(values, arg.PayID)
}
if arg.Start != 0 {
cond = append(cond, "mtime >= ?")
values = append(values, arg.Start)
}
if arg.End != 0 {
cond = append(cond, "mtime <= ?")
values = append(values, arg.End)
}
if tp == "info" {
condStr = d.joinStrings(cond)
if condStr != "" {
sql = fmt.Sprintf(_orderHistorysSQL+" %s %s ", "WHERE", condStr, "ORDER BY mtime DESC LIMIT ?,?")
} else {
sql = fmt.Sprintf(_orderHistorysSQL+" %s ", condStr, "ORDER BY mtime DESC LIMIT ?,?")
}
values = append(values, (arg.PN-1)*arg.PS, arg.PS)
} else if tp == "count" {
condStr = d.joinStrings(cond)
if condStr != "" {
sql = fmt.Sprintf(_countOrderHistorysSQL+" %s", "WHERE", condStr)
} else {
sql = fmt.Sprintf(_countOrderHistorysSQL, condStr)
}
}
return
}
func (d *Dao) joinStrings(is []string) string {
if len(is) == 0 {
return ""
}
if len(is) == 1 {
return is[0]
}
var bfPool = sync.Pool{
New: func() interface{} {
return bytes.NewBuffer([]byte{})
},
}
buf := bfPool.Get().(*bytes.Buffer)
for _, i := range is {
buf.WriteString(i)
buf.WriteString(" AND ")
}
if buf.Len() > 0 {
buf.Truncate(buf.Len() - 4)
}
s := buf.String()
buf.Reset()
bfPool.Put(buf)
return s
}
// MaxOrderHistory max order history.
func (d *Dao) MaxOrderHistory(c context.Context) (max int64, err error) {
row := d.db.QueryRow(c, _maxOrderHistorysSQL)
if err != nil {
err = errors.Wrap(err, "MaxOrderHistory d.db.QueryRow()")
return
}
if err = row.Scan(&max); err != nil {
if err == sql.ErrNoRows {
err = nil
max = 0
return
}
err = errors.Wrap(err, "MaxOrderHistory row.Scan")
}
return
}
// CountOrderHistory count order history.
func (d *Dao) CountOrderHistory(c context.Context, arg *model.ArgPendantOrder) (total int64, err error) {
sqlstr, values := d.BuildOrderInfoSQL(c, arg, "count")
row := d.db.QueryRow(c, sqlstr, values...)
if err != nil {
err = errors.Wrap(err, "CountOrderHistory d.db.QueryRow()")
return
}
if err = row.Scan(&total); err != nil {
if err == sql.ErrNoRows {
err = nil
total = 0
return
}
err = errors.Wrap(err, "CountOrderHistory row.Scan")
}
return
}
// OrderHistorys get order historys.
func (d *Dao) OrderHistorys(c context.Context, arg *model.ArgPendantOrder) (pos []*model.PendantOrder, pids []int64, err error) {
var rows *xsql.Rows
sqlstr, values := d.BuildOrderInfoSQL(c, arg, "info")
if rows, err = d.db.Query(c, sqlstr, values...); err != nil {
err = errors.Wrap(err, "OrderHistorys d.db.Query()")
return
}
defer rows.Close()
for rows.Next() {
po := new(model.PendantOrder)
if err = rows.Scan(&po.UID, &po.OrderID, &po.PayID, &po.AppID, &po.Status, &po.PID, &po.TimeLength, &po.Cost, &po.BuyTime, &po.PayType); err != nil {
err = errors.Wrap(err, "OrderHistorys row.Scan()")
return
}
pos = append(pos, po)
pids = append(pids, po.PID)
}
err = rows.Err()
return
}
// PendantPKGs get pendant pkgs.
func (d *Dao) PendantPKGs(c context.Context, uid int64) (pkgs []*model.PendantPKG, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, _pdPKGsUIDSQL, uid); err != nil {
err = errors.Wrapf(err, "PendantPKGs d.db.Query(%d)", uid)
return
}
defer rows.Close()
for rows.Next() {
pkg := new(model.PendantPKG)
if err = rows.Scan(&pkg.UID, &pkg.PID, &pkg.Expires, &pkg.TP, &pkg.Status, &pkg.IsVip); err != nil {
err = errors.Wrap(err, "PendantPKGs row.Scan()")
return
}
pkgs = append(pkgs, pkg)
}
err = rows.Err()
return
}
// PendantPKGUIDs get pendant pkgs by muilti uid.
func (d *Dao) PendantPKGUIDs(c context.Context, uids []int64, pid int64) (pkgs []*model.PendantPKG, err error) {
var rows *xsql.Rows
if rows, err = d.db.Query(c, fmt.Sprintf(_pdPKGUIDsSQL, xstr.JoinInts(uids)), pid); err != nil {
err = errors.Wrapf(err, "PendantPKGUIDs d.db.Query(%s,%d)", xstr.JoinInts(uids), pid)
return
}
defer rows.Close()
for rows.Next() {
pkg := new(model.PendantPKG)
if err = rows.Scan(&pkg.ID, &pkg.UID, &pkg.PID, &pkg.Expires, &pkg.TP, &pkg.Status, &pkg.IsVip); err != nil {
err = errors.Wrap(err, "PendantPKGUIDs row.Scan()")
return
}
pkgs = append(pkgs, pkg)
}
err = rows.Err()
return
}
// PendantPKG get pendant in pkg.
func (d *Dao) PendantPKG(c context.Context, uid, pid int64) (pkg *model.PendantPKG, err error) {
row := d.db.QueryRow(c, _pdPKGUIDSQL, uid, pid)
if err != nil {
err = errors.Wrapf(err, "PendantPKG d.db.QueryRow(%d,%d)", uid, pid)
return
}
pkg = &model.PendantPKG{}
if err = row.Scan(&pkg.ID, &pkg.UID, &pkg.PID, &pkg.Expires, &pkg.TP, &pkg.Status, &pkg.IsVip); err != nil {
if err == sql.ErrNoRows {
err = nil
pkg = nil
return
}
err = errors.Wrap(err, "PendantPKG row.Scan")
}
return
}
// PendantEquipUID pendant equip by uid.
func (d *Dao) PendantEquipUID(c context.Context, uid int64) (pkg *model.PendantPKG, err error) {
row := d.db.QueryRow(c, _pdEquipUIDSQL, uid, time.Now().Unix())
if err != nil {
err = errors.Wrapf(err, "PendantEquipUID d.db.QueryRow(%d)", uid)
return
}
pkg = &model.PendantPKG{}
if err = row.Scan(&pkg.PID, &pkg.Expires); err != nil {
if err == sql.ErrNoRows {
err = nil
pkg = nil
return
}
err = errors.Wrap(err, "PendantEquipUID row.Scan")
}
return
}
// PendantOperLog get pendant operation log.
func (d *Dao) PendantOperLog(c context.Context, pn, ps int) (opers []*model.PendantOperLog, uids []int64, err error) {
var (
rows *xsql.Rows
offset = (pn - 1) * ps
)
if rows, err = d.db.Query(c, _pdOperationLogSQL, offset, ps); err != nil {
err = errors.Wrapf(err, "PendantOperLog d.db.Query(%d,%d)", offset, ps)
return
}
defer rows.Close()
for rows.Next() {
oper := new(model.PendantOperLog)
if err = rows.Scan(&oper.OID, &oper.Action, &oper.UID, &oper.PID, &oper.SourceType, &oper.CTime, &oper.MTime); err != nil {
err = errors.Wrap(err, "PendantOperLog row.Scan()")
return
}
opers = append(opers, oper)
uids = append(uids, oper.UID)
}
err = rows.Err()
return
}
// PendantOperationLogTotal pendant operation log total.
func (d *Dao) PendantOperationLogTotal(c context.Context) (count int64, err error) {
row := d.db.QueryRow(c, _pdOperationLogTotalSQL)
if err = row.Scan(&count); err != nil {
err = errors.Wrap(err, "d.dao.PendantOperationLogTotal")
}
return
}

View File

@@ -0,0 +1,54 @@
package dao
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)
}
// PendantPointCache get new pendant info red point cache.
func (d *Dao) PendantPointCache(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
}
// SetPendantPointCache set red point cache.
func (d *Dao) SetPendantPointCache(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
}
// DelPendantPointCache delete new pendant info red point cache.
func (d *Dao) DelPendantPointCache(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,54 @@
package dao
import (
"context"
"strconv"
"go-common/library/cache/redis"
"go-common/library/log"
)
const (
_pendantPKG = "pkg_"
_pendantEquip = "pe_"
)
func keyPendantPKG(uid int64) string {
return _pendantPKG + strconv.FormatInt(uid, 10)
}
func keyEquip(uid int64) string {
return _pendantEquip + strconv.FormatInt(uid, 10)
}
// DelPKGCache del package cache
func (d *Dao) DelPKGCache(c context.Context, uids []int64) (err error) {
var (
args = redis.Args{}
conn = d.redis.Get(c)
)
defer conn.Close()
for _, v := range uids {
args = args.Add(keyPendantPKG(v))
}
if err = conn.Send("DEL", args...); err != nil {
log.Error("conn.Send(DEL, %s) error(%v)", args, err)
}
return
}
// DelEquipsCache del batch equip cache .
func (d *Dao) DelEquipsCache(c context.Context, uids []int64) (err error) {
var (
args = redis.Args{}
conn = d.redis.Get(c)
)
defer conn.Close()
for _, v := range uids {
args = args.Add(keyEquip(v))
}
if err = conn.Send("DEL", args...); err != nil {
log.Error("conn.Send(DEL, %s) error(%v)", args, err)
}
return
}

View File

@@ -0,0 +1,22 @@
package dao
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func Test_DelPKGCache(t *testing.T) {
Convey("return someting", t, func() {
err := d.DelPKGCache(context.Background(), []int64{22, 11})
So(err, ShouldBeNil)
})
}
func Test_DelEquipsCache(t *testing.T) {
Convey("return someting", t, func() {
err := d.DelEquipsCache(context.Background(), []int64{22, 11})
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,375 @@
package dao
import (
"context"
"math/rand"
"testing"
"go-common/app/admin/main/usersuit/model"
. "github.com/smartystreets/goconvey/convey"
)
func Test_AddPendantGroup(t *testing.T) {
Convey("return someting", t, func() {
pg := &model.PendantGroup{
Name: "dasdasd",
Rank: 22,
}
gid, err := d.AddPendantGroup(context.Background(), pg)
So(err, ShouldBeNil)
So(gid, ShouldNotBeNil)
})
}
func Test_TxAddPendantGroupRef(t *testing.T) {
Convey("return someting", t, func() {
pr := &model.PendantGroupRef{
GID: 11,
PID: int64(rand.Int31()),
}
tx, err := d.BeginTran(context.Background())
So(err, ShouldBeNil)
effect, err := d.TxAddPendantGroupRef(tx, pr)
So(err, ShouldBeNil)
defer func() {
if err != nil || effect == 0 {
tx.Rollback()
return
}
tx.Commit()
}()
So(err, ShouldBeNil)
})
}
func Test_TxAddPendantInfo(t *testing.T) {
Convey("return someting", t, func() {
pi := &model.PendantInfo{
Name: "dasdasdsads",
Image: "dasdds",
ImageModel: "xxsss",
Rank: 11,
}
tx, err := d.BeginTran(context.Background())
if err != nil {
So(err, ShouldBeNil)
}
id, err := d.TxAddPendantInfo(tx, pi)
if err != nil {
So(err, ShouldBeNil)
}
defer func() {
if err != nil || id == 0 {
tx.Rollback()
return
}
tx.Commit()
}()
So(err, ShouldBeNil)
})
}
func Test_TxAddPendantPrices(t *testing.T) {
Convey("return someting", t, func() {
pp := &model.PendantPrice{
PID: 22,
TP: 1,
Price: 22,
}
tx, err := d.BeginTran(context.Background())
if err != nil {
So(err, ShouldBeNil)
}
effect, err := d.TxAddPendantPrices(tx, pp)
if err != nil {
So(err, ShouldBeNil)
}
defer func() {
if err != nil || effect == 0 {
tx.Rollback()
return
}
tx.Commit()
}()
So(err, ShouldBeNil)
})
}
func Test_AddPendantPKG(t *testing.T) {
Convey("return someting", t, func() {
pkg := &model.PendantPKG{
UID: int64(rand.Int31()),
PID: 11,
Expires: 12312323,
}
_, err := d.AddPendantPKG(context.Background(), pkg)
So(err, ShouldBeNil)
})
}
func Test_TxAddPendantPKGs(t *testing.T) {
uid := int64(rand.Int31())
Convey("return someting", t, func() {
var pkgs []*model.PendantPKG
pkgs = append(pkgs, &model.PendantPKG{UID: uid, PID: 11, Expires: 12312323}, &model.PendantPKG{UID: uid, PID: 22, Expires: 12312323})
tx, err := d.BeginTran(context.Background())
if err != nil {
So(err, ShouldBeNil)
}
effect, err := d.TxAddPendantPKGs(tx, pkgs)
if err != nil {
So(err, ShouldBeNil)
}
defer func() {
if err != nil || effect == 0 {
tx.Rollback()
return
}
tx.Commit()
}()
So(err, ShouldBeNil)
})
}
func Test_AddPendantEquip(t *testing.T) {
Convey("return someting", t, func() {
pkg := &model.PendantPKG{
UID: 22,
PID: 11,
Expires: 12312323,
}
_, err := d.AddPendantEquip(context.Background(), pkg)
So(err, ShouldBeNil)
})
}
func Test_AddPendantOperLog(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.AddPendantOperLog(context.Background(), 1, []int64{1}, 1, "sdsadasd")
So(err, ShouldBeNil)
})
}
func Test_TxUpPendantGroupRef(t *testing.T) {
Convey("return someting", t, func() {
tx, err := d.BeginTran(context.Background())
if err != nil {
So(err, ShouldBeNil)
}
effect, err := d.TxUpPendantGroupRef(tx, 22, 11)
if err != nil {
So(err, ShouldBeNil)
}
defer func() {
if err != nil || effect == 0 {
tx.Rollback()
return
}
tx.Commit()
}()
So(err, ShouldBeNil)
})
}
func Test_TxUpPendantPKGs(t *testing.T) {
Convey("return someting", t, func() {
var pkgs []*model.PendantPKG
pkgs = append(pkgs, &model.PendantPKG{UID: 22, PID: 11, Expires: 12312323}, &model.PendantPKG{UID: 11, PID: 22, Expires: 12312323})
tx, err := d.BeginTran(context.Background())
if err != nil {
So(err, ShouldBeNil)
}
effect, err := d.TxUpPendantPKGs(tx, pkgs)
if err != nil {
So(err, ShouldBeNil)
}
defer func() {
if err != nil || effect == 0 {
tx.Rollback()
return
}
tx.Commit()
}()
So(err, ShouldBeNil)
})
}
func Test_UpPendantGroup(t *testing.T) {
Convey("return someting", t, func() {
pg := &model.PendantGroup{
Name: "weqweqw",
Rank: 2,
Status: 1,
ID: 22,
}
_, err := d.UpPendantGroup(context.Background(), pg)
So(err, ShouldBeNil)
})
}
func Test_UpPendantGroupStatus(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.UpPendantGroupStatus(context.Background(), 22, 1)
So(err, ShouldBeNil)
})
}
func Test_TxUpPendantInfo(t *testing.T) {
Convey("return someting", t, func() {
pi := &model.PendantInfo{
Name: "dasdasdsads",
Image: "dasdds",
ImageModel: "xxsss",
Rank: 11,
ID: 22,
}
tx, err := d.BeginTran(context.Background())
if err != nil {
So(err, ShouldBeNil)
}
effect, err := d.TxUpPendantInfo(tx, pi)
if err != nil {
So(err, ShouldBeNil)
}
defer func() {
if err != nil || effect == 0 {
tx.Rollback()
return
}
tx.Commit()
}()
So(err, ShouldBeNil)
})
}
func Test_UpPendantInfoStatus(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.UpPendantInfoStatus(context.Background(), 22, 1)
So(err, ShouldBeNil)
})
}
func Test_PendantInfoAll(t *testing.T) {
Convey("return someting", t, func() {
_, _, err := d.PendantInfoAll(context.Background(), 1, 2)
So(err, ShouldBeNil)
})
}
func Test_PendantGroupIDs(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantGroupIDs(context.Background(), []int64{11, 22})
So(err, ShouldBeNil)
})
}
func Test_PendantGroupID(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantGroupID(context.Background(), 12)
So(err, ShouldBeNil)
})
}
func Test_PendantInfoIDs(t *testing.T) {
Convey("return someting", t, func() {
_, _, err := d.PendantInfoIDs(context.Background(), []int64{11, 22})
So(err, ShouldBeNil)
})
}
func Test_PendantPriceIDs(t *testing.T) {
Convey("return someting", t, func() {
ppm, err := d.PendantPriceIDs(context.Background(), []int64{11, 22})
So(err, ShouldBeNil)
So(ppm, ShouldNotBeNil)
})
}
func Test_PendantGroupRefRanks(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantGroupRefRanks(context.Background(), 1, 2)
So(err, ShouldBeNil)
})
}
func Test_PendantGroupPIDs(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantGroupPIDs(context.Background(), 11, 1, 2)
So(err, ShouldBeNil)
})
}
func Test_PendantInfoID(t *testing.T) {
Convey("return someting", t, func() {
pi, err := d.PendantInfoID(context.Background(), 11)
So(err, ShouldBeNil)
So(pi, ShouldNotBeNil)
})
}
func Test_PendantInfoAllOnSale(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantInfoAllNoPage(context.Background())
So(err, ShouldBeNil)
})
}
func Test_CountOrderHistory(t *testing.T) {
Convey("return someting", t, func() {
arg := &model.ArgPendantOrder{}
_, err := d.CountOrderHistory(context.Background(), arg)
So(err, ShouldBeNil)
})
}
func Test_OrderHistorys(t *testing.T) {
Convey("return someting", t, func() {
arg := &model.ArgPendantOrder{}
_, _, err := d.OrderHistorys(context.Background(), arg)
So(err, ShouldBeNil)
})
}
func Test_PendantPKGs(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantPKGs(context.Background(), 112)
So(err, ShouldBeNil)
})
}
func Test_PendantPKGUIDs(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantPKGUIDs(context.Background(), []int64{11, 22}, 112)
So(err, ShouldBeNil)
})
}
func Test_PendantPKG(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantPKG(context.Background(), 11, 112)
So(err, ShouldBeNil)
})
}
func Test_PendantEquipUID(t *testing.T) {
Convey("return someting", t, func() {
_, err := d.PendantEquipUID(context.Background(), 11)
So(err, ShouldBeNil)
})
}
func Test_PendantOperLog(t *testing.T) {
Convey("return someting", t, func() {
_, _, err := d.PendantOperLog(context.Background(), 1, 2)
So(err, ShouldBeNil)
})
}
func Test_PendantOperationLogTotal(t *testing.T) {
Convey("return someting", t, func() {
total, err := d.PendantOperationLogTotal(context.Background())
So(err, ShouldBeNil)
So(total, ShouldNotBeNil)
})
}

View File

@@ -0,0 +1,74 @@
package dao
import (
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"io"
"net/http"
"strconv"
"go-common/library/log"
)
const (
_uploadURL = "/bfs/%s/%s"
_template = "%s\n%s\n%s\n%d\n"
_method = "PUT"
)
// Upload upload picture or log file to bfs
func (d *Dao) Upload(c context.Context, fileName, fileType string, expire int64, body io.Reader) (location string, err error) {
var (
url string
req *http.Request
resp *http.Response
code int
)
client := &http.Client{}
url = fmt.Sprintf(d.bfs+_uploadURL, d.bucket, fileName)
if req, err = http.NewRequest(_method, url, body); err != nil {
log.Error("http.NewRequest() Upload(%v) error(%v)", url, err)
return
}
authorization := authorize(d.key, d.secret, _method, d.bucket, fileName, expire)
req.Header.Set("Host", d.bfs)
req.Header.Add("Date", fmt.Sprint(expire))
req.Header.Add("Authorization", authorization)
req.Header.Add("Content-Type", fileType)
resp, err = client.Do(req)
if err != nil {
log.Error("resp.Do(%s) error(%v)", url, err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("status code error:%v", resp.StatusCode)
return
}
code, err = strconv.Atoi(resp.Header.Get("code"))
if err != nil || code != http.StatusOK {
err = fmt.Errorf("response code error:%v", code)
return
}
location = resp.Header.Get("Location")
return
}
// authorize returns authorization for upload file to bfs
func authorize(key, secret, method, bucket, file string, expire int64) (authorization string) {
var (
content string
mac hash.Hash
signature string
)
content = fmt.Sprintf(_template, method, bucket, file, expire)
mac = hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(content))
signature = base64.StdEncoding.EncodeToString(mac.Sum(nil))
authorization = fmt.Sprintf("%s:%s:%d", key, signature, expire)
return
}