go-common/app/service/live/xrewardcenter/dao/anchorReward/dao.go

419 lines
10 KiB
Go
Raw Normal View History

2019-04-22 10:49:16 +00:00
package anchorReward
import (
"context"
"fmt"
"go-common/app/service/live/xrewardcenter/conf"
AnchorTaskModel "go-common/app/service/live/xrewardcenter/model/anchorTask"
model "go-common/app/service/live/xrewardcenter/model/anchorTask"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/orm"
xsql "go-common/library/database/sql"
"go-common/library/log"
xtime "go-common/library/time"
"math"
"time"
"bytes"
"encoding/json"
bm "go-common/library/net/http/blademaster"
"io/ioutil"
"net/http"
"strconv"
"github.com/jinzhu/gorm"
)
// OrderExist .
const (
// 缓存过期时间
rewardConfExpire = 3600
rewardConfPrefix = "rconf_v1_%d"
)
// Dao dao
type Dao struct {
c *conf.Config
mc *memcache.Pool
redis *redis.Pool
orm *gorm.DB
db *xsql.DB
keyRewardConfExpire int32
client *bm.Client
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
mc: memcache.NewPool(c.Memcache),
redis: redis.NewPool(c.Redis),
db: xsql.NewMySQL(c.MySQL),
orm: orm.NewMySQL(c.ORM),
keyRewardConfExpire: rewardConfExpire,
client: bm.NewClient(c.HTTPClient),
}
dao.initORM()
return
}
func keyRewardConf(id int64) string {
return fmt.Sprintf(rewardConfPrefix, id)
}
func (d *Dao) initORM() {
d.orm.LogMode(true)
d.orm.SingularTable(true)
}
//go:generate $GOPATH/src/go-common/app/tool/cache/gen
type _cache interface {
// cache: -sync=true -nullcache=&model.AnchorRewardConf{ID:-1} -check_null_code=$.ID==-1
RewardConf(c context.Context, id int64) (*model.AnchorRewardConf, error)
}
//go:generate $GOPATH/src/go-common/app/tool/cache/mc
type _mc interface {
// 获取奖励配置
// mc: -key=keyRewardConf
CacheRewardConf(c context.Context, id int64) (*model.AnchorRewardConf, error)
// 保存奖励配置
// mc: -key=keyRewardConf -expire=d.keyRewardConfExpire -encode=json|gzip
AddCacheRewardConf(c context.Context, id int64, value *model.AnchorRewardConf) error
}
// AddReward add Reward to a user.
func (d *Dao) AddReward(c context.Context, iRewardID int64, uid int64, iSource int64, iRoomid int64, iLifespan int64) (err error) {
//aReward, _ := getRewardConfByLid(iRewardID)
m, _ := time.ParseDuration(fmt.Sprintf("+%dh", iLifespan))
arg := &AnchorTaskModel.AnchorReward{
Uid: uid,
RewardId: iRewardID,
Roomid: iRoomid,
Source: iSource,
AchieveTime: xtime.Time(time.Now().Unix()),
ExpireTime: xtime.Time(time.Now().Add(m).Unix()),
Status: model.RewardUnUsed,
}
//spew.Dump
// (arg)
if err := d.orm.Create(arg).Error; err != nil {
log.Error("addReward(%v) error(%v)", arg, err)
return err
}
if err := d.SetNewReward(c, uid, int64(1)); err != nil {
log.Error("addRewardMc(%v) error(%v)", uid, err)
}
if err := d.SetHasReward(c, uid, int64(1)); err != nil {
log.Error("SetHasReward(%v) error(%v)", uid, err)
}
log.Info("addReward (%v) succ", arg)
return
}
//GetByUidPage get reward by uid and page.
func (d *Dao) GetByUidPage(c context.Context, uid int64, page int64, pageSize int64, status []int64) (pager *model.AnchorRewardPager, list []*model.AnchorRewardObject, err error) {
err = nil
pager = &model.AnchorRewardPager{}
list = []*model.AnchorRewardObject{}
var (
Items []*AnchorTaskModel.AnchorReward
count int64
)
iOffSet := (page - 1) * pageSize
db := d.orm.Where("status in (?)", status).Where("uid=?", uid)
db.Model(&AnchorTaskModel.AnchorReward{}).Count(&count)
if err = db.Model(&AnchorTaskModel.AnchorReward{}).Limit(pageSize).Offset(iOffSet).Order("mtime DESC, id").Find(&Items).Error; err != nil {
log.Error("get ap_anchor_task_reward_list uid(%v) error(%v)", uid, err)
return
}
for _, v := range Items {
aReward, err := d.RewardConf(c, v.RewardId)
if err != nil {
log.Error("RewardConf(%v) error(%v)", v.RewardId, err)
return pager, list, err
}
if aReward == nil {
continue
}
aListItem := &model.AnchorRewardObject{
Id: v.Id,
RewardType: aReward.RewardType,
Status: v.Status,
RewardId: v.RewardId,
Name: aReward.Name,
Icon: aReward.Icon,
AchieveTime: v.AchieveTime.Time().Format("2006-01-02 15:04:05"),
ExpireTime: v.ExpireTime.Time().Format("2006-01-02 15:04:05"),
UseTime: v.UseTime.Time().Format("2006-01-02 15:04:05"),
Source: v.Source,
RewardIntro: aReward.RewardIntro,
}
list = append(list, aListItem)
}
pager = &model.AnchorRewardPager{
Page: page,
PageSize: pageSize,
TotalPage: int64(math.Ceil(float64(count) / float64(pageSize))),
TotalCount: count,
}
return
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) (err error) {
if d.orm != nil {
d.orm.DB().PingContext(c)
}
err = d.pingMC(c)
return
}
// GetById get reward by id.
func (d *Dao) GetById(id int64) (reward *model.AnchorReward, err error) {
rewards := []*model.AnchorReward{}
if err := d.orm.Model(&model.AnchorReward{}).Find(&rewards, "id=?", id).Error; err != nil {
log.Error("getRewardById (%v) error(%v)", id, err)
return reward, err
}
if len(rewards) != 0 {
reward = rewards[0]
}
return
}
// UseReward use reward by id.
func (d *Dao) UseReward(id int64, usePlat string) (rst bool, err error) {
if err := d.orm.
Model(&model.AnchorReward{}).
Where("id=?", id).
Update(map[string]interface{}{"status": model.RewardUsed, "use_plat": usePlat, "use_time": xtime.Time(time.Now().Unix())}).Error; err != nil {
log.Error("useReward (%v) error(%v)", id, err)
return rst, err
}
rst = true
return
}
// HasNewReward .
func (d *Dao) HasNewReward(c context.Context, uid int64) (rst int64, err error) {
rst, _ = d.GetNewReward(c, uid)
return
}
func (d *Dao) findByUid(uid int64, limitOne bool) (reward *model.AnchorReward, err error) {
rewards := []*model.AnchorReward{}
db := d.orm.Where("uid=?", uid)
if limitOne {
db = db.Limit(1)
}
if err := db.Model(&model.AnchorReward{}).Find(&rewards).Error; err != nil {
log.Error("getRewardById (%v) error(%v)", uid, err)
return reward, err
}
if len(rewards) != 0 {
reward = rewards[0]
}
return
}
// HasReward returns if a user have reward.
func (d *Dao) HasReward(c context.Context, uid int64) (r int64, err error) {
rst, err := d.GetHasReward(c, uid)
if err != nil {
if err == memcache.ErrNotFound {
reward, err2 := d.findByUid(uid, true)
if err2 != nil {
return rst, err2
}
if reward != nil {
rst = int64(1)
d.SetHasReward(c, uid, rst)
} else {
rst = int64(0)
d.SetHasReward(c, uid, rst)
}
return rst, err
}
log.Error("HasReward(%v) error(%v)", uid, err)
return rst, err
}
return rst, err
}
// CheckOrderID check orderid is valid.
func (d *Dao) CheckOrderID(c context.Context, id string) (exist int64, err error) {
exist = 0
if exist, err = d.GetOrder(c, id); err != nil {
//spew.Dump(exist, err)
if err == memcache.ErrNotFound {
err = nil
}
return exist, err
}
return exist, err
}
// SaveOrderID save order id.
func (d *Dao) SaveOrderID(c context.Context, id string) error {
err := d.SaveOrder(c, id)
return err
}
// SetExpire .
func (d *Dao) SetExpire(now time.Time) (err error) {
var (
db = d.orm
)
setMap := map[string]interface{}{
"status": model.RewardExpired,
}
if err = db.Model(model.AnchorReward{}).
Where("status=? AND reward_id = ? AND expire_time <= ?", model.RewardUnUsed, 1, now.Format("2006-01-02 15:04:05")).
Update(setMap).
Error; err != nil {
log.Error("SetExpire (%v) error(%v)", setMap, err)
return err
}
return
}
// CountExpire .
func (d *Dao) CountExpire(interval int64, now time.Time) (err error) {
var (
c = context.TODO()
db = d.orm
result = &[]model.AnchorReward{}
)
dur, _ := time.ParseDuration("-" + strconv.FormatInt(interval, 10) + "s")
begin := now.Add(dur)
//spew.Dump(begin.Format("2006-01-02 15:04:05"))
//spew.Dump(now.Format("2006-01-02 15:04:05"))
sqlTemp :=
"SELECT * FROM ap_anchor_task_reward_list WHERE status = ? AND expire_time > ? AND expire_time <= ? AND reward_id= ?"
db.Raw(sqlTemp,
model.RewardExpired,
begin.Format("2006-01-02 15:04:05"),
now.Format("2006-01-02 15:04:05"),
1).Scan(&result)
for _, v := range *result {
d.AddExpireCountCache(c, fmt.Sprintf(model.CountExpireUserKey, v.Uid), model.ExpireCountTime)
}
return
}
// SendBroadcastV2 .
func (d *Dao) SendBroadcastV2(c context.Context, uid int64, roomid int64, rewardId int64) (err error) {
log.Info("send reward broadcast begin:%d", roomid)
var endPoint string = fmt.Sprintf("http://live-dm.bilibili.co/dm/1/push?cid=%d&ensure=1", roomid)
postJson := make(map[string]interface{})
postJson["cmd"] = "new_anchor_reward"
postJson["uid"] = uid
postJson["roomid"] = roomid
postJson["reward_id"] = rewardId
bytesData, err := json.Marshal(postJson)
if err != nil {
log.Error("json.Marshal(%v) error(%v)", postJson, err)
return
}
req, err := http.NewRequest("POST", endPoint, bytes.NewReader(bytesData))
req.Header.Add("Content-Type", "application/json")
if err != nil {
log.Error("http.NewRequest(%v) url(%v) error(%v)", postJson, endPoint, err)
return
}
var v interface{}
if err = d.client.Do(c, req, v); err != nil {
log.Error("s.client.Do error(%v) res (%v)", err, v)
return
}
log.Info("s.client.Do endpoint (%v) req (%v) res (%v)", endPoint, postJson, v)
return
}
// SendBroadcast .
func (d *Dao) SendBroadcast(uid int64, roomid int64, rewardId int64) (err error) {
log.Info("send reward broadcast begin:%d", roomid)
var endPoint = fmt.Sprintf("http://live-dm.bilibili.co/dm/1/push?cid=%d&ensure=1", roomid)
postJson := make(map[string]interface{})
postJson["cmd"] = "new_anchor_reward"
postJson["uid"] = uid
postJson["roomid"] = roomid
postJson["reward_id"] = rewardId
bytesData, err := json.Marshal(postJson)
if err != nil {
log.Error("json.Marshal(%v) error(%v)", postJson, err)
return
}
req, err := http.NewRequest("POST", endPoint, bytes.NewReader(bytesData))
req.Header.Add("Content-Type", "application/json")
if err != nil {
log.Error("http.NewRequest(%v) url(%v) error(%v)", postJson, endPoint, err)
return
}
client := http.Client{
Timeout: time.Second,
}
// use httpClient to send request
response, err := client.Do(req)
if err != nil {
log.Error("sending request to API endpoint(%v) error(%v)", req, err)
return
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Error("parse resp body(%v) error(%v)", body, err)
}
log.Info("send reward broadcast end:%d", roomid)
return
}