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

Magento 2.4在sales_order_place_after观察者中发送带CSV附件邮件

Magento 2.4 订单生成后自动发送带CSV附件邮件实现方案

现有代码问题前置修正

原有代码存在依赖缺失、属性未赋值的问题,先做基础修复:

  • 类头部补充缺失的命名空间引用,禁止直接调用ObjectManager实例化类,严格遵循Magento2依赖注入规范
  • 构造函数补充邮件发送、文件读取必需的依赖项,补全原有传入但未赋值的类属性
  • 所有路径读取、邮件发送逻辑绑定订单所属门店,适配多门店场景

第一步:补全类引用与构造函数依赖

首先在类文件顶部补充以下use引用:

use Magento\Framework\Filesystem\DirectoryList;
use Psr\Log\LoggerInterface;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Framework\Filesystem\Driver\File as FileDriver;
use Magento\Framework\Mail\MimePart;
use Magento\Framework\Mail\MimeMessage;

修正后的构造函数如下,替换原有构造函数即可:

public function __construct(
    \Magento\Framework\App\RequestInterface $request,
    \Magento\Sales\Model\Order $order,
    \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
    \Magento\Framework\Filesystem $filesystem,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
    \Magento\Customer\Model\Customer $customer,
    \Magento\Store\Model\StoreManagerInterface $storemanager,
    \Magento\Checkout\Model\Session $checkoutSession,
    \Magento\Sales\Model\OrderFactory $orderFactory,
    LoggerInterface $logger,
    \Magento\Catalog\Model\ProductFactory $productFactory,
    \Magento\Catalog\Model\ProductRepository $productRepository,
    TransportBuilder $transportBuilder,
    StateInterface $inlineTranslation,
    FileDriver $fileDriver
) { 
    $this->_scopeConfig = $scopeConfig;
    $this->_customer = $customer;
    $this->_storemanager = $storemanager;
    $this->_request = $request;
    $this->_order = $order;
    $this->_fileFactory = $fileFactory;
    $this->directory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
    $this->_productRepository = $productRepository;
    $this->logger = $logger;
    $this->_checkoutSession = $checkoutSession;
    $this->_orderFactory = $orderFactory;
    $this->transportBuilder = $transportBuilder;
    $this->inlineTranslation = $inlineTranslation;
    $this->fileDriver = $fileDriver;
}

注意:原有构造函数里传入的ObjectManager依赖直接删除,Magento2禁止在业务代码中直接调用ObjectManager,会导致编译报错、模式不兼容问题。


第二步:在execute方法中补充邮件发送逻辑

在原有CSV生成代码的$stream->close();行之后,补充以下邮件发送代码。该代码适配Magento2.4版本的邮件接口,不会出现版本兼容问题:

// CSV文件绝对路径
$filePath = $this->directory->getAbsolutePath($file);
try {
    // 暂停行内翻译,避免邮件内容异常
    $this->inlineTranslation->suspend();

    // 读取CSV文件内容生成附件
    $fileContent = $this->fileDriver->fileGetContents($filePath);
    $attachment = new MimePart(
        $fileContent,
        'text/csv',
        \Zend_Mime::DISPOSITION_ATTACHMENT,
        \Zend_Mime::ENCODING_BASE64,
        basename($filePath)
    );

    // 从系统配置读取发件人信息(通用销售邮箱配置)
    $sender = [
        'name' => $this->_scopeConfig->getValue(
            'trans_email/ident_sales/name',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $order->getStoreId()
        ),
        'email' => $this->_scopeConfig->getValue(
            'trans_email/ident_sales/email',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $order->getStoreId()
        )
    ];

    // 构建邮件
    $transport = $this->transportBuilder->setTemplateIdentifier('sales_order_csv_email') // 此处替换为你自己创建的邮件模板ID
        ->setTemplateOptions([
            'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
            'store' => $order->getStoreId()
        ])
        ->setTemplateVars([
            'order' => $order,
            'customer_name' => $order->getCustomerName()
        ])
        ->setFrom($sender)
        ->addTo($order->getCustomerEmail(), $order->getCustomerName())
        ->addAttachment($attachment) // 2.4版本原生支持addAttachment方法,无需修改核心类
        ->getTransport();

    // 发送邮件
    $transport->sendMessage();
    $this->inlineTranslation->resume();

    // 若不需要留存CSV文件,可取消下方注释,发送成功后自动删除文件
    // $this->fileDriver->deleteFile($filePath);

} catch (\Exception $e) {
    $this->inlineTranslation->resume();
    // 邮件发送失败仅记录日志,不阻断正常下单流程
    $this->logger->error('订单CSV邮件发送失败,订单ID:' . $order->getId() . ',错误信息:' . $e->getMessage());
}

上线前必做配置

  • 进入后台 营销->通信->邮件模板,新建模板选择通用模板,填写邮件正文内容,模板标识设置为代码中对应的sales_order_csv_email
  • 代码上传后执行以下命令生效:
bin/magento setup:di:compile
bin/magento cache:clean

注意事项

  • 不要使用网上流传的直接修改TransportBuilder核心类、实例化废弃Zend_Mail类的方案,上述代码使用2.4版本原生支持的接口,升级小版本不会出现兼容问题
  • 多门店场景下所有配置读取都绑定订单所属门店ID,不会出现门店信息错配
  • 异常捕获逻辑保证邮件发送失败时不会导致用户下单报错,影响转化

内容的提问来源于stack exchange,提问作者samina khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 03:18:28