You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:44:53