dao.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. package anchorReward
  2. import (
  3. "context"
  4. "fmt"
  5. "go-common/app/service/live/xrewardcenter/conf"
  6. AnchorTaskModel "go-common/app/service/live/xrewardcenter/model/anchorTask"
  7. model "go-common/app/service/live/xrewardcenter/model/anchorTask"
  8. "go-common/library/cache/memcache"
  9. "go-common/library/cache/redis"
  10. "go-common/library/database/orm"
  11. xsql "go-common/library/database/sql"
  12. "go-common/library/log"
  13. xtime "go-common/library/time"
  14. "math"
  15. "time"
  16. "bytes"
  17. "encoding/json"
  18. bm "go-common/library/net/http/blademaster"
  19. "io/ioutil"
  20. "net/http"
  21. "strconv"
  22. "github.com/jinzhu/gorm"
  23. )
  24. // OrderExist .
  25. const (
  26. // 缓存过期时间
  27. rewardConfExpire = 3600
  28. rewardConfPrefix = "rconf_v1_%d"
  29. )
  30. // Dao dao
  31. type Dao struct {
  32. c *conf.Config
  33. mc *memcache.Pool
  34. redis *redis.Pool
  35. orm *gorm.DB
  36. db *xsql.DB
  37. keyRewardConfExpire int32
  38. client *bm.Client
  39. }
  40. // New init mysql db
  41. func New(c *conf.Config) (dao *Dao) {
  42. dao = &Dao{
  43. c: c,
  44. mc: memcache.NewPool(c.Memcache),
  45. redis: redis.NewPool(c.Redis),
  46. db: xsql.NewMySQL(c.MySQL),
  47. orm: orm.NewMySQL(c.ORM),
  48. keyRewardConfExpire: rewardConfExpire,
  49. client: bm.NewClient(c.HTTPClient),
  50. }
  51. dao.initORM()
  52. return
  53. }
  54. func keyRewardConf(id int64) string {
  55. return fmt.Sprintf(rewardConfPrefix, id)
  56. }
  57. func (d *Dao) initORM() {
  58. d.orm.LogMode(true)
  59. d.orm.SingularTable(true)
  60. }
  61. //go:generate $GOPATH/src/go-common/app/tool/cache/gen
  62. type _cache interface {
  63. // cache: -sync=true -nullcache=&model.AnchorRewardConf{ID:-1} -check_null_code=$.ID==-1
  64. RewardConf(c context.Context, id int64) (*model.AnchorRewardConf, error)
  65. }
  66. //go:generate $GOPATH/src/go-common/app/tool/cache/mc
  67. type _mc interface {
  68. // 获取奖励配置
  69. // mc: -key=keyRewardConf
  70. CacheRewardConf(c context.Context, id int64) (*model.AnchorRewardConf, error)
  71. // 保存奖励配置
  72. // mc: -key=keyRewardConf -expire=d.keyRewardConfExpire -encode=json|gzip
  73. AddCacheRewardConf(c context.Context, id int64, value *model.AnchorRewardConf) error
  74. }
  75. // AddReward add Reward to a user.
  76. func (d *Dao) AddReward(c context.Context, iRewardID int64, uid int64, iSource int64, iRoomid int64, iLifespan int64) (err error) {
  77. //aReward, _ := getRewardConfByLid(iRewardID)
  78. m, _ := time.ParseDuration(fmt.Sprintf("+%dh", iLifespan))
  79. arg := &AnchorTaskModel.AnchorReward{
  80. Uid: uid,
  81. RewardId: iRewardID,
  82. Roomid: iRoomid,
  83. Source: iSource,
  84. AchieveTime: xtime.Time(time.Now().Unix()),
  85. ExpireTime: xtime.Time(time.Now().Add(m).Unix()),
  86. Status: model.RewardUnUsed,
  87. }
  88. //spew.Dump
  89. // (arg)
  90. if err := d.orm.Create(arg).Error; err != nil {
  91. log.Error("addReward(%v) error(%v)", arg, err)
  92. return err
  93. }
  94. if err := d.SetNewReward(c, uid, int64(1)); err != nil {
  95. log.Error("addRewardMc(%v) error(%v)", uid, err)
  96. }
  97. if err := d.SetHasReward(c, uid, int64(1)); err != nil {
  98. log.Error("SetHasReward(%v) error(%v)", uid, err)
  99. }
  100. log.Info("addReward (%v) succ", arg)
  101. return
  102. }
  103. //GetByUidPage get reward by uid and page.
  104. func (d *Dao) GetByUidPage(c context.Context, uid int64, page int64, pageSize int64, status []int64) (pager *model.AnchorRewardPager, list []*model.AnchorRewardObject, err error) {
  105. err = nil
  106. pager = &model.AnchorRewardPager{}
  107. list = []*model.AnchorRewardObject{}
  108. var (
  109. Items []*AnchorTaskModel.AnchorReward
  110. count int64
  111. )
  112. iOffSet := (page - 1) * pageSize
  113. db := d.orm.Where("status in (?)", status).Where("uid=?", uid)
  114. db.Model(&AnchorTaskModel.AnchorReward{}).Count(&count)
  115. if err = db.Model(&AnchorTaskModel.AnchorReward{}).Limit(pageSize).Offset(iOffSet).Order("mtime DESC, id").Find(&Items).Error; err != nil {
  116. log.Error("get ap_anchor_task_reward_list uid(%v) error(%v)", uid, err)
  117. return
  118. }
  119. for _, v := range Items {
  120. aReward, err := d.RewardConf(c, v.RewardId)
  121. if err != nil {
  122. log.Error("RewardConf(%v) error(%v)", v.RewardId, err)
  123. return pager, list, err
  124. }
  125. if aReward == nil {
  126. continue
  127. }
  128. aListItem := &model.AnchorRewardObject{
  129. Id: v.Id,
  130. RewardType: aReward.RewardType,
  131. Status: v.Status,
  132. RewardId: v.RewardId,
  133. Name: aReward.Name,
  134. Icon: aReward.Icon,
  135. AchieveTime: v.AchieveTime.Time().Format("2006-01-02 15:04:05"),
  136. ExpireTime: v.ExpireTime.Time().Format("2006-01-02 15:04:05"),
  137. UseTime: v.UseTime.Time().Format("2006-01-02 15:04:05"),
  138. Source: v.Source,
  139. RewardIntro: aReward.RewardIntro,
  140. }
  141. list = append(list, aListItem)
  142. }
  143. pager = &model.AnchorRewardPager{
  144. Page: page,
  145. PageSize: pageSize,
  146. TotalPage: int64(math.Ceil(float64(count) / float64(pageSize))),
  147. TotalCount: count,
  148. }
  149. return
  150. }
  151. // Ping dao ping
  152. func (d *Dao) Ping(c context.Context) (err error) {
  153. if d.orm != nil {
  154. d.orm.DB().PingContext(c)
  155. }
  156. err = d.pingMC(c)
  157. return
  158. }
  159. // GetById get reward by id.
  160. func (d *Dao) GetById(id int64) (reward *model.AnchorReward, err error) {
  161. rewards := []*model.AnchorReward{}
  162. if err := d.orm.Model(&model.AnchorReward{}).Find(&rewards, "id=?", id).Error; err != nil {
  163. log.Error("getRewardById (%v) error(%v)", id, err)
  164. return reward, err
  165. }
  166. if len(rewards) != 0 {
  167. reward = rewards[0]
  168. }
  169. return
  170. }
  171. // UseReward use reward by id.
  172. func (d *Dao) UseReward(id int64, usePlat string) (rst bool, err error) {
  173. if err := d.orm.
  174. Model(&model.AnchorReward{}).
  175. Where("id=?", id).
  176. Update(map[string]interface{}{"status": model.RewardUsed, "use_plat": usePlat, "use_time": xtime.Time(time.Now().Unix())}).Error; err != nil {
  177. log.Error("useReward (%v) error(%v)", id, err)
  178. return rst, err
  179. }
  180. rst = true
  181. return
  182. }
  183. // HasNewReward .
  184. func (d *Dao) HasNewReward(c context.Context, uid int64) (rst int64, err error) {
  185. rst, _ = d.GetNewReward(c, uid)
  186. return
  187. }
  188. func (d *Dao) findByUid(uid int64, limitOne bool) (reward *model.AnchorReward, err error) {
  189. rewards := []*model.AnchorReward{}
  190. db := d.orm.Where("uid=?", uid)
  191. if limitOne {
  192. db = db.Limit(1)
  193. }
  194. if err := db.Model(&model.AnchorReward{}).Find(&rewards).Error; err != nil {
  195. log.Error("getRewardById (%v) error(%v)", uid, err)
  196. return reward, err
  197. }
  198. if len(rewards) != 0 {
  199. reward = rewards[0]
  200. }
  201. return
  202. }
  203. // HasReward returns if a user have reward.
  204. func (d *Dao) HasReward(c context.Context, uid int64) (r int64, err error) {
  205. rst, err := d.GetHasReward(c, uid)
  206. if err != nil {
  207. if err == memcache.ErrNotFound {
  208. reward, err2 := d.findByUid(uid, true)
  209. if err2 != nil {
  210. return rst, err2
  211. }
  212. if reward != nil {
  213. rst = int64(1)
  214. d.SetHasReward(c, uid, rst)
  215. } else {
  216. rst = int64(0)
  217. d.SetHasReward(c, uid, rst)
  218. }
  219. return rst, err
  220. }
  221. log.Error("HasReward(%v) error(%v)", uid, err)
  222. return rst, err
  223. }
  224. return rst, err
  225. }
  226. // CheckOrderID check orderid is valid.
  227. func (d *Dao) CheckOrderID(c context.Context, id string) (exist int64, err error) {
  228. exist = 0
  229. if exist, err = d.GetOrder(c, id); err != nil {
  230. //spew.Dump(exist, err)
  231. if err == memcache.ErrNotFound {
  232. err = nil
  233. }
  234. return exist, err
  235. }
  236. return exist, err
  237. }
  238. // SaveOrderID save order id.
  239. func (d *Dao) SaveOrderID(c context.Context, id string) error {
  240. err := d.SaveOrder(c, id)
  241. return err
  242. }
  243. // SetExpire .
  244. func (d *Dao) SetExpire(now time.Time) (err error) {
  245. var (
  246. db = d.orm
  247. )
  248. setMap := map[string]interface{}{
  249. "status": model.RewardExpired,
  250. }
  251. if err = db.Model(model.AnchorReward{}).
  252. Where("status=? AND reward_id = ? AND expire_time <= ?", model.RewardUnUsed, 1, now.Format("2006-01-02 15:04:05")).
  253. Update(setMap).
  254. Error; err != nil {
  255. log.Error("SetExpire (%v) error(%v)", setMap, err)
  256. return err
  257. }
  258. return
  259. }
  260. // CountExpire .
  261. func (d *Dao) CountExpire(interval int64, now time.Time) (err error) {
  262. var (
  263. c = context.TODO()
  264. db = d.orm
  265. result = &[]model.AnchorReward{}
  266. )
  267. dur, _ := time.ParseDuration("-" + strconv.FormatInt(interval, 10) + "s")
  268. begin := now.Add(dur)
  269. //spew.Dump(begin.Format("2006-01-02 15:04:05"))
  270. //spew.Dump(now.Format("2006-01-02 15:04:05"))
  271. sqlTemp :=
  272. "SELECT * FROM ap_anchor_task_reward_list WHERE status = ? AND expire_time > ? AND expire_time <= ? AND reward_id= ?"
  273. db.Raw(sqlTemp,
  274. model.RewardExpired,
  275. begin.Format("2006-01-02 15:04:05"),
  276. now.Format("2006-01-02 15:04:05"),
  277. 1).Scan(&result)
  278. for _, v := range *result {
  279. d.AddExpireCountCache(c, fmt.Sprintf(model.CountExpireUserKey, v.Uid), model.ExpireCountTime)
  280. }
  281. return
  282. }
  283. // SendBroadcastV2 .
  284. func (d *Dao) SendBroadcastV2(c context.Context, uid int64, roomid int64, rewardId int64) (err error) {
  285. log.Info("send reward broadcast begin:%d", roomid)
  286. var endPoint string = fmt.Sprintf("http://live-dm.bilibili.co/dm/1/push?cid=%d&ensure=1", roomid)
  287. postJson := make(map[string]interface{})
  288. postJson["cmd"] = "new_anchor_reward"
  289. postJson["uid"] = uid
  290. postJson["roomid"] = roomid
  291. postJson["reward_id"] = rewardId
  292. bytesData, err := json.Marshal(postJson)
  293. if err != nil {
  294. log.Error("json.Marshal(%v) error(%v)", postJson, err)
  295. return
  296. }
  297. req, err := http.NewRequest("POST", endPoint, bytes.NewReader(bytesData))
  298. req.Header.Add("Content-Type", "application/json")
  299. if err != nil {
  300. log.Error("http.NewRequest(%v) url(%v) error(%v)", postJson, endPoint, err)
  301. return
  302. }
  303. var v interface{}
  304. if err = d.client.Do(c, req, v); err != nil {
  305. log.Error("s.client.Do error(%v) res (%v)", err, v)
  306. return
  307. }
  308. log.Info("s.client.Do endpoint (%v) req (%v) res (%v)", endPoint, postJson, v)
  309. return
  310. }
  311. // SendBroadcast .
  312. func (d *Dao) SendBroadcast(uid int64, roomid int64, rewardId int64) (err error) {
  313. log.Info("send reward broadcast begin:%d", roomid)
  314. var endPoint = fmt.Sprintf("http://live-dm.bilibili.co/dm/1/push?cid=%d&ensure=1", roomid)
  315. postJson := make(map[string]interface{})
  316. postJson["cmd"] = "new_anchor_reward"
  317. postJson["uid"] = uid
  318. postJson["roomid"] = roomid
  319. postJson["reward_id"] = rewardId
  320. bytesData, err := json.Marshal(postJson)
  321. if err != nil {
  322. log.Error("json.Marshal(%v) error(%v)", postJson, err)
  323. return
  324. }
  325. req, err := http.NewRequest("POST", endPoint, bytes.NewReader(bytesData))
  326. req.Header.Add("Content-Type", "application/json")
  327. if err != nil {
  328. log.Error("http.NewRequest(%v) url(%v) error(%v)", postJson, endPoint, err)
  329. return
  330. }
  331. client := http.Client{
  332. Timeout: time.Second,
  333. }
  334. // use httpClient to send request
  335. response, err := client.Do(req)
  336. if err != nil {
  337. log.Error("sending request to API endpoint(%v) error(%v)", req, err)
  338. return
  339. }
  340. body, err := ioutil.ReadAll(response.Body)
  341. if err != nil {
  342. log.Error("parse resp body(%v) error(%v)", body, err)
  343. }
  344. log.Info("send reward broadcast end:%d", roomid)
  345. return
  346. }