这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
一、邮件管理
在发货后,向用户发邮件。
1.1 创建邮件类
运行命令:php artisan make:mail OrderPost
1.2 邮件发送
在resources/views/
下建一个emails
文件夹,并在这个文件夹下新建order-post.blade.php
。先写入一点简单的测试数据:
<p>您的单号:{{$order->order_no}} 已经发货</p>
<h4>商品信息:</h4>
<ul>
@foreach($order->orderDetails()->with('goods')->get() as $detail)
<li>{{$detail->goods->title}}, 单价为:{{$detail->price}},数量为:{{$detail->num}}</li>
@endforeach
</ul>
<h5>总付款:{{$order->amount}}</h5>
然后在Mail\OrderPost.php
中写入:
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class OrderPost extends Mailable
{
use Queueable, SerializesModels;
protected $order;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($order)
{
$this->order = $order;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
return $this->view('emails.order-post', [
'order' => $this->order
]);
}
}
增加订单发货时,发送邮箱:
增加邮箱配置,邮箱配置可点这里查看。
修改我们第一个用户的邮箱(我们可接收到的邮箱):
1.3 发送邮件测试
可以看到,只要我们发货了,就会给用户邮箱发送发货通知。
1.4 优化
在短信发送中,是比较耗时的,我们不能一直等着,需要采用队列,让它自己去慢慢等发送。
修改OrderController.php
:
将
send
改为queue
,但是队列的话,我们这边还没配置,所以我们现在进行对队列的配置。
1、生成队列迁移文件
运行命令php artisan queue:table
运行命令
php artisan migrate
执行迁移文件:
可以看到生成了一个jobs
和failed_jobs
的表,就会把发邮件这块功能放到这个迁移文件里面去排队,这样如果发的邮件比较多的话,也不会很慢,它发一个删一个。当有失败的话它会放到failed_jobs
这个表中:
2、修改队列配置
在.env
中修改队列驱动:
3、运行队列测试
在不运行队列之前,我们使用send
发送邮箱得到的响应是:
可以看到
1312ms
。
接着我们运行队列,看看时间上优化了多少:
运行命令php artisan queue:work
138ms
可以看到整整优化快了10倍,这还不算邮件多的情况。
但是可以看到我们终端一直开着,万一不小断了,就没了,所以肯定是不能出现这种情况的。
所以我们配置守护进程。
4、配置守护进程
进入目录:/etc/supervisor/conf.d
:
运行命令
sudo nano jshopapi.conf
创建jshopapi.conf
文件:
接着将以下内容复制进去:
[program:jshopapi]
process_name=%(program_name)s_%(process_num)02d
command=php /home/vagrant/code/shopProjectApi/artisan queue:work
autostart=true
autorestart=true
user=vagrant
numprocs=2
redirect_stderr=true
stdout_logfile=/home/vagrant/code/shopProjectApi/storage/logs/worker.log
stopwaitsecs=3600
复制进去后
control+x
退出,退出的时候会问你是否保存,你就保存:
输入y回车,接着输入命令
sudo supervisorctl update
启动守护进程:
查看进程状态:
看见有两个进程在守护了。
再去测试发送邮件:
可以看到进程再跑,而不是通过终端。守护进程会一直在跑,就算意外终止,它也会重启跑起来。
也可以看到日志:
5、发货当成事件来处理
1、添加监听器
在app/Providers/EventServiceProvider.php
中进行注册:
'App\Events\OrderPost' => [
'App\Listeners\SendEmailToOrderUser',
],
2、生成事件和监听器
运行命令:php artisan event:generate
3、修改发货逻辑
将不在控制器里去发货直接使用发货事件去发货。
// 发货 使用事件分发
event(new \App\Events\OrderPost(
$order,
$request->input('express_type'),
$request->input('express_no')
));
我们采用事件分发,将订单、快递类型以及快递单号传到事件类中。
所以在
Events\OrderPost.php
中接收这些参数:
接着Listeners\SendEmailToOrderUser.php
修改监听者里面的处理逻辑:
<?php
namespace App\Listeners;
use App\Events\OrderPost;
use App\Mail\OrderPost as MailOrderPost;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;
class SendEmailToOrderUser
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
}
/**
* Handle the event.
*
* @param OrderPost $event
* @return void
*/
public function handle(OrderPost $event)
{
$event->order->express_type = $event->express_type;
$event->order->express_no = $event->express_no;
$event->order->status = 3; // 发货状态
$event->order->save();
// 发货之后,邮件提醒
Mail::to($event->order->user)->queue(new MailOrderPost($event->order));
}
}
4、使用事件方式测试
在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。