NopCommerce 4.2 门店自提时隐藏 Cash On Delivery
结论
在 nopCommerce 4.2 中,客户提交门店自提选项后,系统会将选中的 PickupPoint 保存到当前客户的通用属性 NopCustomerDefaults.SelectedPickupPointAttribute。
因此,HidePaymentMethod 无需读取页面上的单选框。取得当前客户的 PickupPoint 后,如果结果不为 null,返回 true 即可隐藏 Cash On Delivery。原有的“购物车是否需要配送”判断仍需保留。
修改方式
在支付插件中注入以下两个服务:
IWorkContext:用于取得当前客户。IStoreContext:用于取得当前店铺 ID。
同时引入客户、配送和通用属性相关的命名空间:
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Shipping;
using Nop.Services.Common;
添加字段
private readonly IStoreContext _storeContext;
private readonly IWorkContext _workContext;
修改构造函数
public CashOnDeliveryPaymentProcessor(
CashOnDeliveryPaymentSettings cashOnDeliveryPaymentSettings,
ILocalizationService localizationService,
IPaymentService paymentService,
ISettingService settingService,
IShoppingCartService shoppingCartService,
IWebHelper webHelper,
IStoreContext storeContext,
IWorkContext workContext)
{
_cashOnDeliveryPaymentSettings = cashOnDeliveryPaymentSettings;
_localizationService = localizationService;
_paymentService = paymentService;
_settingService = settingService;
_shoppingCartService = shoppingCartService;
_webHelper = webHelper;
_storeContext = storeContext;
_workContext = workContext;
}
nopCommerce 的依赖注入容器通常会自动提供这两个服务,无需额外注册。
修改 HidePaymentMethod
public bool HidePaymentMethod(IList<ShoppingCartItem> cart)
{
var pickupPoint = _workContext.CurrentCustomer.GetAttribute<PickupPoint>(
NopCustomerDefaults.SelectedPickupPointAttribute,
_storeContext.CurrentStore.Id);
if (pickupPoint != null)
return true;
return _cashOnDeliveryPaymentSettings.ShippableProductRequired &&
!_shoppingCartService.ShoppingCartRequiresShipping(cart);
}
也可以把两个条件合并到一个返回表达式中:
public bool HidePaymentMethod(IList<ShoppingCartItem> cart)
{
var pickupPoint = _workContext.CurrentCustomer.GetAttribute<PickupPoint>(
NopCustomerDefaults.SelectedPickupPointAttribute,
_storeContext.CurrentStore.Id);
return pickupPoint != null ||
(_cashOnDeliveryPaymentSettings.ShippableProductRequired &&
!_shoppingCartService.ShoppingCartRequiresShipping(cart));
}
为什么不能直接读取单选框
系统在生成可用支付方式列表时会调用 HidePaymentMethod。此时通常已经离开配送方式的提交阶段,当前请求未必还包含 pickupInStore 单选框字段。
客户提交门店自提选择后,nopCommerce 会把 PickupPoint 保存到当前客户的通用属性中。直接读取客户属性更可靠,也符合结账流程保存数据的方式。
需要注意的地方
门店自提选项必须已经成功提交。如果只在浏览器中点击单选框,尚未保存或刷新结账页面,服务器端就无法读取新的选择。
如果项目使用的 nopCommerce 4.2 源码要求为 GetAttribute 显式传入服务参数,还需要注入 IGenericAttributeService,并改为:
var pickupPoint = _workContext.CurrentCustomer.GetAttribute<PickupPoint>(
_genericAttributeService,
NopCustomerDefaults.SelectedPickupPointAttribute,
_storeContext.CurrentStore.Id);
请以当前项目引用的 nopCommerce 4.2 源码所提供的具体重载为准。
完成修改后,需要重新编译 Nop.Plugin.Payments.CashOnDelivery,将生成结果部署到对应的插件目录,然后重启应用或重新加载插件。测试时至少要覆盖以下两种情况:
- 选择普通配送:Cash On Delivery 按原配置显示。
- 选择 Pick-up in store:支付方式列表中不再显示 Cash On Delivery。
备注:内容仅供参考。
