stockConsumer.php 6.0 KB

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