BalanceCrontab.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. namespace App\Crontab;
  3. use EasySwoole\Crontab\JobInterface;
  4. use EasySwoole\Mysqli\QueryBuilder;
  5. use EasySwoole\ORM\DbManager;
  6. use App\Models\BalancePushSet;
  7. use App\Models\ShopMember;
  8. use App\Models\BalancePushTask;
  9. use App\Models\BalancePushBody;
  10. use App\Models\BalancePushLog;
  11. use App\Com\WechatMessage;
  12. use App\Com\Sms;
  13. class BalanceCrontab implements JobInterface
  14. {
  15. protected $set; //余额推送设置
  16. protected $templateId = 'Gwn-TDRSrKqB6Bp3Bg2NdrXPqXUes0x13JJ87mcNHD4'; //模板ID
  17. public function jobName(): string
  18. {
  19. // 定时任务的名称
  20. return 'BalanceCrontab';
  21. }
  22. public function crontabRule(): string
  23. {
  24. // 定义执行规则 根据 Crontab 来定义
  25. // 这里是每个月1号的早上8点执行
  26. return '0 8 1 * *';
  27. }
  28. public function run()
  29. {
  30. // 定时任务的执行逻辑
  31. $this->set = BalancePushSet::create()->get()->toArray();
  32. //是否启用
  33. if($this->set['enable']!=1){
  34. return;
  35. }
  36. //创建任务
  37. $taskId = $this->createTask();
  38. //生成任务内容以及处理消息发送任务
  39. $this->push_start($taskId);
  40. //处理需要重新发送消息的内容
  41. $this->process_repeat_msg();
  42. }
  43. public function onException(\Throwable $throwable)
  44. {
  45. // 捕获 run 方法内所抛出的异常
  46. }
  47. /**
  48. * 推送开始
  49. */
  50. protected function push_start($task_id){
  51. $operators = explode(",",$this->set['operators']);
  52. foreach($operators as $value){
  53. //查询该运营商用户的余额,上月消费记录等数据
  54. $startTime = strtotime(date('Y-m-01', strtotime('-1 month')));
  55. $endTime = strtotime(date('Y-m-t', strtotime('-1 month')))+86400;
  56. //查询条件
  57. $where = empty($value)?' m.`operators_id`=0 or m.`operators_id` IS NULL or m.`operators_id`=""':' m.`operators_id` = '.$value;
  58. $que_sql = "SELECT m.`id`,m.`openid_wx`,m.`mobile`,m.`credit2`,m.`operators_id`,IFNULL(mo.`consume`,0) AS consume,IF(LENGTH(ou.`key`)<1 OR ou.`key` IS NULL,'wxc80da22c408c9a85',ou.`key`) AS appid,
  59. IF(LENGTH(ou.`key`)<1 OR ou.`key` IS NULL,'前台优选',ou.`operators_name`) AS operators_name
  60. FROM ims_superdesk_shop_member m
  61. LEFT JOIN (SELECT SUM(credit_use) AS consume,openid FROM (SELECT o.`id`,( CASE o.`paytype` WHEN 1 THEN o.`price` WHEN 24 THEN o.`comb_pay_credit` ELSE 0 END) AS credit_use,
  62. o.`openid` FROM ims_superdesk_shop_order o WHERE o.`parentid`=0 AND o.`status` IN (1,2,3) AND o.`createtime`>={$startTime} AND o.`createtime`<{$endTime} ) AS temp_order GROUP BY openid)
  63. AS mo ON mo.openid = m.`openid`
  64. LEFT JOIN ims_superdesk_shop_operators_user ou ON ou.`id` = m.`operators_id`
  65. WHERE {$where};
  66. ";
  67. $queryBuild = new QueryBuilder();
  68. $queryBuild->raw($que_sql);
  69. $res_data = DbManager::getInstance()->query($queryBuild, true, 'default')->toArray();
  70. foreach($res_data['result'] as $k=>$val){
  71. //插入推送内容
  72. $insert = [
  73. 'task_id' => $task_id,
  74. 'member_id' => $val['id'],
  75. //设置启用公众号消息以及该用户存在公众号openid的情况下推送公众号消息,否则推送短信
  76. 'push_type' => !empty($val['openid_wx'])&&$this->set['wechat_msg']==1?1:2,
  77. 'openid' => $val['openid_wx'],
  78. 'mobile' => $val['mobile'],
  79. 'consume_credit' => $val['consume'],
  80. 'balance' => $val['credit2'],
  81. 'end_time' => $endTime-1,
  82. 'operators_id' => $val['operators_id'],
  83. 'operators_name' => $val['operators_name'],
  84. 'status' => 0,
  85. ];
  86. $model = BalancePushBody::create($insert);
  87. $body_id = $model->save();
  88. //开始推送
  89. $this->push_msg($insert,$body_id);
  90. }
  91. }
  92. }
  93. /**
  94. * 开始推送内容
  95. * @param $sendData 任务内容,一般是推送任务内容表的数据
  96. * @param $body_id 任务内容id
  97. * @return Bool 是否发送成功 true是 false否
  98. */
  99. protected function push_msg($sendData,$body_id){
  100. //公众号消息模板推送
  101. if($sendData['push_type']==1){
  102. $wm = new WechatMessage($sendData['operators_id']);
  103. $api_res = $wm->send_message($sendData['openid'],$this->templateId,'',[
  104. //模板数据
  105. 'first' => ['value'=>'尊敬的客户:您上月共消费了'.$sendData['consume_credit'].'积分'],
  106. 'keyword1' => ['value'=>$sendData['balance']],
  107. 'keyword2' => ['value'=>date('Y年m月d日',$sendData['end_time'])],
  108. 'remark' => ['value'=>'欢迎登录「'.$sendData['operators_name'].'」小程序选购心仪的商品。'],
  109. ]);
  110. $status = $api_res['response']['errcode']!==0?2:1; //0无响应 1成功 2失败
  111. }
  112. //手机短信推送
  113. if($sendData['push_type']==2){
  114. $sms = new Sms($sendData['operators_id']);
  115. $api_res = $sms->send($sendData['mobile'],'SMS_232170368',[
  116. 's_1' => $sendData['consume_credit'],
  117. 's_2' => $sendData['balance'],
  118. ]);
  119. $status = $api_res['response']['Code']!='OK'?2:1; //0无响应 1成功 2失败
  120. }
  121. //更新任务内容表
  122. $res = BalancePushBody::create()->update([
  123. 'status' => $status,
  124. ], ['id' => $body_id]);
  125. //写入日志表
  126. BalancePushLog::create()->data([
  127. 'body_id' => $body_id,
  128. 'request' => json_encode($api_res['request']),
  129. 'response' => json_encode($api_res['response']),
  130. 'create_time' => time(),
  131. 'status' => $status,
  132. ],false)->save();
  133. }
  134. function process_repeat_msg(){
  135. $repeat_list = BalancePushTask::create()->where('is_send',2)->all();
  136. foreach($repeat_list as $value){
  137. //获取需要重发任务下属的失败内容
  138. $value = $value->toArray();
  139. $repeat_body = BalancePushBody::create()->where('task_id',$value['id'])->where('status', 1, '!=')->all();
  140. foreach($repeat_body as $val){
  141. $val = $val->toArray();
  142. $this->push_msg($val,$val['id']); //重新推送处理
  143. }
  144. }
  145. }
  146. /**
  147. * 创建任务
  148. * @return int 任务ID
  149. */
  150. protected function createTask(){
  151. $time = time();
  152. $model = BalancePushTask::create([
  153. 'operator' => '系统',
  154. 'create_time' => $time,
  155. 'update_time' => $time,
  156. 'is_send' => 1,
  157. ]);
  158. return $model->save();
  159. }
  160. }