using F9WebAiTest.Application.Common; using F9WebAiTest.Application.Dtos.Prod; using F9WebAiTest.Domain.Common; using F9WebAiTest.Domain.Entities.Base; using F9WebAiTest.Domain.Entities.Prod; namespace F9WebAiTest.Application.Services.Prod; /// /// 选剥茧(对应 F9 生产-选剥茧 XBJ):选茧日报(含盈亏/联统率)、选茧计划及其明细、选茧班组及职工。 /// public interface IXjrbService { // ---- 选茧日报 ---- Task> GetPagedAsync(DateTime? start, DateTime? end, string like, int pageIndex, int pageSize); Task GetByIdAsync(long id); Task SaveAsync(XjrbSaveDto dto); Task DeleteAsync(long id); Task CountYingkuiAsync(XjrbSaveDto dto); // ---- 选茧计划 ---- Task> GetPlanPagedAsync(DateTime? start, DateTime? end, string like, int pageIndex, int pageSize); Task GetPlanByIdAsync(long id); Task SavePlanAsync(XjrbPlanSaveDto dto); Task DeletePlanAsync(long id); // ---- 选茧计划明细 ---- Task> GetPlanItemsAsync(long planId); Task SavePlanItemAsync(XjrbItemSaveDto dto); Task DeletePlanItemAsync(long id); Task CountPlanYingkuiAsync(XjrbItemSaveDto dto); // ---- 选茧班组 ---- Task> GetBanzuPagedAsync(string banci, int? zu, int pageIndex, int pageSize); Task> GetBanzuZhigongAsync(long banzuId); Task SaveBanzuZhigongAsync(List dtos); } public class XjrbService : IXjrbService { private readonly IRepository _xjrbRepo; private readonly IRepository _planRepo; private readonly IRepository _itemRepo; private readonly IRepository _banzuRepo; private readonly IRepository _zgRepo; private readonly IRepository _gyzkRepo; public XjrbService( IRepository xjrbRepo, IRepository planRepo, IRepository itemRepo, IRepository banzuRepo, IRepository zgRepo, IRepository gyzkRepo) { _xjrbRepo = xjrbRepo; _planRepo = planRepo; _itemRepo = itemRepo; _banzuRepo = banzuRepo; _zgRepo = zgRepo; _gyzkRepo = gyzkRepo; } private static decimal Round2(decimal v) => Math.Round(v, 2); private async Task> GyzkDictAsync() => (await _gyzkRepo.GetAllAsync()).ToDictionary(x => x.Id, x => x.ZhuangKouName); // ==================== 选茧日报 ==================== public async Task> GetPagedAsync(DateTime? start, DateTime? end, string like, int pageIndex, int pageSize) { var all = await _xjrbRepo.GetAllAsync(); var q = all.AsQueryable(); if (start.HasValue) q = q.Where(x => x.Date.Date >= start.Value.Date); if (end.HasValue) q = q.Where(x => x.Date.Date <= end.Value.Date); var gyzkDict = await GyzkDictAsync(); if (!string.IsNullOrWhiteSpace(like)) { var key = like.Trim(); q = q.Where(x => x.GyzkId > 0 && gyzkDict.ContainsKey(x.GyzkId) && gyzkDict[x.GyzkId].Contains(key)); } var total = q.LongCount(); var items = q.OrderByDescending(x => x.Date).ThenByDescending(x => x.Id) .Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); return new PageResult { Items = items.Select(ToDto).ToList(), Total = total, PageIndex = pageIndex, PageSize = pageSize }; } private static XjrbListDto ToDto(XjrbRecord x) => new() { Id = x.Id, Date = x.Date, GyzkId = x.GyzkId, YlLrBaoshu = x.YlLrBaoshu, YlLrZhongliang = x.YlLrZhongliang, LtjBaoshu = x.LtjBaoshu, LtjZhongliang = x.LtjZhongliang, HwjjBaoshu = x.HwjjBaoshu, HwjjZhongliang = x.HwjjZhongliang, LjjBaoshu = x.LjjBaoshu, LjjZhongliang = x.LjjZhongliang, MjBaoshu = x.MjBaoshu, MjZhongliang = x.MjZhongliang, SgjBaoshu = x.SgjBaoshu, SgjZhongliang = x.SgjZhongliang, XjjBaoshu = x.XjjBaoshu, XjjZhongliang = x.XjjZhongliang, JyBaoshu = x.JyBaoshu, JyZhongliang = x.JyZhongliang, JhBaoshu = x.JhBaoshu, JhZhongliang = x.JhZhongliang, TotalZhongliang = x.TotalZhongliang, ThBaoshu = x.ThBaoshu, ThZhongliang = x.ThZhongliang, LiantongRate = x.LiantongRate, Yingkui = x.Yingkui }; public async Task GetByIdAsync(long id) { var x = await _xjrbRepo.GetByIdAsync(id); if (x == null) throw new ServiceException("选茧日报不存在", 404); return new XjrbSaveDto { Id = x.Id, Date = x.Date, GyzkId = x.GyzkId, YlLrBaoshu = x.YlLrBaoshu, YlLrZhongliang = x.YlLrZhongliang, LtjBaoshu = x.LtjBaoshu, LtjZhongliang = x.LtjZhongliang, HwjjBaoshu = x.HwjjBaoshu, HwjjZhongliang = x.HwjjZhongliang, LjjBaoshu = x.LjjBaoshu, LjjZhongliang = x.LjjZhongliang, MjBaoshu = x.MjBaoshu, MjZhongliang = x.MjZhongliang, SgjBaoshu = x.SgjBaoshu, SgjZhongliang = x.SgjZhongliang, XjjBaoshu = x.XjjBaoshu, XjjZhongliang = x.XjjZhongliang, JyBaoshu = x.JyBaoshu, JyZhongliang = x.JyZhongliang, JhBaoshu = x.JhBaoshu, JhZhongliang = x.JhZhongliang, ThBaoshu = x.ThBaoshu, ThZhongliang = x.ThZhongliang, LiantongRate = x.LiantongRate, Yingkui = x.Yingkui }; } public async Task SaveAsync(XjrbSaveDto dto) { if (dto.Date == default) throw new ServiceException("请选择选茧日期"); if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); XjrbRecord entity; var isNew = dto.Id == 0; if (isNew) entity = new XjrbRecord(); else { entity = await _xjrbRepo.GetByIdAsync(dto.Id); if (entity == null) throw new ServiceException("选茧日报不存在", 404); } entity.Date = dto.Date.Date; entity.GyzkId = dto.GyzkId; entity.YlLrBaoshu = dto.YlLrBaoshu; entity.YlLrZhongliang = dto.YlLrZhongliang; entity.LtjBaoshu = dto.LtjBaoshu; entity.LtjZhongliang = dto.LtjZhongliang; entity.HwjjBaoshu = dto.HwjjBaoshu; entity.HwjjZhongliang = dto.HwjjZhongliang; entity.LjjBaoshu = dto.LjjBaoshu; entity.LjjZhongliang = dto.LjjZhongliang; entity.MjBaoshu = dto.MjBaoshu; entity.MjZhongliang = dto.MjZhongliang; entity.SgjBaoshu = dto.SgjBaoshu; entity.SgjZhongliang = dto.SgjZhongliang; entity.XjjBaoshu = dto.XjjBaoshu; entity.XjjZhongliang = dto.XjjZhongliang; entity.JyBaoshu = dto.JyBaoshu; entity.JyZhongliang = dto.JyZhongliang; entity.JhBaoshu = dto.JhBaoshu; entity.JhZhongliang = dto.JhZhongliang; entity.ThBaoshu = dto.ThBaoshu; entity.ThZhongliang = dto.ThZhongliang; entity.LiantongRate = dto.LiantongRate; entity.Yingkui = dto.Yingkui; // 合计重量 = 8 类茧重量之和(不含退回、不含领入) entity.TotalZhongliang = Round2(entity.LtjZhongliang + entity.HwjjZhongliang + entity.LjjZhongliang + entity.MjZhongliang + entity.SgjZhongliang + entity.XjjZhongliang + entity.JyZhongliang + entity.JhZhongliang); if (isNew) await _xjrbRepo.AddAsync(entity); else await _xjrbRepo.UpdateAsync(entity); return entity.Id; } public async Task DeleteAsync(long id) { var x = await _xjrbRepo.GetByIdAsync(id); if (x == null) throw new ServiceException("选茧日报不存在", 404); await _xjrbRepo.HardDeleteAsync(x); } /// /// 计算盈亏 / 联统率(对齐 F9 GetXjrbCountYingkuiQuery + GetXjrbLingruStartDateQuery)。 /// 起始日期:由近及远跳过「联统率 = 0(未结算)」的日报,直到碰到已结算的一条为止; /// 累计区间 = [起始日期, 当前日期];累加当前录入值 + 区间内历史日报(排除自身)。 /// 联统率 = 累计联统茧重量 ÷ 累计干茧领入重量 × 100;盈亏 = 累计选出总重量 − 累计干茧领入重量。 /// public async Task CountYingkuiAsync(XjrbSaveDto dto) { if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var date = dto.Date.Date; var all = await _xjrbRepo.GetAllAsync(); var history = all.Where(x => x.GyzkId == dto.GyzkId && x.Date.Date < date && x.Id != dto.Id) .OrderByDescending(x => x.Date).ToList(); // 步骤 1:往回跳过未结算(LiantongRate == 0)的记录,确定起始日期 var startDate = date; foreach (var item in history) { if (item.LiantongRate != 0) break; startDate = item.Date.Date; } // 步骤 2:累计区间(闭区间,排除自身) var range = history.Where(x => x.Date.Date >= startDate && x.Date.Date <= date).ToList(); // 步骤 3:累加(初始值 = 当前表单输入值) decimal ltj = dto.LtjZhongliang; decimal yllr = dto.YlLrZhongliang; decimal allW = dto.LtjZhongliang + dto.HwjjZhongliang + dto.LjjZhongliang + dto.MjZhongliang + dto.SgjZhongliang + dto.XjjZhongliang + dto.JyZhongliang + dto.JhZhongliang; foreach (var item in range) { ltj += item.LtjZhongliang; yllr += item.YlLrZhongliang; allW += item.LtjZhongliang + item.HwjjZhongliang + item.LjjZhongliang + item.MjZhongliang + item.SgjZhongliang + item.XjjZhongliang + item.JyZhongliang + item.JhZhongliang; } // 步骤 4:公式 var rate = yllr != 0 ? Round2(ltj / yllr * 100) : 0; var yingkui = Round2(allW - yllr); return new XjrbYingkuiDto { LiantongRate = rate, Yingkui = yingkui, StartDate = startDate }; } // ==================== 选茧计划 ==================== public async Task> GetPlanPagedAsync(DateTime? start, DateTime? end, string like, int pageIndex, int pageSize) { var all = await _planRepo.GetAllAsync(); var q = all.AsQueryable(); if (start.HasValue) q = q.Where(x => x.Date.Date >= start.Value.Date); if (end.HasValue) q = q.Where(x => x.Date.Date <= end.Value.Date); var gyzkDict = await GyzkDictAsync(); if (!string.IsNullOrWhiteSpace(like)) { var key = like.Trim(); q = q.Where(x => x.GyzkId > 0 && gyzkDict.ContainsKey(x.GyzkId) && gyzkDict[x.GyzkId].Contains(key)); } var total = q.LongCount(); var items = q.OrderByDescending(x => x.Date).ThenByDescending(x => x.Id) .Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); return new PageResult { Items = items.Select(ToPlanDto).ToList(), Total = total, PageIndex = pageIndex, PageSize = pageSize }; } private static XjrbPlanListDto ToPlanDto(XjrbPlan x) => new() { Id = x.Id, Date = x.Date, GyzkId = x.GyzkId, YllingliaodanId = x.YllingliaodanId, YlBaoshu = x.YlBaoshu, YlZhongliang = x.YlZhongliang, LtjBaoshu = x.LtjBaoshu, LtjZhongliang = x.LtjZhongliang, HwjjBaoshu = x.HwjjBaoshu, HwjjZhongliang = x.HwjjZhongliang, WjjBaoshu = x.WjjBaoshu, WjjZhongliang = x.WjjZhongliang, SgjBaoshu = x.SgjBaoshu, SgjZhongliang = x.SgjZhongliang, XjjBaoshu = x.XjjBaoshu, XjjZhongliang = x.XjjZhongliang, JyBaoshu = x.JyBaoshu, JyZhongliang = x.JyZhongliang, JhBaoshu = x.JhBaoshu, JhZhongliang = x.JhZhongliang, TotalZhongliang = x.TotalZhongliang, LiantongRate = x.LiantongRate, Yingkui = x.Yingkui, IsFinish = x.IsFinish }; public async Task GetPlanByIdAsync(long id) { var x = await _planRepo.GetByIdAsync(id); if (x == null) throw new ServiceException("选茧计划不存在", 404); return new XjrbPlanSaveDto { Id = x.Id, Date = x.Date, GyzkId = x.GyzkId, YllingliaodanId = x.YllingliaodanId, YlBaoshu = x.YlBaoshu, YlZhongliang = x.YlZhongliang, LtjBaoshu = x.LtjBaoshu, LtjZhongliang = x.LtjZhongliang, HwjjBaoshu = x.HwjjBaoshu, HwjjZhongliang = x.HwjjZhongliang, WjjBaoshu = x.WjjBaoshu, WjjZhongliang = x.WjjZhongliang, SgjBaoshu = x.SgjBaoshu, SgjZhongliang = x.SgjZhongliang, XjjBaoshu = x.XjjBaoshu, XjjZhongliang = x.XjjZhongliang, JyBaoshu = x.JyBaoshu, JyZhongliang = x.JyZhongliang, JhBaoshu = x.JhBaoshu, JhZhongliang = x.JhZhongliang }; } public async Task SavePlanAsync(XjrbPlanSaveDto dto) { if (dto.Date == default) throw new ServiceException("请选择日期"); if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); XjrbPlan entity; var isNew = dto.Id == 0; if (isNew) entity = new XjrbPlan(); else { entity = await _planRepo.GetByIdAsync(dto.Id); if (entity == null) throw new ServiceException("选茧计划不存在", 404); if (entity.IsFinish) throw new ServiceException("该计划已选茧完成,不能修改"); } entity.Date = dto.Date.Date; entity.GyzkId = dto.GyzkId; entity.YllingliaodanId = dto.YllingliaodanId; entity.YlBaoshu = dto.YlBaoshu; entity.YlZhongliang = dto.YlZhongliang; entity.LtjBaoshu = dto.LtjBaoshu; entity.LtjZhongliang = dto.LtjZhongliang; entity.HwjjBaoshu = dto.HwjjBaoshu; entity.HwjjZhongliang = dto.HwjjZhongliang; entity.WjjBaoshu = dto.WjjBaoshu; entity.WjjZhongliang = dto.WjjZhongliang; entity.SgjBaoshu = dto.SgjBaoshu; entity.SgjZhongliang = dto.SgjZhongliang; entity.XjjBaoshu = dto.XjjBaoshu; entity.XjjZhongliang = dto.XjjZhongliang; entity.JyBaoshu = dto.JyBaoshu; entity.JyZhongliang = dto.JyZhongliang; entity.JhBaoshu = dto.JhBaoshu; entity.JhZhongliang = dto.JhZhongliang; entity.TotalZhongliang = Round2(entity.LtjZhongliang + entity.HwjjZhongliang + entity.WjjZhongliang + entity.SgjZhongliang + entity.XjjZhongliang + entity.JyZhongliang + entity.JhZhongliang); if (isNew) await _planRepo.AddAsync(entity); else await _planRepo.UpdateAsync(entity); return entity.Id; } public async Task DeletePlanAsync(long id) { var x = await _planRepo.GetByIdAsync(id); if (x == null) throw new ServiceException("选茧计划不存在", 404); if (x.IsFinish) throw new ServiceException("该计划已选茧完成,不能删除"); var items = await _itemRepo.FindAsync(i => i.XjrbPlanId == id); if (items.Count > 0) await _itemRepo.HardDeleteRangeAsync(items); await _planRepo.HardDeleteAsync(x); } // ==================== 选茧计划明细 ==================== public async Task> GetPlanItemsAsync(long planId) { var items = await _itemRepo.FindAsync(x => x.XjrbPlanId == planId); return items.OrderBy(x => x.Date).ThenBy(x => x.Id).Select(x => new XjrbItemDto { Id = x.Id, XjrbPlanId = x.XjrbPlanId, Date = x.Date, LtjBaoshu = x.LtjBaoshu, LtjZhongliang = x.LtjZhongliang, HwjjBaoshu = x.HwjjBaoshu, HwjjZhongliang = x.HwjjZhongliang, WjjBaoshu = x.WjjBaoshu, WjjZhongliang = x.WjjZhongliang, SgjBaoshu = x.SgjBaoshu, SgjZhongliang = x.SgjZhongliang, XjjBaoshu = x.XjjBaoshu, XjjZhongliang = x.XjjZhongliang, JyBaoshu = x.JyBaoshu, JyZhongliang = x.JyZhongliang, JhBaoshu = x.JhBaoshu, JhZhongliang = x.JhZhongliang, TotalZhongliang = x.TotalZhongliang, IsFinish = x.IsFinish }).ToList(); } public async Task SavePlanItemAsync(XjrbItemSaveDto dto) { if (dto.XjrbPlanId <= 0) throw new ServiceException("计划无效"); if (dto.Date == default) throw new ServiceException("请选择选茧日期"); var plan = await _planRepo.GetByIdAsync(dto.XjrbPlanId); if (plan == null) throw new ServiceException("选茧计划不存在", 404); if (plan.IsFinish) throw new ServiceException("该计划已选茧完成,不能修改明细"); XjrbItem entity; var isNew = dto.Id == 0; if (isNew) entity = new XjrbItem { XjrbPlanId = dto.XjrbPlanId }; else { entity = await _itemRepo.GetByIdAsync(dto.Id); if (entity == null) throw new ServiceException("选茧明细不存在", 404); } entity.Date = dto.Date.Date; entity.LtjBaoshu = dto.LtjBaoshu; entity.LtjZhongliang = dto.LtjZhongliang; entity.HwjjBaoshu = dto.HwjjBaoshu; entity.HwjjZhongliang = dto.HwjjZhongliang; entity.WjjBaoshu = dto.WjjBaoshu; entity.WjjZhongliang = dto.WjjZhongliang; entity.SgjBaoshu = dto.SgjBaoshu; entity.SgjZhongliang = dto.SgjZhongliang; entity.XjjBaoshu = dto.XjjBaoshu; entity.XjjZhongliang = dto.XjjZhongliang; entity.JyBaoshu = dto.JyBaoshu; entity.JyZhongliang = dto.JyZhongliang; entity.JhBaoshu = dto.JhBaoshu; entity.JhZhongliang = dto.JhZhongliang; entity.TotalZhongliang = Round2(entity.LtjZhongliang + entity.HwjjZhongliang + entity.WjjZhongliang + entity.SgjZhongliang + entity.XjjZhongliang + entity.JyZhongliang + entity.JhZhongliang); entity.IsFinish = dto.IsFinish; if (isNew) await _itemRepo.AddAsync(entity); else await _itemRepo.UpdateAsync(entity); // 勾选「选茧完成」时把盈亏回写计划(对齐 F9 UpdateXjrbPlanYingkuiCommand) if (dto.IsFinish) { var yk = await CountPlanYingkuiAsync(dto); plan.TotalZhongliang = Round2(plan.TotalZhongliang + entity.TotalZhongliang); plan.Yingkui = yk.Yingkui; plan.LiantongRate = yk.LiantongRate; plan.IsFinish = true; await _planRepo.UpdateAsync(plan); } return entity.Id; } public async Task DeletePlanItemAsync(long id) { var x = await _itemRepo.GetByIdAsync(id); if (x == null) throw new ServiceException("选茧明细不存在", 404); var plan = await _planRepo.GetByIdAsync(x.XjrbPlanId); if (plan != null && plan.IsFinish) throw new ServiceException("该计划已选茧完成,不能删除明细"); await _itemRepo.HardDeleteAsync(x); } /// /// 计划维度盈亏(对齐 F9 GetXjrbPlanYingkuiQuery,口径与日报不同): /// 联统率按「包数」:联统茧包数 ÷ 各类茧包数之和 × 100;盈亏 = 累计选出总重量 − 计划原料领入重量。 /// 注:老系统仓储里 wjjBaoshu / wjjZhongliang 源字段交叉写反(疑似 bug),此处已按正确字段聚合。 /// public async Task CountPlanYingkuiAsync(XjrbItemSaveDto dto) { var plan = await _planRepo.GetByIdAsync(dto.XjrbPlanId); if (plan == null) throw new ServiceException("选茧计划不存在", 404); var items = (await _itemRepo.FindAsync(x => x.XjrbPlanId == dto.XjrbPlanId && x.Id != dto.Id)).ToList(); decimal ltjZ = dto.LtjZhongliang, hwjjZ = dto.HwjjZhongliang, wjjZ = dto.WjjZhongliang, sgjZ = dto.SgjZhongliang, xjjZ = dto.XjjZhongliang, jyZ = dto.JyZhongliang, jhZ = dto.JhZhongliang; decimal ltjB = dto.LtjBaoshu, hwjjB = dto.HwjjBaoshu, wjjB = dto.WjjBaoshu, sgjB = dto.SgjBaoshu, xjjB = dto.XjjBaoshu, jyB = dto.JyBaoshu, jhB = dto.JhBaoshu; foreach (var it in items) { ltjZ += it.LtjZhongliang; hwjjZ += it.HwjjZhongliang; wjjZ += it.WjjZhongliang; sgjZ += it.SgjZhongliang; xjjZ += it.XjjZhongliang; jyZ += it.JyZhongliang; jhZ += it.JhZhongliang; ltjB += it.LtjBaoshu; hwjjB += it.HwjjBaoshu; wjjB += it.WjjBaoshu; sgjB += it.SgjBaoshu; xjjB += it.XjjBaoshu; jyB += it.JyBaoshu; jhB += it.JhBaoshu; } var totalZhongliang = Round2(ltjZ + hwjjZ + wjjZ + sgjZ + xjjZ + jyZ + jhZ); var baoshuSum = ltjB + hwjjB + wjjB + sgjB + xjjB + jyB + jhB; var rate = baoshuSum != 0 ? Round2(ltjB / (decimal)baoshuSum * 100) : 0; return new XjrbYingkuiDto { LiantongRate = rate, Yingkui = Round2(totalZhongliang - plan.YlZhongliang), StartDate = plan.Date }; } // ==================== 选茧班组 ==================== public async Task> GetBanzuPagedAsync(string banci, int? zu, int pageIndex, int pageSize) { var all = await _banzuRepo.GetAllAsync(); var q = all.AsQueryable(); if (!string.IsNullOrWhiteSpace(banci)) q = q.Where(x => x.Banci == banci); if (zu.HasValue) q = q.Where(x => x.Zu == zu.Value); var total = q.LongCount(); var items = q.OrderBy(x => x.Banci).ThenBy(x => x.Zu) .Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); return new PageResult { Items = items.Select(x => new XjpbBanzuDto { Id = x.Id, Banci = x.Banci, Zu = x.Zu }).ToList(), Total = total, PageIndex = pageIndex, PageSize = pageSize }; } public async Task> GetBanzuZhigongAsync(long banzuId) { if (banzuId <= 0) return new List(); var list = await _zgRepo.FindAsync(x => x.BanzuId == banzuId); return list.OrderBy(x => x.Sort).ThenBy(x => x.Id).Select(x => new XjpbBanzuZhigongDto { Id = x.Id, BanzuId = x.BanzuId, Banci = x.Banci, Zu = x.Zu, YgId = x.YgId, YgName = x.YgName, YgPhone = x.YgPhone, Sort = x.Sort }).ToList(); } /// /// 班组「编辑录入」批量保存(对齐 F9 XjpbBanzuZhigong_SaveCommand): /// 按班次整体覆盖——先清该班次旧职工与班组,再把「已勾选且有组别」的职工写入,并重建班组。 /// public async Task SaveBanzuZhigongAsync(List dtos) { var list = dtos ?? new List(); var banci = list.FirstOrDefault()?.Banci ?? ""; if (string.IsNullOrWhiteSpace(banci)) throw new ServiceException("班次无效"); // 清理该班次旧数据 var oldZg = await _zgRepo.FindAsync(x => x.Banci == banci); if (oldZg.Count > 0) await _zgRepo.HardDeleteRangeAsync(oldZg); var oldBanzu = await _banzuRepo.FindAsync(x => x.Banci == banci); if (oldBanzu.Count > 0) await _banzuRepo.HardDeleteRangeAsync(oldBanzu); var picked = list.Where(x => x.Selected && x.Zu > 0).ToList(); if (picked.Count == 0) return; // 重建班组(班次 + 组 去重) var banzuDict = new Dictionary(); foreach (var zu in picked.Select(x => x.Zu).Distinct().OrderBy(x => x)) { var banzu = new XjpbBanzu { Banci = banci, Zu = zu }; await _banzuRepo.AddAsync(banzu); banzuDict[zu] = banzu.Id; } var sort = 0; foreach (var p in picked) { await _zgRepo.AddAsync(new XjpbBanzuZhigong { BanzuId = banzuDict.TryGetValue(p.Zu, out var bid) ? bid : 0, Banci = banci, Zu = p.Zu, YgId = p.YgId, YgName = p.YgName ?? "", YgPhone = p.YgPhone ?? "", Sort = p.Sort > 0 ? p.Sort : ++sort }); } } }