using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; using Mapster; using Microsoft.AspNetCore.Mvc; using NCC.Common.Core.Manager; using NCC.Common.Enum; using NCC.Common.Extension; using NCC.Common.Filter; using NCC.Dependency; using NCC.DynamicApiController; using NCC.Extend.Entitys.Dto.LqMdGeneralManagerLifeline; using NCC.Extend.Entitys.Enum; using NCC.Extend.Entitys.lq_md_general_manager_lifeline; using NCC.Extend.Entitys.lq_md_target; using NCC.Extend.Interfaces.LqMdGeneralManagerLifeline; using NCC.FriendlyException; using SqlSugar; using Yitter.IdGenerator; namespace NCC.Extend.LqMdGeneralManagerLifeline { /// /// 门店总经理生命线设置服务 /// [ApiDescriptionSettings(Tag = "绿纤门店总经理生命线设置服务", Name = "LqMdGeneralManagerLifeline", Order = 201)] [Route("api/Extend/[controller]")] public class LqMdGeneralManagerLifelineService : ILqMdGeneralManagerLifelineService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _repository; private readonly SqlSugarScope _db; private readonly IUserManager _userManager; /// /// 初始化一个类型的新实例 /// public LqMdGeneralManagerLifelineService(ISqlSugarRepository repository, IUserManager userManager) { _repository = repository; _db = _repository.Context; _userManager = userManager; } #region 获取门店总经理生命线设置信息 /// /// 获取门店总经理生命线设置信息 /// /// 主键ID /// [HttpGet("{id}")] public async Task GetInfo(string id) { var entity = await _db.Queryable().FirstAsync(p => p.Id == id); _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); var output = entity.Adapt(); return output; } #endregion #region 获取门店总经理生命线设置列表 /// /// 获取门店总经理生命线设置列表 /// /// 请求参数 /// [HttpGet("")] public async Task GetList([FromQuery] LqMdGeneralManagerLifelineListQueryInput input) { var sidx = input.sidx == null ? "id" : input.sidx; var data = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.storeId), p => p.StoreId.Contains(input.storeId)) .WhereIF(!string.IsNullOrEmpty(input.month), p => p.Month == input.month) .WhereIF(!string.IsNullOrEmpty(input.generalManagerId), p => p.GeneralManagerId.Contains(input.generalManagerId)) .Select(it => new LqMdGeneralManagerLifelineListOutput { id = it.Id, storeId = it.StoreId, month = it.Month, generalManagerId = it.GeneralManagerId, managerType = it.ManagerType, lifeline1 = it.Lifeline1, commissionRate1 = it.CommissionRate1, lifeline2 = it.Lifeline2, commissionRate2 = it.CommissionRate2, lifeline3 = it.Lifeline3, commissionRate3 = it.CommissionRate3, remark = it.Remark, createTime = it.CreateTime, createUserId = it.CreateUserId, updateTime = it.UpdateTime, updateUserId = it.UpdateUserId, }) .MergeTable() .OrderBy(sidx + " " + input.sort) .ToPagedListAsync(input.currentPage, input.pageSize); // 设置经理类型中文名称 foreach (var item in data.list) { if (Enum.IsDefined(typeof(ManagerTypeEnum), item.managerType)) { var enumValue = (ManagerTypeEnum)item.managerType; item.managerTypeName = enumValue.GetDescription(); } else { item.managerTypeName = string.Empty; } } return PageResult.SqlSugarPageResult(data); } #endregion #region 新建门店总经理生命线设置 /// /// 新建门店总经理生命线设置 /// /// 参数 /// [HttpPost("")] public async Task Create([FromBody] LqMdGeneralManagerLifelineCrInput input) { var userInfo = await _userManager.GetUserInfo(); // 验证月份格式 if (input.month.Length != 6 || !Regex.IsMatch(input.month, @"^\d{6}$")) { throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为YYYYMM(如:202501)"); } // 验证门店ID、月份、总经理ID的唯一性 var exists = await _db.Queryable() .Where(p => p.StoreId == input.storeId && p.Month == input.month && p.GeneralManagerId == input.generalManagerId) .AnyAsync(); if (exists) { throw NCCException.Oh(ErrorCode.COM1000, "该门店在该月份该总经理已存在生命线设置记录"); } var entity = input.Adapt(); entity.Id = YitIdHelper.NextId().ToString(); entity.CreateTime = DateTime.Now; entity.CreateUserId = userInfo.userId; var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000); } #endregion #region 更新门店总经理生命线设置 /// /// 更新门店总经理生命线设置 /// /// 主键ID /// 参数 /// [HttpPut("{id}")] public async Task Update(string id, [FromBody] LqMdGeneralManagerLifelineUpInput input) { var userInfo = await _userManager.GetUserInfo(); // 验证记录是否存在 var entity = await _db.Queryable().FirstAsync(p => p.Id == id); _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); // 验证月份格式 if (input.month.Length != 6 || !Regex.IsMatch(input.month, @"^\d{6}$")) { throw NCCException.Oh("月份格式必须为YYYYMM(如:202501)"); } // 如果门店ID、月份或总经理ID发生变化,需要验证唯一性 if (entity.StoreId != input.storeId || entity.Month != input.month || entity.GeneralManagerId != input.generalManagerId) { var exists = await _db.Queryable() .Where(p => p.StoreId == input.storeId && p.Month == input.month && p.GeneralManagerId == input.generalManagerId && p.Id != id) .AnyAsync(); if (exists) { throw NCCException.Oh("该门店在该月份该总经理已存在生命线设置记录"); } } var updateEntity = input.Adapt(); updateEntity.Id = id; updateEntity.UpdateTime = DateTime.Now; updateEntity.UpdateUserId = userInfo.userId; var isOk = await _db.Updateable(updateEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001); } #endregion #region 删除门店总经理生命线设置 /// /// 删除门店总经理生命线设置 /// /// 主键ID /// [HttpDelete("{id}")] public async Task Delete(string id) { var entity = await _db.Queryable().FirstAsync(p => p.Id == id); _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); var isOk = await _db.Deleteable().Where(d => d.Id == id).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1002); } #endregion #region 批量创建门店总经理生命线设置(从门店目标表批量创建) /// /// 批量创建门店总经理生命线设置(从门店目标表批量创建) /// /// /// 从 lq_md_target 表中读取数据,根据 F_BusinessUnitGeneralManager 和 F_BusinessUnitManager 字段, /// 批量创建对应的总经理生命线设置记录。 /// /// 示例请求: /// POST /api/Extend/LqMdGeneralManagerLifeline/BatchCreateFromTarget?month=202501 /// /// 业务逻辑: /// 1. 从 lq_md_target 表中查询指定月份的数据 /// 2. 提取 F_StoreId(门店ID)、F_Month(月份)、F_BusinessUnitGeneralManager(总经理ID)、F_BusinessUnitManager(经理ID) /// 3. 对于每个门店目标记录,创建对应的总经理和经理的生命线设置记录 /// 4. 过滤掉已存在的记录,避免重复创建 /// 5. 批量插入新记录 /// /// 月份(YYYYMM格式) /// 批量创建结果 /// 成功返回创建结果 /// 参数错误 /// 服务器内部错误 [HttpPost("BatchCreateFromTarget")] public async Task BatchCreateFromTarget([FromQuery] string month) { var userInfo = await _userManager.GetUserInfo(); // 验证月份格式 if (string.IsNullOrEmpty(month) || month.Length != 6 || !Regex.IsMatch(month, @"^\d{6}$")) { throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为YYYYMM(如:202501)"); } // 从门店目标表中查询数据 var targetData = await _db.Queryable() .Where(p => p.Month == month) .Select(p => new { p.StoreId, p.Month, p.BusinessUnitGeneralManager, p.BusinessUnitManager }) .ToListAsync(); if (targetData == null || targetData.Count == 0) { return new { success = true, message = $"月份 {month} 没有门店目标设置", createdCount = 0, skippedCount = 0 }; } // 查询已存在的记录 var existingRecords = await _db.Queryable().Where(p => p.Month == month).Select(p => new { p.StoreId, p.GeneralManagerId }).ToListAsync(); var existingKeys = existingRecords.Select(p => $"{p.StoreId}_{p.GeneralManagerId}").ToHashSet(); // 构建要创建的生命线设置记录 var entities = new List(); foreach (var target in targetData) { // 创建总经理的生命线设置 if (!string.IsNullOrEmpty(target.BusinessUnitGeneralManager)) { var key = $"{target.StoreId}_{target.BusinessUnitGeneralManager}"; if (!existingKeys.Contains(key)) { entities.Add(new LqMdGeneralManagerLifelineEntity { Id = YitIdHelper.NextId().ToString(), StoreId = target.StoreId, Month = target.Month, ManagerType = ManagerTypeEnum.总经理.GetHashCode(), GeneralManagerId = target.BusinessUnitGeneralManager, Lifeline1 = 0, CommissionRate1 = 0, Lifeline2 = 0, CommissionRate2 = 0, Lifeline3 = 0, CommissionRate3 = 0, Remark = "", CreateTime = DateTime.Now, CreateUserId = userInfo.userId, }); } } // 创建经理的生命线设置(如果经理ID不为空且与总经理ID不同) if (!string.IsNullOrEmpty(target.BusinessUnitManager) && target.BusinessUnitManager != target.BusinessUnitGeneralManager) { var key = $"{target.StoreId}_{target.BusinessUnitManager}"; if (!existingKeys.Contains(key)) { entities.Add(new LqMdGeneralManagerLifelineEntity { Id = YitIdHelper.NextId().ToString(), StoreId = target.StoreId, Month = target.Month, ManagerType = ManagerTypeEnum.经理.GetHashCode(), GeneralManagerId = target.BusinessUnitManager, Lifeline1 = 0, CommissionRate1 = 0, Lifeline2 = 0, CommissionRate2 = 0, Lifeline3 = 0, CommissionRate3 = 0, Remark = "", CreateTime = DateTime.Now, CreateUserId = userInfo.userId, }); } } } int createdCount = 0; int skippedCount = targetData.Count * 2 - entities.Count; // 理论最大记录数 - 实际创建数 if (entities.Count > 0) { createdCount = await _db.Insertable(entities).ExecuteCommandAsync(); } return new { success = true, message = $"批量创建完成:成功创建 {createdCount} 条记录,跳过 {skippedCount} 条已存在的记录", createdCount = createdCount, skippedCount = skippedCount, month = month }; } #endregion #region 复制上月设置 /// /// 复制上月设置 /// /// /// 从上个月复制生命线设置数据到目标月份 /// /// 示例请求: /// POST /api/Extend/LqMdGeneralManagerLifeline/CopyLastMonthData?targetMonth=202502 /// /// 业务逻辑: /// 1. 确定目标月份(如果未指定,使用当前月份) /// 2. 计算上个月份 /// 3. 查询上个月的所有生命线设置数据 /// 4. 查询目标月份已存在的记录 /// 5. 过滤掉已存在的记录,只复制新记录 /// 6. 批量插入新记录 /// /// 目标月份(YYYYMM格式),如果为空则复制到当前月份 /// 复制结果 /// 成功返回复制结果 /// 参数错误 /// 服务器内部错误 [HttpPost("CopyLastMonthData")] public async Task CopyLastMonthData([FromQuery] string targetMonth = null) { var userInfo = await _userManager.GetUserInfo(); // 确定目标月份 string targetMonthStr; if (string.IsNullOrEmpty(targetMonth)) { // 如果未指定,使用当前月份 var now = DateTime.Now; targetMonthStr = now.ToString("yyyyMM"); } else { // 验证月份格式 if (targetMonth.Length != 6 || !Regex.IsMatch(targetMonth, @"^\d{6}$")) { throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为YYYYMM(如:202501)"); } targetMonthStr = targetMonth; } // 计算上个月份 var targetDate = DateTime.ParseExact(targetMonthStr, "yyyyMM", null); var lastMonthDate = targetDate.AddMonths(-1); var lastMonthStr = lastMonthDate.ToString("yyyyMM"); // 查询上个月的所有生命线设置数据 var lastMonthData = await _db.Queryable().Where(p => p.Month == lastMonthStr).ToListAsync(); if (lastMonthData == null || lastMonthData.Count == 0) { return new { success = true, message = $"上个月({lastMonthStr})没有数据可复制", copiedCount = 0, skippedCount = 0 }; } // 查询目标月份已存在的记录 var existingRecords = await _db.Queryable().Where(p => p.Month == targetMonthStr).Select(p => new { p.StoreId, p.GeneralManagerId }).ToListAsync(); var existingKeys = existingRecords.Select(p => $"{p.StoreId}_{p.GeneralManagerId}").ToHashSet(); // 过滤掉已存在的记录,只复制新记录 var newEntities = lastMonthData.Where(p => !existingKeys.Contains($"{p.StoreId}_{p.GeneralManagerId}")) .Select(p => new LqMdGeneralManagerLifelineEntity { Id = YitIdHelper.NextId().ToString(), StoreId = p.StoreId, Month = targetMonthStr, ManagerType = p.ManagerType, GeneralManagerId = p.GeneralManagerId, Lifeline1 = p.Lifeline1, CommissionRate1 = p.CommissionRate1, Lifeline2 = p.Lifeline2, CommissionRate2 = p.CommissionRate2, Lifeline3 = p.Lifeline3, CommissionRate3 = p.CommissionRate3, Remark = p.Remark, CreateTime = DateTime.Now, CreateUserId = userInfo.userId, }).ToList(); int copiedCount = 0; int skippedCount = lastMonthData.Count - newEntities.Count; if (newEntities.Count > 0) { copiedCount = await _db.Insertable(newEntities).ExecuteCommandAsync(); } return new { success = true, message = $"复制完成:成功复制{copiedCount}条记录,跳过{skippedCount}条已存在的记录", copiedCount = copiedCount, skippedCount = skippedCount, lastMonth = lastMonthStr, targetMonth = targetMonthStr }; } #endregion } }