jyActivity.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. package activity
  2. import (
  3. dateFormate "app.yhyue.com/moapp/jybase/date"
  4. "app.yhyue.com/moapp/jybase/go-logger/logger"
  5. "app.yhyue.com/moapp/jybase/redis"
  6. "app.yhyue.com/moapp/message/db"
  7. "app.yhyue.com/moapp/message/handler/award"
  8. "fmt"
  9. "github.com/gogf/gf/v2/os/gcfg"
  10. "github.com/gogf/gf/v2/os/gctx"
  11. "github.com/gogf/gf/v2/os/gtime"
  12. "github.com/gogf/gf/v2/util/gconv"
  13. "time"
  14. )
  15. /*
  16. 投标人专属免费计划
  17. */
  18. type JyActivity struct {
  19. T1, T2, Ed time.Time //预热活动、开始时间、结束时间
  20. DailyClock string //预热活动每天开始时间
  21. ActivityCode string //活动code
  22. Missions map[string]struct { //任务
  23. Points int `json:"points"`
  24. Schedule int `json:"schedule"`
  25. }
  26. ScheduleReward map[int]struct { //进度奖励
  27. SubVip int `json:"subvip"`
  28. Schedule int `json:"schedule"`
  29. }
  30. }
  31. const (
  32. BidderPlanRedis = "main" //redis缓存库名
  33. BidderPlanScheduleCache = "bidderPlan_v1_ScheduleValue_%s" //活动累计进度
  34. BidderPlanFastClickCheck = "bidderPlanFastClickValue_%s" //防止连点
  35. BidderPlanScheduleAwardStatus = "bidderPlan_v1_ScheduleAward_%s_%d" //奖励领取状态
  36. BidderPlanBuySVipStatus = "bidderPlanActivity_v1_BuySVipCacheKey_%s" //购买
  37. BidderPlanInviteMissionsStatus = "bidderPlanActivity_v1_InviteCacheKey_%s" //邀请
  38. BidderPlanShareMissionsStatus = "bidderPlanActivity_v1_ShareCacheKey_%s" //分享
  39. BidderPlanDailyBoonKey = "bidderPlanActivity_v1_DailyBoon_%s" //领取每日限量福利
  40. BidderPlanHasDailyBoonKey = "bidderPlanActivity_v1_HasDailyBoon_%s" //是否领取过每日限量福利
  41. BidderPlanShare = "bidderPlanActivity_v1_ShareOk_%s" //是否分享
  42. )
  43. var MembershipDay *JyActivity
  44. func init() {
  45. MembershipDay = &JyActivity{
  46. T1: gtime.NewFromStrLayout(gcfg.Instance().MustGet(gctx.New(), "jyactivity.dateRange.t1").String(), "2006-01-02T15:04:05Z").Time,
  47. T2: gtime.NewFromStrLayout(gcfg.Instance().MustGet(gctx.New(), "jyactivity.dateRange.t2").String(), "2006-01-02T15:04:05Z").Time,
  48. Ed: gtime.NewFromStrLayout(gcfg.Instance().MustGet(gctx.New(), "jyactivity.dateRange.ed").String(), "2006-01-02T15:04:05Z").Time,
  49. }
  50. MembershipDay.DailyClock = gcfg.Instance().MustGet(gctx.New(), "jyactivity.dailyBoon.clock").String()
  51. MembershipDay.ActivityCode = gcfg.Instance().MustGet(gctx.New(), "jyactivity.code").String()
  52. //加载任务
  53. if loadMissionsErr := gcfg.Instance().MustGet(gctx.New(), "jyactivity.missions").Scan(&MembershipDay.Missions); loadMissionsErr != nil {
  54. logger.Error(fmt.Sprintf("JyBidderPlan 加载任务异常 %v", loadMissionsErr))
  55. }
  56. //加载进度奖励
  57. if loadScheduleErr := gcfg.Instance().MustGet(gctx.New(), "jyactivity.scheduleReward").Scan(&MembershipDay.ScheduleReward); loadScheduleErr != nil {
  58. logger.Error(fmt.Sprintf("JyBidderPlan 加载进度异常 %v", loadScheduleErr))
  59. }
  60. }
  61. // InActivity 是否在活动时间内
  62. // bTime 是否在预热时间段内
  63. // iTime 是否在正式活动时间内
  64. // aTime 是否在全部活动时间内
  65. func (BP *JyActivity) InActivity() (bTime, iTime, aTime bool) {
  66. now := time.Now()
  67. bTime = now.After(MembershipDay.T1) && now.Before(MembershipDay.T2)
  68. aTime = now.After(MembershipDay.T1) && now.Before(MembershipDay.Ed)
  69. if bTime {
  70. return
  71. }
  72. iTime = now.After(MembershipDay.T2) && now.Before(MembershipDay.Ed)
  73. return
  74. }
  75. // cacheLong 缓存时间
  76. func (BP *JyActivity) cacheLong() int {
  77. return 60 * 60 * 24 * 30
  78. }
  79. // FastClickCheck 连点处理,防止重复领取
  80. func (BP *JyActivity) FastClickCheck(userId string) bool {
  81. key := fmt.Sprintf(BidderPlanFastClickCheck, userId)
  82. if redis.Incr(BidderPlanRedis, key) == 1 {
  83. _ = redis.SetExpire(BidderPlanRedis, key, 1)
  84. return true
  85. }
  86. return false
  87. }
  88. // GetSchedule 查询活动任务进度
  89. func (BP *JyActivity) GetSchedule(userId string) int {
  90. return -redis.GetInt(BidderPlanRedis, fmt.Sprintf(BidderPlanScheduleCache, userId))
  91. }
  92. func (BP *JyActivity) GetScheduleQuery(userId string, schedule int) (status int) {
  93. if BP.GetSchedule(userId) < schedule {
  94. return 0
  95. }
  96. key := fmt.Sprintf(BidderPlanScheduleAwardStatus, userId, schedule)
  97. if redis.Get(BidderPlanRedis, key) == nil {
  98. status = gconv.Int(redis.Incr(BidderPlanRedis, key))
  99. _ = redis.SetExpire(BidderPlanRedis, key, BP.cacheLong())
  100. } else {
  101. status = redis.GetInt(BidderPlanRedis, key)
  102. }
  103. if status > 1 {
  104. status = 1
  105. }
  106. return
  107. }
  108. // ScheduleGiven 活动任务进度奖励
  109. func (BP *JyActivity) ScheduleGiven(userId string, schedule int) error {
  110. if _, inActivity, _ := BP.InActivity(); !inActivity {
  111. return fmt.Errorf("不在活动时间内")
  112. }
  113. if BP.GetScheduleQuery(userId, schedule) != 1 {
  114. return fmt.Errorf("非领取状态")
  115. }
  116. scheduleAward, ok := BP.ScheduleReward[schedule]
  117. if !ok {
  118. return fmt.Errorf("未知请求")
  119. }
  120. if err := award.GivenSubVip(userId, award.SubVip{
  121. Num: gconv.Int64(scheduleAward.SubVip),
  122. ActivityCode: BP.ActivityCode,
  123. Desc: fmt.Sprintf("达到%d剑鱼币", schedule),
  124. Date: time.Now().Unix(),
  125. }); err != nil {
  126. return fmt.Errorf("领取奖励异常")
  127. }
  128. key := fmt.Sprintf(BidderPlanScheduleAwardStatus, userId, schedule)
  129. redis.Put(BidderPlanRedis, key, -1, BP.cacheLong())
  130. return nil
  131. }
  132. // AddSchedule 增加活动进度
  133. func (BP *JyActivity) AddSchedule(userId string, value int) (after int) {
  134. if value > 0 {
  135. key := fmt.Sprintf(BidderPlanScheduleCache, userId)
  136. after = -gconv.Int(redis.Decrby(BidderPlanRedis, key, value))
  137. if value == after { //首次设置过期值
  138. _ = redis.SetExpire(BidderPlanRedis, key, BP.cacheLong())
  139. }
  140. }
  141. return
  142. }
  143. // FreeSubscribe 免费订阅
  144. type FreeSubscribe struct {
  145. OAreaP map[string]interface{} `json:"o_area"`
  146. AKey []interface{} `json:"a_key"`
  147. }
  148. // MissionsSVipBuyQuery 购买超级订阅
  149. // status:0 未完成 1 待领取 -1已领取
  150. // 是否购买超级订阅
  151. func (BP *JyActivity) MissionsSVipBuyQuery(userId string) (status int) {
  152. finish := func() bool {
  153. count := db.Mysql.CountBySql(`SELECT count(id) FROM dataexport_order WHERE product_type ='VIP订阅' AND order_money > 0 AND order_status>0 AND create_time > ? AND create_time < ? AND user_id=? `, BP.T2.Format(dateFormate.Date_Full_Layout), BP.Ed.Format(dateFormate.Date_Full_Layout), userId)
  154. if count > 0 {
  155. return true
  156. }
  157. return false
  158. }()
  159. if !finish {
  160. return 0
  161. }
  162. key := fmt.Sprintf(BidderPlanBuySVipStatus, userId)
  163. if redis.Get(BidderPlanRedis, key) == nil {
  164. status = gconv.Int(redis.Incr(BidderPlanRedis, key))
  165. _ = redis.SetExpire(BidderPlanRedis, key, BP.cacheLong())
  166. } else {
  167. status = redis.GetInt(BidderPlanRedis, key)
  168. }
  169. if status > 1 {
  170. status = 1
  171. }
  172. return
  173. }
  174. // MissionsSVipBuyGiven 订阅任务领取奖励
  175. func (BP *JyActivity) MissionsSVipBuyGiven(userId string) error {
  176. if _, inActivity, _ := BP.InActivity(); !inActivity {
  177. return fmt.Errorf("不在活动时间内")
  178. }
  179. status := BP.MissionsSVipBuyQuery(userId)
  180. if status != 1 {
  181. return fmt.Errorf("非领取状态")
  182. }
  183. if givenPointsErr := award.GivenPoints(userId, award.Points{
  184. Num: gcfg.Instance().MustGet(gctx.New(), "jyactivity.missions.buysubvip.points").Int64(),
  185. Type: 1010,
  186. ActivityCode: BP.ActivityCode,
  187. Desc: "购买超级订阅任务完成",
  188. Date: time.Now().Unix(),
  189. }); givenPointsErr != nil {
  190. return fmt.Errorf("领取奖励异常")
  191. }
  192. //设置已领取
  193. redis.Put(BidderPlanRedis, fmt.Sprintf(BidderPlanBuySVipStatus, userId), -1, BP.cacheLong())
  194. //增加任务进度
  195. BP.AddSchedule(userId, gcfg.Instance().MustGet(gctx.New(), "jyactivity.missions.buysubvip.schedule").Int())
  196. return nil
  197. }
  198. // MissionsInviteQuery 邀请任务状态查询
  199. // status:0 未完成 1 待领取 -1已领取
  200. func (BP *JyActivity) MissionsInviteQuery(userId string) (status int) {
  201. status = redis.GetInt(BidderPlanRedis, fmt.Sprintf(BidderPlanInviteMissionsStatus, userId))
  202. if status > 1 {
  203. status = 1
  204. }
  205. return status
  206. }
  207. // MissionsInviteGiven 邀请任务奖励领取
  208. func (BP *JyActivity) MissionsInviteGiven(userId string) error {
  209. if _, inActivity, _ := BP.InActivity(); !inActivity {
  210. return fmt.Errorf("不在活动时间内")
  211. }
  212. status := BP.MissionsInviteQuery(userId)
  213. if status != 1 {
  214. return fmt.Errorf("非领取状态")
  215. }
  216. //领取
  217. if givenPointsErr := award.GivenPoints(userId, award.Points{
  218. Num: gcfg.Instance().MustGet(gctx.New(), "jyactivity.missions.invite.points").Int64(),
  219. Type: 1008,
  220. ActivityCode: BP.ActivityCode,
  221. Desc: "邀请领好礼任务完成",
  222. Date: time.Now().Unix(),
  223. }); givenPointsErr != nil {
  224. return fmt.Errorf("领取奖励异常")
  225. }
  226. //设置已领取
  227. redis.Put(BidderPlanRedis, fmt.Sprintf(BidderPlanInviteMissionsStatus, userId), -1, BP.cacheLong())
  228. //增加任务进度
  229. BP.AddSchedule(userId, gcfg.Instance().MustGet(gctx.New(), "jyactivity.missions.invite.schedule").Int())
  230. return nil
  231. }
  232. // MissionsShareQuery 分享活动
  233. // status:0 未完成 1 待领取 -1已领取
  234. func (BP *JyActivity) MissionsShareQuery(userId string) (status int) {
  235. finished, _ := redis.Exists(BidderPlanRedis, fmt.Sprintf(BidderPlanShare, userId))
  236. if !finished {
  237. return 0
  238. }
  239. key := fmt.Sprintf(BidderPlanShareMissionsStatus, userId)
  240. if redis.Get(BidderPlanRedis, key) == nil {
  241. status = gconv.Int(redis.Incr(BidderPlanRedis, key))
  242. _ = redis.SetExpire(BidderPlanRedis, key, BP.cacheLong())
  243. } else {
  244. status = redis.GetInt(BidderPlanRedis, key)
  245. }
  246. if status > 1 {
  247. status = 1
  248. }
  249. return
  250. }
  251. // MissionsShareGiven 分享活动
  252. func (BP *JyActivity) MissionsShareGiven(userId string) error {
  253. if _, inActivity, _ := BP.InActivity(); !inActivity {
  254. return fmt.Errorf("不在活动时间内")
  255. }
  256. status := BP.MissionsShareQuery(userId)
  257. if status != 1 {
  258. return fmt.Errorf("非领取状态")
  259. }
  260. if givenPointsErr := award.GivenPoints(userId, award.Points{
  261. Num: gcfg.Instance().MustGet(gctx.New(), "jyactivity.missions.share.points").Int64(),
  262. Type: 1011,
  263. ActivityCode: BP.ActivityCode,
  264. Desc: "分享活动任务完成",
  265. Date: time.Now().Unix(),
  266. }); givenPointsErr != nil {
  267. return fmt.Errorf("领取奖励异常")
  268. }
  269. //设置已领取
  270. redis.Put(BidderPlanRedis, fmt.Sprintf(BidderPlanShareMissionsStatus, userId), -1, BP.cacheLong())
  271. //增加任务进度
  272. BP.AddSchedule(userId, gcfg.Instance().MustGet(gctx.New(), "jyactivity.missions.share.schedule").Int())
  273. return nil
  274. }