Nopcommerce 4.5插件开发:为特定客户角色禁用奖励积分
开发Nopcommerce插件:特定客户角色禁用奖励积分
以下是针对需求的分步实现方案,全程遵循Nopcommerce插件开发规范,不修改核心代码:
1. 搭建插件基础结构
创建名为Nop.Plugin.RewardPoints.DisableByCustomerRole的插件项目,包含核心文件:
plugin.json:配置插件名称、版本、依赖等元数据- 继承
BasePlugin的主插件类(处理安装/卸载逻辑) - 自定义设置类(存储禁用积分的角色ID)
- 管理端视图与模型
2. 定义插件设置
2.1 创建设置实体
用于持久化选中的禁用角色ID:
public class RewardPointsDisableByRoleSettings : ISettings { public int[] DisabledCustomerRoleIds { get; set; } = Array.Empty<int>(); }
2.2 注册设置
在主插件类的InstallAsync方法中注册设置:
public override async Task InstallAsync() { await _settingService.SaveSettingAsync(new RewardPointsDisableByRoleSettings()); await base.InstallAsync(); }
3. 扩展奖励积分设置页面
通过Widget插件将角色选择控件嵌入原有设置页面,无需修改核心代码:
3.1 创建Widget类
指定渲染位置为奖励积分设置页的后置区块:
public class RewardPointsSettingsWidget : IWidgetPlugin { private readonly ISettingService _settingService; private readonly ICustomerRoleService _customerRoleService; public RewardPointsSettingsWidget(ISettingService settingService, ICustomerRoleService customerRoleService) { _settingService = settingService; _customerRoleService = customerRoleService; } public async Task<IViewComponentResult> GetViewComponentAsync(string widgetZone, object additionalData) { var settings = await _settingService.LoadSettingAsync<RewardPointsDisableByRoleSettings>(); var roles = await _customerRoleService.GetAllCustomerRolesAsync(true); var model = new RewardPointsDisableByRoleSettingsModel { DisabledCustomerRoleIds = settings.DisabledCustomerRoleIds, AvailableCustomerRoles = roles.Select(r => new SelectListItem { Text = r.Name, Value = r.Id.ToString() }).ToList() }; return View("~/Plugins/Nop.Plugin.RewardPoints.DisableByCustomerRole/Views/Admin/RewardPointsSettingsWidget.cshtml", model); } public bool HideInWidgetList => true; public Task<IList<string>> GetWidgetZonesAsync() => Task.FromResult<IList<string>>(new List<string> { "Admin.RewardPointsSettings.Blocks.After" }); }
3.2 创建视图文件
RewardPointsSettingsWidget.cshtml,复用Nop自带的多角色选择控件:
<div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title">禁用奖励积分的客户角色</h4> </div> <div class="panel-body"> <div class="form-group"> <div class="col-md-3"> <label asp-for="DisabledCustomerRoleIds">选择角色</label> </div> <div class="col-md-9"> <select asp-for="DisabledCustomerRoleIds" asp-items="Model.AvailableCustomerRoles" class="form-control" multiple="multiple"></select> </div> </div> </div> </div>
3.3 创建视图模型
public class RewardPointsDisableByRoleSettingsModel : BaseNopModel { public int[] DisabledCustomerRoleIds { get; set; } [UIHint("CustomerRole")] public List<SelectListItem> AvailableCustomerRoles { get; set; } = new(); }
4. 拦截奖励积分计算逻辑
通过覆盖服务的方式,对指定角色用户禁用积分计算:
4.1 自定义奖励积分服务
public class CustomRewardPointsService : RewardPointsService { private readonly ISettingService _settingService; private readonly ICustomerService _customerService; public CustomRewardPointsService(ISettingService settingService, ICustomerService customerService, IRepository<RewardPointsHistory> rewardPointsHistoryRepository, IRepository<Customer> customerRepository, IWorkContext workContext, ILocalizationService localizationService, IStoreContext storeContext, ISettingService baseSettingService) : base(rewardPointsHistoryRepository, customerRepository, workContext, localizationService, storeContext, baseSettingService) { _settingService = settingService; _customerService = customerService; } public override async Task<int> CalculateRewardPointsAsync(Customer customer, decimal amount, int storeId) { var settings = await _settingService.LoadSettingAsync<RewardPointsDisableByRoleSettings>(); var customerRoles = await _customerService.GetCustomerRolesAsync(customer); // 若用户属于禁用角色,返回0积分 if (customerRoles.Any(r => settings.DisabledCustomerRoleIds.Contains(r.Id))) return 0; return await base.CalculateRewardPointsAsync(customer, amount, storeId); } }
4.2 替换核心服务
在主插件类的PostInitializeAsync方法中替换默认服务:
public override async Task PostInitializeAsync() { _serviceProvider.ReplaceService<IRewardPointsService, CustomRewardPointsService>(ServiceLifetime.Scoped); await base.PostInitializeAsync(); }
5. 保存设置
创建表单处理器,在提交奖励积分设置时保存禁用角色配置:
public class RewardPointsSettingsFormHandler : IFormHandler { private readonly ISettingService _settingService; public RewardPointsSettingsFormHandler(ISettingService settingService) { _settingService = settingService; } public async Task HandleFormSubmittedAsync(IFormCollection form, int storeId) { var settings = await _settingService.LoadSettingAsync<RewardPointsDisableByRoleSettings>(storeId); var disabledRoleIds = form["DisabledCustomerRoleIds"].ToString() .Split(',', StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse) .ToArray(); settings.DisabledCustomerRoleIds = disabledRoleIds; await _settingService.SaveSettingAsync(settings, storeId); } public bool CanHandleForm(string formName) => formName == "RewardPointsSettings"; }
在插件初始化时注册该处理器:
public override async Task InitializeAsync() { _serviceProvider.AddScoped<IFormHandler, RewardPointsSettingsFormHandler>(); await base.InitializeAsync(); }
6. 测试验证
- 编译插件,复制到Nopcommerce的
Plugins目录 - 后台安装插件,进入配置→奖励积分设置,即可看到新增的角色选择区域
- 创建测试用户并分配到禁用角色,下单验证是否不会获得奖励积分
内容的提问来源于stack exchange,提问作者CK Vignesh
相关产品推荐
相关产品推荐

