Files
f9-web-ai-test/backend/F9WebAiTest.Application/Services/QC/YjssService.cs
T
yanpeng200212 a8890c81e9 新增质量模块(工艺执行书 / 样茧试缫)与报表中心
质量模块:
- 11 张工艺执行书表:封面、试产、选剥茧(含混茧明细)、试缫与大样、煮茧(含分车间配温、副煮车间)、自动缫(含大样)、后缫
- 10 张样茧试缫表:原料小样/综合样主表 + 选茧、解舒、茧幅、切剖、清洁洁净、茧丝百回纤度
- 服务与接口、主控指针回写(列表 √ 标记)、封面编号自增、报表数据包
- 前端 8 张报表打印版式、7 类工艺单据与 6 类调查录入弹窗、字段驱动表单/表格组件
- 菜单种子新增「质量」目录,样茧子表增加 YjssType 判别列,避免原料小样与综合样自增 Id 重号串数据

报表中心:
- 报表模板管理、锐浪 grhtml5 加载与预览、全屏设计面板、数据源 Provider(落丝记录、职工花名册)

其他:同步工作进度 1-11 文档、开发数据库快照、.gitignore 忽略运行日志目录
2026-10-22 10:30:37 +08:00

552 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using F9WebAiTest.Application.Common;
using F9WebAiTest.Application.Dtos.QC;
using F9WebAiTest.Domain.Common;
using F9WebAiTest.Domain.Entities.Base;
using F9WebAiTest.Domain.Entities.QC.Yjss;
using F9WebAiTest.Domain.Entities.SYS.YuanliaoZhuangkous;
namespace F9WebAiTest.Application.Services.QC;
public interface IYjssService
{
Task<PageResult<YjssListItemDto>> GetPagedAsync(int pageIndex, int pageSize, int type, int year, string keyword);
Task<YjssListItemDto> SaveYlxyAsync(YjssMainYlxy dto);
Task<YjssListItemDto> SaveZhyAsync(YjssMainZhy dto);
Task DeleteAsync(int type, long id);
Task<YjssDcXjdc> GetXjdcAsync(int type, long yjssId);
Task<bool> SaveXjdcAsync(int type, YjssDcXjdc dto);
Task<List<YjssDcJsdc>> GetJsdcAsync(int type, long yjssId);
Task<bool> SaveJsdcAsync(int type, YjssDcJsdc dto);
Task DeleteJsdcAsync(int type, long id);
Task<YjssJfdcDto> GetJfdcAsync(int type, long yjssId);
Task<bool> SaveJfdcAsync(int type, YjssJfdcDto dto);
Task<YjssDcQpdc> GetQpdcAsync(int type, long yjssId);
Task<bool> SaveQpdcAsync(int type, YjssDcQpdc dto);
Task<YjssDcQjjj> GetQjjjAsync(int type, long yjssId);
Task<bool> SaveQjjjAsync(int type, YjssDcQjjj dto);
Task<YjssJsbhxdDto> GetJsbhxdAsync(int type, long yjssId);
Task<bool> SaveJsbhxdAsync(int type, YjssJsbhxdDto dto);
/// <summary>整页数据(含报表参数区):用于「综合样报表 / 原料小样报表 / 解舒调查报表」</summary>
Task<YjssFullDto> GetFullAsync(int type, long yjssId);
/// <summary>解舒调查平均值汇总(跨多条记录,口径对齐 F9 GetDataByYjssCommand)</summary>
Task<Dictionary<string, object?>> GetJsdcSummaryAsync(int type, long yjssId);
}
/// <summary>
/// 质量模块 —— 样茧试缫(对应 F9 生产\质量\样茧试缫)。
/// 两类样品:原料小样(选茧 / 解舒 / 清洁洁净)、综合样(加 茧幅 / 切剖 / 茧丝百回纤度)。
/// 子表统一外键 yjss_id;一对一子表保存后回写主表指针,解舒/百回纤度回写记录数。
/// </summary>
public class YjssService : IYjssService
{
private readonly IRepository<YjssMainYlxy> _ylxyRepo;
private readonly IRepository<YjssMainZhy> _zhyRepo;
private readonly IRepository<YjssDcXjdc> _xjdcRepo;
private readonly IRepository<YjssDcJsdc> _jsdcRepo;
private readonly IRepository<YjssDcJfdcMain> _jfdcRepo;
private readonly IRepository<YjssDcJfdcItem> _jfdcItemRepo;
private readonly IRepository<YjssDcQpdc> _qpdcRepo;
private readonly IRepository<YjssDcQjjj> _qjjjRepo;
private readonly IRepository<YjssDcJsbhxdMain> _jsbhxdMainRepo;
private readonly IRepository<YjssDcJsbhxd> _jsbhxdRepo;
private readonly IRepository<YuanliaoZhuangkou> _ylzkRepo;
private readonly IRepository<CraftZhuangKou> _gyzkRepo;
public YjssService(
IRepository<YjssMainYlxy> ylxyRepo,
IRepository<YjssMainZhy> zhyRepo,
IRepository<YjssDcXjdc> xjdcRepo,
IRepository<YjssDcJsdc> jsdcRepo,
IRepository<YjssDcJfdcMain> jfdcRepo,
IRepository<YjssDcJfdcItem> jfdcItemRepo,
IRepository<YjssDcQpdc> qpdcRepo,
IRepository<YjssDcQjjj> qjjjRepo,
IRepository<YjssDcJsbhxdMain> jsbhxdMainRepo,
IRepository<YjssDcJsbhxd> jsbhxdRepo,
IRepository<YuanliaoZhuangkou> ylzkRepo,
IRepository<CraftZhuangKou> gyzkRepo)
{
_ylxyRepo = ylxyRepo;
_zhyRepo = zhyRepo;
_xjdcRepo = xjdcRepo;
_jsdcRepo = jsdcRepo;
_jfdcRepo = jfdcRepo;
_jfdcItemRepo = jfdcItemRepo;
_qpdcRepo = qpdcRepo;
_qjjjRepo = qjjjRepo;
_jsbhxdMainRepo = jsbhxdMainRepo;
_jsbhxdRepo = jsbhxdRepo;
_ylzkRepo = ylzkRepo;
_gyzkRepo = gyzkRepo;
}
private static string SampleTypeName(int t) => t switch
{
1 => "定价抽样",
2 => "入库抽样",
3 => "鲜茧抽样",
_ => ""
};
// ==================== 主表 ====================
public async Task<PageResult<YjssListItemDto>> GetPagedAsync(int pageIndex, int pageSize, int type, int year, string keyword)
{
if (year <= 0) year = DateTime.Today.Year;
var items = new List<YjssListItemDto>();
var ylzks = (await _ylzkRepo.FindAsync(x => !x.IsDeleted)).ToDictionary(x => x.Id, x => x.Name);
var gyzks = (await _gyzkRepo.FindAsync(x => !x.IsDeleted)).ToDictionary(x => x.Id, x => x.ZhuangKouName);
if (type == 1)
{
var rows = await _ylxyRepo.FindAsync(x => !x.IsDeleted && x.Date.Year == year);
items = rows.Select(x => new YjssListItemDto
{
Id = x.Id, Type = 1, ZhuangKouId = x.YlzkId,
ZhuangKouName = ylzks.GetValueOrDefault(x.YlzkId, ""),
Date = x.Date, SampleType = x.Type, SampleTypeName = SampleTypeName(x.Type),
ZhongLiang = x.ZhongLiang, HuiChaoLv = x.HuiChaoLv,
XjdcId = x.XjdcId, JsdcCt = x.JsdcCt, QjjjId = x.QjjjId, Memo = x.Memo
}).ToList();
}
else
{
var rows = await _zhyRepo.FindAsync(x => !x.IsDeleted && x.Date.Year == year);
items = rows.Select(x => new YjssListItemDto
{
Id = x.Id, Type = 2, ZhuangKouId = x.GyzkId,
ZhuangKouName = gyzks.GetValueOrDefault(x.GyzkId, ""),
Date = x.Date, SampleType = 2, SampleTypeName = "综合样",
ZhongLiang = x.ZhongLiang, XjdcId = x.XjdcId, JsdcCt = x.JsdcCt,
JfdcId = x.JfdcId, QpdcId = x.QpdcId, QjjjId = x.QjjjId,
JsbhxdCt = x.JsbhxdCt, Memo = x.Memo
}).ToList();
}
if (!string.IsNullOrWhiteSpace(keyword))
items = items.Where(x => x.ZhuangKouName.Contains(keyword)).ToList();
items = items.OrderByDescending(x => x.Date).ThenByDescending(x => x.Id).ToList();
var total = items.Count;
return new PageResult<YjssListItemDto>
{
Total = total, PageIndex = pageIndex, PageSize = pageSize,
Items = items.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()
};
}
public async Task<YjssListItemDto> SaveYlxyAsync(YjssMainYlxy dto)
{
if (dto.YlzkId <= 0) throw new ServiceException("请选择原料庄口");
if (dto.Date == default) dto.Date = DateTime.Today;
var exist = dto.Id > 0 ? await _ylxyRepo.GetByIdAsync(dto.Id) : null;
if (exist == null)
{
dto.Id = 0; dto.IsDeleted = false;
await _ylxyRepo.AddAsync(dto);
}
else
{
dto.CreatedAt = exist.CreatedAt; dto.IsDeleted = false;
await _ylxyRepo.UpdateAsync(dto);
}
var name = (await _ylzkRepo.GetByIdAsync(dto.YlzkId))?.Name ?? "";
return new YjssListItemDto
{
Id = dto.Id, Type = 1, ZhuangKouId = dto.YlzkId, ZhuangKouName = name,
Date = dto.Date, SampleType = dto.Type, SampleTypeName = SampleTypeName(dto.Type),
ZhongLiang = dto.ZhongLiang, HuiChaoLv = dto.HuiChaoLv,
XjdcId = dto.XjdcId, JsdcCt = dto.JsdcCt, QjjjId = dto.QjjjId, Memo = dto.Memo
};
}
public async Task<YjssListItemDto> SaveZhyAsync(YjssMainZhy dto)
{
if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口");
if (dto.Date == default) dto.Date = DateTime.Today;
var exist = dto.Id > 0 ? await _zhyRepo.GetByIdAsync(dto.Id) : null;
if (exist == null)
{
dto.Id = 0; dto.IsDeleted = false;
await _zhyRepo.AddAsync(dto);
}
else
{
dto.CreatedAt = exist.CreatedAt; dto.IsDeleted = false;
await _zhyRepo.UpdateAsync(dto);
}
var name = (await _gyzkRepo.GetByIdAsync(dto.GyzkId))?.ZhuangKouName ?? "";
return new YjssListItemDto
{
Id = dto.Id, Type = 2, ZhuangKouId = dto.GyzkId, ZhuangKouName = name,
Date = dto.Date, SampleType = 2, SampleTypeName = "综合样",
ZhongLiang = dto.ZhongLiang, XjdcId = dto.XjdcId, JsdcCt = dto.JsdcCt,
JfdcId = dto.JfdcId, QpdcId = dto.QpdcId, QjjjId = dto.QjjjId,
JsbhxdCt = dto.JsbhxdCt, Memo = dto.Memo
};
}
public async Task DeleteAsync(int type, long id)
{
if (type == 1)
{
var e = await _ylxyRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404);
await _ylxyRepo.DeleteAsync(e);
}
else
{
var e = await _zhyRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404);
await _zhyRepo.DeleteAsync(e);
}
// 连带软删除子单据(按 主表 Id + 样品类型 精确定位)
foreach (var x in await _xjdcRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _xjdcRepo.DeleteAsync(x);
foreach (var x in await _jsdcRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _jsdcRepo.DeleteAsync(x);
foreach (var x in await _jfdcItemRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _jfdcItemRepo.DeleteAsync(x);
foreach (var x in await _jfdcRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _jfdcRepo.DeleteAsync(x);
foreach (var x in await _qpdcRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _qpdcRepo.DeleteAsync(x);
foreach (var x in await _qjjjRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _qjjjRepo.DeleteAsync(x);
foreach (var x in await _jsbhxdRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _jsbhxdRepo.DeleteAsync(x);
foreach (var x in await _jsbhxdMainRepo.FindAsync(x => !x.IsDeleted && x.YjssId == id && x.YjssType == type)) await _jsbhxdMainRepo.DeleteAsync(x);
}
// ==================== 选茧调查 ====================
public async Task<YjssDcXjdc> GetXjdcAsync(int type, long yjssId)
=> await _xjdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type)
?? new YjssDcXjdc { YjssId = yjssId, YjssType = type };
public async Task<bool> SaveXjdcAsync(int type, YjssDcXjdc dto)
{
dto.YjssType = type;
var exist = await _xjdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == dto.YjssId && x.YjssType == type);
var id = await UpsertAsync(_xjdcRepo, dto, exist);
await SetParentPointerAsync(type, dto.YjssId, xjdcId: id, qjjjId: null, jfdcId: null, qpdcId: null, jsdcCt: null, jsbhxdCt: null);
return true;
}
// ==================== 解舒调查(多条) ====================
public async Task<List<YjssDcJsdc>> GetJsdcAsync(int type, long yjssId)
=> (await _jsdcRepo.FindAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type))
.OrderBy(x => x.XuHao).ThenBy(x => x.Id).ToList();
public async Task<bool> SaveJsdcAsync(int type, YjssDcJsdc dto)
{
dto.YjssType = type;
var exist = dto.Id > 0 ? await _jsdcRepo.GetByIdAsync(dto.Id) : null;
if (exist == null)
{
dto.Id = 0; dto.IsDeleted = false;
if (dto.XuHao <= 0) dto.XuHao = (await GetJsdcAsync(type, dto.YjssId)).Count + 1;
await _jsdcRepo.AddAsync(dto);
}
else
{
dto.CreatedAt = exist.CreatedAt; dto.IsDeleted = false;
await _jsdcRepo.UpdateAsync(dto);
}
var ct = (await _jsdcRepo.FindAsync(x => !x.IsDeleted && x.YjssId == dto.YjssId && x.YjssType == type)).Count;
await SetParentPointerAsync(type, dto.YjssId, null, null, null, null, ct, null);
return true;
}
public async Task DeleteJsdcAsync(int type, long id)
{
var e = await _jsdcRepo.GetByIdAsync(id) ?? throw new ServiceException("记录不存在", 404);
await _jsdcRepo.DeleteAsync(e);
var ct = (await _jsdcRepo.FindAsync(x => !x.IsDeleted && x.YjssId == e.YjssId && x.YjssType == e.YjssType)).Count;
await SetParentPointerAsync(type, e.YjssId, null, null, null, null, ct, null);
}
// ==================== 茧幅调查 ====================
public async Task<YjssJfdcDto> GetJfdcAsync(int type, long yjssId)
{
var main = await _jfdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type);
var dto = new YjssJfdcDto { Main = main ?? new YjssDcJfdcMain { YjssId = yjssId, YjssType = type } };
if (main != null)
dto.Items = (await _jfdcItemRepo.FindAsync(x => !x.IsDeleted && x.JfdcId == main.Id))
.OrderBy(x => x.Sort).ThenBy(x => x.JianFu).ToList();
return dto;
}
public async Task<bool> SaveJfdcAsync(int type, YjssJfdcDto dto)
{
dto.Main.YjssType = type;
var exist = await _jfdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == dto.Main.YjssId && x.YjssType == type);
var id = await UpsertAsync(_jfdcRepo, dto.Main, exist);
var olds = await _jfdcItemRepo.FindAsync(x => x.JfdcId == id);
if (olds.Count > 0) await _jfdcItemRepo.HardDeleteRangeAsync(olds);
var rows = dto.Items ?? new List<YjssDcJfdcItem>();
for (var i = 0; i < rows.Count; i++)
{
rows[i].Id = 0; rows[i].JfdcId = id; rows[i].YjssId = dto.Main.YjssId;
rows[i].YjssType = type; rows[i].Sort = i + 1;
await _jfdcItemRepo.AddAsync(rows[i]);
}
await SetParentPointerAsync(type, dto.Main.YjssId, null, null, id, null, null, null);
return true;
}
// ==================== 切剖调查 ====================
public async Task<YjssDcQpdc> GetQpdcAsync(int type, long yjssId)
=> await _qpdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type)
?? new YjssDcQpdc { YjssId = yjssId, YjssType = type };
public async Task<bool> SaveQpdcAsync(int type, YjssDcQpdc dto)
{
dto.YjssType = type;
var exist = await _qpdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == dto.YjssId && x.YjssType == type);
var id = await UpsertAsync(_qpdcRepo, dto, exist);
await SetParentPointerAsync(type, dto.YjssId, null, null, null, id, null, null);
return true;
}
// ==================== 清洁洁净 ====================
public async Task<YjssDcQjjj> GetQjjjAsync(int type, long yjssId)
=> await _qjjjRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type)
?? new YjssDcQjjj { YjssId = yjssId, YjssType = type };
public async Task<bool> SaveQjjjAsync(int type, YjssDcQjjj dto)
{
dto.YjssType = type;
var exist = await _qjjjRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == dto.YjssId && x.YjssType == type);
var id = await UpsertAsync(_qjjjRepo, dto, exist);
await SetParentPointerAsync(type, dto.YjssId, null, id, null, null, null, null);
return true;
}
// ==================== 茧丝百回纤度 ====================
public async Task<YjssJsbhxdDto> GetJsbhxdAsync(int type, long yjssId)
{
var main = await _jsbhxdMainRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type);
var dto = new YjssJsbhxdDto { Main = main ?? new YjssDcJsbhxdMain { YjssId = yjssId, YjssType = type } };
if (main != null)
dto.Items = (await _jsbhxdRepo.FindAsync(x => !x.IsDeleted && x.JsbhxdMainId == main.Id))
.OrderBy(x => x.HuiShu).ToList();
return dto;
}
public async Task<bool> SaveJsbhxdAsync(int type, YjssJsbhxdDto dto)
{
dto.Main.YjssType = type;
var exist = await _jsbhxdMainRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == dto.Main.YjssId && x.YjssType == type);
var id = await UpsertAsync(_jsbhxdMainRepo, dto.Main, exist);
var olds = await _jsbhxdRepo.FindAsync(x => x.JsbhxdMainId == id);
if (olds.Count > 0) await _jsbhxdRepo.HardDeleteRangeAsync(olds);
var rows = dto.Items ?? new List<YjssDcJsbhxd>();
for (var i = 0; i < rows.Count; i++)
{
rows[i].Id = 0; rows[i].JsbhxdMainId = id; rows[i].YjssId = dto.Main.YjssId;
rows[i].YjssType = type; rows[i].Sort = i + 1;
await _jsbhxdRepo.AddAsync(rows[i]);
}
await SetParentPointerAsync(type, dto.Main.YjssId, null, null, null, null, null, rows.Count);
return true;
}
// ==================== 整页 / 报表 ====================
public async Task<YjssFullDto> GetFullAsync(int type, long yjssId)
{
var dto = new YjssFullDto { Type = type };
if (type == 1)
{
var m = await _ylxyRepo.GetByIdAsync(yjssId) ?? throw new ServiceException("原料小样不存在", 404);
dto.ZhuangKouName = (await _ylzkRepo.GetByIdAsync(m.YlzkId))?.Name ?? "";
dto.Date = m.Date; dto.ZhongLiang = m.ZhongLiang; dto.HuiChaoLv = m.HuiChaoLv;
dto.SampleTypeName = SampleTypeName(m.Type); dto.Memo = m.Memo;
}
else
{
var m = await _zhyRepo.GetByIdAsync(yjssId) ?? throw new ServiceException("综合样不存在", 404);
dto.ZhuangKouName = (await _gyzkRepo.GetByIdAsync(m.GyzkId))?.ZhuangKouName ?? "";
dto.Date = m.Date; dto.ZhongLiang = m.ZhongLiang; dto.SampleTypeName = "综合样"; dto.Memo = m.Memo;
}
var xjdc = await _xjdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type);
if (xjdc != null) dto.Xjdc = xjdc;
dto.Jsdc = await GetJsdcAsync(type, yjssId);
var jfdcMain = await _jfdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type);
if (jfdcMain != null)
dto.Jfdc = new YjssJfdcDto
{
Main = jfdcMain,
Items = (await _jfdcItemRepo.FindAsync(x => !x.IsDeleted && x.JfdcId == jfdcMain.Id)).OrderBy(x => x.JianFu).ToList()
};
dto.Qpdc = await _qpdcRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type);
dto.Qjjj = await _qjjjRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type);
var bhMain = await _jsbhxdMainRepo.FirstOrDefaultAsync(x => !x.IsDeleted && x.YjssId == yjssId && x.YjssType == type);
if (bhMain != null)
dto.Jsbhxd = new YjssJsbhxdDto
{
Main = bhMain,
Items = (await _jsbhxdRepo.FindAsync(x => !x.IsDeleted && x.JsbhxdMainId == bhMain.Id)).OrderBy(x => x.HuiShu).ToList()
};
BuildParameters(dto);
return dto;
}
public async Task<Dictionary<string, object?>> GetJsdcSummaryAsync(int type, long yjssId)
{
var list = await GetJsdcAsync(type, yjssId);
var valid = list.Where(x => x.YiJianSiChang > 0).ToList();
decimal Avg(Func<YjssDcJsdc, decimal> f)
{
var v = list.Where(x => f(x) > 0).Select(f).ToList();
return v.Count == 0 ? 0 : Math.Round(v.Average(), 2, MidpointRounding.AwayFromZero);
}
return new Dictionary<string, object?>
{
["解舒样茧粒数"] = valid.Select(x => x.JieShuLiShu).DefaultIfEmpty(0).Max(),
["解舒样茧重量"] = valid.Select(x => x.JieShuZhongLiang).DefaultIfEmpty(0).Max(),
["一茧丝长"] = Avg(x => x.YiJianSiChang),
["解舒率"] = Avg(x => x.JieShuLv),
["解舒丝长"] = Avg(x => x.JieShuSiChang),
["茧丝纤度"] = Avg(x => x.JianSiXianDu),
["解舒光折"] = Avg(x => x.JieShuGuangZhe),
["万米吊糙"] = Avg(x => x.XwWanMiDiaoCao),
["落绪外"] = Math.Round(list.Where(x => x.LdfbWai > 0).Select(x => (decimal)x.LdfbWai).DefaultIfEmpty(0).Average(), 0, MidpointRounding.AwayFromZero),
["落绪中"] = Math.Round(list.Where(x => x.LdfbZhong > 0).Select(x => (decimal)x.LdfbZhong).DefaultIfEmpty(0).Average(), 0, MidpointRounding.AwayFromZero),
["落绪内"] = Math.Round(list.Where(x => x.LdfbNei > 0).Select(x => (decimal)x.LdfbNei).DefaultIfEmpty(0).Average(), 0, MidpointRounding.AwayFromZero),
["记录数"] = list.Count
};
}
/// <summary>按 F9 RepDt_Qc_Yjss_* 的中文键组装报表参数区</summary>
private static void BuildParameters(YjssFullDto dto)
{
var p = dto.Parameters;
p["查询时间"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
p["庄口名称"] = dto.ZhuangKouName;
p["日期"] = dto.Date.ToString("yyyy/M/d");
p["样茧重量"] = dto.ZhongLiang;
p["类型"] = dto.SampleTypeName;
p["回潮率"] = dto.HuiChaoLv;
p["备注"] = dto.Memo;
var x = dto.Xjdc;
if (x != null)
{
p["公斤茧粒"] = x.GongJinLiShu;
p["解舒样茧粒数"] = x.JieShuLiShu;
p["解舒样茧重量"] = x.JieShuZhongLiang;
p["茧重联统茧"] = x.ZlLtj; p["茧重好五级茧"] = x.ZlHwj; p["茧重五级茧"] = x.ZlWj;
p["茧重棉茧"] = x.ZlMianJian; p["茧重黄斑"] = x.ZlHuangBan; p["茧重蛆茧"] = x.ZlQuJian;
p["茧重双宫"] = x.ZlShuangGong; p["茧重血茧"] = x.ZlXueJian; p["茧重薄皮"] = x.ZlBaoPi;
p["茧重茧衣"] = x.ZlJianYi; p["茧重霉茧"] = x.ZlMeiJian;
p["比例联统茧"] = x.BlLtj; p["比例好五级茧"] = x.BlHwj; p["比例五级茧"] = x.BlWj;
p["比例棉茧"] = x.BlMianJian; p["比例黄斑"] = x.BlHuangBan; p["比例蛆茧"] = x.BlQuJian;
p["比例双宫"] = x.BlShuangGong; p["比例血茧"] = x.BlXueJian; p["比例薄皮"] = x.BlBaoPi;
p["比例茧衣"] = x.BlJianYi; p["比例霉茧"] = x.BlMeiJian;
}
var q = dto.Qpdc;
if (q != null)
{
p["茧层率"] = q.JianCengLv; p["公量茧层率"] = q.JianCengLvGongLiang; p["脱胶率"] = q.TuoJiaoLv;
p["原量全茧"] = q.YlQuanJian; p["原量茧层"] = q.YlJianCeng; p["原量蛹体"] = q.YlYongTi;
p["干量煮茧后"] = q.GlZhuJian; p["干量茧层"] = q.GlJianCeng; p["干量蛹体"] = q.GlYongTi;
p["粒数僵蚕"] = q.LsJiangCan; p["粒数内染"] = q.LsNeiRan; p["粒数霉蛹"] = q.LsMeiYong; p["粒数毛脚"] = q.LsMaoJiao;
p["比例僵蚕"] = q.BlJiangCan; p["比例内染"] = q.BlNeiRan; p["比例霉蛹"] = q.BlMeiYong; p["比例毛脚"] = q.BlMaoJiao;
}
var jj = dto.Qjjj;
if (jj != null)
{
p["清洁"] = jj.QingJie; p["洁净"] = jj.JingJie; p["片数"] = jj.PianShu;
p["一度"] = jj.YdYiDu; p["二度"] = jj.YdErDu; p["三度"] = jj.YdSanDu;
p["洁净100"] = jj.Jj100; p["洁净95"] = jj.Jj95; p["洁净90"] = jj.Jj90; p["洁净85"] = jj.Jj85;
p["洁净80"] = jj.Jj80; p["洁净75"] = jj.Jj75; p["洁净70"] = jj.Jj70; p["洁净65"] = jj.Jj65; p["洁净60"] = jj.Jj60;
p["特大糙"] = jj.QjTdc; p["废丝"] = jj.QjFs; p["大糙"] = jj.QjDc; p["黏附糙"] = jj.QjNfc;
p["大长结"] = jj.QjDcj; p["重螺旋"] = jj.QjZlx;
p["小糙"] = jj.QjXc; p["长结"] = jj.QjCj; p["螺旋"] = jj.QjLx; p["环结及裂丝"] = jj.QjHjls;
}
if (dto.Jfdc != null)
{
p["平均茧幅"] = dto.Jfdc.Main.PingJunJianFu;
p["最大茧幅"] = dto.Jfdc.Main.ZuiDaJianFu;
p["茧幅整齐率"] = dto.Jfdc.Main.ZhengQiLv;
p["茧幅均方差"] = dto.Jfdc.Main.JunFangCha;
}
if (dto.Jsbhxd != null)
{
p["茧丝纤度均方差"] = dto.Jsbhxd.Main.XianDuJunFangCha;
p["最大开差"] = dto.Jsbhxd.Main.ZuiDaKaiCha;
p["内外开差"] = dto.Jsbhxd.Main.NeiWaiKaiCha;
p["外三百回"] = dto.Jsbhxd.Main.WaiSanBaiHui;
p["中三百回"] = dto.Jsbhxd.Main.ZhongSanBaiHui;
p["内三百回"] = dto.Jsbhxd.Main.NeiSanBaiHui;
p["白色茧单纤"] = dto.Jsbhxd.Main.BaiSeJianDanXian;
p["灰色茧单纤"] = dto.Jsbhxd.Main.HuiSeJianDanXian;
p["红色茧单纤"] = dto.Jsbhxd.Main.HongSeJianDanXian;
}
}
// ==================== 内部工具 ====================
private async Task SetParentPointerAsync(int type, long yjssId,
long? xjdcId, long? qjjjId, long? jfdcId, long? qpdcId, int? jsdcCt, int? jsbhxdCt)
{
if (type == 1)
{
var m = await _ylxyRepo.GetByIdAsync(yjssId);
if (m == null) return;
if (xjdcId.HasValue) m.XjdcId = xjdcId.Value;
if (qjjjId.HasValue) m.QjjjId = qjjjId.Value;
if (jsdcCt.HasValue) m.JsdcCt = jsdcCt.Value;
await _ylxyRepo.UpdateAsync(m);
}
else
{
var m = await _zhyRepo.GetByIdAsync(yjssId);
if (m == null) return;
if (xjdcId.HasValue) m.XjdcId = xjdcId.Value;
if (qjjjId.HasValue) m.QjjjId = qjjjId.Value;
if (jfdcId.HasValue) m.JfdcId = jfdcId.Value;
if (qpdcId.HasValue) m.QpdcId = qpdcId.Value;
if (jsdcCt.HasValue) m.JsdcCt = jsdcCt.Value;
if (jsbhxdCt.HasValue) m.JsbhxdCt = jsbhxdCt.Value;
await _zhyRepo.UpdateAsync(m);
}
}
private static async Task<long> UpsertAsync<T>(IRepository<T> 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;
}
}