Laravel中BCC地址获取为空及非全局变量跨函数复用需求
解决方案
1. 复用BCC邮箱地址(避免全局变量)
把获取BCC邮箱的逻辑提取成模型静态方法,这样在update和destroy方法里都能直接调用,不用重复写查询代码:
在User模型中添加:
public static function getBccEmail() { $bccUser = self::select('email') ->join('config', 'email', '=', 'value') ->where('config.name', '=', 'bcc_user') ->first(); return $bccUser ? $bccUser->email : ''; }
之后在update和destroy方法里直接调用:
$bcc = User::getBccEmail();
这样就不用在两个方法里重复写相同的查询逻辑,也避免了全局变量。
2. 同步发送Slack通知(与邮件并行)
Laravel的通知系统支持多渠道发送,创建一个通知类同时处理邮件和Slack通知,触发一次就能同时发送两种通知,代码更简洁:
步骤1:生成通知类
运行Artisan命令:
php artisan make:notification TravelStatusUpdated
步骤2:编辑通知类
在app/Notifications/TravelStatusUpdated.php中编写逻辑:
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; class TravelStatusUpdated extends Notification { use Queueable; public $travelRequest; public $status; public $bcc; public function __construct($travelRequest, $status, $bcc) { $this->travelRequest = $travelRequest; $this->status = $status; $this->bcc = $bcc; } public function via(object $notifiable): array { // 同时发送邮件和Slack return ['mail', 'slack']; } public function toMail(object $notifiable): MailMessage { $subject = $this->status === 'Approved' ? 'Travel Approved by Manager' : 'Travel Declined'; $mailMessage = (new MailMessage) ->subject($subject) ->view('emails.travel.managerresult', [ 'user' => $this->travelRequest->user, 'status' => $this->status ]); // 添加BCC if ($this->bcc) { $mailMessage->bcc($this->bcc); } return $mailMessage; } public function toSlack(object $notifiable): SlackMessage { $user = $this->travelRequest->user; return (new SlackMessage) ->content("Travel request for {$user->name} has been {$this->status}!") ->attachment(function ($attachment) use ($user) { $attachment->fields([ 'User Email' => $user->email, 'Request ID' => $this->travelRequest->id, ]); }); } }
步骤3:在控制器中触发通知
修改update方法中的邮件发送逻辑,替换成通知:
// 替换原来的Mail::send逻辑 $user = $travel_request->user; $user->notify(new TravelStatusUpdated($travel_request, 'Approved', $bcc));
同理,destroy方法中替换:
$user = $travel_request->user; $user->notify(new TravelStatusUpdated($travel_request, 'Declined', $bcc));
步骤4:处理Travel Admin的邮件+Slack通知
为Travel Admin创建单独的通知类:
php artisan make:notification TravelAdminNotification
编写通知类:
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; class TravelAdminNotification extends Notification { use Queueable; public $request; public $bcc; public function __construct($request, $bcc) { $this->request = $request; $this->bcc = $bcc; } public function via(object $notifiable): array { return ['mail', 'slack']; } public function toMail(object $notifiable): MailMessage { $mailMessage = (new MailMessage) ->subject('Travel Request pending booking') ->view('emails.travel.admin', [ 'request' => $this->request ]); if ($this->bcc) { $mailMessage->bcc($this->bcc); } return $mailMessage; } public function toSlack(object $notifiable): SlackMessage { return (new SlackMessage) ->content("New travel request needs booking!") ->attachment(function ($attachment) { $attachment->fields([ 'Request ID' => $this->request->id, 'Manager' => auth()->user()->name, ]); }); } }
然后在update方法中替换原来的循环发送逻辑:
// 获取travel admins并发送通知 $travelAdmins = User::select('email', 'id') ->join('role_dashboard_user', 'role_dashboard_user.user_id', '=', 'users.id') ->join('roles', 'roles.id', '=', 'role_dashboard_user.role_id') ->where('roles.name', '=', 'travel_admin') ->get(); foreach ($travelAdmins as $admin) { $admin->notify(new TravelAdminNotification($travel_request, $bcc)); }
3. 原代码中的小问题修正
- 原代码中
$travel_request->user->first():如果travel_request和user是一对一关系,直接用$travel_request->user即可,不需要first() - 查询travel admins时,原代码中
dashboard_user表名大概率是笔误,应该改为users
内容的提问来源于stack exchange,提问作者Naam
相关产品推荐
相关产品推荐

