HbController.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. /**
  3. * 红包定时任务
  4. * - 沉睡召回:./yii hb/auto-send-sleep-recall
  5. * - 会员日:./yii hb/auto-send-member-day
  6. */
  7. namespace console\controllers;
  8. use bizHd\custom\models\Custom;
  9. use bizHd\hb\classes\HbAutoRuleClass;
  10. use bizHd\hb\classes\HbAutoSendLogClass;
  11. use bizHd\hb\models\HbAutoRule;
  12. use common\components\noticeUtil;
  13. use yii\console\Controller;
  14. use Yii;
  15. class HbController extends Controller
  16. {
  17. /**
  18. * 沉睡召回红包:每天执行一次
  19. * 条件:recentExpend 早于 N 天前(或从未下单),且距上次发放也已超过 N 天
  20. */
  21. public function actionAutoSendSleepRecall()
  22. {
  23. try {
  24. date_default_timezone_set('PRC');
  25. ini_set('memory_limit', '512M');
  26. set_time_limit(0);
  27. $rules = HbAutoRuleClass::getAllByCondition([
  28. 'type' => HbAutoRule::TYPE_SLEEP,
  29. 'status' => HbAutoRule::STATUS_ON,
  30. ]);
  31. if (empty($rules)) {
  32. echo "无开启的沉睡召回规则\n";
  33. return;
  34. }
  35. $totalIssued = 0;
  36. foreach ($rules as $rule) {
  37. $extra = json_decode($rule['extra'] ?? '', true);
  38. $days = max(1, (int)($extra['unOrderDays'] ?? 30));
  39. $threshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));
  40. $shopId = (int)$rule['shopId'];
  41. $query = Custom::find()
  42. ->select('id, userId, shopId, recentExpend, member, delStatus')
  43. ->where(['shopId' => $shopId])
  44. ->andWhere(['or',
  45. ['recentExpend' => '0000-00-00 00:00:00'],
  46. ['<', 'recentExpend', $threshold],
  47. ])
  48. ->orderBy('id ASC');
  49. // delStatus 字段若存在则过滤已删
  50. try {
  51. $query->andWhere(['delStatus' => 0]);
  52. } catch (\Throwable $e) {
  53. // 忽略
  54. }
  55. foreach ($query->batch(200) as $customs) {
  56. foreach ($customs as $custom) {
  57. $customId = (int)$custom->id;
  58. $lastSend = HbAutoSendLogClass::getLastSendTime($rule['id'], $customId);
  59. // 冷却:上次发放后需再过 N 天
  60. if ($lastSend && strtotime($lastSend) > strtotime("-{$days} days")) {
  61. continue;
  62. }
  63. $n = HbAutoRuleClass::issueToCustom($rule, $custom->attributes);
  64. $totalIssued += $n;
  65. }
  66. }
  67. }
  68. echo "沉睡召回发放完成,红包张数:{$totalIssued}\n";
  69. Yii::info("沉睡召回发放完成,红包张数:{$totalIssued}", __METHOD__);
  70. } catch (\Exception $e) {
  71. $msg = $e->getMessage();
  72. Yii::error('沉睡召回红包任务失败:' . $msg, __METHOD__);
  73. noticeUtil::push("沉睡召回红包任务失败:{$msg}", '15280215347');
  74. echo "沉睡召回红包任务失败:{$msg}\n";
  75. }
  76. }
  77. /**
  78. * 会员日红包:建议每小时执行
  79. * 按 extra.sendDay / sendTime / target 匹配,每月每客户只发一次
  80. */
  81. public function actionAutoSendMemberDay()
  82. {
  83. try {
  84. date_default_timezone_set('PRC');
  85. ini_set('memory_limit', '512M');
  86. set_time_limit(0);
  87. $now = time();
  88. $day = (int)date('j', $now);
  89. $hm = date('H:i', $now);
  90. $cycleTag = date('Ym', $now);
  91. $rules = HbAutoRuleClass::getAllByCondition([
  92. 'type' => HbAutoRule::TYPE_MEMBER_DAY,
  93. 'status' => HbAutoRule::STATUS_ON,
  94. ]);
  95. if (empty($rules)) {
  96. echo "无开启的会员日规则\n";
  97. return;
  98. }
  99. $totalIssued = 0;
  100. foreach ($rules as $rule) {
  101. $extra = json_decode($rule['extra'] ?? '', true) ?: [];
  102. $sendDay = (int)($extra['sendDay'] ?? 0);
  103. $sendTime = trim((string)($extra['sendTime'] ?? '10:00'));
  104. $target = (int)($extra['target'] ?? 1);
  105. if ($sendDay !== $day) {
  106. continue;
  107. }
  108. // 当前小时已到或超过设定时间即可发(每小时跑,靠 cycleTag 去重)
  109. if ($hm < $sendTime) {
  110. continue;
  111. }
  112. $shopId = (int)$rule['shopId'];
  113. $query = Custom::find()
  114. ->select('id, userId, shopId, member, delStatus')
  115. ->where(['shopId' => $shopId])
  116. ->orderBy('id ASC');
  117. try {
  118. $query->andWhere(['delStatus' => 0]);
  119. } catch (\Throwable $e) {
  120. }
  121. // target=2 仅会员(member>0)
  122. if ($target === 2) {
  123. $query->andWhere(['>', 'member', 0]);
  124. }
  125. foreach ($query->batch(200) as $customs) {
  126. foreach ($customs as $custom) {
  127. $customId = (int)$custom->id;
  128. if (HbAutoSendLogClass::hasCycle($rule['id'], $customId, $cycleTag)) {
  129. continue;
  130. }
  131. $n = HbAutoRuleClass::issueToCustom($rule, $custom->attributes, $cycleTag);
  132. $totalIssued += $n;
  133. }
  134. }
  135. }
  136. echo "会员日发放完成,红包张数:{$totalIssued}\n";
  137. Yii::info("会员日发放完成,红包张数:{$totalIssued}", __METHOD__);
  138. } catch (\Exception $e) {
  139. $msg = $e->getMessage();
  140. Yii::error('会员日红包任务失败:' . $msg, __METHOD__);
  141. noticeUtil::push("会员日红包任务失败:{$msg}", '15280215347');
  142. echo "会员日红包任务失败:{$msg}\n";
  143. }
  144. }
  145. }