我有一个 Laravel 作业,当发送订单时,会向用户发送一封电子邮件,其中包含一些内容和动态数据。我为此使用 sendgrid 模板。目前,我可以使用一些数据成功向用户发送邮件,但在通过邮件发送产品图像时遇到问题。当我收到邮件时,我收到这样的邮件:
<img src="http://avala-dev.com/api/product/1/image/1" alt="Product Image">
如果我在浏览器的新选项卡中输入该网址,我会收到图像,但在我的邮件中它不会显示,它只会显示这样的 img 标签。我的图像存储在
storage/app/documents
文件夹中,类似于 5b602461-de87-4f46-a320-1f883dbaa686.webp
该怎么做才能渲染该图像并在邮件中显示它?任何帮助表示赞赏。这是我的代码。
PendingOrderJob.php
<?php
namespace App\Jobs;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use SendGrid;
use SendGrid\Mail\Mail;
class PendingOrderJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $user;
public $email;
public $order;
public $cart;
public function __construct($user, $email, $order, $cart)
{
$this->user = $user;
$this->email = $email;
$this->order = $order;
$this->cart = $cart;
}
public function handle()
{
$user = $this->user;
$email_template = config('sendgrid.templates.events.pending_order');
$productsData = [];
foreach ($this->order->products as $product) {
$productData = [
'category_id' => $product->category_id,
'group_id' => $product->group_id,
'type' => $product->type,
'sku' => $product->sku,
'name' => $product->name,
'visible' => $product->visible,
];
$productData['images'] = $product->images->map(function ($image) use ($product) {
return route('product-image', ['id' => $product->id, 'image_id' => $image->id]);
})->toArray();
$productsData[] = $productData;
}
$price = [];
$quantity = [];
foreach ($this->order->products as $product) {
$price[] = $product->pivot->price;
$quantity[] = $product->pivot->quantity;
}
$cartData = [
'user_id' => $this->cart->user_id,
'start_date' => $this->cart->start_date,
'end_date' => $this->cart->end_date,
'points_required' => $this->cart->points_required,
'price' => $this->cart->price
];
$email = new Mail();
$email->setFrom(config('sendgrid.credentials.email', ''), config('sendgrid.credentials.name', ''));
$email->setSubject("Pending Order");
$email->addTo($user->email, 'toolbox');
$email->addDynamicTemplateDatas([
'user_email' => $user->email,
'order_id' => $this->order->id,
'status' => $this->order->status,
'note' => $this->order->note,
'price' => $price,
'quantity' => $quantity,
'cart' => $cartData,
'products' => $productsData,
]);
$email->setTemplateId($email_template);
$sendgrid = new SendGrid(config('sendgrid.credentials.secret_key'));
try {
$response = $sendgrid->send($email);
} catch (Exception $e) {
Log::error('Pending Order Job Failed: ' . $e->getMessage());
}
}
}
api.php
Route::middleware(['throttle:1000,1'])->group(function () {
Route::match(['get', 'delete'], 'product/{id}/image/{image_id}', [ProductController::class, 'image'])
->name('product-image');
});
产品控制器.php
public function image(Request $request, $id, $imageID)
{
if ($request->method() === 'DELETE') {
$product = Product::findOrFail($id);
$image = $product->images()
->where('document_id', $imageID)
->delete();
return;
}
if ($request->method() === 'GET') {
$product = Product::findOrFail($id);
$image = $product->images()
->where('document_id', $imageID)
->firstOrFail();
// Get the image data from storage
$imageData = Storage::get($image->path);
// Determine the MIME type of the image
$mimeType = Storage::mimeType($image->path);
// Return the image data as a response
return Response::make($imageData, 200, [
'Content-Type' => $mimeType,
'Content-Disposition' => 'inline; filename="' . $image->name . '"',
]);
}
}
在我的 sendgrid 模板上,我将这些图像称为这样的
{{#each products.product}}
{{#each product.images}}
<img src={{this}} alt="Product Image">
{{/each}}
{{/each}}
我在 Laravel 中从公共存储过渡到本地存储时遇到了类似的挑战。
解决方案涉及将图像直接嵌入到
MailMessage
中。
我正在使用通知向用户发送邮件,我添加了通知类的更新代码:
public function toMail($notifiable)
{
$ccEmail = config("constants.team_email");
$mailMessage = new MailMessage();
$mailMessage->cc($ccEmail);
$mailMessage->subject("Hello User, ".$notifiable->name);
$data = ['user' => $this->user];
if (isset($notifiable->image_path)) {
$userImg = Swift_Image::fromPath(Storage::disk('local')->path($notifiable->image)); // storage path "users/images/sdnfjnDjknklsdf7frnksj.jpg"
$mailMessage->withSwiftMessage(function ($message) use ($userImg) {
$message->embed($userImg);
}); // embed the image in mail message
$data['userImg'] = 'cid:' . $userImg->getId(); // store embed image's id in var
}
$mailMessage->markdown('emails.my-temp', $data);
return $mailMessage;
}
在电子邮件模板(/views/emails/my-temp.blade.php)中,您可以像这样显示嵌入的图像:
@if(isset($userImg))
<img src="{{ $userImg }}">
@endif
有关更多详细信息,您可以参考 Swift Mailer 文档:https://swiftmailer.symfony.com/docs/messages.html