Plantask.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <?php
  2. namespace app\index\controller;
  3. use think\Controller;
  4. use think\Db;
  5. use app\common\library\Email;
  6. class Plantask extends Controller
  7. {
  8. //关于本文件里的计划任务
  9. //只有 public 方法,auto_开头的才是计划任务,其他private 方法都是工具方法
  10. ////////////////////////////////////////下面都是计划任务方法///////////////////////////////////////////////////////////////
  11. //明天有课,通知。计划任务10分钟执行一次
  12. public function auto_lesson_slot_notice(){
  13. $starttime = strtotime(date('Y-m-d')) + 86400;
  14. $endtime = $starttime + 86399;
  15. $map = [
  16. 'status' => 0,
  17. 'starttime' => ['BETWEEN',[$starttime,$endtime]],
  18. 'notice_status' => 0,
  19. ];
  20. $task_list = Db::name('lesson_slot')->where($map)->order('starttime asc')->limit(1)->select();
  21. if(empty($task_list)){
  22. echo 'empty';
  23. exit;
  24. }
  25. foreach($task_list as $slot){
  26. //找出这节课时的预约单
  27. $map = [
  28. 'order.order_status' => 10,
  29. 'order.slot_id' => $slot['id'],
  30. ];
  31. $order_list = Db::name('lesson_order')->alias('order')
  32. ->field('lesson.name,lesson.name_en,user.firstname,user.lastname,user.email,user.whatsapp')
  33. ->join('user','order.user_id = user.id','LEFT')
  34. ->join('lesson','order.lesson_id = lesson.id','LEFT')
  35. ->where($map)->order('order.id asc')->select();
  36. //$order_list = $this->list_lang($order_list,['name']);
  37. if(empty($order_list)){
  38. continue;
  39. }
  40. $coach_name = Db::name('coach')->where('id',$slot['coach_ids'])->value('nickname');
  41. //给这些预约单的用户发邮件
  42. try {
  43. $obj = new Email();
  44. foreach($order_list as $order){
  45. $result = $obj
  46. ->to($order['email'])
  47. ->subject('Don’t forget about your class tomorrow!')
  48. ->message('Hi,'.$order['firstname']. ' ' .$order['lastname'].',您预约的['.$order['name'].']将于'.date('Y-m-d H:i',$slot['starttime']).'开课,请合理安排时间,准时来上课哦!')
  49. ->send();
  50. //发whatsapp
  51. $parameters = [
  52. [
  53. 'type' => 'text',
  54. 'text' => $order['firstname'].' '.$order['lastname'],
  55. ],
  56. [
  57. 'type' => 'text',
  58. 'text' => $order['name_en'],
  59. ],
  60. [
  61. 'type' => 'text',
  62. 'text' => $coach_name,
  63. ],
  64. [
  65. 'type' => 'text',
  66. 'text' => date('Y-m-d H:i',$slot['starttime']),
  67. ],
  68. ];
  69. $this->whatapp($order['whatsapp'],'the_class_will_start_tomorrow','en_US',$parameters);
  70. }
  71. } catch (Exception $e) {
  72. }
  73. //这节课时,任务完成
  74. $update = [
  75. 'notice_status' => 1,
  76. ];
  77. Db::name('lesson_slot')->where('id',$slot['id'])->update($update);
  78. }
  79. }
  80. //课程取消,通知。计划任务5分钟执行一次
  81. public function auto_lesson_slot_cancel(){
  82. $map = [
  83. 'status' => 30,
  84. 'cancel_notice_status' => 0,
  85. ];
  86. $task_list = Db::name('lesson_slot')->where($map)->order('starttime asc')->limit(1)->select();
  87. if(empty($task_list)){
  88. echo 'empty';
  89. exit;
  90. }
  91. foreach($task_list as $slot){
  92. //找出这节课时的预约单
  93. $map = [
  94. 'order.order_status' => 10,
  95. 'order.slot_id' => $slot['id'],
  96. ];
  97. $order_list = Db::name('lesson_order')->alias('order')
  98. ->field('lesson.name,lesson.name_en,user.firstname,user.lastname,user.email,user.whatsapp')
  99. ->join('user','order.user_id = user.id','LEFT')
  100. ->join('lesson','order.lesson_id = lesson.id','LEFT')
  101. ->where($map)->order('order.id asc')->select();
  102. //$order_list = $this->list_lang($order_list,['name']);
  103. if(empty($order_list)){
  104. continue;
  105. }
  106. //给这些预约单的用户发邮件
  107. try {
  108. $obj = new Email();
  109. foreach($order_list as $order){
  110. $result = $obj
  111. ->to($order['email'])
  112. ->subject('Class is Cancelled!')
  113. ->message('Hi,'.$order['firstname']. ' ' .$order['lastname'].',您预约的['.$order['name'].']将于'.date('Y-m-d H:i:s',$slot['starttime']).'开课,请合理安排时间,准时来上课哦!')
  114. ->send();
  115. //发whatsapp
  116. $parameters = [
  117. [
  118. 'type' => 'text',
  119. 'text' => $order['firstname'].' '.$order['lastname'],
  120. ],
  121. [
  122. 'type' => 'text',
  123. 'text' => $order['name_en'],
  124. ],
  125. [
  126. 'type' => 'text',
  127. 'text' => date('Y-m-d H:i',$slot['starttime']),
  128. ],
  129. ];
  130. $this->whatapp($order['whatsapp'],'the_class_cancelled','en_US',$parameters);
  131. }
  132. } catch (Exception $e) {
  133. }
  134. //这节课时,任务完成
  135. $update = [
  136. 'cancel_notice_status' => 1,
  137. ];
  138. Db::name('lesson_slot')->where('id',$slot['id'])->update($update);
  139. }
  140. }
  141. //购买新套餐之后,通知。计划任务5分钟执行一次
  142. public function auto_after_buy_package(){
  143. $map = [
  144. 'order.order_status' => 1,
  145. 'order.buy_notice_status' => 0,
  146. 'order.is_gift' => 0,
  147. ];
  148. $task_list = Db::name('package_order')->alias('order')
  149. ->field('order.id,order.endtime,p.name,p.name_en,user.firstname,user.lastname,user.email,user.whatsapp')
  150. ->join('lesson_package p','order.package_id = p.id','LEFT')
  151. ->join('user','order.user_id = user.id','LEFT')
  152. ->where($map)->order('order.paytime asc')->limit(1)->select();
  153. if(empty($task_list)){
  154. echo 'empty';
  155. exit;
  156. }
  157. $obj = new Email();
  158. foreach($task_list as $order){
  159. try {
  160. //给这些用户发邮件
  161. $result = $obj
  162. ->to($order['email'])
  163. ->subject('Elin Dance Studio 您购买的套餐已到账')
  164. ->message('Hi,'.$order['firstname']. ' ' .$order['lastname'].',您购买的套餐['.$order['name'].']即日起生效!')
  165. ->send();
  166. //发whatsapp
  167. $parameters = [
  168. [
  169. 'type' => 'text',
  170. 'text' => $order['firstname'].' '.$order['lastname'],
  171. ],
  172. [
  173. 'type' => 'text',
  174. 'text' => $order['name_en'],
  175. ],
  176. /*[
  177. 'type' => 'text',
  178. 'text' => date('Y-m-d H:i',$slot['starttime']),
  179. ],*/
  180. ];
  181. $this->whatapp($order['whatsapp'],'buy_new_package','en_US',$parameters);
  182. } catch (Exception $e) {
  183. }
  184. //任务完成
  185. $update = [
  186. 'buy_notice_status' => 1,
  187. ];
  188. Db::name('package_order')->where('id',$order['id'])->update($update);
  189. }
  190. }
  191. //套餐将要到期,一个月,两周,一周,逐级通知,提醒三次。计划任务分别一小时执行一次
  192. public function auto_package_order_notice_mon(){
  193. $map = [
  194. 'order.order_status' => 1,
  195. 'order.remain' => ['gt',0],
  196. 'order.endtime' => ['lt',time()+(86400*30)],
  197. 'order.notice_status' => 0,
  198. ];
  199. $task_list = Db::name('package_order')->alias('order')
  200. ->field('order.id,order.endtime,p.name,p.name_en,p.remain,user.firstname,user.lastname,user.email,user.whatsapp')
  201. ->join('lesson_package p','order.package_id = p.id','LEFT')
  202. ->join('user','order.user_id = user.id','LEFT')
  203. ->where($map)->order('endtime asc')->limit(2)->select();
  204. if(empty($task_list)){
  205. echo 'empty';
  206. exit;
  207. }
  208. $obj = new Email();
  209. foreach($task_list as $order){
  210. try {
  211. //给这些用户发邮件
  212. $result = $obj
  213. ->to($order['email'])
  214. ->subject('Elin Dance Studio 套餐到期提醒!')
  215. ->message('Hi,'.$order['firstname']. ' ' .$order['lastname'].',您购买的套餐['.$order['name'].']将于'.date('Y-m-d H:i:s',$order['endtime']).'过期,建议您在过期内使用完毕!')
  216. ->send();
  217. //发whatsapp
  218. $parameters = [
  219. [
  220. 'type' => 'text',
  221. 'text' => $order['firstname'].' '.$order['lastname'],
  222. ],
  223. [
  224. 'type' => 'text',
  225. 'text' => '30',
  226. ],
  227. [
  228. 'type' => 'text',
  229. 'text' => $order['name_en'],
  230. ],
  231. [
  232. 'type' => 'text',
  233. 'text' => date('Y-m-d H:i',$order['endtime']),
  234. ],
  235. [
  236. 'type' => 'text',
  237. 'text' => ''.$order['remain'].'',
  238. ],
  239. ];
  240. $this->whatapp($order['whatsapp'],'package_expiration_reminder','en_US',$parameters);
  241. } catch (Exception $e) {
  242. }
  243. //任务完成
  244. $update = [
  245. 'notice_status' => 1,//月通知已发送
  246. ];
  247. Db::name('package_order')->where('id',$order['id'])->update($update);
  248. }
  249. }
  250. public function auto_package_order_notice_2week(){
  251. $map = [
  252. 'order.order_status' => 1,
  253. 'order.remain' => ['gt',0],
  254. 'order.endtime' => ['lt',time()+(86400*14)],
  255. 'order.notice_status' => 1,
  256. ];
  257. $task_list = Db::name('package_order')->alias('order')
  258. ->field('order.id,order.endtime,p.name,p.name_en,p.remain,user.firstname,user.lastname,user.email,user.whatsapp')
  259. ->join('lesson_package p','order.package_id = p.id','LEFT')
  260. ->join('user','order.user_id = user.id','LEFT')
  261. ->where($map)->order('endtime asc')->limit(2)->select();
  262. if(empty($task_list)){
  263. echo 'empty';
  264. exit;
  265. }
  266. $obj = new Email();
  267. foreach($task_list as $order){
  268. try {
  269. //给这些用户发邮件
  270. $result = $obj
  271. ->to($order['email'])
  272. ->subject('Elin Dance Studio 套餐到期提醒!')
  273. ->message('Hi,'.$order['firstname']. ' ' .$order['lastname'].',您购买的套餐['.$order['name'].']将于'.date('Y-m-d H:i:s',$order['endtime']).'过期,建议您在过期内使用完毕!')
  274. ->send();
  275. //发whatsapp
  276. $parameters = [
  277. [
  278. 'type' => 'text',
  279. 'text' => $order['firstname'].' '.$order['lastname'],
  280. ],
  281. [
  282. 'type' => 'text',
  283. 'text' => '14',
  284. ],
  285. [
  286. 'type' => 'text',
  287. 'text' => $order['name_en'],
  288. ],
  289. [
  290. 'type' => 'text',
  291. 'text' => date('Y-m-d H:i',$order['endtime']),
  292. ],
  293. [
  294. 'type' => 'text',
  295. 'text' => ''.$order['remain'].'',
  296. ],
  297. ];
  298. $this->whatapp($order['whatsapp'],'package_expiration_reminder','en_US',$parameters);
  299. } catch (Exception $e) {
  300. }
  301. //任务完成
  302. $update = [
  303. 'notice_status' => 2,//2周通知已发送
  304. ];
  305. Db::name('package_order')->where('id',$order['id'])->update($update);
  306. }
  307. }
  308. public function auto_package_order_notice_1week(){
  309. $map = [
  310. 'order.order_status' => 1,
  311. 'order.remain' => ['gt',0],
  312. 'order.endtime' => ['lt',time()+(86400*7)],
  313. 'order.notice_status' => 2,
  314. ];
  315. $task_list = Db::name('package_order')->alias('order')
  316. ->field('order.id,order.endtime,p.name,p.name_en,p.remain,user.firstname,user.lastname,user.email,user.whatsapp')
  317. ->join('lesson_package p','order.package_id = p.id','LEFT')
  318. ->join('user','order.user_id = user.id','LEFT')
  319. ->where($map)->order('endtime asc')->limit(2)->select();
  320. if(empty($task_list)){
  321. echo 'empty';
  322. exit;
  323. }
  324. $obj = new Email();
  325. foreach($task_list as $order){
  326. try {
  327. //给这些用户发邮件
  328. $result = $obj
  329. ->to($order['email'])
  330. ->subject('Elin Dance Studio 套餐到期提醒!')
  331. ->message('Hi,'.$order['firstname']. ' ' .$order['lastname'].',您购买的套餐['.$order['name'].']将于'.date('Y-m-d H:i:s',$order['endtime']).'过期,建议您在过期内使用完毕!')
  332. ->send();
  333. //发whatsapp
  334. $parameters = [
  335. [
  336. 'type' => 'text',
  337. 'text' => $order['firstname'].' '.$order['lastname'],
  338. ],
  339. [
  340. 'type' => 'text',
  341. 'text' => '7',
  342. ],
  343. [
  344. 'type' => 'text',
  345. 'text' => $order['name_en'],
  346. ],
  347. [
  348. 'type' => 'text',
  349. 'text' => date('Y-m-d H:i',$order['endtime']),
  350. ],
  351. [
  352. 'type' => 'text',
  353. 'text' => ''.$order['remain'].'',
  354. ],
  355. ];
  356. $this->whatapp($order['whatsapp'],'package_expiration_reminder','en_US',$parameters);
  357. } catch (Exception $e) {
  358. }
  359. //任务完成
  360. $update = [
  361. 'notice_status' => 3,//2周通知已发送
  362. ];
  363. Db::name('package_order')->where('id',$order['id'])->update($update);
  364. }
  365. }
  366. /////////////////////////////////////////下面都是工具方法////////////////////////////////////////////////
  367. public function whatapp($receive_mobile,$template,$code,$parameters){
  368. if(empty($receive_mobile)){return true;}
  369. $token = config('site.whatsapp_token');
  370. //发送者
  371. $mobile_id = '337736419413019'; //Elin Dance Stuido 2:+65 8015 4154 , WhatsApp Business Account ID: 336509229537586
  372. //发送
  373. $url = 'https://graph.facebook.com/v19.0/'.$mobile_id.'/messages';
  374. $header = [
  375. 'Authorization: Bearer ' . $token,
  376. 'Content-Type: application/json',
  377. ];
  378. $body = [
  379. 'messaging_product' => 'whatsapp',
  380. 'recipient_type' => 'individual',
  381. 'to' => $receive_mobile,
  382. 'type' => 'template',
  383. 'template' => [
  384. 'name' => $template,
  385. 'language' => [
  386. 'code' => $code
  387. ],
  388. 'components' => [
  389. [
  390. 'type' => 'body',
  391. 'parameters' => $parameters
  392. ]
  393. ],
  394. ],
  395. ];
  396. $body = json_encode($body);
  397. $rs = curl_post($url,$body,$header);
  398. return true;
  399. }
  400. //结果集信息里,多个字段需要翻译
  401. private function list_lang($list,$field,$lang = ''){
  402. if(!$list || empty($list)){
  403. return $list;
  404. }
  405. foreach($list as $vo => $info){
  406. $list[$vo] = $this->info_lang($info,$field);
  407. }
  408. return $list;
  409. }
  410. //单条信息里,多个字段需要翻译
  411. private function info_lang($data,$field,$lang = ''){
  412. if(!$data || empty($data)){
  413. return $data;
  414. }
  415. foreach($data as $key => $val){
  416. if(in_array($key,$field)){
  417. if($lang == 'EN'){
  418. $data[$key] = $data[$key.'_en'];
  419. unset($data[$key.'_en']);
  420. }else{
  421. unset($data[$key.'_en']);
  422. }
  423. }
  424. }
  425. return $data;
  426. }
  427. }