
本文详细讲解如何在 magento 2 中基于商品自定义属性(如“same day delivery available”)控制自定义配送方式(如“same day delivery”)在结账页的显示逻辑,涵盖属性加载配置、运费收集器逻辑增强及关键注意事项。
本文详细讲解如何在 magento 2 中基于商品自定义属性(如“same day delivery available”)控制自定义配送方式(如“same day delivery”)在结账页的显示逻辑,涵盖属性加载配置、运费收集器逻辑增强及关键注意事项。
在 Magento 2 中,自定义配送方式默认对所有订单开放。若需实现精细化控制(例如:仅当购物车中所有商品均支持“当日达”时才显示“Same Day Delivery”选项),必须在运费计算环节(collectRates)动态校验商品属性,并确保该属性在结账上下文中可被安全访问。
✅ 核心实现步骤
1. 确保商品属性在结账时可用
Magento 默认不会将全部商品属性加载到 Quote\Item 对象中,因此需显式声明该属性属于 quote_item 属性组。在模块根目录下创建文件:
app/code/Balaji/CustomShipping/etc/catalog_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
<group name="quote_item">
<attribute name="same_day_delivery_available"/>
</group>
</config>⚠️ 注意:name 值必须与你在后台创建商品属性时设置的 Attribute Code 完全一致(如 same_day_delivery_available),区分大小写且不可含空格或特殊字符。
2. 在运费收集器中添加动态校验逻辑
修改你的运费模型类(如 Balaji\CustomShipping\Model\Carrier\Customshipping),在 collectRates(RateRequest $request) 方法中,在启用开关检查之后插入如下逻辑:
if (!$this->getConfigFlag('active')) {
return false;
}
// 新增:校验购物车中所有商品是否均支持当日达
foreach ($request->getAllItems() as $item) {
$product = $item->getProduct();
// 安全获取属性值(兼容空值、布尔类型)
$isAvailable = $product->getData('same_day_delivery_available');
if ($isAvailable !== true && $isAvailable !== 1 && $isAvailable !== '1' && $isAvailable !== 'yes') {
return false; // 任一商品不支持 → 隐藏该配送方式
}
}? 提示:使用 $product->getData() 是因属性已通过 catalog_attributes.xml 加载;若仍返回 null,请确认属性作用范围(Scope)为 Store View 或 Global,且已在对应 Store View 中赋值。
3. (可选)增强健壮性:跳过虚拟商品与非销售商品
为避免逻辑误判,建议过滤掉虚拟商品、赠品或未启用商品:
foreach ($request->getAllItems() as $item) {
if ($item->getProduct()->getTypeId() === \Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL
|| !$item->getProduct()->isSalable()) {
continue; // 虚拟商品不参与配送判断
}
$isAvailable = $item->getProduct()->getData('same_day_delivery_available');
if (!$isAvailable) {
return false;
}
}4. 清除缓存并验证
执行以下命令使配置生效:
bin/magento setup:upgrade bin/magento setup:di:compile bin/magento cache:clean bin/magento cache:flush
然后在前台添加若干测试商品(部分设为 Same Day Delivery Available = No),观察结账页的配送方式列表是否按预期动态隐藏。
? 关键注意事项
- 属性数据类型:若后台将 same_day_delivery_available 设为 Yes/No 类型,其存储值为整数 1(Yes)或 0(No),推荐用 === true 或 == 1 判断,避免松散比较陷阱。
- 性能考量:该逻辑在每次结账请求中执行,若商品量极大,建议结合 Quote\Item 的 getProduct() 已缓存机制,无需额外查询数据库。
- 多地址结账(MSA):当前逻辑适用于单地址场景;如启用多地址配送,需遍历 Quote\Address 并分别校验各收货地址下的商品。
- 前端兜底:服务端控制是核心,但也可配合 JavaScript 在前端二次隐藏 UI 元素,提升用户体验一致性。
通过以上配置,你的“Same Day Delivery”配送方式将真正实现业务驱动的智能展示——既保障规则严谨性,又保持系统扩展性,是 Magento 2 高级定制开发的典型实践范例。

















