using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Mapster; using Microsoft.AspNetCore.Mvc; using NCC.ClayObject; using NCC.Common.Configuration; using NCC.Common.Core.Manager; using NCC.Common.Enum; using NCC.Common.Extension; using NCC.Common.Filter; using NCC.Common.Helper; using NCC.Common.Model.NPOI; using NCC.DataEncryption; using NCC.Dependency; using NCC.DynamicApiController; using NCC.Extend.Entitys.Dto.LqHytkHytk; using NCC.Extend.Entitys.Dto.LqHytkJksyj; using NCC.Extend.Entitys.Dto.LqHytkKjbsyj; using NCC.Extend.Entitys.Dto.LqHytkMx; using NCC.Extend.Entitys.Enum; using NCC.Extend.Entitys.lq_hytk_hytk; using NCC.Extend.Entitys.lq_hytk_jksyj; using NCC.Extend.Entitys.lq_hytk_kjbsyj; using NCC.Extend.Entitys.lq_hytk_mx; using NCC.Extend.Entitys.lq_kd_pxmx; using NCC.Extend.Entitys.lq_xmzl; using NCC.Extend.Interfaces.LqHytkHytk; using NCC.FriendlyException; using NCC.JsonSerialization; using SqlSugar; using Yitter.IdGenerator; namespace NCC.Extend.LqHytkHytk { /// /// 退卡_信息表服务 /// [ApiDescriptionSettings(Tag = "绿纤退卡信息表服务", Name = "LqHytkHytk", Order = 200)] [Route("api/Extend/[controller]")] public class LqHytkHytkService : ILqHytkHytkService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _lqHytkHytkRepository; private readonly ISqlSugarRepository _lqHytkMxRepository; private readonly ISqlSugarRepository _lqHytkJksyjRepository; private readonly ISqlSugarRepository _lqHytkKjbsyjRepository; private readonly SqlSugarScope _db; private readonly IUserManager _userManager; /// /// 初始化一个类型的新实例 /// public LqHytkHytkService( ISqlSugarRepository lqHytkHytkRepository, ISqlSugarRepository lqHytkMxRepository, ISqlSugarRepository lqHytkJksyjRepository, ISqlSugarRepository lqHytkKjbsyjRepository, IUserManager userManager ) { _lqHytkHytkRepository = lqHytkHytkRepository; _lqHytkMxRepository = lqHytkMxRepository; _lqHytkJksyjRepository = lqHytkJksyjRepository; _lqHytkKjbsyjRepository = lqHytkKjbsyjRepository; _db = _lqHytkHytkRepository.Context; _userManager = userManager; } #region 获取退卡信息列表 /// /// 获取退卡信息列表 /// /// /// 获取退卡记录列表,支持根据健康师ID或科技部老师ID筛选,返回品项明细、健康师业绩和科技部老师业绩 /// /// 示例请求: /// ```json /// GET /api/Extend/LqHytkHytk?jksId=健康师ID&kjblsId=科技部老师ID&currentPage=1&pageSize=10 /// ``` /// /// 参数说明: /// - jksId: 健康师ID(可选,传入后只返回该健康师参与的退卡记录) /// - kjblsId: 科技部老师ID(可选,传入后只返回该老师参与的退卡记录) /// - id: 退卡编号(可选) /// - md: 门店ID(可选) /// - hy: 会员ID(可选) /// - tksj: 退卡时间(可选,格式:yyyy-MM-dd,yyyy-MM-dd) /// - currentPage: 当前页码(必填) /// - pageSize: 每页数量(必填) /// /// 返回数据说明: /// - 退卡基本信息:id、门店信息、会员信息、退卡金额、退卡时间等 /// - lqHytkMxList: 退卡品项明细列表,每个明细包含品项信息、退款金额、项目次数等 /// - lqHytkJksyjList: 健康师业绩列表,每个业绩包含健康师信息、业绩金额、手工费、退卡品项次数等 /// - lqHytkKjbsyjList: 科技部老师业绩列表,每个业绩包含科技部老师信息、业绩金额、手工费、退卡品项次数等 /// /// 查询参数 /// 分页的退卡记录列表,包含退卡基本信息、品项明细、健康师业绩、科技部老师业绩 /// 成功返回退卡列表 /// 参数错误 /// 服务器内部错误 [HttpGet("")] public async Task GetList([FromQuery] LqHytkHytkListQueryInput input) { var sidx = input.sidx == null ? "id" : input.sidx; List queryTksj = input.tksj != null ? input.tksj.Split(',').ToObeject>() : null; DateTime? startTksj = queryTksj != null ? Ext.GetDateTime(queryTksj.First()) : null; DateTime? endTksj = queryTksj != null ? Ext.GetDateTime(queryTksj.Last()) : null; // 根据是否传入健康师ID或科技部老师ID,动态构建查询 ISugarQueryable baseQuery = null; if (!string.IsNullOrEmpty(input.jksId) && !string.IsNullOrEmpty(input.kjblsId)) { // 同时传入健康师ID和科技部老师ID,需要同时关联两个业绩表(不过滤有效性) baseQuery = _db.Queryable( (jksyj, kjbsyj, hytk) => jksyj.Gltkbh == hytk.Id && kjbsyj.Gltkbh == hytk.Id) .Where((jksyj, kjbsyj, hytk) => jksyj.Jkszh == input.jksId) .Where((jksyj, kjbsyj, hytk) => kjbsyj.Kjblszh == input.kjblsId) .Select((jksyj, kjbsyj, hytk) => hytk) .Distinct() .MergeTable(); } else if (!string.IsNullOrEmpty(input.jksId)) { // 只传入健康师ID,关联健康师业绩表(不过滤有效性) baseQuery = _db.Queryable( (jksyj, hytk) => jksyj.Gltkbh == hytk.Id) .Where((jksyj, hytk) => jksyj.Jkszh == input.jksId) .Select((jksyj, hytk) => hytk) .Distinct() .MergeTable(); } else if (!string.IsNullOrEmpty(input.kjblsId)) { // 只传入科技部老师ID,关联科技部老师业绩表(不过滤有效性) baseQuery = _db.Queryable( (kjbsyj, hytk) => kjbsyj.Gltkbh == hytk.Id) .Where((kjbsyj, hytk) => kjbsyj.Kjblszh == input.kjblsId) .Select((kjbsyj, hytk) => hytk) .Distinct() .MergeTable(); } else { // 没有传入健康师ID或科技部老师ID,使用原来的查询逻辑 baseQuery = _db.Queryable(); } var data = await baseQuery .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) .WhereIF(!string.IsNullOrEmpty(input.md), p => p.Md.Equals(input.md)) .WhereIF(!string.IsNullOrEmpty(input.mdbh), p => p.Mdbh.Contains(input.mdbh)) .WhereIF(!string.IsNullOrEmpty(input.mdmc), p => p.Mdmc.Contains(input.mdmc)) .WhereIF(!string.IsNullOrEmpty(input.hy), p => p.Hy.Equals(input.hy)) .WhereIF(!string.IsNullOrEmpty(input.hymc), p => p.Hymc.Contains(input.hymc)) .WhereIF(!string.IsNullOrEmpty(input.hyzh), p => p.Hyzh.Contains(input.hyzh)) .WhereIF(!string.IsNullOrEmpty(input.gklx), p => p.Gklx.Contains(input.gklx)) .WhereIF(input.tkje.HasValue, p => p.Tkje == input.tkje) .WhereIF(input.sgfy.HasValue, p => p.Sgfy == input.sgfy) .WhereIF(!string.IsNullOrEmpty(input.bz), p => p.Bz.Contains(input.bz)) .WhereIF(!string.IsNullOrEmpty(input.tkzt), p => p.Tkzt.Contains(input.tkzt)) .WhereIF(!string.IsNullOrEmpty(input.tkyy), p => p.Tkyy.Contains(input.tkyy)) .WhereIF(!string.IsNullOrEmpty(input.fileUrl), p => p.FileUrl.Contains(input.fileUrl)) .WhereIF(queryTksj != null, p => p.Tksj >= new DateTime(startTksj.ToDate().Year, startTksj.ToDate().Month, startTksj.ToDate().Day, 0, 0, 0)) .WhereIF(queryTksj != null, p => p.Tksj <= new DateTime(endTksj.ToDate().Year, endTksj.ToDate().Month, endTksj.ToDate().Day, 23, 59, 59)) .WhereIF(!string.IsNullOrEmpty(input.czry), p => p.Czry.Equals(input.czry)) .WhereIF(input.isEffective != 0, p => p.IsEffective == input.isEffective) .Select(it => new LqHytkHytkListOutput { id = it.Id, md = it.Md, mdbh = it.Mdbh, mdmc = it.Mdmc, hy = it.Hy, hymc = it.Hymc, hyzh = it.Hyzh, gklx = it.Gklx, tkje = it.Tkje, sgfy = it.Sgfy, bz = it.Bz, tkzt = it.Tkzt, tkyy = it.Tkyy, tksj = it.Tksj, czry = it.Czry, fileUrl = it.FileUrl, isEffective = it.IsEffective, cancelRemark = it.CancelRemark, actualRefundAmount = it.ActualRefundAmount }) .MergeTable() .OrderBy(sidx + " " + input.sort) .ToPagedListAsync(input.currentPage, input.pageSize); // 获取当前页的退卡记录ID列表 var refundIds = data.list.Select(x => x.id).ToList(); // 批量查询品项明细(不过滤有效性,返回所有记录) var itemDetails = new List(); if (refundIds.Any()) { itemDetails = await _db.Queryable() .Where(x => refundIds.Contains(x.RefundInfoId)) .Select(x => new LqHytkMxInfoOutput { id = x.Id, refundInfoId = x.RefundInfoId, billingItemId = x.BillingItemId, px = x.Px, pxmc = x.Pxmc, pxjg = x.Pxjg, tkje = x.Tkje, projectNumber = x.ProjectNumber, isEffective = x.IsEffective, sourceType = x.SourceType, totalPrice = x.TotalPrice }) .ToListAsync(); } // 批量查询健康师业绩(性能优化:一次性查询所有退卡的健康师业绩,不过滤有效性) var jksyjList = new List(); if (refundIds.Any()) { jksyjList = await _db.Queryable() .Where(x => refundIds.Contains(x.Gltkbh)) .Select(x => new LqHytkJksyjInfoOutput { id = x.Id, gltkbh = x.Gltkbh, jks = x.Jks, jksxm = x.Jksxm, jkszh = x.Jkszh, jksyj = x.Jksyj, tksj = x.Tksj, F_jsjid = x.F_jsjid, F_tkpxid = x.F_tkpxid, F_LaborCost = x.F_LaborCost, F_tkpxNumber = x.F_tkpxNumber }) .ToListAsync(); } // 批量查询科技部老师业绩(性能优化:一次性查询所有退卡的科技部老师业绩,不过滤有效性) var kjbsyjList = new List(); if (refundIds.Any()) { kjbsyjList = await _db.Queryable() .Where(x => refundIds.Contains(x.Gltkbh)) .Select(x => new LqHytkKjbsyjInfoOutput { id = x.Id, gltkbh = x.Gltkbh, kjbls = x.Kjbls, kjblsxm = x.Kjblsxm, kjblszh = x.Kjblszh, kjblsyj = x.Kjblsyj, tksj = x.Tksj, F_tkpxid = x.F_tkpxid, F_LaborCost = x.F_LaborCost, F_tkpxNumber = x.F_tkpxNumber }) .ToListAsync(); } // 按退卡ID分组品项明细 var itemDetailsGrouped = itemDetails.GroupBy(x => x.refundInfoId) .ToDictionary(g => g.Key, g => g.ToList()); // 按退卡ID分组健康师业绩 var jksyjGrouped = jksyjList.GroupBy(x => x.gltkbh) .ToDictionary(g => g.Key, g => g.ToList()); // 按退卡ID分组科技部老师业绩 var kjbsyjGrouped = kjbsyjList.GroupBy(x => x.gltkbh) .ToDictionary(g => g.Key, g => g.ToList()); // 为每个退卡记录分配品项明细、健康师业绩和科技部老师业绩 foreach (var item in data.list) { item.lqHytkMxList = itemDetailsGrouped.ContainsKey(item.id) ? itemDetailsGrouped[item.id] : new List(); item.lqHytkJksyjList = jksyjGrouped.ContainsKey(item.id) ? jksyjGrouped[item.id] : new List(); item.lqHytkKjbsyjList = kjbsyjGrouped.ContainsKey(item.id) ? kjbsyjGrouped[item.id] : new List(); } return PageResult.SqlSugarPageResult(data); } #endregion #region 创建退卡信息及其关联的品项明细、健康师业绩、科技部老师业绩信息 /// /// 创建退卡信息及其关联的品项明细、健康师业绩、科技部老师业绩信息 /// /// /// 参数说明: /// - md: 门店ID /// - hy: 会员ID /// - lqHytkMxList: 退卡品项明细列表 /// /// 退卡创建参数 /// 无返回值 /// 创建成功 /// 参数错误或数据验证失败 /// 服务器内部错误 [HttpPost("")] public async Task Create([FromBody] LqHytkHytkCrInput input) { var userInfo = await _userManager.GetUserInfo(); var entity = input.Adapt(); entity.Id = YitIdHelper.NextId().ToString(); entity.F_CreateTime = DateTime.Now; entity.F_CreateUser = userInfo.userId; entity.IsEffective = StatusEnum.有效.GetHashCode(); entity.Czry = userInfo.userId; try { // 开启事务 _db.BeginTran(); // 新增退卡主表记录 var newEntity = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteReturnEntityAsync(); // 收集所有需要插入的实体,然后批量插入 var allMxEntities = new List(); var allJksyjEntities = new List(); var allKjbsyjEntities = new List(); // 处理品项明细列表 if (input.lqHytkMxList != null && input.lqHytkMxList.Any()) { foreach (var item in input.lqHytkMxList) { // 创建品项明细实体 var lqHytkMxEntity = new LqHytkMxEntity { Id = YitIdHelper.NextId().ToString(), RefundInfoId = newEntity.Id, BillingItemId = item.billingItemId, MemberId = newEntity.Hy, CreateTime = DateTime.Now, CreateUser = userInfo.userId, Px = item.px, Pxmc = item.pxmc, Pxjg = item.pxjg, Tkje = item.tkje, Tksj = input.tksj, ProjectNumber = item.F_ProjectNumber ?? 1, SourceType = item.F_SourceType, TotalPrice = item.F_TotalPrice ?? (item.pxjg * (item.F_ProjectNumber ?? 1)), IsEffective = StatusEnum.有效.GetHashCode(), ItemCategory = await _db.Queryable().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(), PerformanceType = await _db.Queryable().Where(x => x.Id == item.px).Select(x => x.Fl3).FirstAsync() ?? "", BeautyType = await _db.Queryable().Where(x => x.Id == item.px).Select(x => x.BeautyType).FirstAsync(), }; allMxEntities.Add(lqHytkMxEntity); // 收集该品项关联的健康师业绩 if (item.lqHytkJksyjList != null && item.lqHytkJksyjList.Any()) { foreach (var ijks_tem in item.lqHytkJksyjList) { allJksyjEntities.Add(new LqHytkJksyjEntity { Id = YitIdHelper.NextId().ToString(), Gltkbh = newEntity.Id, Jks = ijks_tem.jks, Jksxm = ijks_tem.jksxm, Jkszh = ijks_tem.jkszh, Jksyj = ijks_tem.jksyj, Tksj = input.tksj, F_jsjid = ijks_tem.F_jsjid, F_tkpxid = ijks_tem.F_tkpxid, F_LaborCost = ijks_tem.F_LaborCost, F_tkpxNumber = ijks_tem.F_tkpxNumber, F_CreateTime = DateTime.Now, F_CreateUser = userInfo.userId, CardReturn = lqHytkMxEntity.Id, IsEffective = StatusEnum.有效.GetHashCode(), ItemCategory = lqHytkMxEntity.ItemCategory, ItemId = lqHytkMxEntity.Px, StoreId = newEntity.Md, ItemName = lqHytkMxEntity.Pxmc, PerformanceType = lqHytkMxEntity.PerformanceType, BeautyType = lqHytkMxEntity.BeautyType, } ); } } // 收集该品项关联的科技部老师业绩 if (item.lqHytkKjbsyjList != null && item.lqHytkKjbsyjList.Any()) { foreach (var ikjbs_tem in item.lqHytkKjbsyjList) { allKjbsyjEntities.Add( new LqHytkKjbsyjEntity { Id = YitIdHelper.NextId().ToString(), Gltkbh = newEntity.Id, Kjbls = ikjbs_tem.kjbls, Kjblsxm = ikjbs_tem.kjblsxm, Kjblszh = ikjbs_tem.kjblszh, Kjblsyj = ikjbs_tem.kjblsyj, Tksj = input.tksj, F_tkpxid = ikjbs_tem.F_tkpxid, F_LaborCost = ikjbs_tem.F_LaborCost, F_tkpxNumber = ikjbs_tem.F_tkpxNumber, F_CreateTime = DateTime.Now, F_CreateUser = userInfo.userId, CardReturn = lqHytkMxEntity.Id, IsEffective = StatusEnum.有效.GetHashCode(), ItemCategory = lqHytkMxEntity.ItemCategory, ItemId = lqHytkMxEntity.Px, StoreId = newEntity.Md, ItemName = lqHytkMxEntity.Pxmc, PerformanceType = lqHytkMxEntity.PerformanceType, BeautyType = lqHytkMxEntity.BeautyType, } ); } } } } // 批量插入品项明细 if (allMxEntities.Any()) { await _db.Insertable(allMxEntities).ExecuteCommandAsync(); } // 批量插入健康师业绩 if (allJksyjEntities.Any()) { await _db.Insertable(allJksyjEntities).ExecuteCommandAsync(); } // 批量插入科技部老师业绩 if (allKjbsyjEntities.Any()) { await _db.Insertable(allKjbsyjEntities).ExecuteCommandAsync(); } // 关闭事务 _db.CommitTran(); } catch (Exception ex) { _db.RollbackTran(); throw NCCException.Oh(ErrorCode.COM1005, ex.Message); } } #endregion #region 更新退卡信息及其关联的品项明细、健康师业绩、科技部老师业绩信息 /// /// 更新退卡信息及其关联的品项明细、健康师业绩、科技部老师业绩信息 /// /// /// 更新退卡记录及其关联的品项明细、健康师业绩、科技部老师业绩信息 /// 先删除原有的关联数据,再插入新的数据 /// /// 退卡ID /// 退卡更新参数 /// 无返回值 /// 更新成功 /// 参数错误或数据验证失败 /// 服务器内部错误 [HttpPut("{id}")] public async Task Update(string id, [FromBody] LqHytkHytkUpInput input) { var userInfo = await _userManager.GetUserInfo(); var entity = input.Adapt(); entity.Id = id; entity.F_ModifyTime = DateTime.Now; entity.F_ModifyUser = userInfo.userId; try { // 开启事务 _db.BeginTran(); // 更新退卡主表记录 await _db.Updateable(entity).IgnoreColumns(true).ExecuteCommandAsync(); // 删除原有的关联数据 await _db.Deleteable().Where(x => x.RefundInfoId == id).ExecuteCommandAsync(); await _db.Deleteable().Where(x => x.Gltkbh == id).ExecuteCommandAsync(); await _db.Deleteable().Where(x => x.Gltkbh == id).ExecuteCommandAsync(); // 收集所有需要插入的实体,然后批量插入 var allMxEntities = new List(); var allJksyjEntities = new List(); var allKjbsyjEntities = new List(); // 处理品项明细列表 if (input.lqHytkMxList != null && input.lqHytkMxList.Any()) { foreach (var item in input.lqHytkMxList) { // 创建品项明细实体 var lqHytkMxEntity = new LqHytkMxEntity { Id = YitIdHelper.NextId().ToString(), RefundInfoId = id, BillingItemId = item.billingItemId, MemberId = entity.Hy, CreateTime = DateTime.Now, CreateUser = userInfo.userId, Tksj = input.tksj, Px = item.px, Pxmc = item.pxmc, Pxjg = item.pxjg, Tkje = item.tkje, ProjectNumber = item.F_ProjectNumber ?? 1, SourceType = item.F_SourceType, TotalPrice = item.F_TotalPrice ?? (item.pxjg * (item.F_ProjectNumber ?? 1)), ItemCategory = await _db.Queryable().Where(x => x.Id == item.px).Select(x => x.Qt2).FirstAsync(), PerformanceType = await _db.Queryable().Where(x => x.Id == item.px).Select(x => x.Fl3).FirstAsync() ?? "", BeautyType = await _db.Queryable().Where(x => x.Id == item.px).Select(x => x.BeautyType).FirstAsync(), }; allMxEntities.Add(lqHytkMxEntity); // 收集该品项关联的健康师业绩 if (item.lqHytkJksyjList != null && item.lqHytkJksyjList.Any()) { foreach (var ijks_tem in item.lqHytkJksyjList) { allJksyjEntities.Add( new LqHytkJksyjEntity { Id = YitIdHelper.NextId().ToString(), Gltkbh = id, Jks = ijks_tem.jks, Jksxm = ijks_tem.jksxm, Jkszh = ijks_tem.jkszh, Jksyj = ijks_tem.jksyj, Tksj = input.tksj, F_jsjid = ijks_tem.F_jsjid, F_tkpxid = ijks_tem.F_tkpxid, F_LaborCost = ijks_tem.F_LaborCost, F_tkpxNumber = ijks_tem.F_tkpxNumber, F_CreateTime = DateTime.Now, F_CreateUser = userInfo.userId, ItemCategory = lqHytkMxEntity.ItemCategory, ItemId = lqHytkMxEntity.Px, StoreId = entity.Md, ItemName = lqHytkMxEntity.Pxmc, PerformanceType = lqHytkMxEntity.PerformanceType, BeautyType = lqHytkMxEntity.BeautyType, } ); } } // 收集该品项关联的科技部老师业绩 if (item.lqHytkKjbsyjList != null && item.lqHytkKjbsyjList.Any()) { foreach (var ikjbs_tem in item.lqHytkKjbsyjList) { allKjbsyjEntities.Add( new LqHytkKjbsyjEntity { Id = YitIdHelper.NextId().ToString(), Gltkbh = id, Kjbls = ikjbs_tem.kjbls, Kjblsxm = ikjbs_tem.kjblsxm, Kjblszh = ikjbs_tem.kjblszh, Kjblsyj = ikjbs_tem.kjblsyj, Tksj = input.tksj, F_tkpxid = ikjbs_tem.F_tkpxid, F_LaborCost = ikjbs_tem.F_LaborCost, F_tkpxNumber = ikjbs_tem.F_tkpxNumber, F_CreateTime = DateTime.Now, F_CreateUser = userInfo.userId, ItemCategory = lqHytkMxEntity.ItemCategory, ItemId = lqHytkMxEntity.Px, StoreId = entity.Md, ItemName = lqHytkMxEntity.Pxmc, PerformanceType = lqHytkMxEntity.PerformanceType, BeautyType = lqHytkMxEntity.BeautyType, } ); } } } } // 批量插入品项明细 if (allMxEntities.Any()) { await _db.Insertable(allMxEntities).ExecuteCommandAsync(); } // 批量插入健康师业绩 if (allJksyjEntities.Any()) { await _db.Insertable(allJksyjEntities).ExecuteCommandAsync(); } // 批量插入科技部老师业绩 if (allKjbsyjEntities.Any()) { await _db.Insertable(allKjbsyjEntities).ExecuteCommandAsync(); } // 关闭事务 _db.CommitTran(); } catch (Exception ex) { _db.RollbackTran(); throw NCCException.Oh(ErrorCode.COM1005, ex.Message); } } #endregion #region 作废退卡信息 /// /// 作废退卡信息 /// /// 主键 /// [HttpPut("VoidRefundCardInfo/{id}")] public async Task VoidRefundCardInfo(string id, [FromQuery] string remarks = null) { try { var entity = await _db.Queryable().FirstAsync(p => p.Id == id && p.IsEffective == StatusEnum.有效.GetHashCode()); if (entity == null) { throw NCCException.Oh("退卡信息不存在或已被作废"); } // 开启事务 _db.BeginTran(); // 更新主表 entity.IsEffective = StatusEnum.无效.GetHashCode(); entity.F_ModifyTime = DateTime.Now; entity.CancelRemark = remarks; await _db.Updateable(entity).ExecuteCommandAsync(); // 更新明细表 await _db.Updateable().SetColumns(it => new LqHytkMxEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.RefundInfoId == id).ExecuteCommandAsync(); // 更新健康师业绩表 await _db.Updateable().SetColumns(it => new LqHytkJksyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.Gltkbh == id).ExecuteCommandAsync(); // 更新科技部业绩表 await _db.Updateable().SetColumns(it => new LqHytkKjbsyjEntity { IsEffective = StatusEnum.无效.GetHashCode() }).Where(w => w.Gltkbh == id).ExecuteCommandAsync(); // 提交事务 _db.CommitTran(); return entity; } catch (Exception ex) { _db.RollbackTran(); throw NCCException.Oh($"删除退卡信息失败: {ex.Message}"); } } #endregion #region 物理删除退卡信息 /// /// 物理删除退卡信息 /// /// /// 彻底删除退卡记录及其所有关联数据,包括: /// - 退卡主表记录 /// - 退卡品项明细记录 /// - 退卡健康师业绩记录 /// - 退卡科技部老师业绩记录 /// /// 注意:此操作不可逆,请谨慎使用 /// /// 退卡记录主键ID /// 删除结果 /// 删除成功 /// 退卡记录不存在 /// 服务器内部错误 [HttpDelete("physical/{id}")] public async Task PhysicalDelete(string id) { try { // 检查退卡记录是否存在 var entity = await _db.Queryable().FirstAsync(p => p.Id == id); if (entity == null) { throw NCCException.Oh("退卡记录不存在"); } // 开启事务 _db.BeginTran(); // 1. 删除退卡品项明细记录 await _db.Deleteable().Where(x => x.RefundInfoId == id).ExecuteCommandAsync(); // 2. 删除退卡健康师业绩记录 await _db.Deleteable().Where(x => x.Gltkbh == id).ExecuteCommandAsync(); // 3. 删除退卡科技部老师业绩记录 await _db.Deleteable().Where(x => x.Gltkbh == id).ExecuteCommandAsync(); // 4. 删除退卡主表记录 await _db.Deleteable().Where(x => x.Id == id).ExecuteCommandAsync(); // 提交事务 _db.CommitTran(); return new { success = true, message = "退卡记录已彻底删除", deletedId = id, deletedTime = DateTime.Now }; } catch (Exception ex) { // 回滚事务 _db.RollbackTran(); throw NCCException.Oh($"物理删除退卡记录失败: {ex.Message}"); } } #endregion #region 获取退卡信息详情 /// /// 获取退卡信息详情 /// /// /// 获取退卡记录及其关联的品项明细、健康师业绩、科技部老师业绩信息 /// 按照退卡的完整格式返回数据,不包含汇总信息 /// /// 返回数据结构: /// - 主表信息:退卡基础信息、门店信息、会员信息、退卡金额等 /// - 品项明细列表:每个品项包含完整的项目信息(项目次数、是否有效、来源类型等) /// - 健康师业绩列表:按品项关联的健康师业绩信息 /// - 科技部老师业绩列表:按品项关联的科技部老师业绩信息 /// /// 退卡记录主键ID /// 退卡记录完整信息 /// 查询成功 /// 退卡记录不存在 /// 服务器内部错误 [HttpGet("{id}")] public async Task GetInfo(string id) { try { // 1. 查询主表信息 var entity = await _db.Queryable().Where(p => p.Id == id).FirstAsync(); if (entity == null) { throw NCCException.Oh("退卡记录不存在"); } var output = entity.Adapt(); // 2. 查询品项明细列表 var lqHytkMxList = await _db.Queryable().Where(w => w.RefundInfoId == entity.Id).ToListAsync(); // 3. 查询健康师业绩列表 var lqHytkJksyjList = await _db.Queryable().Where(w => w.Gltkbh == entity.Id).ToListAsync(); // 4. 查询科技部老师业绩列表 var lqHytkKjbsyjList = await _db.Queryable().Where(w => w.Gltkbh == entity.Id).ToListAsync(); // 5. 构建品项明细输出,每个品项关联对应的业绩信息 var mxOutputList = new List(); foreach (var mx in lqHytkMxList) { var mxOutput = new LqHytkMxInfoOutput { id = mx.Id, refundInfoId = mx.RefundInfoId, billingItemId = mx.BillingItemId, px = mx.Px, pxmc = mx.Pxmc, pxjg = mx.Pxjg, tkje = mx.Tkje, projectNumber = mx.ProjectNumber, sourceType = mx.SourceType, totalPrice = mx.TotalPrice, isEffective = mx.IsEffective, }; // 关联该品项的健康师业绩 var jksyjForMx = lqHytkJksyjList.Where(j => j.CardReturn == mx.Id).ToList(); mxOutput.lqHytkJksyjList = jksyjForMx.Adapt>(); // 关联该品项的科技部老师业绩 var kjbsyjForMx = lqHytkKjbsyjList.Where(k => k.CardReturn == mx.Id).ToList(); mxOutput.lqHytkKjbsyjList = kjbsyjForMx.Adapt>(); mxOutputList.Add(mxOutput); } // 6. 设置输出结果 output.lqHytkMxList = mxOutputList; // 7. 设置全局业绩列表(用于兼容性,但主要使用品项关联的业绩) output.lqHytkJksyjList = lqHytkJksyjList.Adapt>(); output.lqHytkKjbsyjList = lqHytkKjbsyjList.Adapt>(); return output; } catch (Exception ex) { throw NCCException.Oh($"获取退卡记录详情失败: {ex.Message}"); } } #endregion } }