BalanceCrontab.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. // if ($value != 46) {
  55. // continue;
  56. // }
  57. //----------------临时调试----------------
  58. //查询该运营商用户的余额,上月消费记录等数据
  59. $startTime = strtotime(date('Y-m-01', strtotime('-1 month')));
  60. $endTime = strtotime(date('Y-m-t', strtotime('-1 month')))+86400;
  61. //查询条件
  62. $where = empty($value)?' m.`operators_id`=0 or m.`operators_id` IS NULL or m.`operators_id`=""':' m.`operators_id` = '.$value;
  63. $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,
  64. IF(LENGTH(ou.`key`)<1 OR ou.`key` IS NULL,'前台优选',ou.`operators_name`) AS operators_name
  65. FROM ims_superdesk_shop_member m
  66. 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,
  67. 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)
  68. AS mo ON mo.openid = m.`openid`
  69. LEFT JOIN ims_superdesk_shop_operators_user ou ON ou.`id` = m.`operators_id`
  70. WHERE {$where};
  71. ";
  72. $queryBuild = new QueryBuilder();
  73. $queryBuild->raw($que_sql);
  74. $res_data = DbManager::getInstance()->query($queryBuild, true, 'default')->toArray();
  75. foreach($res_data['result'] as $k=>$val){
  76. //----------------临时调试----------------
  77. // if (!in_array($val['mobile'], ['13410844128', '13823684008', '13600151177', '13544145803'])) {
  78. // continue;
  79. // }
  80. //----------------临时调试----------------
  81. //插入推送内容
  82. $insert = [
  83. 'task_id' => $task_id,
  84. 'member_id' => $val['id'],
  85. //设置启用公众号消息以及该用户存在公众号openid的情况下推送公众号消息,否则推送短信
  86. 'push_type' => !empty($val['openid_wx'])&&$this->set['wechat_msg']==1?1:2,
  87. 'openid' => $val['openid_wx'],
  88. 'mobile' => $val['mobile'],
  89. 'consume_credit' => $val['consume'],
  90. 'balance' => $val['credit2'],
  91. 'end_time' => $endTime-1,
  92. 'operators_id' => $val['operators_id'],
  93. 'operators_name' => $val['operators_name'],
  94. 'status' => 0,
  95. ];
  96. //公众号消息模板推送屏蔽
  97. if($insert['push_type']==1 && !empty($this->set['wechat_msg_id'])){
  98. $wechat_msg_id = explode(",",$this->set['wechat_msg_id']);
  99. if (in_array($insert['member_id'],$wechat_msg_id)) {
  100. continue;
  101. }
  102. }
  103. //手机短信推送屏蔽
  104. if($insert['push_type']==2 && !empty($this->set['sms_id'])){
  105. $sms_id = explode(",",$this->set['sms_id']);
  106. if (in_array($insert['member_id'],$sms_id)) {
  107. continue;
  108. }
  109. }
  110. $model = BalancePushBody::create($insert);
  111. $body_id = $model->save();
  112. //开始推送
  113. $this->push_msg($insert,$body_id);
  114. }
  115. }
  116. }
  117. /**
  118. * 开始推送内容
  119. * @param $sendData 任务内容,一般是推送任务内容表的数据
  120. * @param $body_id 任务内容id
  121. * @return Bool 是否发送成功 true是 false否
  122. */
  123. protected function push_msg($sendData,$body_id){
  124. //公众号消息模板推送
  125. if($sendData['push_type']==1){
  126. $wm = new WechatMessage($sendData['operators_id']);
  127. $api_res = $wm->send_message($sendData['openid'],$this->templateId,'',[
  128. //模板数据
  129. 'first' => ['value'=>'尊敬的客户:您上月共消费了'.$sendData['consume_credit'].'积分'],
  130. 'keyword1' => ['value'=>$sendData['balance']],
  131. 'keyword2' => ['value'=>date('Y年m月d日',$sendData['end_time'])],
  132. 'remark' => ['value'=>'欢迎登录「'.$sendData['operators_name'].'」小程序选购心仪的商品。'],
  133. // 'remark' => ['value'=>'开工红包派发中,最高888元,点击领取', 'color' => '#E3170D'],
  134. // 'remark' => ['value'=>'做最美的女神,点击领取走心好礼', 'color' => '#E3170D'],
  135. ]);
  136. $status = $api_res['response']['errcode']!==0?2:1; //0无响应 1成功 2失败
  137. }
  138. //手机短信推送
  139. if($sendData['push_type']==2){
  140. $sms = new Sms($sendData['operators_id']);
  141. $api_res = $sms->send($sendData['mobile'],'SMS_232170368',[
  142. 's_1' => $sendData['consume_credit'],
  143. 's_2' => $sendData['balance'],
  144. ]);
  145. $status = $api_res['response']['Code']!='OK'?2:1; //0无响应 1成功 2失败
  146. }
  147. //更新任务内容表
  148. $res = BalancePushBody::create()->update([
  149. 'status' => $status,
  150. ], ['id' => $body_id]);
  151. //写入日志表
  152. BalancePushLog::create()->data([
  153. 'body_id' => $body_id,
  154. 'request' => json_encode($api_res['request']),
  155. 'response' => json_encode($api_res['response']),
  156. 'create_time' => time(),
  157. 'status' => $status,
  158. ],false)->save();
  159. }
  160. function process_repeat_msg(){
  161. $repeat_list = BalancePushTask::create()->where('is_send',2)->all();
  162. foreach($repeat_list as $value){
  163. //获取需要重发任务下属的失败内容
  164. $value = $value->toArray();
  165. $repeat_body = BalancePushBody::create()->where('task_id',$value['id'])->where('status', 1, '!=')->all();
  166. foreach($repeat_body as $val){
  167. $val = $val->toArray();
  168. $this->push_msg($val,$val['id']); //重新推送处理
  169. }
  170. }
  171. }
  172. /**
  173. * 创建任务
  174. * @return int 任务ID
  175. */
  176. protected function createTask(){
  177. $time = time();
  178. $model = BalancePushTask::create([
  179. 'operator' => '系统',
  180. 'create_time' => $time,
  181. 'update_time' => $time,
  182. 'is_send' => 1,
  183. ]);
  184. return $model->save();
  185. }
  186. }