<?php namespace app\index\controller; use think\Controller; use think\Db; use app\common\library\Email; class Plantask extends Controller { //关于本文件里的计划任务 //只有 public 方法,auto_开头的才是计划任务,其他private 方法都是工具方法 ////////////////////////////////////////下面都是计划任务方法/////////////////////////////////////////////////////////////// //明天有课,通知。计划任务10分钟执行一次 public function auto_lesson_slot_notice(){ $starttime = strtotime(date('Y-m-d')) + 86400; $endtime = $starttime + 86399; $map = [ 'status' => 0, 'starttime' => ['BETWEEN',[$starttime,$endtime]], 'notice_status' => 0, ]; $task_list = Db::name('lesson_slot')->where($map)->order('starttime asc')->limit(1)->select(); if(empty($task_list)){ echo 'empty'; exit; } foreach($task_list as $slot){ //这节课时,任务完成 $update = [ 'notice_status' => 1, ]; Db::name('lesson_slot')->where('id',$slot['id'])->update($update); //找出这节课时的预约单 $map = [ 'order.order_status' => 10, 'order.slot_id' => $slot['id'], 'order.jointype' => 1, //预约类型:1=预约,2=候补 ]; $order_list = Db::name('lesson_order')->alias('order') ->field('lesson.name,lesson.name_en,user.firstname,user.lastname,user.email,user.whatsapp') ->join('user','order.user_id = user.id','LEFT') ->join('lesson','order.lesson_id = lesson.id','LEFT') ->where($map)->order('order.id asc')->select(); if(!empty($order_list)){ $coach_name = Db::name('coach')->where('id',$slot['coach_ids'])->value('nickname'); //给这些预约单的用户发邮件 try { foreach($order_list as $order){ $message = 'Hi,'.$order['firstname']. ' ' .$order['lastname'].'!<br/> We are looking forward to seeing you at the following class tomorrow!<br/> Class:'.$order['name_en'].'<br/> Date: '.date('D l Y',$slot['starttime']).'<br/> Time: '.date('H:i a',$slot['starttime']).'<br/> Please arrive 10 minutes before the class timing to prepare for the harness fitting!<br/> We are located at 450 Alexandra Road, #02-01,<br/> Singapore 119960. For those who are driving, parking is available on level 2 of the building. For those who are taking public transport, the nearest mrt is Labrador Park MRT (7-10 minutes walk) and there is also a bus stop available just outside the building!<br/> We look forward to seeing you for an amazing session! ❤<br/> Best Regards,<br/> Elin Dance Studio<br/> <img src="'.config('website_url').'/assets/img/logo3.png" style="width:100px;height:100px"> '; $obj = new Email(); $result = $obj ->to($order['email']) ->subject('You have a class tomorrow!') ->message($message) ->send(); $obj = ''; //发whatsapp $parameters = [ [ 'type' => 'text', 'text' => $order['firstname'].' '.$order['lastname'], ], [ 'type' => 'text', 'text' => $order['name_en'], ], [ 'type' => 'text', 'text' => $coach_name, ], [ 'type' => 'text', 'text' => date('D l Y',$slot['starttime']), ], [ 'type' => 'text', 'text' => date('H:i a',$slot['starttime']), ], ]; $this->whatapp($order['whatsapp'],'the_class_will_start_tomorrow','en_US',$parameters); } } catch (Exception $e) { } } } } //课程取消,通知。计划任务5分钟执行一次 public function auto_lesson_slot_cancel(){ exit; $map = [ 'slot.status' => 30, 'slot.cancel_notice_status' => 0, ]; $task_list = Db::name('lesson_slot')->alias('slot') ->field('slot.*,coach.nickname as coach_nickname,coach.email as coach_email,coach.whatsapp as coach_whatsapp,lesson.name_en as lesson_name_en') ->join('coach','slot.coach_ids = coach.id','LEFT') ->join('lesson','slot.lesson_id = lesson.id','LEFT') ->where($map)->order('slot.starttime asc')->limit(1)->select(); if(empty($task_list)){ echo 'empty'; exit; } foreach($task_list as $slot){ //这节课时,任务完成 $update = [ 'cancel_notice_status' => 1, ]; Db::name('lesson_slot')->where('id',$slot['id'])->update($update); //找出这节课时的预约单 $map = [ 'order.slot_id' => $slot['id'], ]; $order_list = Db::name('lesson_order')->alias('order') ->field('user.firstname,user.lastname,user.email,user.whatsapp') ->join('user','order.user_id = user.id','LEFT') ->where('(order.jointype = 1 and order.order_status = 10) or (order.jointype = 2 and order.order_status = 0)') //已支付的 或 候补单 ->where($map)->order('order.id asc')->select(); //把教练也加入到发送列表里 $coach_sender = [ 'firstname' => $slot['coach_nickname'], 'lastname' => '', 'email' => $slot['coach_email'], 'whatsapp' => $slot['coach_whatsapp'], ]; $order_list[] = $coach_sender; if(empty($order_list)){ continue; } //给这些预约单的用户发邮件 try { foreach($order_list as $order){ $message = 'Hi,'.$order['firstname']. ' ' .$order['lastname'].'!<br/> We regret to inform you that the following class has been cancelled.<br/> Class:'.$slot['lesson_name_en'].'<br/> Date: '.date('d F Y',$slot['starttime']).'<br/> Time: '.date('H:i a',$slot['starttime']).'<br/> Thank you for your kind understanding and look forward to seeing you in our studio soon!❤<br/> Best Regards,<br/> Elin Dance Studio<br/> <img src="'.config('website_url').'/assets/img/logo3.png" style="width:136px;height:115px"> '; if(!empty($order['email'])){ $obj = new Email(); $result = $obj ->to($order['email']) ->subject('Class is Cancelled!') ->message($message) ->send(); } $obj = ''; //$coach_name = Db::name('coach')->where('id',$slot['coach_ids'])->value('nickname'); //发whatsapp $parameters = [ [ 'type' => 'text', 'text' => $order['firstname'].' '.$order['lastname'], ], [ 'type' => 'text', 'text' => $slot['lesson_name_en'], ], /* [ 'type' => 'text', 'text' => $coach_name, ],*/ [ 'type' => 'text', 'text' => date('D l Y',$slot['starttime']) .' at '.date('H:i a',$slot['starttime']), ], ]; if(!empty($order['whatsapp'])){ $this->whatapp($order['whatsapp'],'class_cancelled','en_US',$parameters); } } } catch (Exception $e) { } } } //购买新套餐之后,通知。计划任务5分钟执行一次 public function auto_after_buy_package(){ $map = [ 'order.order_status' => 1, 'order.buy_notice_status' => 0, 'order.is_gift' => 0, ]; $task_list = Db::name('package_order')->alias('order') ->field('order.id,order.starttime,order.endtime,p.name,p.name_en,user.firstname,user.lastname,user.email,user.whatsapp') ->join('lesson_package p','order.package_id = p.id','LEFT') ->join('user','order.user_id = user.id','LEFT') ->where($map)->order('order.paytime asc')->limit(1)->select(); if(empty($task_list)){ echo 'empty'; exit; } foreach($task_list as $order){ //任务完成 $update = [ 'buy_notice_status' => 1, ]; Db::name('package_order')->where('id',$order['id'])->update($update); try { $message = 'Hi,'.$order['firstname']. ' ' .$order['lastname'].'!<br/> Thank you for your purchase of the '.$order['name_en'].' plan!<br/> <b>Please note</b>: Plans that are 5 hours and above need to be activated by us! This is so that you can use up your current plans first (if any)!<br/> When you wish to activate, please send a WhatsApp message to 8879-9689 to activate your package to start booking classes.<br/> Once activated, your plan’s validity period will begin.<br/> You can view the unactivated packages in the app.<br/> We look forward to seeing you soon!❤<br/> Best Regards,<br/> Elin Dance Studio<br/> <img src="'.config('website_url').'/assets/img/logo3.png" style="width:136px;height:115px"> '; //给这些用户发邮件 $obj = new Email(); $result = $obj ->to($order['email']) ->subject('Your plan purchase has been received!') ->message($message) ->send(); $obj = ''; //发whatsapp $parameters = [ [ 'type' => 'text', 'text' => $order['firstname'].' '.$order['lastname'], ], [ 'type' => 'text', 'text' => $order['name_en'], ], /*[ 'type' => 'text', 'text' => date('Y-m-d H:i',$order['starttime']), ], [ 'type' => 'text', 'text' => date('Y-m-d H:i',$order['endtime']), ], [ 'type' => 'text', 'text' => $order['firstname'].' '.$order['lastname'], ],*/ ]; $this->whatapp($order['whatsapp'],'buy_new_package','en_US',$parameters); } catch (Exception $e) { } } } //套餐将要到期,一个月,两周,一周,逐级通知,提醒三次。计划任务分别一小时执行一次 public function auto_package_order_notice_mon(){ $map = [ 'order.order_status' => 1, 'order.use_status' => 1, 'order.remain' => ['gt',0], 'order.endtime' => ['lt',time()+(86400*30)], 'order.notice_status' => 0, ]; $task_list = Db::name('package_order')->alias('order') ->field('order.id,order.endtime,p.name,p.name_en,order.remain,user.firstname,user.lastname,user.email,user.whatsapp') ->join('lesson_package p','order.package_id = p.id','LEFT') ->join('user','order.user_id = user.id','LEFT') ->where($map)->order('endtime asc')->limit(2)->select(); if(empty($task_list)){ echo 'empty'; exit; } foreach($task_list as $order){ //任务完成 $update = [ 'notice_status' => 1,//月通知已发送 ]; Db::name('package_order')->where('id',$order['id'])->update($update); try { $message = 'Hi,'.$order['firstname']. ' ' .$order['lastname'].'!<br/> We wanted to let you know that the following plan is set to expire in one month’s time!<br/> Plan: '.$order['name_en'].'<br/> Expiry Date: '.date('d F Y',$order['endtime']).'<br/> Please note that any unutilised hours will automatically be forfeited in the system. Book your next session now and continue working towards those amazing goals you have set for yourself!<br/> If you would like to sign up for another plan, you can contact us at 8879-9689 or check on the app!❤<br/> Best Regards,<br/> Elin Dance Studio<br/> <img src="'.config('website_url').'/assets/img/logo3.png" style="width:136px;height:115px"> '; //给这些用户发邮件 $obj = new Email(); $result = $obj ->to($order['email']) ->subject('Your Membership Plan is Expiring in One Month’s Time!') ->message($message) ->send(); $obj = ''; //发whatsapp $parameters = [ [ 'type' => 'text', 'text' => $order['firstname'].' '.$order['lastname'], ], [ 'type' => 'text', 'text' => $order['name_en'], ], [ 'type' => 'text', 'text' => 'one month’s time', ], [ 'type' => 'text', 'text' => date('D l Y',$order['endtime']), ], [ 'type' => 'text', 'text' => ''.$order['remain'].'', ], ]; $this->whatapp($order['whatsapp'],'package_expiration_reminder','en_US',$parameters); } catch (Exception $e) { } } } public function auto_package_order_notice_2week(){ $map = [ 'order.order_status' => 1, 'order.use_status' => 1, 'order.remain' => ['gt',0], 'order.endtime' => ['lt',time()+(86400*14)], 'order.notice_status' => 1, ]; $task_list = Db::name('package_order')->alias('order') ->field('order.id,order.endtime,p.name,p.name_en,order.remain,user.firstname,user.lastname,user.email,user.whatsapp') ->join('lesson_package p','order.package_id = p.id','LEFT') ->join('user','order.user_id = user.id','LEFT') ->where($map)->order('endtime asc')->limit(2)->select(); if(empty($task_list)){ echo 'empty'; exit; } foreach($task_list as $order){ //任务完成 $update = [ 'notice_status' => 2,//2周通知已发送 ]; Db::name('package_order')->where('id',$order['id'])->update($update); try { $message = 'Hi,'.$order['firstname']. ' ' .$order['lastname'].'!<br/> We wanted to let you know that the following plan is set to expire in two week’s time!<br/> Plan: '.$order['name_en'].'<br/> Expiry Date: '.date('d F Y',$order['endtime']).'<br/> Please note that any unutilised hours will automatically be forfeited in the system. Book your next session now and continue working towards those amazing goals you have set for yourself!<br/> If you would like to sign up for another plan, you can contact us at 8879-9689 or check on the app!❤<br/> Best Regards,<br/> Elin Dance Studio<br/> <img src="'.config('website_url').'/assets/img/logo3.png" style="width:136px;height:115px"> '; //给这些用户发邮件 $obj = new Email(); $result = $obj ->to($order['email']) ->subject('Your Membership Plan is Expiring in Two Week’s Time!') ->message($message) ->send(); $obj = ''; //发whatsapp $parameters = [ [ 'type' => 'text', 'text' => $order['firstname'].' '.$order['lastname'], ], [ 'type' => 'text', 'text' => $order['name_en'], ], [ 'type' => 'text', 'text' => '2 week’s time', ], [ 'type' => 'text', 'text' => date('D l Y',$order['endtime']), ], [ 'type' => 'text', 'text' => ''.$order['remain'].'', ], ]; $this->whatapp($order['whatsapp'],'package_expiration_reminder','en_US',$parameters); } catch (Exception $e) { } } } public function auto_package_order_notice_1week(){ $map = [ 'order.order_status' => 1, 'order.use_status' => 1, 'order.remain' => ['gt',0], 'order.endtime' => ['lt',time()+(86400*7)], 'order.notice_status' => 2, ]; $task_list = Db::name('package_order')->alias('order') ->field('order.id,order.endtime,p.name,p.name_en,order.remain,user.firstname,user.lastname,user.email,user.whatsapp') ->join('lesson_package p','order.package_id = p.id','LEFT') ->join('user','order.user_id = user.id','LEFT') ->where($map)->order('endtime asc')->limit(2)->select(); if(empty($task_list)){ echo 'empty'; exit; } foreach($task_list as $order){ //任务完成 $update = [ 'notice_status' => 3,//1周通知已发送 ]; Db::name('package_order')->where('id',$order['id'])->update($update); try { $message = 'Hi,'.$order['firstname']. ' ' .$order['lastname'].'!<br/> We wanted to let you know that the following plan is set to expire in one week’s time!<br/> Plan: '.$order['name_en'].'<br/> Expiry Date: '.date('d F Y',$order['endtime']).'<br/> Please note that any unutilised hours will automatically be forfeited in the system. Book your next session now and continue working towards those amazing goals you have set for yourself!<br/> If you would like to sign up for another plan, you can contact us at 8879-9689 or check on the app!❤<br/> Best Regards,<br/> Elin Dance Studio<br/> <img src="'.config('website_url').'/assets/img/logo3.png" style="width:136px;height:115px"> '; //给这些用户发邮件 $obj = new Email(); $result = $obj ->to($order['email']) ->subject('Your Membership Plan is Expiring in One Week’s Time!') ->message($message) ->send(); $obj = ''; //发whatsapp $parameters = [ [ 'type' => 'text', 'text' => $order['firstname'].' '.$order['lastname'], ], [ 'type' => 'text', 'text' => $order['name_en'], ], [ 'type' => 'text', 'text' => '1 week’s time', ], [ 'type' => 'text', 'text' => date('D l Y',$order['endtime']), ], [ 'type' => 'text', 'text' => ''.$order['remain'].'', ], ]; $this->whatapp($order['whatsapp'],'package_expiration_reminder','en_US',$parameters); } catch (Exception $e) { } } } /** * 复制本周的课程表 */ public function auto_slot_copyweek_old(){ $week = date('w'); if($week != 1){ //exit; } //先查找 下周有没有数据 $starttime = strtotime('this week Monday') + (86400*7); $endtime = $starttime + (86400*7); $check = Db::name('lesson_slot')->where('starttime','BETWEEN',[$starttime,$endtime])->find(); if($check){ echo '下周有数据了'; exit; } echo '准备复制'; //拿上周,复制到下周 $starttime = strtotime('this week Monday') - (86400*7); // 获取本周一的时间戳 $endtime = $starttime + (86400*7); $list = Db::name('lesson_slot')->where('is_show',1)->where('starttime','BETWEEN',[$starttime,$endtime])->order('starttime asc')->select(); if(empty($list)){ echo 'empty'; exit; } foreach($list as $key => &$val){ unset($val['id']); $val['starttime'] = $val['starttime'] + (86400*14); $val['endtime'] = $val['endtime'] + (86400*14); $val['bookednum'] = 0; $val['status'] = 0; $val['notice_status'] = 0; $val['finishtime'] = 0; $val['cancel_reason'] = ''; $val['cancel_time'] = 0; $val['cancel_notice_status'] = 0; } Db::name('lesson_slot')->insertAll($list); echo '复制完成'; //$this->success('已复制到下周'); } //每两周一次 //周一早上,复制本周+下周的课,到下下周+下下下周 public function auto_slot_copyweek(){ $week = date('w'); if($week != 1){ echo '不是周一'; exit; } $check = Db::name('plantask')->where('key','auto_slot_copyweek')->whereTime('lasttime','week')->find(); if($check){ echo '本周执行过了'; exit; } $check = Db::name('plantask')->where('key','auto_slot_copyweek')->whereTime('lasttime','last week')->find(); if($check){ echo '上周执行过了'; exit; } //先查找 下周有没有数据 /*$starttime = strtotime('this week Monday') + (86400*14); $endtime = $starttime + (86400*14); $check = Db::name('lesson_slot')->where('starttime','BETWEEN',[$starttime,$endtime])->find(); if($check){ echo '下下周和下下下周有数据了'; exit; }*/ echo '准备复制'; //复制本周+下周的课 $starttime = strtotime('this week Monday'); // 获取本周一的时间戳 $endtime = $starttime + (86400*14); $list = Db::name('lesson_slot')->where('starttime','BETWEEN',[$starttime,$endtime])->order('starttime asc')->select(); if(empty($list)){ echo 'empty'; exit; } //到下下周+下下下周 foreach($list as $key => &$val){ unset($val['id']); $val['starttime'] = $val['starttime'] + (86400*14); $val['endtime'] = $val['endtime'] + (86400*14); $val['bookednum'] = 0; $val['status'] = 0; $val['notice_status'] = 0; $val['finishtime'] = 0; $val['cancel_reason'] = ''; $val['cancel_time'] = 0; $val['is_show'] = 0; $val['cancel_notice_status'] = 0; } Db::startTrans(); $rs1 = Db::name('plantask')->where('key','auto_slot_copyweek')->update(['lasttime'=>time()]); if($rs1 === false){ Db::rollback(); $this->error('同步失败'); } $rs2 = Db::name('lesson_slot')->insertAll($list); if(!$rs2){ Db::rollback(); $this->error('复制失败'); } Db::commit(); echo '复制完成'; } /////////////////////////////////////////下面都是工具方法//////////////////////////////////////////////// //发送whatapp消息的方法 private function whatapp($receive_mobile,$template,$code,$parameters){ if(empty($receive_mobile)){return true;} $token = config('site.whatsapp_token'); //发送者 $mobile_id = '337736419413019'; //Elin Dance Stuido 2:+65 8015 4154 , WhatsApp Business Account ID: 336509229537586 //发送 $url = 'https://graph.facebook.com/v19.0/'.$mobile_id.'/messages'; $header = [ 'Authorization: Bearer ' . $token, 'Content-Type: application/json', ]; $body = [ 'messaging_product' => 'whatsapp', 'recipient_type' => 'individual', 'to' => $receive_mobile, 'type' => 'template', 'template' => [ 'name' => $template, 'language' => [ 'code' => $code ], 'components' => [ [ 'type' => 'body', 'parameters' => $parameters ] ], ], ]; $body = json_encode($body); $rs = curl_post($url,$body,$header); return true; } //结果集信息里,多个字段需要翻译 private function list_lang($list,$field,$lang = ''){ if(!$list || empty($list)){ return $list; } foreach($list as $vo => $info){ $list[$vo] = $this->info_lang($info,$field); } return $list; } //单条信息里,多个字段需要翻译 private function info_lang($data,$field,$lang = ''){ if(!$data || empty($data)){ return $data; } foreach($data as $key => $val){ if(in_array($key,$field)){ if($lang == 'EN'){ $data[$key] = $data[$key.'_en']; unset($data[$key.'_en']); }else{ unset($data[$key.'_en']); } } } return $data; } }