Laravel8下按id_filiale关联向对应邮箱发送指定合同数据的实现咨询
Laravel 合同匹配分公司邮件发送实现思路
前置配置
首先完成两个基础配置,避免后续手动处理数据:
- 分公司模型字段转换
Table2的adm_emails是JSON格式存储,在对应Filiale模型中添加字段类型转换,Laravel会自动把数据库的JSON转为PHP数组:
// app/Models/Filiale.php protected $casts = [ 'adm_emails' => 'array' ];
- 模型关联配置
在合同对应的Contrat模型中配置和分公司模型的关联:
// app/Models/Contrat.php public function filiale() { return $this->belongsTo(Filiale::class, 'id_filiale', 'id_filiale'); }
核心发送逻辑
1. 查询带关联的合同数据
用预加载查询获取所有合同及对应的分公司邮箱数据,避免N+1性能问题:
$contratList = Contrat::with('filiale')->get();
2. 遍历发送邮件
可以根据数据量选择同步发送或者队列异步发送:
foreach ($contratList as $contrat) { $emailList = $contrat->filiale->adm_emails; // 可选:对重复邮箱去重,避免同一收件人收到多份相同邮件 $emailList = array_unique($emailList); // 空邮箱校验,避免报错 if (empty($emailList)) continue; // 方式1:小数据量直接同步发送 Mail::to($emailList)->send(new \App\Mail\ContractNotify($contrat)); // 方式2:大数据量推荐用队列异步发送,避免请求超时 // Mail::to($emailList)->queue(new \App\Mail\ContractNotify($contrat)); }
注意:Laravel的
Mail::to()方法直接支持传入邮箱数组批量发送,不需要循环单个邮箱调用,效率更高。
3. 自定义邮件类
先通过Artisan命令生成邮件类:
php artisan make:mail ContractNotify
编辑邮件类配置内容、模板:
// app/Mail/ContractNotify.php class ContractNotify extends Mailable { use Queueable, SerializesModels; // 直接注入合同数据 public function __construct(public Contrat $contrat) {} public function build() { return $this->subject('新合同通知') ->view('emails.contract_notify') // 对应自定义的邮件模板视图 ->with([ 'numeroContrat' => $this->contrat->numero_contrat, 'contratContent' => $this->contrat->contrat ]); } }
可选优化点
- 发送日志留痕:每次发送后记录收件人、合同ID、发送状态等信息,方便后续排查问题
- 失败重试配置:如果用队列发送,可以配置队列重试次数、失败回调,把发送失败的记录存到数据库后续手动补发
- 频率控制:如果邮箱服务商有发送频率限制,可以给队列添加延迟配置,控制发送速度
内容的提问来源于stack exchange,提问作者saadia
相关产品推荐
相关产品推荐

