using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Mapster; using Microsoft.AspNetCore.Mvc; using NCC.Common.Core.Manager; using NCC.Common.Filter; using NCC.Dependency; using NCC.DynamicApiController; using NCC.Extend.Entitys.Dto.LqPackageInfo; using NCC.Extend.Entitys.Enum; using NCC.Extend.Entitys.lq_package_info; using NCC.Extend.Entitys.lq_package_item_detail; using NCC.Extend.Interfaces.LqPackageInfo; using NCC.FriendlyException; using SqlSugar; using Yitter.IdGenerator; namespace NCC.Extend.LqPackageInfo { /// /// 营销活动服务 /// [ApiDescriptionSettings(Tag = "绿纤营销活动服务", Name = "LqPackageInfo", Order = 200)] [Route("api/Extend/[controller]")] public class LqPackageInfoService : ILqPackageInfoService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _packageInfoRepository; private readonly SqlSugarScope _db; private readonly IUserManager _userManager; /// /// 构造函数 /// /// 营销活动仓储 /// 用户管理器 public LqPackageInfoService(ISqlSugarRepository packageInfoRepository, IUserManager userManager) { _packageInfoRepository = packageInfoRepository; _db = packageInfoRepository.Context; _userManager = userManager; } #region 添加营销活动 /// /// 添加营销活动 /// /// 营销活动创建输入 /// 营销活动ID /// /// 创建新的营销活动,包含活动基本信息和品项明细 /// /// 示例请求: /// ```json /// { /// "activityName": "春季护肤优惠活动", /// "activityDesc": "春季护肤特惠活动", /// "startTime": "2025-03-01T00:00:00", /// "endTime": "2025-03-31T23:59:59", /// "minItemQuantity": 2, /// "activityRules": "活动规则说明", /// "activityImages": "[\"image1.jpg\"]", /// "sortOrder": 1, /// "activityItems": [ /// { /// "itemId": "ITEM001", /// "itemName": "面部清洁", /// "itemCategory": "基础护理", /// "itemRemark": "推荐品项" /// } /// ] /// } /// ``` /// /// 参数说明: /// - activityName: 营销活动名称 /// - activityDesc: 营销活动描述 /// - startTime: 活动开始时间 /// - endTime: 活动结束时间 /// - minItemQuantity: 至少购买品项数量 /// - activityRules: 活动规则说明 /// - activityImages: 活动图片(JSON格式) /// - sortOrder: 排序 /// - activityItems: 营销活动品项明细列表 /// /// 成功创建营销活动,返回营销活动ID /// 请求参数错误 /// 服务器内部错误 [HttpPost("CreatePackageInfoAsync")] public async Task CreatePackageInfoAsync(LqPackageInfoCrInput input) { try { // 验证活动时间 if (input.StartTime >= input.EndTime) { throw NCCException.Oh("活动开始时间必须小于结束时间"); } // 验证品项明细 if (input.ActivityItems == null || !input.ActivityItems.Any()) { throw NCCException.Oh("营销活动必须包含至少一个品项"); } // 验证至少购买品项数量 if (input.ActivityItems.Count < input.MinItemQuantity) { throw NCCException.Oh($"品项数量不能少于至少购买品项数量({input.MinItemQuantity})"); } // 开始事务 _db.BeginTran(); try { // 创建营销活动实体 var packageInfo = input.Adapt(); packageInfo.Id = YitIdHelper.NextId().ToString(); packageInfo.CreateTime = DateTime.Now; packageInfo.UpdateTime = DateTime.Now; packageInfo.CreateUser = _userManager.UserId; packageInfo.UpdateUser = _userManager.UserId; packageInfo.IsEffective = StatusEnum.有效.GetHashCode(); // 保存营销活动 await _db.Insertable(packageInfo).ExecuteCommandAsync(); // 创建营销活动品项明细 var packageItemDetails = input.ActivityItems.Select(item => { var packageItemDetail = item.Adapt(); packageItemDetail.Id = YitIdHelper.NextId().ToString(); packageItemDetail.ActivityId = packageInfo.Id; packageItemDetail.CreateTime = DateTime.Now; packageItemDetail.UpdateTime = DateTime.Now; packageItemDetail.IsEffective = StatusEnum.有效.GetHashCode(); return packageItemDetail; }).ToList(); // 批量保存营销活动品项明细 if (packageItemDetails.Any()) { await _db.Insertable(packageItemDetails).ExecuteCommandAsync(); } // 提交事务 _db.CommitTran(); return packageInfo.Id; } catch { // 回滚事务 _db.RollbackTran(); throw; } } catch (Exception ex) { throw NCCException.Oh($"添加营销活动失败: {ex.Message}"); } } #endregion #region 获取营销活动列表 /// /// 获取营销活动列表 /// /// 营销活动列表查询输入 /// 营销活动列表 /// /// 获取营销活动列表,支持按活动名称、时间范围等条件筛选 /// /// 查询参数说明: /// - activityName: 活动名称(模糊查询) /// - activityDesc: 活动描述(模糊查询) /// - startTimeStart: 活动开始时间范围开始 /// - startTimeEnd: 活动开始时间范围结束 /// - endTimeStart: 活动结束时间范围开始 /// - endTimeEnd: 活动结束时间范围结束 /// - minItemQuantity: 至少购买品项数量 /// - createTimeStart: 创建时间范围开始 /// - createTimeEnd: 创建时间范围结束 /// /// 成功获取营销活动列表 /// 请求参数错误 /// 服务器内部错误 [HttpGet("GetPackageInfoListAsync")] public async Task GetPackageInfoListAsync([FromQuery] LqPackageInfoListQueryInput input) { var sidx = input.sidx == null ? "CreateTime" : input.sidx; var data = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.ActivityName), w => w.ActivityName.Contains(input.ActivityName)) .WhereIF(!string.IsNullOrEmpty(input.ActivityDesc), w => w.ActivityDesc.Contains(input.ActivityDesc)) .WhereIF(input.StartTimeStart.HasValue, w => w.StartTime >= input.StartTimeStart.Value) .WhereIF(input.StartTimeEnd.HasValue, w => w.StartTime <= input.StartTimeEnd.Value) .WhereIF(input.EndTimeStart.HasValue, w => w.EndTime >= input.EndTimeStart.Value) .WhereIF(input.EndTimeEnd.HasValue, w => w.EndTime <= input.EndTimeEnd.Value) .WhereIF(input.MinItemQuantity.HasValue, w => w.MinItemQuantity == input.MinItemQuantity.Value) .WhereIF(input.CreateTimeStart.HasValue, w => w.CreateTime >= input.CreateTimeStart.Value) .WhereIF(input.CreateTimeEnd.HasValue, w => w.CreateTime <= input.CreateTimeEnd.Value) .Select(it => new LqPackageInfoListOutput { Id = it.Id, ActivityName = it.ActivityName, ActivityDesc = it.ActivityDesc, StartTime = it.StartTime, EndTime = it.EndTime, MinItemQuantity = it.MinItemQuantity, ActivityRules = it.ActivityRules, SortOrder = it.SortOrder, CreateTime = it.CreateTime }).MergeTable().OrderBy(sidx + " " + input.sort).ToPagedListAsync(input.currentPage, input.pageSize); return PageResult.SqlSugarPageResult(data); } #endregion #region 获取营销活动详情 /// /// 获取营销活动详情 /// /// 营销活动ID /// 营销活动详情 [HttpGet("GetPackageInfoDetailAsync")] public async Task GetPackageInfoDetailAsync(string id) { var data = await _db.Queryable().Where(w => w.Id == id).FirstAsync(); var output = data.Adapt(); return output; } #endregion #region 更新营销活动 /// /// 更新营销活动 /// /// 营销活动更新输入 /// 营销活动ID /// /// 更新营销活动信息,包括活动基本信息和品项明细 /// /// 示例请求: /// ```json /// { /// "id": "123456789", /// "activityName": "春季护肤优惠活动", /// "activityDesc": "春季护肤特惠活动", /// "startTime": "2025-03-01T00:00:00", /// "endTime": "2025-03-31T23:59:59", /// "minItemQuantity": 2, /// "activityRules": "活动规则说明", /// "activityImages": "[\"image1.jpg\"]", /// "sortOrder": 1, /// "activityItems": [ /// { /// "itemId": "ITEM001", /// "itemName": "面部清洁", /// "itemCategory": "基础护理", /// "itemRemark": "推荐品项" /// } /// ] /// } /// ``` /// /// 参数说明: /// - id: 营销活动ID(必填) /// - activityName: 营销活动名称 /// - activityDesc: 营销活动描述 /// - startTime: 活动开始时间 /// - endTime: 活动结束时间 /// - minItemQuantity: 至少购买品项数量 /// - activityRules: 活动规则说明 /// - activityImages: 活动图片(JSON格式) /// - sortOrder: 排序 /// - activityItems: 营销活动品项明细列表 /// /// 成功更新营销活动,返回营销活动ID /// 请求参数错误 /// 营销活动不存在 /// 服务器内部错误 [HttpPut("UpdatePackageInfoAsync")] public async Task UpdatePackageInfoAsync(LqPackageInfoUpInput input) { try { // 验证活动时间 if (input.StartTime >= input.EndTime) { throw NCCException.Oh("活动开始时间必须小于结束时间"); } // 验证品项明细 if (input.ActivityItems == null || !input.ActivityItems.Any()) { throw NCCException.Oh("营销活动必须包含至少一个品项"); } // 验证至少购买品项数量 if (input.ActivityItems.Count < input.MinItemQuantity) { throw NCCException.Oh($"品项数量不能少于至少购买品项数量({input.MinItemQuantity})"); } // 检查营销活动是否存在 var existingActivity = await _db.Queryable() .Where(w => w.Id == input.Id) .FirstAsync(); if (existingActivity == null) { throw NCCException.Oh("营销活动不存在"); } // 开始事务 _db.BeginTran(); try { // 更新营销活动基本信息 var updateResult = await _db.Updateable() .SetColumns(it => new LqPackageInfoEntity { ActivityName = input.ActivityName, ActivityDesc = input.ActivityDesc, StartTime = input.StartTime, EndTime = input.EndTime, MinItemQuantity = input.MinItemQuantity, ActivityRules = input.ActivityRules, ActivityImages = input.ActivityImages, SortOrder = input.SortOrder, UpdateTime = DateTime.Now, UpdateUser = _userManager.UserId }) .Where(w => w.Id == input.Id) .ExecuteCommandAsync(); if (updateResult <= 0) { throw NCCException.Oh("更新营销活动失败"); } // 删除原有的品项明细 await _db.Deleteable() .Where(w => w.ActivityId == input.Id) .ExecuteCommandAsync(); // 创建新的品项明细 var packageItemDetails = input.ActivityItems.Select(item => { var packageItemDetail = item.Adapt(); packageItemDetail.Id = YitIdHelper.NextId().ToString(); packageItemDetail.ActivityId = input.Id; packageItemDetail.CreateTime = DateTime.Now; packageItemDetail.UpdateTime = DateTime.Now; packageItemDetail.IsEffective = 1; return packageItemDetail; }).ToList(); // 批量保存新的品项明细 if (packageItemDetails.Any()) { await _db.Insertable(packageItemDetails).ExecuteCommandAsync(); } // 提交事务 _db.CommitTran(); return input.Id; } catch { // 回滚事务 _db.RollbackTran(); throw; } } catch (Exception ex) { throw NCCException.Oh($"更新营销活动失败: {ex.Message}"); } } #endregion #region 标记删除营销活动 /// /// 标记删除营销活动 /// /// 营销活动ID /// 营销活动ID [HttpDelete("MarkDeletePackageInfoAsync")] public async Task MarkDeletePackageInfoAsync(string id) { var entity = await _db.Queryable().Where(w => w.Id == id).FirstAsync(); if (entity == null) { throw NCCException.Oh("营销活动不存在"); } entity.IsEffective = StatusEnum.无效.GetHashCode(); await _db.Updateable(entity).ExecuteCommandAsync(); await _db.Updateable().SetColumns(it => new LqPackageItemDetailEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.ActivityId == id).ExecuteCommandAsync(); return id; } #endregion #region 获取当前时间有效的活动 /// /// 获取当前时间有效的活动 /// /// 当前时间有效的活动 [HttpGet("GetCurrentTimeEffectiveActivityAsync")] public async Task GetCurrentTimeEffectiveActivityAsync() { var data = await _db.Queryable().Where(w => w.StartTime <= DateTime.Now && w.EndTime >= DateTime.Now && w.IsEffective == StatusEnum.有效.GetHashCode()).ToListAsync(); var output = data.Adapt>(); return output; } #endregion } }