stockConsumer.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. /**
  3. * 库存管理消费者
  4. * 处理花材库存补充、扣减等库存操作
  5. */
  6. namespace common\components\rabbitmq;
  7. use bizGhs\product\classes\ProductClass;
  8. use bizHd\birthday\classes\BirthdayGiftClass;
  9. use bizHd\groupBuy\classes\GroupBuyClass;
  10. use bizHd\product\classes\ProductClass as hdProductClass;
  11. use common\components\noticeUtil;
  12. use mikemadisonweb\rabbitmq\components\ConsumerInterface;
  13. use PhpAmqpLib\Message\AMQPMessage;
  14. use Yii;
  15. class stockConsumer extends baseConsumer
  16. {
  17. /**
  18. * 执行消费者逻辑
  19. *
  20. * @param AMQPMessage $msg 消息对象
  21. * @return string 消息处理结果
  22. *
  23. * ConsumerInterface::MSG_ACK - 确认消息(标记为已处理)并从队列中删除
  24. * ConsumerInterface::MSG_REJECT - 拒绝并从队列中删除消息
  25. * ConsumerInterface::MSG_REQUEUE - 拒绝并重新入队消息
  26. */
  27. public function execute(AMQPMessage $msg)
  28. {
  29. try {
  30. $this->ensureDbConnection();
  31. // 反序列化消息体
  32. $data = unserialize($msg->body);
  33. if (!is_array($data)) {
  34. noticeUtil::push("库存的消费者报错:Invalid notify message format: {$msg->body}");
  35. return ConsumerInterface::MSG_REJECT;
  36. }
  37. print_r($data);
  38. // 根据操作类型分发处理
  39. $type = $data['type'] ?? null;
  40. if ($type == 'limit_buy_clear') {
  41. Yii::info('限购延迟消息开始消费: ' . json_encode($data, JSON_UNESCAPED_UNICODE), __METHOD__);
  42. Yii::getLogger()->flush(true);
  43. }
  44. switch ($type) {
  45. case 'add':
  46. $result = true;
  47. echo '持久化OK---';
  48. break;
  49. case 'limit_buy_clear':
  50. echo 'limit_buy_clear---';
  51. $result = $this->runWithDbReconnect(function () use ($data) {
  52. return $this->clearOrderItemLimitBuy($data);
  53. });
  54. break;
  55. case 'birthday_gift_expire':
  56. $giftId = intval($data['giftId']);
  57. echo 'birthday_gift_expire --- giftId=' . $giftId;
  58. $result = $this->runWithDbReconnect(function () use ($giftId) {
  59. return BirthdayGiftClass::expireById($giftId);
  60. });
  61. break;
  62. case 'group_buy_expire':
  63. $groupBuyId = intval($data['groupBuyId']);
  64. echo 'group_buy_expire --- groupBuyId=' . $groupBuyId;
  65. $result = $this->runWithDbReconnect(function () use ($groupBuyId) {
  66. return GroupBuyClass::expireById($groupBuyId);
  67. });
  68. break;
  69. default:
  70. noticeUtil::push("库存的消费者报错,未知 type: {$type}");
  71. $result = false;
  72. }
  73. if ($result) {
  74. return ConsumerInterface::MSG_ACK;
  75. } else {
  76. noticeUtil::push("库存的消费者报错:Stock message processing failed");
  77. //return ConsumerInterface::MSG_REQUEUE;
  78. return ConsumerInterface::MSG_ACK;
  79. }
  80. } catch (\Exception $e) {
  81. noticeUtil::push("库存的消费者报错:" . $e->getMessage());
  82. //return ConsumerInterface::MSG_REQUEUE;
  83. return ConsumerInterface::MSG_ACK;
  84. }
  85. }
  86. /**
  87. * 清空订单项限购值
  88. *
  89. * @param array $data
  90. * @return bool
  91. */
  92. private function clearOrderItemLimitBuy($data)
  93. {
  94. $productId = intval($data['productId']);
  95. if ($productId <= 0) {
  96. noticeUtil::push('取消限购的消费者报错:limit_buy_clear 缺少 productId');
  97. return true;
  98. }
  99. $clearAt = intval($data['clearAt'] ?? 0);
  100. if ($clearAt <= 0) {
  101. noticeUtil::push('取消限购的消费者报错:limit_buy_clear 缺少 clearAt');
  102. return true;
  103. }
  104. $ptType = $data['ptType'] ?? 'ghs';
  105. $productClass = $ptType == 'ghs' ? ProductClass::class : hdProductClass::class;
  106. // 旧消息直接忽略,避免“先到期的旧消息”提前清空
  107. if (!$productClass::checkLimitBuyClearMessage($productId, $clearAt)) {
  108. return true;
  109. }
  110. $recurring = intval($data['recurring'] ?? 0);
  111. if ($recurring == 1) {
  112. $result = $productClass::clearLimitBuyRecordByProductId($productId);
  113. if ($result) {
  114. $intervalDays = intval($data['intervalDays'] ?? 0);
  115. $clearHour = intval($data['clearHour'] ?? -1);
  116. if ($intervalDays <= 0 || $clearHour < 0 || $clearHour > 23) {
  117. $config = $productClass::getLimitBuyClearLoopConfigByProductId($productId);
  118. $intervalDays = intval($config['intervalDays'] ?? 0);
  119. $clearHour = intval($config['clearHour'] ?? -1);
  120. }
  121. if ($intervalDays > 0 && $clearHour >= 0 && $clearHour <= 23) {
  122. $productClass::createRecurringLimitBuyCache($productId, $intervalDays, $clearHour);
  123. } else {
  124. $productClass::clearLimitBuyClearMark($productId);
  125. noticeUtil::push('循环限购清理成功但缺少下一次调度配置: ' . json_encode([
  126. 'ptType' => $ptType,
  127. 'productId' => $productId,
  128. 'clearAt' => $clearAt,
  129. ], JSON_UNESCAPED_UNICODE));
  130. }
  131. } else {
  132. noticeUtil::push('限购字段清理失败: ' . json_encode([
  133. 'ptType' => $ptType,
  134. 'productId' => $productId,
  135. 'clearAt' => $clearAt,
  136. ], JSON_UNESCAPED_UNICODE));
  137. }
  138. return $result;
  139. }
  140. $result = $productClass::clearLimitBuyByProductId($productId);
  141. if ($result) {
  142. $productClass::clearLimitBuyClearMark($productId);
  143. } else {
  144. noticeUtil::push('限购字段清理失败: ' . json_encode([
  145. 'ptType' => $ptType,
  146. 'productId' => $productId,
  147. 'clearAt' => $clearAt,
  148. ], JSON_UNESCAPED_UNICODE));
  149. }
  150. return $result;
  151. }
  152. }