ActivityRedis.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. namespace addons\shopro\library\activity;
  3. use addons\shopro\facade\Redis;
  4. use app\admin\model\shopro\activity\Activity as ActivityModel;
  5. use addons\shopro\library\activity\traits\ActivityRedis as ActivityRedisTrait;
  6. class ActivityRedis
  7. {
  8. use ActivityRedisTrait;
  9. public function __construct() {
  10. }
  11. /**
  12. * 将活动设置到 redis 中
  13. *
  14. * @param mixed $activity
  15. * @param array $goodsList
  16. * @return void
  17. */
  18. public function setActivity($activity)
  19. {
  20. $activity = ActivityModel::with('activity_sku_prices')->where('id', $activity['id'])->find();
  21. // hash 键值
  22. $keyActivity = $this->keyActivity($activity->id, $activity->type);
  23. // 删除旧的可变数据,需要排除销量 key
  24. if (Redis::EXISTS($keyActivity)) {
  25. // 如果 hashKey 存在,删除规格
  26. $activityCache = $this->getActivityByKey($keyActivity);
  27. foreach ($activityCache as $field => $value) {
  28. // 是商品规格,并且不是销量
  29. if (strpos($field, $this->hashGoodsPrefix) !== false && strpos($field, '-sale') === false) {
  30. // 商品规格信息,删掉
  31. Redis::HDEL($keyActivity, $field);
  32. }
  33. }
  34. }
  35. Redis::HMSET(
  36. $keyActivity,
  37. [
  38. 'id' => $activity['id'],
  39. 'title' => $activity['title'],
  40. 'type' => $activity['type'],
  41. 'type_text' => $activity['type_text'],
  42. 'classify' => $activity['classify'],
  43. 'goods_ids' => $activity['goods_ids'],
  44. 'richtext_id' => $activity['richtext_id'],
  45. 'richtext_title' => $activity['richtext_title'],
  46. 'prehead_time' => strtotime($activity['prehead_time']),
  47. 'start_time' => strtotime($activity['start_time']),
  48. 'end_time' => strtotime($activity['end_time']),
  49. 'rules' => is_array($activity['rules']) ? json_encode($activity['rules']) : $activity['rules'],
  50. ]
  51. );
  52. // 将活动规格保存 redis
  53. foreach ($activity['activity_sku_prices'] as $goods) {
  54. unset($goods['sales']); // 规格销量单独字段保存 goods-id-id-sale key
  55. $keyActivityGoods = $this->keyActivityGoods($goods['goods_id'], $goods['goods_sku_price_id']);
  56. // 获取当前规格的销量,修改库存的时候,需要把 stock 加上这部分销量
  57. $cacheSale = Redis::HGET($keyActivity, $keyActivityGoods . '-sale');
  58. $goods['stock'] = $goods['stock'] + $cacheSale;
  59. Redis::HSET($keyActivity, $keyActivityGoods, json_encode($goods));
  60. }
  61. // 将 hash 键值存入 有序集合,score 为 id
  62. Redis::ZADD($this->zsetKey, strtotime($activity['start_time']), $keyActivity);
  63. }
  64. /**
  65. * 删除活动缓存
  66. *
  67. * @param object $activity
  68. * @return void
  69. */
  70. public function delActivity($activity)
  71. {
  72. // hash 键值
  73. $keyActivity = $this->keyActivity($activity->id, $activity->type);
  74. // 删除 hash
  75. Redis::DEL($keyActivity);
  76. // 删除集合
  77. Redis::ZREM($this->zsetKey, $keyActivity);
  78. }
  79. /**
  80. * 根据活动类型,获取所有活动(前端:秒杀商品列表,拼团商品列表)
  81. *
  82. * @param array $activityTypes 要查询的活动类型
  83. * @param array|string $status 要查询的活动的状态
  84. * @param string $format_type // 格式化类型,默认clear,清理多余的字段,比如拼团的 团信息 normal=格式化拼团,秒杀等|promo=格式化满减,满折,赠送
  85. * @return array
  86. */
  87. public function getActivityList($activityTypes = [], $status = 'all', $format_type = 'normal')
  88. {
  89. // 获取对应的活动类型的集合
  90. $keysActivity = $this->getKeysActivityByTypes($activityTypes, $status);
  91. $activityList = [];
  92. foreach ($keysActivity as $keyActivity) {
  93. // 格式化活动
  94. $activity = $this->formatActivityByKey($keyActivity, $format_type);
  95. if ($activity) {
  96. $activityList[] = $activity;
  97. }
  98. }
  99. return $activityList;
  100. }
  101. /**
  102. * 查询商品列表,详情时,获取这个商品对应的秒杀拼团等活动
  103. *
  104. * @param integer $goods_id
  105. * @param Array $activityTypes
  106. * @param array|string $status 要查询的活动的状态
  107. * @param string $format_type
  108. * @return array
  109. */
  110. public function getGoodsActivitys($goods_id, $activityTypes = [], $status = 'all', $format_type = 'goods')
  111. {
  112. // 获取商品第一条活动的 hash key
  113. $keysActivity = $this->getkeysActivityByGoods($goods_id, $activityTypes, $status);
  114. // 如果存在活动
  115. foreach ($keysActivity as $keyActivity) {
  116. // 格式化活动
  117. $activity = $this->formatActivityByKey($keyActivity, $format_type, ['goods_id' => $goods_id]);
  118. if ($activity) {
  119. $activityList[] = $activity;
  120. }
  121. }
  122. return $activityList ?? [];
  123. }
  124. /**
  125. * 获取是商品的特定的活动
  126. *
  127. * @param integer $goods_id
  128. * @param integer $activity_id
  129. * @param array|string $status 要查询的活动的状态
  130. * @param string $format_type
  131. * @return array
  132. */
  133. public function getGoodsActivityByActivity($goods_id, $activity_id, $status = 'all', $format_type = 'goods') //33,8
  134. {
  135. // 获取商品第一条活动的 hash key
  136. $keyActivity = $this->getKeyActivityById($activity_id);
  137. if (!$keyActivity) {
  138. return null;
  139. }
  140. //dump($keyActivity); //hash-activity:groupon:8
  141. $activity = $this->formatActivityByKey($keyActivity, $format_type, ['goods_id' => $goods_id]);
  142. if ($activity) {
  143. // 判断商品
  144. $goods_ids = array_values(array_filter(explode(',', $activity['goods_ids'])));
  145. if (!in_array($goods_id, $goods_ids) && !empty($goods_ids)) {
  146. return null;
  147. }
  148. // 判断状态
  149. $status = is_array($status) ? $status : [$status];
  150. if (!in_array('all', $status)) {
  151. if (!in_array($activity['status'], $status)) {
  152. return null;
  153. }
  154. }
  155. //倒计时
  156. /*if(isset($activity['end_time'])){
  157. $activity['seconds'] = $activity['end_time'] - time();
  158. }*/
  159. }
  160. return $activity ?? null;
  161. }
  162. }