uservip.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package vip
  2. import (
  3. "bet24.com/log"
  4. "bet24.com/servers/common"
  5. inventory "bet24.com/servers/micros/item_inventory/proto"
  6. item "bet24.com/servers/micros/item_inventory/proto"
  7. notification "bet24.com/servers/micros/notification/proto"
  8. //"bet24.com/servers/micros/userservices/handler/userinfo"
  9. "encoding/json"
  10. "time"
  11. pb "bet24.com/servers/micros/userservices/proto"
  12. )
  13. type userVip struct {
  14. userId int // 用户ID
  15. pb.UserVip // 用户vip 信息
  16. purchaseHistories []pb.PurchaseHistory // 购买历史记录
  17. }
  18. // 为防止获取vip数据的时候进行领取,改在onUserEter触发领取动作
  19. func newUserVip(userId int) *userVip {
  20. user := new(userVip)
  21. user.userId = userId
  22. user.loadDataFromDB()
  23. return user
  24. }
  25. func (uv *userVip) onUserEntered() {
  26. //uv.checkDailyAward()
  27. uv.checkVipExpired()
  28. }
  29. // 加载用户vip 信息
  30. func (uv *userVip) loadDataFromDB() {
  31. uv.UserVip = trans_getVipInfo(uv.userId)
  32. uv.purchaseHistories = trans_getPackagePurchaseHistory(uv.userId)
  33. }
  34. // 检查每日礼包是否能领取
  35. func (uv *userVip) checkDailyAward() (bool, *pb.VipInfo, int) {
  36. if !uv.IsVip() {
  37. return false, nil, pb.VipAward_Nonmember
  38. }
  39. if common.GetDayIndex(uv.DailyPackageClaimDay) >= common.GetDayIndex(common.GetTimeStamp()) {
  40. return false, nil, pb.VipAward_ReceivedAward
  41. }
  42. // 获取当前等级的每日礼包
  43. sysVip := mgr.getVipByLevel(uv.Level)
  44. if sysVip == nil {
  45. return false, nil, pb.VipAward_ConfigNotExist
  46. }
  47. if len(sysVip.DailyPackage) == 0 {
  48. return false, nil, pb.VipAward_NoReward
  49. }
  50. return true, sysVip, pb.VipAward_Success
  51. }
  52. // 领取每日奖励
  53. func (uv *userVip) giftDailyAward() bool {
  54. b, sysVip, _ := uv.checkDailyAward()
  55. if !b {
  56. return false
  57. }
  58. // 更新领取时间
  59. uv.DailyPackageClaimDay = common.GetTimeStamp()
  60. // 写入数据库
  61. go uv.updateUserVip()
  62. inventory.AddItems(uv.userId, sysVip.DailyPackage, "vip daily award", common.LOGTYPE_LOGIN_AWARD)
  63. d, _ := json.Marshal(sysVip.DailyPackage)
  64. log.Debug("giftDailyAward send award UserId[%d] Items%v", uv.userId, sysVip.DailyPackage)
  65. notification.AddNotification(uv.userId, notification.Notification_VipGiftPack, string(d))
  66. return true
  67. }
  68. // 检查vip是否过期
  69. func (uv *userVip) checkVipExpired() {
  70. // 本来就不是vip
  71. if uv.Expire == 0 {
  72. return
  73. }
  74. // expire有数值,表示上次登录还是vip
  75. if !uv.IsVip() {
  76. uv.onVipExpired()
  77. return
  78. }
  79. time.AfterFunc(time.Duration(uv.Expire-common.GetTimeStamp())*time.Second, uv.onVipExpired)
  80. //time.AfterFunc(10*time.Second, uv.onVipExpired)
  81. }
  82. // vip过期
  83. func (uv *userVip) onVipExpired() {
  84. if uv.userId == 0 {
  85. return
  86. }
  87. // 如果定时器期间重新充值了vip,则再启定时器
  88. if uv.Expire-int(time.Now().Unix()) > 5 {
  89. time.AfterFunc(time.Duration(uv.Expire-int(time.Now().Unix()))*time.Second, uv.onVipExpired)
  90. return
  91. }
  92. uv.Expire = 0
  93. go uv.updateUserVip()
  94. log.Debug("onVipExpired %d", uv.userId)
  95. notification.AddNotification(uv.userId, notification.Notification_VipExpire, "")
  96. }
  97. // 会员时间
  98. func (uv *userVip) dumpVipTime() {
  99. expire := "not vip"
  100. if uv.Expire > 0 {
  101. expire = common.TimeStampToString(int64(uv.Expire))
  102. }
  103. claim := common.TimeStampToString(int64(uv.DailyPackageClaimDay))
  104. log.Debug("userVip.dumpVipTime %d:[lv:%d (%d)] Expire[%s] Claim[%s]", uv.userId, uv.Level, uv.Point, expire, claim)
  105. }
  106. // 判断是否能购买礼包
  107. func (uv *userVip) canBuyPackage(productId string) bool {
  108. if !uv.IsVip() {
  109. return false
  110. }
  111. purchasePackage := mgr.getPurchasePackageInfo(productId)
  112. // 礼包不存在
  113. if purchasePackage == nil {
  114. log.Debug("userVip.canBuyPackage [%s] not found", productId)
  115. return false
  116. }
  117. if purchasePackage.PurchaseLimitType == pb.PurchaseLimit_none {
  118. return true
  119. }
  120. var purchaseCount int
  121. if purchasePackage.PurchaseLimitType == pb.PurchaseLimit_daily {
  122. nowDayIndex := common.GetDayIndex(common.GetTimeStamp())
  123. for _, v := range uv.purchaseHistories {
  124. if v.ProductId != productId {
  125. continue
  126. }
  127. if nowDayIndex == common.GetDayIndex(int(v.PurchaseTime)) {
  128. purchaseCount++
  129. }
  130. }
  131. } else if purchasePackage.PurchaseLimitType == pb.PurchaseLimit_weekly {
  132. nowWeekIndex := common.GetWeekIndex(common.GetTimeStamp())
  133. for _, v := range uv.purchaseHistories {
  134. if v.ProductId != productId {
  135. continue
  136. }
  137. if nowWeekIndex == common.GetWeekIndex(int(v.PurchaseTime)) {
  138. purchaseCount++
  139. }
  140. }
  141. } else if purchasePackage.PurchaseLimitType == pb.PurchaseLimit_monthly {
  142. nowMonthIndex := common.GetMonthIndex(common.GetTimeStamp())
  143. for _, v := range uv.purchaseHistories {
  144. if v.ProductId != productId {
  145. continue
  146. }
  147. if nowMonthIndex == common.GetMonthIndex(int(v.PurchaseTime)) {
  148. purchaseCount++
  149. }
  150. }
  151. }
  152. return purchaseCount < purchasePackage.PurchaseLimitCount
  153. }
  154. // 实际购买礼包(已完成支付),发放道具,添加购买历史记录
  155. func (uv *userVip) buyPackage(productId string) {
  156. purchasePackage := mgr.getPurchasePackageInfo(productId)
  157. if purchasePackage == nil {
  158. log.Release("userVip.buyPackage [%s] not found", productId)
  159. return
  160. }
  161. // 发放道具
  162. inventory.AddItems(uv.userId, purchasePackage.Items, "vip package", common.LOGTYPE_PACK_VIP)
  163. d, _ := json.Marshal(purchasePackage.Items)
  164. notification.AddNotification(uv.userId, notification.Notification_VipGiftBagPurchase, string(d))
  165. // 添加购买记录历史
  166. trans_addPackagePurchaseHistory(uv.userId, productId)
  167. uv.purchaseHistories = append(uv.purchaseHistories, pb.PurchaseHistory{
  168. ProductId: productId,
  169. PurchaseTime: common.GetNowTime().Unix(),
  170. })
  171. }
  172. // 添加vip点数,可能触发升级,升级如果当前是vip,则需要发放登录道具和升级道具
  173. func (uv *userVip) addVipPoint(point int) {
  174. if point <= 0 {
  175. log.Release("uservip.addVipPoint user [%d] point[%d]", uv.userId, point)
  176. return
  177. }
  178. //log.Debug("userVip.addVipPoint %d", point)
  179. uv.Point += point
  180. //log.Debug("userVip.addVipPoint after %d", uv.Point)
  181. defer uv.sendNotification(notification.Notification_VipAttributeChange)
  182. defer func() {
  183. go uv.updateUserVip()
  184. }()
  185. // 检查是否升级
  186. newLevel := mgr.getVipByPoint(uv.Point)
  187. // 级别没有变化
  188. if newLevel <= uv.Level {
  189. return
  190. }
  191. uv.Level = newLevel
  192. // 不是vip
  193. if !uv.IsVip() {
  194. return
  195. }
  196. // 升级并发放道具
  197. uv.sendUpgradeItems(true)
  198. }
  199. // 升级,发放道具
  200. func (uv *userVip) sendUpgradeItems(isNotice bool) {
  201. // 处理跨等级
  202. var giftPack []item.ItemPack
  203. for i := 0; i <= uv.Level; i++ {
  204. vipInfo := mgr.getVipByLevel(i)
  205. if vipInfo == nil {
  206. continue
  207. }
  208. giftPack = append(giftPack, vipInfo.UpgragePackage...)
  209. }
  210. if len(giftPack) == 0 {
  211. return
  212. }
  213. // 合并同类道具
  214. giftPack = item.GroupItems(giftPack)
  215. // 把所有的道具设置成一个
  216. for i := 0; i < len(giftPack); i++ {
  217. giftPack[i].Count = 1
  218. }
  219. inventory.AddItemsWithExpireTime(uv.userId, giftPack, "vip upgrade", common.LOGTYPE_PACK_TIMELIMITED, uv.Expire)
  220. if isNotice {
  221. d, _ := json.Marshal(giftPack)
  222. notification.AddNotification(uv.userId, notification.Notification_VipGiftBagUpgrade, string(d))
  223. }
  224. }
  225. // 添加vip时长(已完成支付)
  226. func (uv *userVip) addVipSeconds(seconds int) {
  227. if seconds <= 0 {
  228. log.Release("uservip.addSeconds user [%d] seconds[%d]", uv.userId, seconds)
  229. return
  230. }
  231. var isNotice bool
  232. if uv.Expire == 0 {
  233. // 重新恢复vip状态
  234. uv.Expire = common.GetTimeStamp() + seconds
  235. isNotice = true
  236. // 启动定时器
  237. time.AfterFunc(time.Duration(uv.Expire-int(time.Now().Unix()))*time.Second, uv.onVipExpired)
  238. } else {
  239. // 原本就是vip,不需要处理道具发放
  240. uv.Expire += seconds
  241. }
  242. // 发放升级礼包的时效道具
  243. uv.sendUpgradeItems(isNotice)
  244. uv.updateUserVip()
  245. uv.sendNotification(notification.Notification_VipAddDuration)
  246. }
  247. // 修改用户的vip信息
  248. func (uv *userVip) updateUserVip() {
  249. trans_updateUserVip(uv.userId, uv.Level, uv.Point, uv.Expire, uv.DailyPackageClaimDay)
  250. pb.UpdateUserInfo(uv.userId)
  251. }
  252. // vip属性变化
  253. func (uv *userVip) sendNotification(noticeCode int) {
  254. d, _ := json.Marshal(uv.UserVip)
  255. notification.AddNotification(uv.userId, noticeCode, string(d))
  256. }