ActivityRedis.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. <?php
  2. namespace addons\shopro\library\activity\traits;
  3. use addons\shopro\facade\Redis;
  4. use app\admin\model\shopro\activity\Activity;
  5. use think\helper\Str;
  6. /**
  7. * 获取活动 redis 基础方法
  8. */
  9. trait ActivityRedis
  10. {
  11. protected $zsetKey = 'zset-activity'; // 活动集合 key
  12. protected $hashPrefix = 'hash-activity:'; // 活动前缀
  13. protected $hashGoodsPrefix = 'goods-'; // 活动中商品的前缀
  14. protected $hashGrouponPrefix = 'groupon-';
  15. protected $hashKanPrefix = 'kan-'; //砍价的
  16. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 获取活动相关信息 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  17. /**
  18. * 获取活动完整信息
  19. *
  20. * @param integer $id
  21. * @param string $type
  22. * @return array
  23. */
  24. public function getActivity($id, $type)
  25. {
  26. $keyActivity = $this->keyActivity($id, $type);
  27. return $this->getActivityByKey($keyActivity);
  28. }
  29. /**
  30. * 通过活动的键值,获取活动完整信息
  31. *
  32. * @param string $activityHashKey
  33. * @return array
  34. */
  35. public function getActivityByKey($keyActivity)
  36. {
  37. // 取出整条 hash 记录
  38. $activity = Redis::HGETALL($keyActivity);
  39. return $activity;
  40. }
  41. /**
  42. * 删除活动
  43. *
  44. * @param integer $id
  45. * @param string $type
  46. * @return void
  47. */
  48. public function delActivity($id, $type)
  49. {
  50. $keyActivity = $this->keyActivity($id, $type);
  51. $this->delActivityByKey($keyActivity);
  52. }
  53. /**
  54. * 通过 key 删除活动
  55. *
  56. * @param string $keyActivity
  57. * @return void
  58. */
  59. public function delActivityByKey($keyActivity)
  60. {
  61. // 删除 hash
  62. Redis::DEL($keyActivity);
  63. // 删除集合
  64. Redis::ZREM($this->zsetKey, $keyActivity);
  65. }
  66. /**
  67. * 获取活动的状态
  68. *
  69. * @param string $keyActivity
  70. * @return string
  71. */
  72. public function getActivityStatusByKey($keyActivity)
  73. {
  74. $prehead_time = Redis::HGET($keyActivity, 'prehead_time'); // 预热时间
  75. $start_time = Redis::HGET($keyActivity, 'start_time'); // 开始时间
  76. $end_time = Redis::HGET($keyActivity, 'end_time'); // 结束时间
  77. // 获取活动状态
  78. $status = Activity::getStatusCode($prehead_time, $start_time, $end_time);
  79. return $status;
  80. }
  81. // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 获取活动相关信息 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
  82. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 操作活动 hash ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  83. /**
  84. * 计算每个规格的真实库存、销量
  85. *
  86. * @param array $goods
  87. * @param string $keyActivity
  88. * @return array
  89. */
  90. private function calcGoods($goods, $keyActivity)
  91. {
  92. // 销量 key
  93. $keyActivityGoods = $this->keyActivityGoods($goods['goods_id'], $goods['goods_sku_price_id'], true);
  94. // 缓存中的销量
  95. $cacheSale = Redis::HGET($keyActivity, $keyActivityGoods);
  96. $stock = $goods['stock'] - $cacheSale;
  97. $goods['stock'] = $stock > 0 ? $stock : 0;
  98. $goods['sales'] = $cacheSale ? : 0; //销量不能是false
  99. return $goods;
  100. }
  101. // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 操作活动 hash ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
  102. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 格式化活动内容 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  103. /**
  104. * 格式化活动
  105. *
  106. * @param string array $keyActivity 活动 key 或者活动完整信息
  107. * @param string $type 格式化方式
  108. * @param array $data 额外参数
  109. * @return array
  110. */
  111. public function formatActivityByKey($keyActivity, $type = 'normal', $data = [])
  112. {
  113. $activity = $this->{'formatActivity' . Str::studly($type)}($keyActivity, $data);
  114. return $activity;
  115. }
  116. /**
  117. * 正常模式,只移除销量, 团信息,保留全部商品规格数据
  118. *
  119. * @param string|array $originalActivity
  120. * @param array $data 额外数据,商品 id
  121. * @return array|null
  122. */
  123. public function formatActivityNormal($originalActivity, $data = [])
  124. {
  125. if (is_string($originalActivity)) {
  126. // 传入的是活动的key
  127. $keyActivity = $originalActivity;
  128. $originalActivity = $this->getActivityByKey($originalActivity);
  129. } else {
  130. $keyActivity = $this->keyActivity($originalActivity['id'], $originalActivity['type']);
  131. }
  132. $activity = [];
  133. foreach ($originalActivity as $key => $value) {
  134. // 包含 -sale 全部跳过
  135. if (strpos($key, '-sale') !== false) {
  136. continue;
  137. } else if (strpos($key, $this->hashGrouponPrefix) !== false) {
  138. // 拼团的参团人数,团用户,移除
  139. continue;
  140. } else if ($key == 'rules') {
  141. $activity[$key] = json_decode($value, true);
  142. } else {
  143. // 普通键值
  144. $activity[$key] = $value;
  145. }
  146. }
  147. if ($activity) {
  148. // 处理活动状态
  149. $activity['status'] = Activity::getStatusCode($activity['prehead_time'], $activity['start_time'], $activity['end_time']);
  150. $activity['status_text'] = Activity::getStatusText($activity['status']);
  151. }
  152. return $activity ?: null;
  153. }
  154. /**
  155. * 简洁模式,只保留活动表基本信息
  156. *
  157. * @param string $originalActivity
  158. * @param array $data 额外数据,商品 id
  159. * @return array|null
  160. */
  161. private function formatActivityClear($originalActivity, $data = [])
  162. {
  163. if (is_string($originalActivity)) {
  164. // 传入的是活动的key
  165. $keyActivity = $originalActivity;
  166. $originalActivity = $this->getActivityByKey($originalActivity);
  167. } else {
  168. $keyActivity = $this->keyActivity($originalActivity['id'], $originalActivity['type']);
  169. }
  170. $activity = [];
  171. foreach ($originalActivity as $key => $value) {
  172. // 包含 -sale 全部跳过
  173. if (strpos($key, $this->hashGoodsPrefix) !== false) {
  174. continue;
  175. } else if (strpos($key, $this->hashGrouponPrefix) !== false) {
  176. // 拼团的参团人数,团用户,移除
  177. continue;
  178. } else if ($key == 'rules') {
  179. $activity[$key] = json_decode($value, true);
  180. } else {
  181. // 普通键值
  182. $activity[$key] = $value;
  183. }
  184. }
  185. if ($activity) {
  186. // 处理活动状态
  187. $activity['status'] = Activity::getStatusCode($activity['prehead_time'], $activity['start_time'], $activity['end_time']);
  188. $activity['status_text'] = Activity::getStatusText($activity['status']);
  189. }
  190. return $activity ?: null;
  191. }
  192. /**
  193. * 获取并按照商品展示格式化活动数据
  194. *
  195. * @param string $originalActivity hash key
  196. * @param array $data 额外数据,商品 id
  197. * @return array|null
  198. */
  199. private function formatActivityGoods($originalActivity, $data = [])
  200. {
  201. $goods_id = $data['goods_id'] ?? 0;
  202. if (is_string($originalActivity)) {
  203. // 传入的是活动的key
  204. $keyActivity = $originalActivity;
  205. $originalActivity = $this->getActivityByKey($originalActivity);
  206. } else {
  207. $keyActivity = $this->keyActivity($originalActivity['id'], $originalActivity['type']);
  208. }
  209. $activity = [];
  210. // 商品前缀
  211. $goodsPrefix = $this->hashGoodsPrefix . ($goods_id ? $goods_id . '-' : '');
  212. // dump($keyActivity);
  213. // dump($goodsPrefix);
  214. // dump($originalActivity);
  215. /*
  216. string(23) "hash-activity:groupon:8"
  217. string(9) "goods-33-"
  218. array(15) {
  219. ["title"] => string(15) "百人砍价团"
  220. ["type_text"] => string(6) "拼团"
  221. ["richtext_id"] => string(1) "0"
  222. ["goods_ids"] => string(2) "33"
  223. ["richtext_title"] => string(0) ""
  224. ["id"] => string(1) "8"
  225. ["rules"] => string(287) "{"is_commission":"0","is_free_shipping":"0","sales_show_type":"goods","team_num":"2","is_alone":"1","is_fictitious":"1","fictitious_num":"1","fictitious_time":"1","is_team_card":"1","is_leader_discount":"0","valid_time":"24","limit_num":"100","refund_type":"back","order_auto_close":"5"}"
  226. ["goods-33-95"] => string(258) "{"id":43,"activity_id":8,"goods_sku_price_id":95,"goods_id":33,"stock":100,"price":"6.00","ext":{"is_leader_discount":"0","leader_price":"6.00"},"status":"up","createtime":"2024-11-29 10:39:54","updatetime":"2024-12-02 18:26:43","status_text":"\u4e0a\u67b6"}"
  227. ["prehead_time"] => string(1) "1"
  228. ["goods-33-93"] => string(258) "{"id":41,"activity_id":8,"goods_sku_price_id":93,"goods_id":33,"stock":100,"price":"5.21","ext":{"is_leader_discount":"0","leader_price":"5.21"},"status":"up","createtime":"2024-11-29 10:39:54","updatetime":"2024-12-02 18:26:43","status_text":"\u4e0a\u67b6"}"
  229. ["classify"] => string(8) "activity"
  230. ["start_time"] => string(1) "1"
  231. ["end_time"] => string(10) "1735315199"
  232. ["goods-33-94"] => string(258) "{"id":42,"activity_id":8,"goods_sku_price_id":94,"goods_id":33,"stock":100,"price":"5.50","ext":{"is_leader_discount":"0","leader_price":"5.50"},"status":"up","createtime":"2024-11-29 10:39:54","updatetime":"2024-12-02 18:26:43","status_text":"\u4e0a\u67b6"}"
  233. ["type"] => string(7) "groupon"
  234. }
  235. */
  236. foreach ($originalActivity as $key => $value) {
  237. // 包含 -sale 全部跳过
  238. if (strpos($key, '-sale') !== false) {
  239. continue;
  240. } else if (strpos($key, $goodsPrefix) !== false) {
  241. // 商品规格信息,或者特定商品规格信息
  242. $goods = json_decode($value, true);
  243. // 计算销量库存数据
  244. $goods = $this->calcGoods($goods, $keyActivity);
  245. // 商品规格项
  246. $activity['activity_sku_prices'][] = $goods;
  247. } else if ($goods_id && strpos($key, $this->hashGoodsPrefix) !== false) { //去掉 goods- 开头的,也就是那个商品几个规格
  248. // 需要特定商品时,移除别的非当前商品的数据
  249. continue;
  250. } else if (strpos($key, $this->hashGrouponPrefix) !== false) {
  251. // 拼团的参团人数,团用户,移除
  252. continue;
  253. } else if ($key == 'rules') {
  254. $activity[$key] = json_decode($value, true);
  255. } else {
  256. // 普通键值
  257. $activity[$key] = $value;
  258. }
  259. }
  260. //dump($activity);exit;
  261. if ($activity) {
  262. // 处理活动状态
  263. $activity['status'] = Activity::getStatusCode($activity['prehead_time'], $activity['start_time'], $activity['end_time']);
  264. $activity['status_text'] = Activity::getStatusText($activity['status']);
  265. }
  266. //计算砍价的
  267. return $activity ?: null;
  268. }
  269. /**
  270. * 获取并按照折扣格式展示格式化活动数据
  271. *
  272. * @param string $originalActivity hash key
  273. * @param array $data 额外数据
  274. * @return array|null
  275. */
  276. public function formatActivityPromo($originalActivity, $data = [])
  277. {
  278. if (is_string($originalActivity)) {
  279. // 传入的是活动的key
  280. $keyActivity = $originalActivity;
  281. $originalActivity = $this->getActivityByKey($originalActivity);
  282. } else {
  283. $keyActivity = $this->keyActivity($originalActivity['id'], $originalActivity['type']);
  284. }
  285. $activity = [];
  286. foreach ($originalActivity as $key => $value) {
  287. if ($key == 'rules') {
  288. $rules = json_decode($value, true);
  289. $activity[$key] = $rules;
  290. } else {
  291. // 普通键值
  292. $activity[$key] = $value;
  293. }
  294. }
  295. if ($activity) {
  296. // 处理活动状态
  297. $activity['status'] = Activity::getStatusCode($activity['prehead_time'], $activity['start_time'], $activity['end_time']);
  298. $activity['status_text'] = Activity::getStatusText($activity['status']);
  299. }
  300. return $activity ?: null;
  301. }
  302. // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 格式化活动内容 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
  303. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 获取活动的 keys 数组 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  304. /**
  305. * 获取所有活动的 keys
  306. *
  307. * @return array
  308. */
  309. /*array(7) {
  310. [0] => string(23) "hash-activity:groupon:8"
  311. [1] => string(23) "hash-activity:groupon:2"
  312. [2] => string(23) "hash-activity:groupon:3"
  313. [3] => string(23) "hash-activity:seckill:4"
  314. [4] => string(23) "hash-activity:seckill:5"
  315. [5] => string(23) "hash-activity:seckill:6"
  316. [6] => string(23) "hash-activity:seckill:7"
  317. }*/
  318. public function getKeysActivity()
  319. {
  320. // 获取活动集合
  321. $keysActivity = Redis::ZRANGE($this->zsetKey, 0, 999999999);
  322. return $keysActivity;
  323. }
  324. /**
  325. * 通过活动 id 获取活动的 key(不知道活动类型,只知道 id 的时候用)
  326. *
  327. * @param integer $id
  328. * @return string
  329. */
  330. public function getKeyActivityById($id)
  331. {
  332. $keysActivity = $this->getKeysActivity();
  333. //找 :8的,找到第一个就跳出
  334. foreach ($keysActivity as $keyActivity) {
  335. $suffix = ':' . $id;
  336. // 判断是否是要找的活动id, 截取 hashKey 后面几位,是否为当前要查找的活动 id
  337. if (substr($keyActivity, (strlen($keyActivity) - strlen($suffix))) == $suffix) {
  338. $currentKeyActivity = $keyActivity;
  339. break;
  340. }
  341. }
  342. return $currentKeyActivity ?? null;
  343. }
  344. /**
  345. * 通过活动 id 和 活动 type 获取 活动 key
  346. *
  347. * @param integer $activity_id
  348. * @param string $activity_type
  349. * @return string
  350. */
  351. public function getKeyActivityByIdType($activity_id, $activity_type)
  352. {
  353. $keyActivity = $this->keyActivity($activity_id, $activity_type);
  354. return $keyActivity;
  355. }
  356. /**
  357. * 获取对应活动类型的 活动 keys
  358. *
  359. * @param array $activityTypes
  360. * @param array|string $status 要查询的活动的状态
  361. * @return array
  362. */
  363. public function getKeysActivityByTypes($activityTypes, $status = 'all')
  364. {
  365. $status = is_array($status) ? $status : [$status];
  366. $activityTypes = is_array($activityTypes) ? $activityTypes : [$activityTypes];
  367. $activityTypes = array_values(array_filter(array_unique($activityTypes))); // 过滤空值
  368. $keysActivity = $this->getKeysActivity();
  369. // 获取对应的活动类型的集合
  370. $keysActivityTypes = [];
  371. foreach ($keysActivity as $keyActivity) {
  372. // 循环要查找的活动类型数组
  373. foreach ($activityTypes as $type) {
  374. $prefix = $this->hashPrefix . $type . ':';
  375. if (strpos($keyActivity, $prefix) === 0) { // 是要查找的类型
  376. $keysActivityTypes[] = $keyActivity;
  377. break;
  378. }
  379. }
  380. }
  381. // 判断活动状态
  382. if (!in_array('all', $status)) {
  383. foreach ($keysActivityTypes as $key => $keyActivity) {
  384. $activity_status = $this->getActivityStatusByKey($keyActivity);
  385. if (!in_array($activity_status, $status)) {
  386. unset($keysActivityTypes[$key]);
  387. }
  388. }
  389. }
  390. return array_values($keysActivityTypes);
  391. }
  392. /**
  393. * 通过商品获取该商品参与的活动的hash key
  394. *
  395. * @param integer $goods_id
  396. * @param Array $activityType
  397. * @param array|string $status 要查询的活动的状态
  398. * @return array
  399. */
  400. private function getkeysActivityByGoods($goods_id, $activityType = [], $status = 'all')
  401. {
  402. // 获取对应类型的活动集合
  403. $keysActivity = $this->getKeysActivityByTypes($activityType, $status);
  404. $keysActivityGoods = [];
  405. foreach ($keysActivity as $keyActivity) {
  406. // 判断这条活动是否包含该商品
  407. $goods_ids = array_filter(explode(',', Redis::HGET($keyActivity, 'goods_ids')));
  408. if (!in_array($goods_id, $goods_ids) && !empty($goods_ids)) {
  409. continue;
  410. }
  411. $keysActivityGoods[] = $keyActivity;
  412. }
  413. return $keysActivityGoods;
  414. }
  415. // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 获取活动的 keys 数组 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
  416. // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 获取活动相关 key ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  417. /**
  418. * 获取活动 hash 的 key
  419. *
  420. * @param integer $activity_id 活动 id
  421. * @param string $activity_type 活动类型
  422. * @return string
  423. */
  424. private function keyActivity($activity_id, $activity_type)
  425. {
  426. // 示例 hash-activity:groupon:25
  427. return $this->hashPrefix . $activity_type . ':' . $activity_id;
  428. }
  429. /**
  430. * 获取活动 hash 中 商品相关的 key (is_sale 对应的活动商品的销量)
  431. *
  432. * @param integer $goods_id 商品
  433. * @param integer $sku_price_id 规格
  434. * @param boolean $is_sale 对应的活动商品的销量
  435. * @return string
  436. */
  437. private function keyActivityGoods($goods_id, $sku_price_id, $is_sale = false)
  438. {
  439. // 示例 商品规格:goods-25-30 or 商品规格销量:goods-25-30-sale
  440. return $this->hashGoodsPrefix . $goods_id . '-' . $sku_price_id . ($is_sale ? '-sale' : '');
  441. }
  442. /**
  443. * 获取活动中 拼团 的团数据的 key
  444. *
  445. * @param integer $groupon_id
  446. * @param integer $goods_id
  447. * @param string $type 空=团 key|num=团人数|users=团用户
  448. * @return string
  449. */
  450. private function keyActivityGroupon($groupon_id, $goods_id, $type = '')
  451. {
  452. return $this->hashGrouponPrefix . $groupon_id . '-' . $goods_id . ($type ? '-' . $type : '');
  453. }
  454. /**
  455. * 获取活动相关的所有 key
  456. *
  457. * @param array $detail 商品相关数据
  458. * @param array $activity 活动相关数据
  459. * @return array
  460. */
  461. public function keysActivity($detail, $activity)
  462. {
  463. // 获取 hash key
  464. $keyActivity = $this->keyActivity($activity['activity_id'], $activity['activity_type']);
  465. $keyGoodsSkuPrice = '';
  466. $keySale = '';
  467. if (isset($detail['goods_sku_price_id']) && $detail['goods_sku_price_id']) {
  468. // 获取 hash 表中商品 sku 的 key
  469. $keyGoodsSkuPrice = $this->keyActivityGoods($detail['goods_id'], $detail['goods_sku_price_id']);
  470. // 获取 hash 表中商品 sku 的 销量的 key
  471. $keySale = $this->keyActivityGoods($detail['goods_id'], $detail['goods_sku_price_id'], true);
  472. }
  473. // 需要拼团的字段
  474. $keyGroupon = '';
  475. $keyGrouponNum = '';
  476. $keyGrouponUserlist = '';
  477. if (isset($detail['groupon_id']) && $detail['groupon_id']) {
  478. // 获取 hash 表中团 key
  479. $keyGroupon = $this->keyActivityGroupon($detail['groupon_id'], $detail['goods_id']);
  480. // 获取 hash 表中团当前人数 key
  481. $keyGrouponNum = $this->keyActivityGroupon($detail['groupon_id'], $detail['goods_id'], 'num');
  482. // 获取 hash 表中团当前人员列表 key
  483. $keyGrouponUserlist = $this->keyActivityGroupon($detail['groupon_id'], $detail['goods_id'], 'users');
  484. }
  485. return compact('keyActivity', 'keyGoodsSkuPrice', 'keySale', 'keyGroupon', 'keyGrouponNum', 'keyGrouponUserlist');
  486. }
  487. // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 获取活动相关 key ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
  488. }