步骤:

  • 注册和配置模块。
  • 在管理面板创建新的字段。
  • 定义运输模型。
  • 创建运输模型。
  • 运行命令启用运输方式。

注册和配置模块:

首先,需要注册和配置模块。

app/code/Test/Shipping/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="Test_Shipping" setup_version="0.0.1"/>
</config>

app/code/Test/Shipping 目录中创建 registration.php 并在其中添加如下代码注册模块:


<?php
    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'Test_Shipping',
        __DIR__
    );

在管理面板中创建新字段:

app/code/Test/Shipping/etc/adminhtml 目录中创建 system.xml 文件并添加如下内容:


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="../../../../Magento/Config/etc/system_file.xsd">
    <system>
        <section id="carriers" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1"
                 showInStore="1">
            <group id="testshipping" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Test Shipping Method</label>
                <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Enabled</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="title" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Title</label>
                </field>
                <field id="name" translate="label" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Method Name</label>
                </field>
                <field id="price" translate="label" type="text" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Shipping Cost</label>
                    <validate>validate-number validate-zero-or-greater</validate>
                </field>
                <field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Displayed Error Message</label>
                </field>
                <field id="sallowspecific" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="0">
                    <label>Ship to Applicable Countries</label>
                    <frontend_class>shipping-applicable-country</frontend_class>
                    <source_model>Magento\Shipping\Model\Config\Source\Allspecificcountries</source_model>
                </field>
                <field id="specificcountry" translate="label" type="multiselect" sortOrder="91" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Ship to Specific Countries</label>
                    <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
                    <can_be_empty>1</can_be_empty>
                </field>
                <field id="showmethod" translate="label" type="text" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Show Method if Not Applicable</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Sort Order</label>
                </field>
            </group>
        </section>
    </system>
</config>


定义运输模型:

app/code/Test/Shipping/etc 目录中创建 config.xml 并添加如下内容来定义运输模型:


<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <carriers>
            <testshipping>
                <active>0</active>
                <title>Test Shipping</title>
                <name>Custom Test Shipping</name>
                <sallowspecific>0</sallowspecific>
                <price>0</price>
                <model>Test\Shipping\Model\Carrier\CustomShipping</model>
                <specificerrmsg>This shipping method is not available. To use this shipping method, please contact us.</specificerrmsg>
            </testshipping>
        </carriers>
    </default>
</config>


创建运输模型:

我们在上一步中定义了 Shipping Model 类,现在我们通过在 app/Test/Shipping/Model/Carrier 目录中创建 CustomShipping.php 并添加如下代码来创建运输模型:


<?php
namespace Test\Shipping\Model\Carrier;

use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;

class CustomShipping extends AbstractCarrier implements CarrierInterface
{
    //这个地方不要用下划线连接:test_shipping 这种方式会在前台支付时提示没有选择运输方式。
    protected $_code = 'testshipping';

    protected $_isFixed = true;

    protected $_rateResultFactory;

    protected $_rateMethodFactory;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Magento\Shipping\Model\Rate\ResultFactory $_rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $_rateMethodFactory,
        \Psr\Log\LoggerInterface $logger,
        array $data = []
    )
    {
        $this->_rateResultFactory = $_rateResultFactory;
        $this->_rateMethodFactory = $_rateMethodFactory;

        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }

    public function getAllowedMethods()
    {
        return [$this->getCarrierCode() => __($this->getConfigData('name'))];
    }

    public function collectRates(RateRequest $request)
    {
        if (!$this->isActive()) {
            return false;
        }

        $result = $this->_rateResultFactory->create();
        $method = $this->_rateMethodFactory->create();
        $shippingPrice = $this->getConfigData('price');

        /**
         * Set carrier's method data
         */
        $method->setCarrier($this->getCarrierCode());
        $method->setCarrierTitle($this->getConfigData('title'));

        /**
         * Displayed as shipping method under Carrier
         */
        $method->setMethod($this->getCarrierCode());
        $method->setMethodTitle($this->getConfigData('name'));
        $method->setPrice($shippingPrice);
        $method->setCost($shippingPrice);

        $result->append($method);

        return $result;
    }
}



运行命令启用运输方式:

完成上述所有步骤后,在项目根目录使用如下命令来启用我们自定义的 Shipping Method(运输方式):


php bin/magento module:status
php bin/magento module:enable Test_Shipping
php bin/magento setup:upgrade

#begin
#在developer模式下可以不使用以下两个命令
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
#end

php bin/magento cache:clean
php bin/magento cache:flush

查看结果:

  1. 完成以上步骤后,即可通过后台面板设置自定义运输方式的相关参数:
file
  1. 前台订单结账时可以选用自定义的运输方式:
file
file
  1. 后台订单中的运输方式信息:
file