419 lines
10 KiB
Go
419 lines
10 KiB
Go
|
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
|
||
|
}
|