Magento 2.3.6 结账条款协议勾选值未存入数据库的问题及自定义存储方案咨询
Magento 2.3.6 结账条款协议勾选值未存入数据库的问题及自定义存储方案咨询
你好,针对你遇到的问题,先给你明确一下:默认情况下Magento 2.3.6确实不会将结账时条款协议的勾选状态关联到订单存储到数据库中。你提到的checkout_agreement和checkout_agreement_store这两张表,仅用于存储协议的内容、显示规则以及和门店的关联关系,并不会记录具体订单对应的用户勾选行为。
如果需要存储这些信息(关联customer_id、store_id、agreement_id、order_id以及勾选状态/协议内容),由于你无法升级版本也不能安装插件,只能通过自定义开发模块来实现,具体步骤如下:
1. 创建自定义模块基础结构
首先在app/code目录下新建你的模块目录,比如app/code/YourVendor/AgreementLog,然后创建必要的模块配置文件:
registration.php:
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'YourVendor_AgreementLog', __DIR__ );
etc/module.xml:
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="YourVendor_AgreementLog" setup_version="1.0.0"> <sequence> <module name="Magento_Checkout"/> <module name="Magento_Sales"/> </sequence> </module> </config>
2. 新建自定义数据库表
创建安装脚本Setup/InstallSchema.php,用来生成存储协议勾选记录的表:
<?php namespace YourVendor\AgreementLog\Setup; use Magento\Framework\Setup\InstallSchemaInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\Setup\ModuleContextInterface; class InstallSchema implements InstallSchemaInterface { public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $installer = $setup; $installer->startSetup(); $table = $installer->getConnection()->newTable( $installer->getTable('checkout_agreement_order_log') )->addColumn( 'log_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, ['identity' => true, 'nullable' => false, 'primary' => true], 'Log ID' )->addColumn( 'order_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, ['nullable' => false], 'Order ID' )->addColumn( 'customer_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, ['nullable' => true], 'Customer ID' )->addColumn( 'store_id', \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, null, ['nullable' => false], 'Store ID' )->addColumn( 'agreement_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, null, ['nullable' => false], 'Checkout Agreement ID' )->addColumn( 'is_accepted', \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, null, ['nullable' => false, 'default' => 0], 'Is Agreement Accepted' )->addColumn( 'agreement_text', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, '64k', [], 'Agreement Text' )->addColumn( 'created_at', \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, null, ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT], 'Created At' )->addForeignKey( $installer->getFkName('checkout_agreement_order_log', 'order_id', 'sales_order', 'entity_id'), 'order_id', $installer->getTable('sales_order'), 'entity_id', \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE )->addForeignKey( $installer->getFkName('checkout_agreement_order_log', 'agreement_id', 'checkout_agreement', 'agreement_id'), 'agreement_id', $installer->getTable('checkout_agreement'), 'agreement_id', \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE )->setComment( 'Checkout Agreement Acceptance Log' ); $installer->getConnection()->createTable($table); $installer->endSetup(); } }
3. 监听订单创建事件,记录勾选状态
创建事件配置文件etc/events.xml:
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="checkout_submit_all_after"> <observer name="log_checkout_agreement_acceptance" instance="YourVendor\AgreementLog\Observer\LogAgreementAcceptance"/> </event> </config>
然后创建观察者类Observer/LogAgreementAcceptance.php,用来获取勾选信息并写入数据库:
<?php namespace YourVendor\AgreementLog\Observer; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Checkout\Model\Session as CheckoutSession; use Magento\Checkout\Model\Agreement\AgreementFactory; use Magento\Framework\App\ResourceConnection; use Magento\Store\Model\StoreManagerInterface; class LogAgreementAcceptance implements ObserverInterface { protected $checkoutSession; protected $agreementFactory; protected $resourceConnection; protected $storeManager; public function __construct( CheckoutSession $checkoutSession, AgreementFactory $agreementFactory, ResourceConnection $resourceConnection, StoreManagerInterface $storeManager ) { $this->checkoutSession = $checkoutSession; $this->agreementFactory = $agreementFactory; $this->resourceConnection = $resourceConnection; $this->storeManager = $storeManager; } public function execute(Observer $observer) { $order = $observer->getOrder(); if (!$order) { return; } // 获取结账时用户勾选的协议ID $acceptedAgreementIds = $this->checkoutSession->getAcceptedAgreements(); if (!is_array($acceptedAgreementIds) || empty($acceptedAgreementIds)) { return; } $storeId = $this->storeManager->getStore()->getId(); $customerId = $order->getCustomerId(); $orderId = $order->getId(); $connection = $this->resourceConnection->getConnection(); $tableName = $this->resourceConnection->getTableName('checkout_agreement_order_log'); foreach ($acceptedAgreementIds as $agreementId) { // 获取协议内容 $agreement = $this->agreementFactory->create()->load($agreementId); if (!$agreement->getId()) { continue; } // 插入记录 $data = [ 'order_id' => $orderId, 'customer_id' => $customerId, 'store_id' => $storeId, 'agreement_id' => $agreementId, 'is_accepted' => 1, 'agreement_text' => $agreement->getContent() ]; $connection->insert($tableName, $data); } // 清除session中的数据,避免重复记录 $this->checkoutSession->unsAcceptedAgreements(); } }
4. 启用模块并部署
执行以下命令启用模块并更新数据库:
bin/magento module:enable YourVendor_AgreementLog bin/magento setup:upgrade bin/magento setup:di:compile bin/magento cache:clean
完成以上步骤后,用户在结账时勾选的条款协议信息就会被存入checkout_agreement_order_log表中,你可以通过该表关联order_id、customer_id、agreement_id等信息,随时查询用户的勾选状态和对应的协议内容。
备注:内容来源于stack exchange,提问作者Michael Sarto
相关产品推荐
相关产品推荐

