using F9WebAiTest.Application.Common; using F9WebAiTest.Application.Dtos.QC; using F9WebAiTest.Domain.Common; using F9WebAiTest.Domain.Entities.Base; using F9WebAiTest.Domain.Entities.QC.Gyzxs; namespace F9WebAiTest.Application.Services.QC; public interface IGyzxsService { Task> GetDocVersionPagedAsync(int pageIndex, int pageSize, int year, string keyword); Task CreateDocVersionAsync(long gyzkId); Task DeleteDocVersionAsync(long id); Task GetFengMianAsync(long gyzkId); Task SaveFengMianAsync(GyzxsFengMian dto); Task GetShichanAsync(long gyzkId, string guige); Task SaveShichanAsync(GyzxsShichan dto); Task GetXbjAsync(long gyzkId); Task SaveXbjAsync(GyzxsXbjDto dto); Task GetXbjSsDyAsync(long gyzkId, string guige); Task SaveXbjSsDyAsync(GyzxsXbjSsDy dto); Task GetZhuJianAsync(long gyzkId); Task SaveZhuJianAsync(GyzxsZhuJianDto dto); Task GetZdsAsync(long gyzkId, string guige); Task SaveZdsAsync(GyzxsZdsDto dto); Task GetHsAsync(long gyzkId, string guige); Task SaveHsAsync(GyzxsHs dto); /// 报表数据(type: fengmian / gyzxs / xbj / shichan / ssdy / zhujian / zds / zdsdy) Task GetPrintDataAsync(string type, long gyzkId, string guige); } /// /// 质量模块 —— 工艺执行书(对应 F9 生产\质量\工艺执行书)。 /// 设计要点:以工艺庄口为主体,7 张子单据各自按「庄口(+规格)」唯一, /// 任一子单据保存都会 upsert 主控表 qc_gyzxs_doc_version 的对应指针列。 /// public class GyzxsService : IGyzxsService { private readonly IRepository _zkRepo; private readonly IRepository _versionRepo; private readonly IRepository _fengMianRepo; private readonly IRepository _shichanRepo; private readonly IRepository _xbjRepo; private readonly IRepository _hunjianRepo; private readonly IRepository _ssdyRepo; private readonly IRepository _zhuJianRepo; private readonly IRepository _zjCheJianRepo; private readonly IRepository _zjFuZhuRepo; private readonly IRepository _zdsRepo; private readonly IRepository _zdsDyRepo; private readonly IRepository _hsRepo; public GyzxsService( IRepository zkRepo, IRepository versionRepo, IRepository fengMianRepo, IRepository shichanRepo, IRepository xbjRepo, IRepository hunjianRepo, IRepository ssdyRepo, IRepository zhuJianRepo, IRepository zjCheJianRepo, IRepository zjFuZhuRepo, IRepository zdsRepo, IRepository zdsDyRepo, IRepository hsRepo) { _zkRepo = zkRepo; _versionRepo = versionRepo; _fengMianRepo = fengMianRepo; _shichanRepo = shichanRepo; _xbjRepo = xbjRepo; _hunjianRepo = hunjianRepo; _ssdyRepo = ssdyRepo; _zhuJianRepo = zhuJianRepo; _zjCheJianRepo = zjCheJianRepo; _zjFuZhuRepo = zjFuZhuRepo; _zdsRepo = zdsRepo; _zdsDyRepo = zdsDyRepo; _hsRepo = hsRepo; } // ==================== 主控(庄口年度列表) ==================== public async Task> GetDocVersionPagedAsync(int pageIndex, int pageSize, int year, string keyword) { if (year <= 0) year = DateTime.Today.Year; var zks = (await _zkRepo.FindAsync(x => !x.IsDeleted && x.BelongingYear == year)) .OrderBy(x => x.Sort).ThenBy(x => x.ZhuangKouCode).ToList(); if (!string.IsNullOrWhiteSpace(keyword)) zks = zks.Where(x => x.ZhuangKouName.Contains(keyword) || x.ZhuangKouCode.Contains(keyword) || x.ProductionDisplayName.Contains(keyword)).ToList(); var versions = (await _versionRepo.FindAsync(x => !x.IsDeleted)) .GroupBy(x => x.GyzkId).ToDictionary(g => g.Key, g => g.OrderByDescending(v => v.Id).First()); // 规格集合:来自试产 / 自动缫 / 后缫 / 试缫大样 var guigeMap = new Dictionary>(); void Collect(IEnumerable<(long GyzkId, string Guige)> rows) { foreach (var (gk, gg) in rows) { if (string.IsNullOrWhiteSpace(gg)) continue; if (!guigeMap.TryGetValue(gk, out var set)) guigeMap[gk] = set = new HashSet(); set.Add(gg); } } Collect((await _shichanRepo.FindAsync(x => !x.IsDeleted)).Select(x => (x.GyzkId, x.Guige))); Collect((await _zdsRepo.FindAsync(x => !x.IsDeleted)).Select(x => (x.GyzkId, x.Guige))); Collect((await _hsRepo.FindAsync(x => !x.IsDeleted)).Select(x => (x.GyzkId, x.Guige))); Collect((await _ssdyRepo.FindAsync(x => !x.IsDeleted)).Select(x => (x.GyzkId, x.Guige))); var total = zks.Count; var page = zks.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); return new PageResult { Total = total, PageIndex = pageIndex, PageSize = pageSize, Items = page.Select(zk => { versions.TryGetValue(zk.Id, out var v); guigeMap.TryGetValue(zk.Id, out var gs); return new GyzxsDocVersionDto { Id = v?.Id ?? 0, GyzkId = zk.Id, ZhuangKouName = zk.ZhuangKouName, ZhuangKouCode = zk.ZhuangKouCode, Year = zk.BelongingYear, Sort = zk.Sort, ShichanId = v?.ShichanId ?? 0, FengMianId = v?.FengMianId ?? 0, XbjId = v?.XbjId ?? 0, XbjSsdyId = v?.XbjSsdyId ?? 0, ZhuJianId = v?.ZhuJianId ?? 0, ZdsId = v?.ZdsId ?? 0, ZdsDyId = v?.ZdsDyId ?? 0, HsId = v?.HsId ?? 0, Guiges = gs?.OrderBy(x => x).ToList() ?? new List() }; }).ToList() }; } public async Task CreateDocVersionAsync(long gyzkId) { var zk = await _zkRepo.GetByIdAsync(gyzkId) ?? throw new ServiceException("工艺庄口不存在", 404); var exist = await _versionRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId); if (exist == null) { exist = new GyzxsDocVersion { GyzkId = gyzkId }; await _versionRepo.AddAsync(exist); } return new GyzxsDocVersionDto { Id = exist.Id, GyzkId = gyzkId, ZhuangKouName = zk.ZhuangKouName, ZhuangKouCode = zk.ZhuangKouCode, Year = zk.BelongingYear, Sort = zk.Sort }; } public async Task DeleteDocVersionAsync(long id) { var v = await _versionRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404); await _versionRepo.DeleteAsync(v); } /// 主控表 upsert:任一子单据保存后回写指针列 private async Task TouchVersionAsync(long gyzkId, Action apply) { var v = await _versionRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId); if (v == null) { v = new GyzxsDocVersion { GyzkId = gyzkId }; apply(v); await _versionRepo.AddAsync(v); } else { apply(v); await _versionRepo.UpdateAsync(v); } } // ==================== 封面 ==================== public async Task GetFengMianAsync(long gyzkId) { var exist = await _fengMianRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId); if (exist != null) return exist; // 新封面:按 F9 规则预生成编号 SJZ-{年度}-工艺-{序号} var zk = await _zkRepo.GetByIdAsync(gyzkId); var year = zk?.BelongingYear ?? DateTime.Today.Year; var prefix = $"SJZ-{year}-工艺-"; var used = (await _fengMianRepo.FindAsync(x => !x.IsDeleted)) .Where(x => x.BianHao != null && x.BianHao.StartsWith(prefix)); var max = 0; foreach (var f in used) { if (int.TryParse(f.BianHao.Substring(prefix.Length), out var n) && n > max) max = n; } return new GyzxsFengMian { GyzkId = gyzkId, BianHao = prefix + (max + 1), ShengChanCheJian = "" }; } public async Task SaveFengMianAsync(GyzxsFengMian dto) { if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var exist = await _fengMianRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == dto.GyzkId); var id = await UpsertAsync(_fengMianRepo, dto, exist); await TouchVersionAsync(dto.GyzkId, v => v.FengMianId = id); return true; } // ==================== 试产(试缫工艺单) ==================== public async Task GetShichanAsync(long gyzkId, string guige) => await _shichanRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId && x.Guige == (guige ?? "")) ?? new GyzxsShichan { GyzkId = gyzkId, Guige = guige ?? "" }; public async Task SaveShichanAsync(GyzxsShichan dto) { if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var exist = await _shichanRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == dto.GyzkId && x.Guige == (dto.Guige ?? "")); var id = await UpsertAsync(_shichanRepo, dto, exist); await TouchVersionAsync(dto.GyzkId, v => v.ShichanId = id); return true; } // ==================== 混剥选茧 ==================== public async Task GetXbjAsync(long gyzkId) { var e = await _xbjRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId); var dto = new GyzxsXbjDto { Xbj = e ?? new GyzxsXbj { GyzkId = gyzkId } }; if (e != null) dto.HunJian = (await _hunjianRepo.FindAsync(x => !x.IsDeleted && x.XbjId == e.Id)) .OrderBy(x => x.Sort).ThenBy(x => x.Id).ToList(); return dto; } public async Task SaveXbjAsync(GyzxsXbjDto dto) { if (dto.Xbj.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var exist = await _xbjRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == dto.Xbj.GyzkId); var id = await UpsertAsync(_xbjRepo, dto.Xbj, exist); var olds = await _hunjianRepo.FindAsync(x => x.XbjId == id); if (olds.Count > 0) await _hunjianRepo.HardDeleteRangeAsync(olds); var rows = dto.HunJian ?? new List(); for (var i = 0; i < rows.Count; i++) { rows[i].Id = 0; rows[i].XbjId = id; rows[i].Sort = i + 1; await _hunjianRepo.AddAsync(rows[i]); } await TouchVersionAsync(dto.Xbj.GyzkId, v => v.XbjId = id); return true; } // ==================== 试缫与大样 ==================== public async Task GetXbjSsDyAsync(long gyzkId, string guige) => await _ssdyRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId && x.Guige == (guige ?? "")) ?? new GyzxsXbjSsDy { GyzkId = gyzkId, Guige = guige ?? "" }; public async Task SaveXbjSsDyAsync(GyzxsXbjSsDy dto) { if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var exist = await _ssdyRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == dto.GyzkId && x.Guige == (dto.Guige ?? "")); var id = await UpsertAsync(_ssdyRepo, dto, exist); await TouchVersionAsync(dto.GyzkId, v => v.XbjSsdyId = id); return true; } // ==================== 煮茧 ==================== public async Task GetZhuJianAsync(long gyzkId) { var e = await _zhuJianRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId); var dto = new GyzxsZhuJianDto { ZhuJian = e ?? new GyzxsZhuJian { GyzkId = gyzkId } }; if (e != null) { dto.CheJian = (await _zjCheJianRepo.FindAsync(x => !x.IsDeleted && x.ZhuJianId == e.Id)) .OrderBy(x => x.Sort).ThenBy(x => x.Id).ToList(); dto.FuZhu = (await _zjFuZhuRepo.FindAsync(x => !x.IsDeleted && x.ZhuJianId == e.Id)) .OrderBy(x => x.Sort).ThenBy(x => x.Id).ToList(); } return dto; } public async Task SaveZhuJianAsync(GyzxsZhuJianDto dto) { if (dto.ZhuJian.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var exist = await _zhuJianRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == dto.ZhuJian.GyzkId); var id = await UpsertAsync(_zhuJianRepo, dto.ZhuJian, exist); var oldChe = await _zjCheJianRepo.FindAsync(x => x.ZhuJianId == id); if (oldChe.Count > 0) await _zjCheJianRepo.HardDeleteRangeAsync(oldChe); var che = dto.CheJian ?? new List(); for (var i = 0; i < che.Count; i++) { che[i].Id = 0; che[i].ZhuJianId = id; che[i].Sort = i + 1; await _zjCheJianRepo.AddAsync(che[i]); } var oldFz = await _zjFuZhuRepo.FindAsync(x => x.ZhuJianId == id); if (oldFz.Count > 0) await _zjFuZhuRepo.HardDeleteRangeAsync(oldFz); var fz = dto.FuZhu ?? new List(); for (var i = 0; i < fz.Count; i++) { fz[i].Id = 0; fz[i].ZhuJianId = id; fz[i].Sort = i + 1; await _zjFuZhuRepo.AddAsync(fz[i]); } await TouchVersionAsync(dto.ZhuJian.GyzkId, v => v.ZhuJianId = id); return true; } // ==================== 自动缫(含大样) ==================== public async Task GetZdsAsync(long gyzkId, string guige) { var e = await _zdsRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId && x.Guige == (guige ?? "")); var dto = new GyzxsZdsDto { Zds = e ?? new GyzxsZds { GyzkId = gyzkId, Guige = guige ?? "" } }; if (e != null) dto.Dyzl = await _zdsDyRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.ZdsId == e.Id); return dto; } public async Task SaveZdsAsync(GyzxsZdsDto dto) { if (dto.Zds.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var exist = await _zdsRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == dto.Zds.GyzkId && x.Guige == (dto.Zds.Guige ?? "")); var id = await UpsertAsync(_zdsRepo, dto.Zds, exist); var dy = dto.Dyzl; if (dy != null) { var oldDy = await _zdsDyRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.ZdsId == id); dy.ZdsId = id; dy.GyzkId = dto.Zds.GyzkId; if (string.IsNullOrWhiteSpace(dy.Guige)) dy.Guige = dto.Zds.Guige; var dyId = await UpsertAsync(_zdsDyRepo, dy, oldDy); await TouchVersionAsync(dto.Zds.GyzkId, v => v.ZdsDyId = dyId); } await TouchVersionAsync(dto.Zds.GyzkId, v => v.ZdsId = id); return true; } // ==================== 后缫(工艺执行书) ==================== public async Task GetHsAsync(long gyzkId, string guige) => await _hsRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == gyzkId && x.Guige == (guige ?? "")) ?? new GyzxsHs { GyzkId = gyzkId, Guige = guige ?? "", ZhiXingDate = DateTime.Today }; public async Task SaveHsAsync(GyzxsHs dto) { if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口"); var exist = await _hsRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.GyzkId == dto.GyzkId && x.Guige == (dto.Guige ?? "")); var id = await UpsertAsync(_hsRepo, dto, exist); await TouchVersionAsync(dto.GyzkId, v => v.HsId = id); return true; } // ==================== 报表数据 ==================== public async Task GetPrintDataAsync(string type, long gyzkId, string guige) { var zk = await _zkRepo.GetByIdAsync(gyzkId); var zkName = zk?.ZhuangKouName ?? ""; var dto = new GyzxsPrintDto { ReportName = type }; switch ((type ?? "").ToLowerInvariant()) { case "fengmian": { var e = await GetFengMianAsync(gyzkId); dto.Title = "桑蚕丝工艺设计书"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["编号"] = string.IsNullOrWhiteSpace(e.BianHao) ? $"SJZ-{zk?.BelongingYear ?? DateTime.Today.Year}-工艺" : e.BianHao; dto.Parameters["缫制规格"] = e.Guige; dto.Parameters["原料总量"] = $"{e.YuanLiaoZhongLiang:0.##}吨"; dto.Parameters["生产丝量"] = $"{e.ShengSiZhongLiang:0.##}吨"; dto.Parameters["缫制车间"] = e.ShengChanCheJian; dto.Parameters["生产时间"] = FormatRange(e.ShengChanStartDate, e.ShengChanEndDate); dto.Parameters["发送部门"] = e.FaSongBuMen; dto.Parameters["日期"] = DateTime.Today.ToString("yyyy年MM月dd日"); break; } case "gyzxs": // 后缫 = 工艺执行书 { var e = await GetHsAsync(gyzkId, guige); dto.Title = "工艺执行书"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["执行时间"] = e.ZhiXingDate?.ToString("yyyy/M/d") ?? ""; dto.Parameters["生丝规格"] = e.Guige; dto.Parameters["前缫生产车间"] = e.QianSaoCheJian; dto.Parameters["预缫天数"] = e.YuSaoTianShu; dto.Parameters["整理规格"] = e.ZhengLiGuiGe; // 生产指标 dto.Parameters["单产"] = e.SczbDanChan; dto.Parameters["日产"] = e.SczbRiChan; dto.Parameters["编丝量"] = e.SczbBianSiLiang; dto.Parameters["整检量"] = e.SczbZhengJianLiang; dto.Parameters["生产正品率"] = e.SczbShengChanZhengPinLv; dto.Parameters["商检正品率"] = e.SczbShangJianZhengPinLv; dto.Parameters["切断"] = e.SczbQieDuan; dto.Parameters["效率"] = e.SczbXiaoLv; dto.Parameters["编检品质疵点"] = e.SczbPinZhiCiDian; // 工艺条件及控制指标 dto.Parameters["车速"] = e.GyzbCheSu; dto.Parameters["小䈅待返时间"] = e.GyzbXiaoYuDaiFanShiJian; dto.Parameters["车间温度"] = e.GyzbCheJianWenDu; dto.Parameters["车间相对湿度"] = e.GyzbCheJianXiangDuiShiDu; dto.Parameters["车厢温度"] = e.GyzbCheXiangWenDu; dto.Parameters["车厢湿度"] = e.GyzbCheXiangShiDu; dto.Parameters["平衡室温度"] = e.GyzbPingHengShiWenDu; dto.Parameters["平衡室相对湿度"] = e.GyzbPingHengShiXiangDuiShiDu; dto.Parameters["小䈅给湿温度"] = e.GyzbXiaoYuGeiShiWenDu; dto.Parameters["小䈅丝片平衡时间"] = e.GyzbXiaoYuSiPianPingHengShiJian; dto.Parameters["真空度"] = e.GyzbZhenKongDu; dto.Parameters["抽气次数"] = e.GyzbChouQiCiShu; dto.Parameters["大䈅丝片平衡时间"] = e.GyzbDaYuSiPianPingHengShiJian; dto.Parameters["大䈅丝片回潮率"] = e.GyzbDaYuSiPianHuiChaoLv; dto.Parameters["生丝回潮率"] = e.GyzbShengSiHuiChaoLv; dto.Parameters["大䈅丝片宽度"] = e.GyzbDaYuSiPianKuanDu; dto.Parameters["屑丝对丝率"] = e.GyzbXieSiDuiSiLv; dto.Parameters["大䈅丝片疵点"] = e.GyzbDaYuSiPianCiDian; dto.Parameters["主要技术措施"] = e.JiShuCuoShi; dto.Parameters["设计"] = e.SheJiRen; dto.Parameters["审核"] = e.ShenHeRen; dto.Parameters["审批"] = e.PiFuRen; break; } case "xbj": { var e = await GetXbjAsync(gyzkId); var x = e.Xbj; dto.Title = "混剥选茧工艺执行书"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["换庄时间"] = x.HuanZhuangDate?.ToString("yyyy/M/d") ?? ""; dto.Parameters["缫制规格"] = x.Guige; dto.Parameters["缫制车间"] = x.CheJian; dto.Parameters["日产量"] = x.ScRiChanLiang; dto.Parameters["班产量"] = x.ScBanChanLiang; dto.Parameters["上车率"] = x.ScShangCheLv; dto.Parameters["联统茧率"] = x.ScLianTongLv; dto.Parameters["五级茧率"] = x.ScWuJiLv; dto.Parameters["下茧茧衣率"] = x.ScXiaJiaoLv; dto.Parameters["茧衣率"] = x.ScJianYiLv; dto.Parameters["技术措施要求"] = x.ScJiShuCuoShi; dto.Parameters["统号茧五级茧率"] = x.QcTongHaoWuJiLv; dto.Parameters["统号茧下茧率"] = x.QcTongHaoXiaJianLv; dto.Parameters["五级茧联统茧率"] = x.QcWuJiLianTongLv; dto.Parameters["五级茧下脚率"] = x.QcWuJiXiaJiaoLv; dto.Parameters["下脚茧联统率"] = x.QcXiaJiaoLianTongLv; dto.Parameters["下脚茧次茧率"] = x.QcXiaJiaoCiJianLv; dto.Parameters["好五茧组产量"] = x.QcZbHaoWuZuChanLiang; dto.Parameters["六级组产量"] = x.QcZbLiuJiZuChanLiang; dto.Parameters["棉茧组产量"] = x.QcZbMianJianZuChanLiang; dto.Parameters["下脚组产量"] = x.QcZbXiaJiaoZuChanLiang; dto.Parameters["双宫组产量"] = x.QcZbShuangGongZuChanLiang; dto.Parameters["公斤粒数"] = x.QcZbGongJinLiShu; dto.Parameters["剥光率"] = x.QcZbBaoGuangLv; dto.Parameters["质量控制茧衣率"] = x.QcZbJianYiLv; dto.Parameters["合计包数"] = e.HunJian.Sum(i => i.BaoShu); dto.Parameters["合计比例"] = e.HunJian.Sum(i => i.BiLi); dto.Parameters["合计混茧包数"] = e.HunJian.Sum(i => i.HunJianBaoShu); dto.Sub1 = e.HunJian.Select((i, idx) => new Dictionary { ["序号"] = idx + 1, ["庄别"] = i.ZhuangBie, ["总包数"] = i.BaoShu, ["比例"] = i.BiLi, ["混茧包数"] = i.HunJianBaoShu }).ToList(); break; } case "shichan": { var e = await GetShichanAsync(gyzkId, guige); dto.Title = "自动缫试缫工艺单"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["试缫日期"] = e.ScDate?.ToString("yyyy/M/d") ?? ""; dto.Parameters["换庄方式"] = e.HuanZhuangFangShi; dto.Parameters["规格"] = e.Guige; dto.Parameters["生产车间"] = e.ScCheJian; dto.Parameters["一茧丝长"] = e.YiJianSiChang; dto.Parameters["解舒率"] = e.JieShuLv; dto.Parameters["解舒丝长"] = e.JieShuSiChang; dto.Parameters["茧层率"] = e.JianCengLv; dto.Parameters["茧丝纤度"] = e.JianSiXianDu; dto.Parameters["解舒光折"] = e.JieShuGuangZhe; dto.Parameters["万吊"] = e.WanDiao; dto.Parameters["车速"] = e.ZdsCheSu; dto.Parameters["允许粒数"] = e.ZdsYunXuLiShu; dto.Parameters["缫折"] = e.ZdsSaoZhe; dto.Parameters["中心纤度"] = e.ZdsZhongXinXianDu; dto.Parameters["中心粒符率"] = e.ZdsZhongXinLiFuLv; dto.Parameters["缫丝温度"] = e.ZdsSaoSiWenDu; dto.Parameters["计算纤度"] = e.ZdsJiSuanXianDu; dto.Parameters["允许粒符率"] = e.ZdsYunXuLiFuLv; dto.Parameters["索绪温度"] = e.ZdsSuoXuWenDu; dto.Parameters["平均粒数"] = e.ZdsPingJunLiShu; dto.Parameters["白茧引绪"] = e.ZdsBaiJianYinXu; dto.Parameters["理绪温度"] = e.ZdsLiXuWenDu; dto.Parameters["中心粒数"] = e.ZdsZhongXinLiShu; dto.Parameters["给茧口宽度"] = e.ZdsGeiJianKouKuanDu; dto.Parameters["落丝笼数"] = e.ZdsLuoSiLongShu; dto.Parameters["笼茧粒数"] = e.ZdsLongJianLiShu; dto.Parameters["煮茧车速"] = e.ZjCheSu; dto.Parameters["蒸煮室温度"] = $"{e.ZjZhengZhuShi1}、{e.ZjZhengZhuShi2}、{e.ZjZhengZhuShi3}"; dto.Parameters["外层中层内层掉绪"] = $"{e.ZjLuoXuWai} {e.ZjLuoXuZhong} {e.ZjLuoXuNei}"; dto.Parameters["调整部温度"] = e.ZjTiaoZhengBuWenDu; dto.Parameters["出口温度"] = e.ZjChuKouWenDu; dto.Parameters["附煮车间"] = e.ZjFuZhuCheJian; dto.Parameters["附煮庄口"] = e.ZjFuZhuGyzkName; dto.Parameters["设计"] = e.SheJiRen; dto.Parameters["审核"] = e.ShenHeRen; dto.Parameters["审批"] = e.PiFuRen; break; } case "ssdy": { var e = await GetXbjSsDyAsync(gyzkId, guige); dto.Title = "(三)试缫与大样资料"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["规格"] = e.Guige; dto.Parameters["主要技术措施"] = e.JiShuCuoShi; dto.Parameters["设计"] = e.SheJiRen; dto.Parameters["审核"] = e.ShenHeRen; dto.Parameters["审批"] = e.PiFuRen; dto.Main = new List> { new() { ["项目"] = "试缫", ["上车率"] = e.SsShangCheLv, ["联统率"] = e.SsLianTongLv, ["次茧率"] = e.SsCiJianLv, ["次六级"] = e.SsCiLiuJiLv, ["棉茧率"] = e.SsMianJianLv, ["下脚率"] = e.SsXiaJiaoLv, ["双宫率"] = e.SsShuangGongLv, ["茧衣率"] = e.SsJianYiLv, ["400粒重"] = e.SsLiJianZhong, ["公斤粒数"] = e.SsGongJinLiShu }, new() { ["项目"] = "大样", ["上车率"] = e.DyShangCheLv, ["联统率"] = e.DyLianTongLv, ["次茧率"] = e.DyCiJianLv, ["次六级"] = e.DyCiLiuJiLv, ["棉茧率"] = e.DyMianJianLv, ["下脚率"] = e.DyXiaJiaoLv, ["双宫率"] = e.DyShuangGongLv, ["茧衣率"] = e.DyJianYiLv, ["400粒重"] = e.DyLiJianZhong, ["公斤粒数"] = e.DyGongJinLiShu } }; break; } case "zhujian": { var e = await GetZhuJianAsync(gyzkId); var z = e.ZhuJian; dto.Title = "煮茧工艺执行书"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["缫制规格"] = z.Guige; dto.Parameters["换庄时间"] = z.HuanZhuangDate?.ToString("yyyy/M/d") ?? ""; dto.Parameters["接缫方式"] = z.HuanZhuangFangShi; dto.Parameters["生产车间"] = z.CheJian; dto.Parameters["煮茧机号"] = z.ZhuJianJi; // 庄口原料性能 dto.Parameters["公斤粒数"] = z.YlGongJinLiShu; dto.Parameters["缩绉"] = z.YlSuoZhou; dto.Parameters["茧层率"] = z.YlJianCengLv; dto.Parameters["清洁"] = z.YlQingJie; dto.Parameters["净度"] = z.YlJingDu; dto.Parameters["粒茧丝长"] = z.YlLiJianSiChang; dto.Parameters["解舒率"] = z.YlJieShuLv; dto.Parameters["解舒丝长"] = z.YlJieShuSiChang; dto.Parameters["茧丝纤度"] = z.YlJianSiXianDu; dto.Parameters["万米吊糙"] = z.YlWanMiDiaoCao; dto.Parameters["解舒光折"] = z.YlJieShuGuangZhe; // 工艺技术指标 dto.Parameters["实缫解舒"] = z.GyzbJieShuLv; dto.Parameters["实缫万吊"] = z.GyzbWanDiao; dto.Parameters["工艺清洁"] = z.GyzbQingJie; dto.Parameters["工艺净度"] = z.GyzbJingDu; dto.Parameters["丝胶溶失率"] = z.GyzbSiJiaoRongShiLv; dto.Parameters["组落丝笼数"] = z.GyzbZuLuoSiLongShu; dto.Parameters["缫折"] = z.GyzbSaoZhe; dto.Parameters["笼茧粒数"] = z.GyzbLongJianLiShu; dto.Parameters["每桶茧量"] = z.GyzbMeiTongJianLiang; dto.Parameters["每包桶数"] = z.GyzbMeiBaoTongShu; dto.Parameters["每小时用茧笼数"] = z.GyzbMeiXiaoShiYongJianLong; dto.Parameters["条吐率"] = z.GyzbTiaoTuLv; // 真空渗透 dto.Parameters["真空度"] = z.ZkstZhenKongDu; dto.Parameters["吸水温度"] = z.ZkstXiShuiWenDu; dto.Parameters["达到最高真空度时长"] = z.ZkstDaZhenKongShiChang; dto.Parameters["液面到最高位时长"] = z.ZkstZuiGaoWeiShiChang; dto.Parameters["关水后继续真空时长"] = z.ZkstGuanShuiZhenKongShiChang; dto.Parameters["出茧温度"] = z.ZkstChuJianWenDu; dto.Parameters["全机回转时间"] = z.ZkstQuanJiHuiZhuanShiJian; dto.Parameters["主要技术措施"] = z.JiShuCuoShi; dto.Parameters["设计"] = z.SheJiRen; dto.Parameters["审核"] = z.ShenHeRen; dto.Parameters["审批"] = z.PiFuRen; dto.Sub1 = e.CheJian.Select(c => new Dictionary { ["车间"] = c.CheJian, ["低温渗透"] = c.DiWenShenTou, ["蒸煮室1"] = c.ZhengZhuShi1, ["蒸煮室2"] = c.ZhengZhuShi2, ["蒸煮室3"] = c.ZhengZhuShi3, ["调整部1"] = c.TiaoZhengBu1, ["调整部2"] = c.TiaoZhengBu2, ["调整部3"] = c.TiaoZhengBu3, ["调整部4"] = c.TiaoZhengBu4, ["调整部5"] = c.TiaoZhengBu5, ["出茧温度"] = c.ChuJianWenDu, ["全机回转时间"] = c.HuiZhuanShiJian }).ToList(); dto.Sub2 = e.FuZhu.Select(c => new Dictionary { ["附煮车间"] = c.CheJian, ["解舒"] = c.JieShuLv, ["万吊"] = c.WanDiao, ["缫折"] = c.SaoZhe, ["温度1"] = c.WenDu1, ["温度2"] = c.WenDu2, ["温度3"] = c.WenDu3, ["温度4"] = c.WenDu4, ["温度5"] = c.WenDu5 }).ToList(); break; } case "zds": { var e = await GetZdsAsync(gyzkId, guige); var z = e.Zds; dto.Title = "自动缫车间生产工艺执行书(表一)"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["接缫日期"] = z.HuanZhuangDate?.ToString("yyyy/M/d") ?? ""; dto.Parameters["换庄方式"] = z.HuanZhuangFangShi; dto.Parameters["规格"] = z.Guige; dto.Parameters["生产车间"] = z.CheJian; dto.Parameters["预缫天数"] = z.YuSaoTianShu; dto.Parameters["预缫丝量"] = z.YuSaoSiLiang; // 茧质概况 dto.Parameters["一茧丝长"] = z.ZgYiJianSiChang; dto.Parameters["解舒丝长"] = z.ZgJieShuSiChang; dto.Parameters["解舒率"] = z.ZgJieShuLv; dto.Parameters["茧丝纤度"] = z.ZgJianSiXianDu; dto.Parameters["解舒光折"] = z.ZgJieShuGuangZhe; dto.Parameters["万米吊糙"] = z.ZgWanMiDiaoCao; dto.Parameters["清洁分"] = z.ZgQingJie; dto.Parameters["洁净分"] = z.ZgJingDu; dto.Parameters["茧层率"] = z.ZgJianCengLv; dto.Parameters["茧丝纤度均方差"] = z.ZgXianDuJunFangCha; dto.Parameters["外三百回"] = z.ZgWaiSanBaiHui; dto.Parameters["中三百回"] = z.ZgZhongSanBaiHui; dto.Parameters["内三百回"] = z.ZgNeiSanBaiHui; dto.Parameters["最大开差"] = z.ZgZuiDaKaiCha; dto.Parameters["内外开差"] = z.ZgNeiWaiKaiCha; dto.Parameters["白色茧单纤"] = z.ZgBaiSeJianDanXian; dto.Parameters["灰色茧单纤"] = z.ZgHuiSeJianDanXian; dto.Parameters["红色茧单纤"] = z.ZgHongSeJianDanXian; dto.Parameters["落绪外"] = z.ZgLuoXuWai; dto.Parameters["落绪中"] = z.ZgLuoXuZhong; dto.Parameters["落绪内"] = z.ZgLuoXuNei; dto.Parameters["平均茧幅"] = z.ZgPingJunJianFu; dto.Parameters["茧幅整齐率"] = z.ZgJianFuZhengQiLv; dto.Parameters["茧丝百回纤度"] = z.ZgJianSiBaiHuiXianDu; // 生产指标 dto.Parameters["品味"] = z.SczbPinWei; dto.Parameters["缫折"] = z.SczbSaoZhe; dto.Parameters["台产"] = z.SczbTaiChan; dto.Parameters["偏差"] = z.SczbPianCha; dto.Parameters["总差"] = z.SczbZongCha; dto.Parameters["清洁"] = z.SczbQingJie; dto.Parameters["洁净"] = z.SczbJingJie; dto.Parameters["匀二变化"] = z.SczbYunEr; dto.Parameters["生产正品率"] = z.SczbZhengPinLv; // 工艺技术指标 dto.Parameters["车速"] = z.GyzbCheSu; dto.Parameters["添绪次数"] = z.GyzbTianXuCiShu; dto.Parameters["运转率"] = z.GyzbYunZhuanLv; dto.Parameters["中心纤度"] = z.GyzbZhongXinXianDu; dto.Parameters["设计单纤度"] = z.GyzbSheJiDanXianDu; dto.Parameters["平均粒数"] = z.GyzbPingJunLiShu; dto.Parameters["中心粒数"] = z.GyzbZhongXinLiShu; dto.Parameters["允许粒数"] = z.GyzbYunXuLiShu; dto.Parameters["引绪"] = z.GyzbYinXu; dto.Parameters["中心粒符率"] = z.GyzbZhongXinLiFuLv; dto.Parameters["允许粒符率"] = z.GyzbYunXuLiFuLv; dto.Parameters["给茧口宽度"] = z.GyzbGeiJianKouKuanDu; dto.Parameters["条吐率"] = z.GyzbTiaoTuLv; dto.Parameters["丝鞘长度"] = z.GyzbSiQiaoChangDu; dto.Parameters["车头汽压"] = z.GyzbCheTouQiYa; dto.Parameters["索绪温度"] = z.GyzbSuoXuWenDu; dto.Parameters["理绪温度"] = z.GyzbLiXuWenDu; dto.Parameters["偏心盘茧量"] = z.GyzbPianXinPanJianLiang; dto.Parameters["缫汤温度"] = z.GyzbSaoTangWenDu; dto.Parameters["加茧口茧量"] = z.GyzbJiaJianKouJianLiang; dto.Parameters["无绪率"] = z.GyzbWuXuLv; dto.Parameters["蓬糙茧率"] = z.GyzbPengCaoJianLv; dto.Parameters["加茧均匀率"] = z.GyzbJiaJianJunYunLv; dto.Parameters["正确添绪率"] = z.GyzbZhengQueTianXuLv; dto.Parameters["桶茧量"] = z.GyzbTongJianLiang; dto.Parameters["落丝笼数"] = z.GyzbLuoSiLongShu; dto.Parameters["设计"] = z.SheJiRen; dto.Parameters["审核"] = z.ShenHeRen; dto.Parameters["审批"] = z.PiFuRen; break; } case "zdsdy": { var e = await GetZdsAsync(gyzkId, guige); var d = e.Dyzl ?? new GyzxsZdsDyzl { GyzkId = gyzkId, Guige = guige ?? "" }; dto.Title = "自动缫大样(表二)"; dto.Parameters["庄口名称"] = zkName; dto.Parameters["规格"] = d.Guige; dto.Parameters["偏差"] = d.PianCha; dto.Parameters["清洁"] = d.QingJie; dto.Parameters["净度"] = d.JingDu; dto.Parameters["解舒率"] = d.JieShuLv; dto.Parameters["万米吊糙"] = d.WanMiDiaoCao; dto.Parameters["缫折"] = d.SaoZhe; dto.Parameters["技术措施及要求"] = d.JiShuCuoShi; dto.Parameters["设计"] = d.SheJiRen; dto.Parameters["审核"] = d.ShenHeRen; dto.Parameters["审批"] = d.PiFuRen; break; } default: throw new ServiceException($"未知的报表类型:{type}"); } return dto; } // ==================== 内部工具 ==================== private static async Task UpsertAsync(IRepository repo, T dto, T? exist) where T : class, IEntity { if (exist == null) { dto.Id = 0; dto.IsDeleted = false; await repo.AddAsync(dto); return dto.Id; } dto.Id = exist.Id; dto.CreatedAt = exist.CreatedAt; dto.IsDeleted = false; await repo.UpdateAsync(dto); return dto.Id; } private static string FormatRange(DateTime? start, DateTime? end) { if (start == null && end == null) return ""; var s = start?.ToString("yy年M月d日") ?? ""; var e2 = end?.ToString("yy年M月d日") ?? ""; return string.IsNullOrEmpty(e2) ? s : $"{s}-{e2}"; } }