新增工资/仓储/生产日报等模块,移除旧考勤模块

- 新增 PayRoll(工资)、Wms(仓储)、Prod(车速/缫丝/考勤/丝片检测/丝片台账/纤检日报/质量日报) 模块
- 新增对应 Domain 实体、Application DTO/Service、Api Controller 与前端页面
- 移除旧 Attendance 考勤模块(Controller/Service/Entity/DTO 及 5 个前端页面),由 Prod/Kaoqin 取代
- 调整路由、仪表盘、Lsjl 流丝记录实体与服务
- 更新业务种子数据与 DbSeeder
- 补充工作进度文档 14-27
This commit is contained in:
yanpeng200212
2026-10-27 09:09:57 +08:00
parent 69c4052a64
commit 1f1b184411
119 changed files with 21576 additions and 1668 deletions
@@ -0,0 +1,609 @@
using F9WebAiTest.Application.Common;
using F9WebAiTest.Application.Dtos.Prod;
using F9WebAiTest.Domain.Common;
using F9WebAiTest.Domain.Entities.Base;
using F9WebAiTest.Domain.Entities.Prod;
using F9WebAiTest.Domain.Entities.SYS.Registries;
using F9WebAiTest.Domain.Enums.SYS.Employees;
using SysDept = F9WebAiTest.Domain.Entities.SYS.Departments;
namespace F9WebAiTest.Application.Services.Prod;
/// <summary>
/// 煮茧日报(生产-前缫):某日某车间某庄口某规格一条日报,含「机组」「班次」「机组班次」三层明细。
/// 对应 F9 Page_Zjrb(列表)、Page_Zjrb_EditV2(录入)、Zjrb_SaveCommand / Zjrb_DelCommand /
/// CalculateJizuSaosiHoursCommand(计算缫丝时长)。
///
/// 计算口径(与 F9 前端 Page_Zjrb_EditV2 一致,服务端保存时重算):
/// 机组.今缫桶数 = 甲班 + 乙班
/// 机组.今存桶数 = 上存 + 今缫 − 今落(今落为 0 且余量够一个标准桶时自动补「工艺落丝桶数」)
/// 班次.今缫重量 = 该班次机组今缫桶数 × 每桶茧量 ÷ 1000
/// 班次.领入/退回重量 = 包数 × 联统茧标重(标重未配置则保留录入值)
/// 班次.今缫包数 = 今缫重量 ÷ 联统茧标重(四舍五入取整)
/// 班次.今存 = 上存 + 领入 − 今缫 − 退回
/// 主表 = 甲班 + 乙班
/// </summary>
public interface IZjrbService
{
/// <summary>日报列表(账期起止 + 车间 + 关键字)</summary>
Task<PageResult<ZjrbReadDto_View>> GetPagedAsync(DateTime dateFrom, DateTime dateTo, long depId,
string like, int pageIndex, int pageSize);
/// <summary>某条日报的机组明细(列表页下半表)</summary>
Task<List<ZjrbJizuDto>> GetJizuListAsync(long zjrbId);
/// <summary>修改回填:主表 + 班次 + 机组 + 机组班次</summary>
Task<ZjrbSaveDto> GetForEditAsync(long id);
/// <summary>新增:按上一日结存带出上存、每桶茧量、工艺落丝桶数,并按机组车台生成机组行</summary>
Task<ZjrbSaveDto> BuildDefaultsAsync(DateTime date, long depId, long gyzkId, string guige);
/// <summary>保存(整条替换:主表 upsert + 三层明细先删后建)</summary>
Task<long> SaveAsync(ZjrbSaveDto dto);
/// <summary>删除(四张表级联物理删除)</summary>
Task DeleteAsync(long id);
/// <summary>计算缫丝时长(整日整车间重算:单班 9 小时 / 双班 18 小时,按茧量比例分配)</summary>
Task<int> CalculateJizuSaosiHoursAsync(DateTime date, long depId);
}
public class ZjrbService : IZjrbService
{
/// <summary>单班 / 双班的机组标准时长</summary>
private const decimal SingleBanciHours = 9m;
private const decimal TwoBanciHours = 18m;
/// <summary>联统茧标重的参数配置位置(与 F9 一致)</summary>
private const string RegistryCategory = @"生产\前缫\煮茧";
private const string RegistryKey = "联统茧标重";
private readonly IRepository<ZjrbRecord> _zjrbRepo;
private readonly IRepository<ZjrbJizu> _jizuRepo;
private readonly IRepository<ZjrbBanci> _banciRepo;
private readonly IRepository<ZjrbJizuBanci> _jizuBanciRepo;
private readonly IRepository<JizuChetai> _jzctRepo;
private readonly IRepository<ChejianBanci> _cjbcRepo;
private readonly IRepository<CraftZhuangKou> _gyzkRepo;
private readonly IRepository<Registry> _registryRepo;
private readonly IRepository<SysDept.Department> _deptRepo;
public ZjrbService(IRepository<ZjrbRecord> zjrbRepo, IRepository<ZjrbJizu> jizuRepo,
IRepository<ZjrbBanci> banciRepo, IRepository<ZjrbJizuBanci> jizuBanciRepo,
IRepository<JizuChetai> jzctRepo, IRepository<ChejianBanci> cjbcRepo,
IRepository<CraftZhuangKou> gyzkRepo, IRepository<Registry> registryRepo,
IRepository<SysDept.Department> deptRepo)
{
_zjrbRepo = zjrbRepo;
_jizuRepo = jizuRepo;
_banciRepo = banciRepo;
_jizuBanciRepo = jizuBanciRepo;
_jzctRepo = jzctRepo;
_cjbcRepo = cjbcRepo;
_gyzkRepo = gyzkRepo;
_registryRepo = registryRepo;
_deptRepo = deptRepo;
}
// ==================== 查询 ====================
public async Task<PageResult<ZjrbReadDto_View>> GetPagedAsync(DateTime dateFrom, DateTime dateTo, long depId,
string like, int pageIndex, int pageSize)
{
if (pageIndex <= 0) pageIndex = 1;
if (pageSize <= 0) pageSize = 20;
var from = dateFrom.Date;
var to = dateTo.Date;
if (to < from) (from, to) = (to, from);
var ctx = await BuildContextAsync();
var rows = await _zjrbRepo.FindAsync(x => x.Date >= from && x.Date <= to);
if (depId > 0) rows = rows.Where(x => x.DeptId == depId).ToList();
if (!string.IsNullOrWhiteSpace(like))
{
var kw = like.Trim();
rows = rows.Where(x =>
ctx.GyzkNames.GetValueOrDefault(x.GyzkId, "").Contains(kw, StringComparison.OrdinalIgnoreCase)
|| (x.Guige ?? "").Contains(kw, StringComparison.OrdinalIgnoreCase))
.ToList();
}
var total = rows.Count;
var pageRows = rows
.OrderByDescending(x => x.Date)
.ThenBy(x => ctx.DeptNames.GetValueOrDefault(x.DeptId, ""))
.ThenBy(x => x.GyzkId)
.ThenBy(x => x.Guige)
.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
var ids = pageRows.Select(x => x.Id).ToList();
var jizus = ids.Count == 0
? new List<ZjrbJizu>()
: await _jizuRepo.FindAsync(x => ids.Contains(x.ZjrbId));
var items = pageRows.Select(x =>
{
var jz = jizus.Where(j => j.ZjrbId == x.Id).ToList();
return new ZjrbReadDto_View
{
Id = x.Id,
Date = x.Date,
DepId = x.DeptId,
DepName = ctx.DeptNames.GetValueOrDefault(x.DeptId, ""),
GyzkId = x.GyzkId,
GyzkName = ctx.GyzkNames.GetValueOrDefault(x.GyzkId, ""),
Guige = x.Guige ?? "",
LastDate = x.LastDate,
StandardLuositongshu = x.StandardLuositongshu,
MeitongJianliang = x.MeitongJianliang,
BaoshuShangcun = x.BaoshuShangcun,
BaoshuLingru = x.BaoshuLingru,
BaoshuSaosi = x.BaoshuSaosi,
BaoshuTuihui = x.BaoshuTuihui,
BaoshuJincun = x.BaoshuJincun,
JianliangShangcun = x.JianliangShangcun,
JianliangLingru = x.JianliangLingru,
JianliangSaosi = x.JianliangSaosi,
JianliangTuihui = x.JianliangTuihui,
JianliangJincun = x.JianliangJincun,
TongshuShangcun = jz.Sum(j => j.TongshuShangcun),
TongshuJinsao = jz.Sum(j => j.TongshuJinsao),
TongshuJinluo = jz.Sum(j => j.TongshuJinluo),
TongshuJincun = jz.Sum(j => j.TongshuJincun),
JizuSaosiHours = jz.Sum(j => j.JizuSaosiHours)
};
}).ToList();
return new PageResult<ZjrbReadDto_View>
{
Items = items,
Total = total,
PageIndex = pageIndex,
PageSize = pageSize
};
}
public async Task<List<ZjrbJizuDto>> GetJizuListAsync(long zjrbId)
{
var jizus = (await _jizuRepo.FindAsync(x => x.ZjrbId == zjrbId)).OrderBy(x => x.Jizu).ToList();
var jb = await _jizuBanciRepo.FindAsync(x => x.ZjrbId == zjrbId);
return jizus.Select(j => ToJizuDto(j, jb)).ToList();
}
public async Task<ZjrbSaveDto> GetForEditAsync(long id)
{
var master = await _zjrbRepo.GetByIdAsync(id);
if (master == null) throw new ServiceException("煮茧日报不存在或已删除");
var ctx = await BuildContextAsync();
var banciRows = (await _banciRepo.FindAsync(x => x.ZjrbId == id)).OrderBy(x => x.Banci).ToList();
var jizuRows = (await _jizuRepo.FindAsync(x => x.ZjrbId == id)).OrderBy(x => x.Jizu).ToList();
var jbRows = await _jizuBanciRepo.FindAsync(x => x.ZjrbId == id);
var dto = new ZjrbSaveDto
{
Id = master.Id,
Date = master.Date,
DepId = master.DeptId,
DepName = ctx.DeptNames.GetValueOrDefault(master.DeptId, ""),
GyzkId = master.GyzkId,
GyzkName = ctx.GyzkNames.GetValueOrDefault(master.GyzkId, ""),
Guige = master.Guige ?? "",
LastDate = master.LastDate,
StandardLuositongshu = master.StandardLuositongshu,
MeitongJianliang = master.MeitongJianliang,
LiantongBiaozhong = await GetLiantongBiaozhongAsync(),
BaoshuShangcun = master.BaoshuShangcun,
BaoshuLingru = master.BaoshuLingru,
BaoshuSaosi = master.BaoshuSaosi,
BaoshuTuihui = master.BaoshuTuihui,
BaoshuJincun = master.BaoshuJincun,
JianliangShangcun = master.JianliangShangcun,
JianliangLingru = master.JianliangLingru,
JianliangSaosi = master.JianliangSaosi,
JianliangTuihui = master.JianliangTuihui,
JianliangJincun = master.JianliangJincun,
Bancis = banciRows.Select(ToBanciDto).ToList(),
Jizus = jizuRows.Select(j => ToJizuDto(j, jbRows)).ToList()
};
// 历史数据可能缺班次行(或车间班次配置调整过),按配置补齐甲乙班
var need = (await GetBanciKindsAsync(master.DeptId));
foreach (var b in need)
{
if (dto.Bancis.All(x => x.Banci != b))
dto.Bancis.Add(new ZjrbBanciDto { Banci = b, BanciName = b.ToString() });
}
dto.Bancis = dto.Bancis.OrderBy(x => x.Banci).ToList();
return dto;
}
public async Task<ZjrbSaveDto> BuildDefaultsAsync(DateTime date, long depId, long gyzkId, string guige)
{
if (depId <= 0) throw new ServiceException("请选择车间");
var ctx = await BuildContextAsync();
var d = date.Date;
var g = (guige ?? string.Empty).Trim();
// 上一日:同车间 + 同庄口(+ 同规格)的最近一条日报
var candidates = await _zjrbRepo.FindAsync(x => x.Date < d && x.DeptId == depId && x.GyzkId == gyzkId);
var last = candidates
.Where(x => string.IsNullOrEmpty(g) || (x.Guige ?? "") == g)
.OrderByDescending(x => x.Date)
.FirstOrDefault();
var dto = new ZjrbSaveDto
{
Date = d,
DepId = depId,
DepName = ctx.DeptNames.GetValueOrDefault(depId, ""),
GyzkId = gyzkId,
GyzkName = ctx.GyzkNames.GetValueOrDefault(gyzkId, ""),
Guige = g,
LiantongBiaozhong = await GetLiantongBiaozhongAsync()
};
List<ZjrbBanci> lastBancis = new();
List<ZjrbJizu> lastJizus = new();
if (last != null)
{
dto.LastDate = last.Date;
dto.StandardLuositongshu = last.StandardLuositongshu;
dto.MeitongJianliang = last.MeitongJianliang;
lastBancis = await _banciRepo.FindAsync(x => x.ZjrbId == last.Id);
lastJizus = await _jizuRepo.FindAsync(x => x.ZjrbId == last.Id);
}
// 班次行:按车间班次配置;未配置则固定甲乙两班
foreach (var b in await GetBanciKindsAsync(depId))
{
var prev = lastBancis.FirstOrDefault(x => x.Banci == b);
dto.Bancis.Add(new ZjrbBanciDto
{
Banci = b,
BanciName = b.ToString(),
BaoshuShangcun = prev?.BaoshuJincun ?? 0,
JianliangShangcun = prev?.JianliangJincun ?? 0
});
}
// 机组行:按机组车台配置;上存桶数取上一日该机组今存桶数
var jizus = (await _jzctRepo.FindAsync(x => x.DepartmentId == depId))
.Select(x => x.Jizu).Distinct().OrderBy(x => x).ToList();
foreach (var jz in jizus)
{
var prev = lastJizus.FirstOrDefault(x => x.Jizu == jz);
dto.Jizus.Add(new ZjrbJizuDto
{
Jizu = jz,
TongshuShangcun = prev?.TongshuJincun ?? 0
});
}
return dto;
}
// ==================== 保存 / 删除 ====================
public async Task<long> SaveAsync(ZjrbSaveDto dto)
{
if (dto == null) throw new ServiceException("参数不能为空");
if (dto.Date == default) throw new ServiceException("请选择日期");
if (dto.DepId <= 0) throw new ServiceException("请选择车间");
if (dto.GyzkId <= 0) throw new ServiceException("请选择工艺庄口");
if (dto.MeitongJianliang <= 0) throw new ServiceException("每桶茧量必须大于 0");
if (dto.StandardLuositongshu <= 0) throw new ServiceException("工艺落丝桶数必须大于 0");
if (dto.Bancis == null || dto.Bancis.Count == 0) throw new ServiceException("请至少保留一个班次行");
var d = dto.Date.Date;
var guige = (dto.Guige ?? string.Empty).Trim();
// 唯一性:同 日期 + 车间 + 庄口 + 规格
var exists = await _zjrbRepo.AnyAsync(x =>
x.Id != dto.Id && x.Date == d && x.DeptId == dto.DepId && x.GyzkId == dto.GyzkId && x.Guige == guige);
if (exists) throw new ServiceException("已存在相同的煮茧日报!");
Normalize(dto, guige);
long id = dto.Id;
if (id > 0)
{
var master = await _zjrbRepo.GetByIdAsync(id);
if (master == null) throw new ServiceException("煮茧日报不存在或已删除");
CopyMaster(dto, master);
await _zjrbRepo.UpdateAsync(master);
await DeleteChildrenAsync(id);
}
else
{
var master = new ZjrbRecord { LastDate = dto.LastDate };
CopyMaster(dto, master);
await _zjrbRepo.AddAsync(master);
id = master.Id;
}
// 班次
foreach (var b in dto.Bancis)
{
await _banciRepo.AddAsync(new ZjrbBanci
{
ZjrbId = id,
Banci = b.Banci,
BaoshuShangcun = b.BaoshuShangcun,
BaoshuLingru = b.BaoshuLingru,
BaoshuSaosi = b.BaoshuSaosi,
BaoshuTuihui = b.BaoshuTuihui,
BaoshuJincun = b.BaoshuJincun,
JianliangShangcun = b.JianliangShangcun,
JianliangLingru = b.JianliangLingru,
JianliangSaosi = b.JianliangSaosi,
JianliangTuihui = b.JianliangTuihui,
JianliangJincun = b.JianliangJincun
});
}
// 机组 + 机组班次(机组班次挂在刚生成的机组 Id 上)
foreach (var j in dto.Jizus)
{
var jizu = await _jizuRepo.AddAsync(new ZjrbJizu
{
ZjrbId = id,
Jizu = j.Jizu,
JizuSaosiHours = j.JizuSaosiHours,
TongshuShangcun = j.TongshuShangcun,
TongshuJinsao = j.TongshuJinsaoJiaban + j.TongshuJinsaoYiban,
TongshuJinluo = j.TongshuJinluo,
TongshuJincun = j.TongshuJincun
});
foreach (var b in dto.Bancis)
{
await _jizuBanciRepo.AddAsync(new ZjrbJizuBanci
{
ZjrbId = id,
ZjrbJizuId = jizu.Id,
Jizu = j.Jizu,
Banci = b.Banci,
TongshuJinsao = b.Banci == Prod_Banci_Enum.甲 ? j.TongshuJinsaoJiaban : j.TongshuJinsaoYiban
});
}
}
await _zjrbRepo.SaveChangesAsync();
return id;
}
public async Task DeleteAsync(long id)
{
var master = await _zjrbRepo.GetByIdAsync(id);
if (master == null) throw new ServiceException("煮茧日报不存在或已删除");
await DeleteChildrenAsync(id);
await _zjrbRepo.HardDeleteAsync(master);
}
private async Task DeleteChildrenAsync(long zjrbId)
{
var jizuRows = await _jizuRepo.FindAsync(x => x.ZjrbId == zjrbId);
if (jizuRows.Count > 0) await _jizuRepo.HardDeleteRangeAsync(jizuRows);
var banciRows = await _banciRepo.FindAsync(x => x.ZjrbId == zjrbId);
if (banciRows.Count > 0) await _banciRepo.HardDeleteRangeAsync(banciRows);
var jbRows = await _jizuBanciRepo.FindAsync(x => x.ZjrbId == zjrbId);
if (jbRows.Count > 0) await _jizuBanciRepo.HardDeleteRangeAsync(jbRows);
}
// ==================== 计算缫丝时长 ====================
public async Task<int> CalculateJizuSaosiHoursAsync(DateTime date, long depId)
{
if (depId <= 0) throw new ServiceException("请选择车间");
var d = date.Date;
var reports = await _zjrbRepo.FindAsync(x => x.Date == d && x.DeptId == depId);
if (reports.Count == 0) throw new ServiceException("该日该车间没有煮茧日报,无法计算缫丝时长");
var reportMap = reports.ToDictionary(x => x.Id);
var ids = reportMap.Keys.ToList();
var jizus = await _jizuRepo.FindAsync(x => ids.Contains(x.ZjrbId));
if (jizus.Count == 0) throw new ServiceException("该日该车间没有机组明细,无法计算缫丝时长");
var jbRows = await _jizuBanciRepo.FindAsync(x => ids.Contains(x.ZjrbId));
// 双班判据:该机组「今缫桶数 > 0」的班次个数为 2 → 18 小时,否则 9 小时
var hasTwoBanci = jizus.Select(x => x.Jizu).Distinct().ToDictionary(
jz => jz,
jz => jbRows.Where(x => x.Jizu == jz && x.TongshuJinsao > 0)
.Select(x => x.Banci).Distinct().Count() == 2);
// 机组总茧量 = Σ(每桶茧量 × 机组今缫桶数)
var totalJianliang = jizus.GroupBy(x => x.Jizu).ToDictionary(
g => g.Key,
g => g.Sum(x => (decimal)reportMap[x.ZjrbId].MeitongJianliang * x.TongshuJinsao));
var changed = 0;
var groups = jizus.GroupBy(x => new
{
reportMap[x.ZjrbId].GyzkId,
Guige = reportMap[x.ZjrbId].Guige ?? "",
x.Jizu
});
foreach (var group in groups)
{
var jz = group.Key.Jizu;
var totalHours = hasTwoBanci.GetValueOrDefault(jz) ? TwoBanciHours : SingleBanciHours;
var jizuTotal = totalJianliang.GetValueOrDefault(jz);
var current = group.Sum(x => (decimal)reportMap[x.ZjrbId].MeitongJianliang * x.TongshuJinsao);
var ratio = jizuTotal > 0 ? current / jizuTotal : 0m;
var newHours = Math.Round(ratio * totalHours, 1, MidpointRounding.AwayFromZero);
foreach (var item in group)
{
if (item.JizuSaosiHours == newHours) continue;
item.JizuSaosiHours = newHours;
await _jizuRepo.UpdateAsync(item);
changed++;
}
}
return changed;
}
// ==================== 内部:口径重算 / 上下文 ====================
/// <summary>按 F9 编辑页口径重算派生字段(机组今存、班次重量与今存、主表合计)</summary>
private static void Normalize(ZjrbSaveDto dto, string guige)
{
dto.Guige = guige;
foreach (var j in dto.Jizus)
{
if (j.JizuSaosiHours < 0) throw new ServiceException($"机组{j.Jizu}的缫丝时长不能为负数");
if (j.JizuSaosiHours > 20) throw new ServiceException($"机组{j.Jizu}缫丝时长不能大于 20");
j.TongshuJinsao = j.TongshuJinsaoJiaban + j.TongshuJinsaoYiban;
if (j.TongshuJinsao > 0 && j.JizuSaosiHours <= 0)
throw new ServiceException($"机组{j.Jizu}今缫桶数大于 0 时,请输入缫丝时长");
var pre = j.TongshuShangcun + j.TongshuJinsao - j.TongshuJinluo;
if (j.TongshuJinluo == 0 && dto.StandardLuositongshu > 0 && pre >= dto.StandardLuositongshu)
{
j.TongshuJinluo = dto.StandardLuositongshu;
pre -= dto.StandardLuositongshu;
}
j.TongshuJincun = pre;
}
foreach (var b in dto.Bancis)
{
if (b.BaoshuShangcun > 0 && b.JianliangShangcun <= 0)
throw new ServiceException($"{b.Banci}班上存包数大于 0 时,请填写上存重量");
var tongshu = dto.Jizus.Sum(j => b.Banci == Prod_Banci_Enum.甲
? j.TongshuJinsaoJiaban
: j.TongshuJinsaoYiban);
b.JianliangSaosi = Math.Round(tongshu * (decimal)dto.MeitongJianliang / 1000m, 1,
MidpointRounding.AwayFromZero);
if (dto.LiantongBiaozhong > 0)
{
b.JianliangLingru = Math.Round(b.BaoshuLingru * dto.LiantongBiaozhong, 1,
MidpointRounding.AwayFromZero);
b.JianliangTuihui = Math.Round(b.BaoshuTuihui * dto.LiantongBiaozhong, 1,
MidpointRounding.AwayFromZero);
b.BaoshuSaosi = (int)Math.Round(b.JianliangSaosi / dto.LiantongBiaozhong, 0,
MidpointRounding.AwayFromZero);
}
b.JianliangJincun = b.JianliangShangcun + b.JianliangLingru - b.JianliangSaosi - b.JianliangTuihui;
b.BaoshuJincun = b.BaoshuShangcun + b.BaoshuLingru - b.BaoshuSaosi - b.BaoshuTuihui;
}
// 主表 = 甲班 + 乙班
dto.BaoshuShangcun = dto.Bancis.Sum(x => x.BaoshuShangcun);
dto.BaoshuLingru = dto.Bancis.Sum(x => x.BaoshuLingru);
dto.BaoshuSaosi = dto.Bancis.Sum(x => x.BaoshuSaosi);
dto.BaoshuTuihui = dto.Bancis.Sum(x => x.BaoshuTuihui);
dto.BaoshuJincun = dto.Bancis.Sum(x => x.BaoshuJincun);
dto.JianliangShangcun = dto.Bancis.Sum(x => x.JianliangShangcun);
dto.JianliangLingru = dto.Bancis.Sum(x => x.JianliangLingru);
dto.JianliangSaosi = dto.Bancis.Sum(x => x.JianliangSaosi);
dto.JianliangTuihui = dto.Bancis.Sum(x => x.JianliangTuihui);
dto.JianliangJincun = dto.Bancis.Sum(x => x.JianliangJincun);
}
private static void CopyMaster(ZjrbSaveDto dto, ZjrbRecord master)
{
master.Date = dto.Date.Date;
master.DeptId = dto.DepId;
master.GyzkId = dto.GyzkId;
master.Guige = dto.Guige ?? "";
master.LastDate = dto.LastDate;
master.StandardLuositongshu = dto.StandardLuositongshu;
master.MeitongJianliang = dto.MeitongJianliang;
master.BaoshuShangcun = dto.BaoshuShangcun;
master.BaoshuLingru = dto.BaoshuLingru;
master.BaoshuSaosi = dto.BaoshuSaosi;
master.BaoshuTuihui = dto.BaoshuTuihui;
master.BaoshuJincun = dto.BaoshuJincun;
master.JianliangShangcun = dto.JianliangShangcun;
master.JianliangLingru = dto.JianliangLingru;
master.JianliangSaosi = dto.JianliangSaosi;
master.JianliangTuihui = dto.JianliangTuihui;
master.JianliangJincun = dto.JianliangJincun;
}
private static ZjrbBanciDto ToBanciDto(ZjrbBanci x) => new()
{
Id = x.Id,
ZjrbId = x.ZjrbId,
Banci = x.Banci,
BanciName = x.Banci.ToString(),
BaoshuShangcun = x.BaoshuShangcun,
BaoshuLingru = x.BaoshuLingru,
BaoshuSaosi = x.BaoshuSaosi,
BaoshuTuihui = x.BaoshuTuihui,
BaoshuJincun = x.BaoshuJincun,
JianliangShangcun = x.JianliangShangcun,
JianliangLingru = x.JianliangLingru,
JianliangSaosi = x.JianliangSaosi,
JianliangTuihui = x.JianliangTuihui,
JianliangJincun = x.JianliangJincun
};
private static ZjrbJizuDto ToJizuDto(ZjrbJizu x, List<ZjrbJizuBanci> jbRows) => new()
{
Id = x.Id,
ZjrbId = x.ZjrbId,
Jizu = x.Jizu,
JizuSaosiHours = x.JizuSaosiHours,
TongshuShangcun = x.TongshuShangcun,
TongshuJinsaoJiaban = jbRows.FirstOrDefault(b => b.ZjrbJizuId == x.Id && b.Banci == Prod_Banci_Enum.甲)
?.TongshuJinsao ?? 0,
TongshuJinsaoYiban = jbRows.FirstOrDefault(b => b.ZjrbJizuId == x.Id && b.Banci == Prod_Banci_Enum.乙)
?.TongshuJinsao ?? 0,
TongshuJinsao = x.TongshuJinsao,
TongshuJinluo = x.TongshuJinluo,
TongshuJincun = x.TongshuJincun
};
/// <summary>车间班次配置;未配置时固定甲乙两班</summary>
private async Task<List<Prod_Banci_Enum>> GetBanciKindsAsync(long depId)
{
var cfgs = await _cjbcRepo.FindAsync(x => x.DeptId == depId);
if (cfgs.Count == 0) return new List<Prod_Banci_Enum> { Prod_Banci_Enum.甲, Prod_Banci_Enum.乙 };
return cfgs.Select(x => x.Banci).Distinct().OrderBy(x => x).ToList();
}
private async Task<decimal> GetLiantongBiaozhongAsync()
{
var row = await _registryRepo.FirstOrDefaultAsync(x =>
x.Category == RegistryCategory && x.KeyName == RegistryKey);
if (row == null || string.IsNullOrWhiteSpace(row.Value)) return 0m;
return decimal.TryParse(row.Value, out var v) ? v : 0m;
}
private sealed class Ctx
{
public Dictionary<long, string> DeptNames { get; init; } = new();
public Dictionary<long, string> GyzkNames { get; init; } = new();
}
private async Task<Ctx> BuildContextAsync()
{
var depts = await _deptRepo.GetAllAsync();
var gyzks = await _gyzkRepo.GetAllAsync();
return new Ctx
{
DeptNames = depts.ToDictionary(d => d.Id, d => d.Name),
GyzkNames = gyzks.ToDictionary(z => z.Id, z => z.ProductionDisplayName is { Length: > 0 } n
? n
: z.ZhuangKouName)
};
}
}