From 4de1ff6021f56973470f8420141d5a55f1bdfbba Mon Sep 17 00:00:00 2001 From: jianweie code Date: Wed, 31 Jul 2024 00:34:29 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E5=88=86=E5=8F=91=E4=BC=98=E6=83=A0=E5=88=B8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E6=8C=89=E7=94=A8=E6=88=B7=E7=BB=84=E5=88=86=E5=8F=91?= =?UTF-8?q?=E7=9A=84=E9=98=9F=E5=88=97=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CoreCms.Net.Configuration/GlobalConstVars.cs | 5 + CoreCms.Net.Configuration/GlobalEnumVars.cs | 11 ++ .../Config/RedisMessageQueueSetup.cs | 36 ++++++- .../User/ICoreCmsUserRepository.cs | 8 ++ .../User/ICoreCmsUserServices.cs | 5 + CoreCms.Net.Model/CoreCms.Net.Model.xml | 25 +++++ CoreCms.Net.Model/FromBody/FMPromotion.cs | 44 ++++++++ .../CouponDistributionSubscribe.cs | 101 ++++++++++++++++++ .../User/CoreCmsUserRepository.cs | 13 +++ .../User/CoreCmsUserServices.cs | 12 +++ .../Promotion/CoreCmsPromotionController.cs | 77 +++++++------ .../CoreCms.Net.Web.Admin.xml | 4 +- CoreCms.Net.Web.Admin/Program.cs | 3 + .../wwwroot/views/promotion/coupon/grant.html | 39 ++++++- .../wwwroot/views/promotion/coupon/index.html | 10 +- CoreCms.Net.Web.WebApi/Program.cs | 2 +- 16 files changed, 355 insertions(+), 40 deletions(-) create mode 100644 CoreCms.Net.Model/FromBody/FMPromotion.cs create mode 100644 CoreCms.Net.RedisMQ/CouponDistributionSubscribe.cs diff --git a/CoreCms.Net.Configuration/GlobalConstVars.cs b/CoreCms.Net.Configuration/GlobalConstVars.cs index e41fe781..ce0c124f 100644 --- a/CoreCms.Net.Configuration/GlobalConstVars.cs +++ b/CoreCms.Net.Configuration/GlobalConstVars.cs @@ -409,6 +409,11 @@ namespace CoreCms.Net.Configuration //订单支付成功后,用户升级处理 public const string UserUpGrade = "UserUpGradeQueue"; + /// + /// 优惠券发放给用户组队列 + /// + public const string CouponDistributionSubscribe = "CouponDistributionSubscribe"; + //消息相关 //发送微信模板消息 diff --git a/CoreCms.Net.Configuration/GlobalEnumVars.cs b/CoreCms.Net.Configuration/GlobalEnumVars.cs index 190e5aac..38b7b659 100644 --- a/CoreCms.Net.Configuration/GlobalEnumVars.cs +++ b/CoreCms.Net.Configuration/GlobalEnumVars.cs @@ -948,6 +948,17 @@ namespace CoreCms.Net.Configuration invalid = 3 } + /// + /// 优惠券分发方式 + /// + public enum CouponDistributionMode + { + [Description("个人分发")] + Single = 1, + [Description("用户组分发")] + UserGroup = 2 + } + #endregion #region payments支付================================= diff --git a/CoreCms.Net.Core/Config/RedisMessageQueueSetup.cs b/CoreCms.Net.Core/Config/RedisMessageQueueSetup.cs index cb5f05dc..06826257 100644 --- a/CoreCms.Net.Core/Config/RedisMessageQueueSetup.cs +++ b/CoreCms.Net.Core/Config/RedisMessageQueueSetup.cs @@ -12,7 +12,12 @@ namespace CoreCms.Net.Core.Config /// public static class RedisMessageQueueSetup { - public static void AddRedisMessageQueueSetup(this IServiceCollection services) + /// + /// 接口端消息队列 + /// + /// + /// + public static void AddRedisMessageQueueSetupForApi(this IServiceCollection services) { if (services == null) throw new ArgumentNullException(nameof(services)); @@ -46,5 +51,34 @@ namespace CoreCms.Net.Core.Config m.ShowLog = false; }); } + + /// + /// 管理端消息队列 + /// + /// + /// + public static void AddRedisMessageQueueSetupForAdmin(this IServiceCollection services) + { + if (services == null) throw new ArgumentNullException(nameof(services)); + + services.AddInitQ(m => + { + //没消息时挂起时长(毫秒) + m.SuspendTime = 1000; + + //每次消费消息间隔时间(毫秒) + m.IntervalTime = 1000; + + //redis服务器地址 + m.ConnectionString = AppSettingsConstVars.RedisConfigConnectionString; + //对应的订阅者类,需要new一个实例对象,当然你也可以传参,比如日志对象 + m.ListSubscribe = new List() { + typeof(CouponDistributionSubscribe), + }; + //显示日志 + m.ShowLog = false; + }); + } + } } diff --git a/CoreCms.Net.IRepository/User/ICoreCmsUserRepository.cs b/CoreCms.Net.IRepository/User/ICoreCmsUserRepository.cs index 72498591..a1a799c1 100644 --- a/CoreCms.Net.IRepository/User/ICoreCmsUserRepository.cs +++ b/CoreCms.Net.IRepository/User/ICoreCmsUserRepository.cs @@ -59,5 +59,13 @@ namespace CoreCms.Net.IRepository /// /// Task> StatisticsOrder(int day); + + + /// + /// 根据会员组获取会员id + /// + /// + Task> GetUserIdsByGrade(int gradeId); + } } \ No newline at end of file diff --git a/CoreCms.Net.IServices/User/ICoreCmsUserServices.cs b/CoreCms.Net.IServices/User/ICoreCmsUserServices.cs index 1c8e453e..581f35c4 100644 --- a/CoreCms.Net.IServices/User/ICoreCmsUserServices.cs +++ b/CoreCms.Net.IServices/User/ICoreCmsUserServices.cs @@ -143,5 +143,10 @@ namespace CoreCms.Net.IServices /// Task InviteCommission(string orderId); + /// + /// 根据会员组获取会员id + /// + /// + Task> GetUserIdsByGrade(int gradeId); } } \ No newline at end of file diff --git a/CoreCms.Net.Model/CoreCms.Net.Model.xml b/CoreCms.Net.Model/CoreCms.Net.Model.xml index 52d41244..07c5f048 100644 --- a/CoreCms.Net.Model/CoreCms.Net.Model.xml +++ b/CoreCms.Net.Model/CoreCms.Net.Model.xml @@ -9941,6 +9941,31 @@ 团购或秒杀传递的业务序列 + + + 优惠券分发 + + + + + 序列 + + + + + 分发方式 + + + + + 用户序列 + + + + + 用户组类别 + + 后台查询报表综合提交参数 diff --git a/CoreCms.Net.Model/FromBody/FMPromotion.cs b/CoreCms.Net.Model/FromBody/FMPromotion.cs new file mode 100644 index 00000000..62209479 --- /dev/null +++ b/CoreCms.Net.Model/FromBody/FMPromotion.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CoreCms.Net.Model.FromBody +{ + /// + /// 优惠券分发 + /// + public class FMCouponDistribution + { + /// + /// 序列 + /// + [Display(Name = "序列")] + [Required(ErrorMessage = "请提交优惠券序列")] + public int id { get; set; } + + /// + /// 分发方式 + /// + [Display(Name = "分发方式")] + [Required(ErrorMessage = "请提交优惠券分发方式")] + public int distributionMode { get; set; } + + /// + /// 用户序列 + /// + [Display(Name = "用户序列")] + [Required(ErrorMessage = "请提交优惠券用户序列")] + public long userIdOrMobile { get; set; } = 0; + + /// + /// 用户组类别 + /// + [Display(Name = "用户组类别")] + [Required(ErrorMessage = "请提交优惠券用户组类别")] + public int userGrade { get; set; } = 0; + + } +} diff --git a/CoreCms.Net.RedisMQ/CouponDistributionSubscribe.cs b/CoreCms.Net.RedisMQ/CouponDistributionSubscribe.cs new file mode 100644 index 00000000..f9690fe6 --- /dev/null +++ b/CoreCms.Net.RedisMQ/CouponDistributionSubscribe.cs @@ -0,0 +1,101 @@ +using System; +using System.Threading.Tasks; +using CoreCms.Net.Configuration; +using CoreCms.Net.IServices; +using CoreCms.Net.Loging; +using CoreCms.Net.Model.Entities; +using CoreCms.Net.Model.FromBody; +using InitQ.Abstractions; +using InitQ.Attributes; +using Newtonsoft.Json; +using NLog; +using SqlSugar; + +namespace CoreCms.Net.RedisMQ +{ + public class CouponDistributionSubscribe : IRedisSubscribe + { + private readonly ICoreCmsUserGradeServices _userGradeServices; + private readonly ICoreCmsUserServices _userServices; + private readonly ICoreCmsCouponServices _coreCmsCouponServices; + private readonly ICoreCmsPromotionServices _coreCmsPromotionServices; + + + /// + /// 构造函数 + /// + public CouponDistributionSubscribe(ICoreCmsUserGradeServices userGradeServices, ICoreCmsUserServices userServices, ICoreCmsCouponServices coreCmsCouponServices, ICoreCmsPromotionServices coreCmsPromotionServices) + { + _userGradeServices = userGradeServices; + _userServices = userServices; + _coreCmsCouponServices = coreCmsCouponServices; + _coreCmsPromotionServices = coreCmsPromotionServices; + } + + + /// + /// 优惠券发放给用户组队列 + /// + /// + /// + [Subscribe(RedisMessageQueueKey.CouponDistributionSubscribe)] + private async Task CouponDistributionQueue(string msg) + { + try + { + var model = JsonConvert.DeserializeObject(msg); + if (model.id == 0) + { + NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "优惠券发放给用户组队列", "优惠券获取失败" + msg); + await Task.CompletedTask; + } + + var promotion = await _coreCmsPromotionServices.QueryByIdAsync(model.id); + if (promotion == null) + { + NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "优惠券发放给用户组队列", "优惠券获取失败" + msg); + await Task.CompletedTask; + } + + var userGrade = _userGradeServices.QueryListByClauseAsync(p => p.id == model.userGrade); + if (userGrade == null) + { + NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "优惠券发放给用户组队列", "用户等级获取失败" + msg); + await Task.CompletedTask; + } + + //获取用户id + var userIds = await _userServices.GetUserIdsByGrade(model.userGrade); + if (userIds.Count > 0) + { + var successCount = 0; + var errorCount = 0; + foreach (var id in userIds) + { + var result = await _coreCmsCouponServices.AddData(id, model.id, promotion); + if (result.status) + { + successCount++; + } + else + { + errorCount++; + } + } + NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, $"优惠券发放给用户组队列", $"成功{successCount},失败{errorCount}" + msg); + } + else + { + NLogUtil.WriteAll(NLog.LogLevel.Info, LogType.RedisMessageQueue, "优惠券发放给用户组队列", "用户为空" + msg); + } + } + catch (Exception ex) + { + NLogUtil.WriteAll(NLog.LogLevel.Error, LogType.RedisMessageQueue, "优惠券发放给用户组队列", msg, ex); + throw; + } + await Task.CompletedTask; + } + + } +} diff --git a/CoreCms.Net.Repository/User/CoreCmsUserRepository.cs b/CoreCms.Net.Repository/User/CoreCmsUserRepository.cs index 5ef1f317..16b0be50 100644 --- a/CoreCms.Net.Repository/User/CoreCmsUserRepository.cs +++ b/CoreCms.Net.Repository/User/CoreCmsUserRepository.cs @@ -205,5 +205,18 @@ namespace CoreCms.Net.Repository return outs; } + /// + /// 根据会员组获取会员id + /// + /// + public async Task> GetUserIdsByGrade(int gradeId) + { + + var ids = await DbClient.Queryable().Where(p => p.grade == gradeId).Select(p => p.id) + .ToListAsync(); + return ids; + } + + } } diff --git a/CoreCms.Net.Services/User/CoreCmsUserServices.cs b/CoreCms.Net.Services/User/CoreCmsUserServices.cs index c4ad80b5..0a7d5592 100644 --- a/CoreCms.Net.Services/User/CoreCmsUserServices.cs +++ b/CoreCms.Net.Services/User/CoreCmsUserServices.cs @@ -983,4 +983,16 @@ public class CoreCmsUserServices : BaseServices, ICoreCmsUserServic } #endregion + + + /// + /// 根据会员组获取会员id + /// + /// + public async Task> GetUserIdsByGrade(int gradeId) + { + var ids = await _dal.GetUserIdsByGrade(gradeId); + return ids; + } + } \ No newline at end of file diff --git a/CoreCms.Net.Web.Admin/Controllers/Promotion/CoreCmsPromotionController.cs b/CoreCms.Net.Web.Admin/Controllers/Promotion/CoreCmsPromotionController.cs index 5189edbe..e1a0e158 100644 --- a/CoreCms.Net.Web.Admin/Controllers/Promotion/CoreCmsPromotionController.cs +++ b/CoreCms.Net.Web.Admin/Controllers/Promotion/CoreCmsPromotionController.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; +using CoreCms.Net.Caching.AutoMate.RedisCache; using CoreCms.Net.Configuration; using CoreCms.Net.Filter; using CoreCms.Net.IServices; @@ -28,6 +29,7 @@ using CoreCms.Net.Web.Admin.Infrastructure; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; using NPOI.HSSF.UserModel; using SqlSugar; @@ -55,7 +57,7 @@ namespace CoreCms.Net.Web.Admin.Controllers private readonly ICoreCmsCouponServices _coreCmsCouponServices; private readonly ICoreCmsUserServices _userServices; private readonly ICoreCmsGoodsServices _goodsServices; - + private readonly IRedisOperationRepository _redisOperationRepository; /// /// 构造函数 @@ -69,7 +71,7 @@ namespace CoreCms.Net.Web.Admin.Controllers , ICoreCmsUserGradeServices coreCmsUserGradeServices , ICoreCmsPromotionConditionServices coreCmsPromotionConditionServices , ICoreCmsPromotionResultServices coreCmsPromotionResultServices - , ICoreCmsCouponServices coreCmsCouponServices, ICoreCmsGoodsServices goodsServices, ICoreCmsUserServices userServices) + , ICoreCmsCouponServices coreCmsCouponServices, ICoreCmsGoodsServices goodsServices, ICoreCmsUserServices userServices, IRedisOperationRepository redisOperationRepository) { _webHostEnvironment = webHostEnvironment; _coreCmsPromotionServices = coreCmsPromotionServices; @@ -83,6 +85,7 @@ namespace CoreCms.Net.Web.Admin.Controllers _coreCmsCouponServices = coreCmsCouponServices; _goodsServices = goodsServices; _userServices = userServices; + _redisOperationRepository = redisOperationRepository; } #region 获取列表============================================================ @@ -438,11 +441,15 @@ namespace CoreCms.Net.Web.Admin.Controllers jm.msg = "不存在此信息"; return jm; } + + var userGrade = await _coreCmsUserGradeServices.QueryAsync(false, true); + jm.code = 0; jm.data = new { - model + model, + userGrade }; return jm; @@ -458,7 +465,7 @@ namespace CoreCms.Net.Web.Admin.Controllers /// [HttpPost] [Description("分发优惠券提交")] - public async Task DoGrant([FromBody] FMIntId entity) + public async Task DoGrant([FromBody] FMCouponDistribution entity) { var jm = new AdminUiCallBack(); @@ -469,41 +476,42 @@ namespace CoreCms.Net.Web.Admin.Controllers return jm; } - if (entity.data == null) + //单人分发模式 + if (entity.distributionMode == (int)GlobalEnumVars.CouponDistributionMode.Single) { - jm.msg = "请输入合法的序列或手机号码"; - return jm; - } - - var userId = entity.data.ObjectToString(); - - CoreCmsUser user = null; - if (CommonHelper.IsMobile(userId)) - { - user = await _userServices.QueryByClauseAsync(p => p.mobile == userId, true); - } - else - { - int id = 0; - var isInt = int.TryParse(userId, out id); - if (isInt && id > 0) + if (entity.userIdOrMobile == 0) { - user = await _userServices.QueryByClauseAsync(p => p.id == id, true); + jm.msg = "请输入合法的序列或手机号码"; + return jm; } + CoreCmsUser user = null; + if (CommonHelper.IsMobile(entity.userIdOrMobile.ToString())) + { + user = await _userServices.QueryByClauseAsync(p => p.mobile == entity.userIdOrMobile.ToString(), true); + } + else + { + user = await _userServices.QueryByClauseAsync(p => p.id == entity.userIdOrMobile, true); + } + if (user == null) + { + jm.msg = "用户查询失败"; + return jm; + } + + var result = await _coreCmsCouponServices.AddData(user.id, entity.id, model); + + jm.code = result.status ? 0 : 1; + jm.msg = result.status ? "发放成功" : "发放失败"; } - if (user == null) + // 用户组分发模式 + else if (entity.distributionMode == (int)GlobalEnumVars.CouponDistributionMode.UserGroup) { - jm.msg = "用户查询失败"; - return jm; + await _redisOperationRepository.ListLeftPushAsync(RedisMessageQueueKey.CouponDistributionSubscribe, JsonConvert.SerializeObject(entity)); + + jm.code = 0; + jm.msg = "已经提交消息队列。"; } - - var result = await _coreCmsCouponServices.AddData(user.id, entity.id, model); - - //事物处理过程结束 - var bl = result.status; - jm.code = bl ? 0 : 1; - jm.msg = bl ? "发放成功" : "发放失败"; - return jm; } #endregion @@ -859,7 +867,8 @@ namespace CoreCms.Net.Web.Admin.Controllers { jm.msg = GlobalErrorCodeVars.Code15016; return jm; - } else if (model.type == (int)GlobalEnumVars.PromotionType.Coupon) + } + else if (model.type == (int)GlobalEnumVars.PromotionType.Coupon) { jm.msg = GlobalErrorCodeVars.Code15030; return jm; diff --git a/CoreCms.Net.Web.Admin/CoreCms.Net.Web.Admin.xml b/CoreCms.Net.Web.Admin/CoreCms.Net.Web.Admin.xml index 9f3fce93..77f7dbf4 100644 --- a/CoreCms.Net.Web.Admin/CoreCms.Net.Web.Admin.xml +++ b/CoreCms.Net.Web.Admin/CoreCms.Net.Web.Admin.xml @@ -2955,7 +2955,7 @@ 促销表 - + 构造函数 @@ -3006,7 +3006,7 @@ - + 分发优惠券提交 diff --git a/CoreCms.Net.Web.Admin/Program.cs b/CoreCms.Net.Web.Admin/Program.cs index b5f30d0b..31ca27cb 100644 --- a/CoreCms.Net.Web.Admin/Program.cs +++ b/CoreCms.Net.Web.Admin/Program.cs @@ -72,6 +72,9 @@ builder.Services.AddSingleton
+ +
+ + +
+ +
+ +
- +
请输入用户手机号码或者用户序列
+
+ +
+ +
+
请选择用户级别
+
+