一、机组车台功能完善 - 车间下拉改为只取「前缫」职责类型的部门(新增接口 /api/jizuchetai/qianxian-deps) - 补齐校验:车间、机组号、开始车台号必填;结束车台号不得小于开始车台号;同车间同机组不可重复 - 前端页面同步调整:车间改为下拉选择、增加必填提示、表格加 row-key 二、数据导入(新增 ProdSeedData,幂等导入器) - biz_prod_qs_jzct:机组车台 35 条(其中 11 条已删除)→ 有效 24 条 - biz_prod_qs_cjbc:车间班次 7 条(其中 1 条已删除)→ 有效 6 条 - F9 的部门 Id 通过部门名称映射到本系统部门;已删除的数据不导入; 已存在且一致的数据不重复写入,缺失的自动补回
358 lines
16 KiB
C#
358 lines
16 KiB
C#
using F9WebAiTest.Application.Common;
|
|
using F9WebAiTest.Application.Dtos;
|
|
using F9WebAiTest.Application.Dtos.Base;
|
|
using F9WebAiTest.Domain.Common;
|
|
using F9WebAiTest.Domain.Entities;
|
|
using F9WebAiTest.Domain.Entities.Base;
|
|
using F9WebAiTest.Domain.Enums.SYS.Departments;
|
|
using SysDept = F9WebAiTest.Domain.Entities.SYS.Departments;
|
|
|
|
namespace F9WebAiTest.Application.Services.Base;
|
|
|
|
// ==================== 工艺庄口 ====================
|
|
public interface ICraftZhuangKouService
|
|
{
|
|
Task<PageResult<CraftZhuangKouDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword, int? year);
|
|
Task<CraftZhuangKouDto> CreateAsync(CraftZhuangKouCreateDto dto);
|
|
Task<CraftZhuangKouDto> UpdateAsync(long id, CraftZhuangKouCreateDto dto);
|
|
Task DeleteAsync(long id);
|
|
}
|
|
|
|
public class CraftZhuangKouService : ICraftZhuangKouService
|
|
{
|
|
private readonly IRepository<CraftZhuangKou> _repo;
|
|
public CraftZhuangKouService(IRepository<CraftZhuangKou> repo) => _repo = repo;
|
|
|
|
private static string BendiWaidiName(int v) => v switch { 1 => "本地", 2 => "外地", _ => "" };
|
|
|
|
public async Task<PageResult<CraftZhuangKouDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword, int? year)
|
|
{
|
|
var all = await _repo.GetAllAsync();
|
|
var q = all.AsQueryable();
|
|
if (!string.IsNullOrWhiteSpace(keyword))
|
|
q = q.Where(x => x.ZhuangKouName.Contains(keyword) || x.ZhuangKouCode.Contains(keyword) || x.ProductionDisplayName.Contains(keyword));
|
|
if (year.HasValue)
|
|
q = q.Where(x => x.BelongingYear == year.Value);
|
|
|
|
var total = q.LongCount();
|
|
var items = q.OrderBy(x => x.Sort).ThenBy(x => x.Id)
|
|
.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
|
|
|
|
return new PageResult<CraftZhuangKouDto>
|
|
{
|
|
Items = items.Select(ToDto).ToList(),
|
|
Total = total, PageIndex = pageIndex, PageSize = pageSize
|
|
};
|
|
}
|
|
|
|
public async Task<CraftZhuangKouDto> CreateAsync(CraftZhuangKouCreateDto dto)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(dto.ZhuangKouName)) throw new ServiceException("庄口名称不能为空");
|
|
var e = new CraftZhuangKou
|
|
{
|
|
BelongingYear = dto.BelongingYear, BendiWaidi = dto.BendiWaidi, JidiWaigou = dto.JidiWaigou,
|
|
ZhuangKouCode = dto.ZhuangKouCode, ZhuangKouName = dto.ZhuangKouName,
|
|
ProductionDisplayName = dto.ProductionDisplayName, Chandi = dto.Chandi,
|
|
Sort = dto.Sort, Memo = dto.Memo, IsJiezhuang = dto.IsJiezhuang
|
|
};
|
|
await _repo.AddAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return ToDto(e);
|
|
}
|
|
|
|
public async Task<CraftZhuangKouDto> UpdateAsync(long id, CraftZhuangKouCreateDto dto)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
e.BelongingYear = dto.BelongingYear; e.BendiWaidi = dto.BendiWaidi; e.JidiWaigou = dto.JidiWaigou;
|
|
e.ZhuangKouCode = dto.ZhuangKouCode; e.ZhuangKouName = dto.ZhuangKouName;
|
|
e.ProductionDisplayName = dto.ProductionDisplayName; e.Chandi = dto.Chandi;
|
|
e.Sort = dto.Sort; e.Memo = dto.Memo; e.IsJiezhuang = dto.IsJiezhuang;
|
|
await _repo.UpdateAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return ToDto(e);
|
|
}
|
|
|
|
public async Task DeleteAsync(long id)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
await _repo.DeleteAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
}
|
|
|
|
private static CraftZhuangKouDto ToDto(CraftZhuangKou e) => new()
|
|
{
|
|
Id = e.Id, BelongingYear = e.BelongingYear, BendiWaidi = e.BendiWaidi, BendiWaidiName = BendiWaidiName(e.BendiWaidi),
|
|
JidiWaigou = e.JidiWaigou, ZhuangKouCode = e.ZhuangKouCode, ZhuangKouName = e.ZhuangKouName,
|
|
ProductionDisplayName = e.ProductionDisplayName, Chandi = e.Chandi, Sort = e.Sort, Memo = e.Memo, IsJiezhuang = e.IsJiezhuang
|
|
};
|
|
}
|
|
|
|
// ==================== 生丝规格 ====================
|
|
public interface IShengsiGuigeService
|
|
{
|
|
Task<PageResult<ShengsiGuigeDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword);
|
|
Task<List<string>> GetAllGuigeAsync();
|
|
Task<ShengsiGuigeDto> CreateAsync(ShengsiGuigeDto dto);
|
|
Task<ShengsiGuigeDto> UpdateAsync(long id, ShengsiGuigeDto dto);
|
|
Task DeleteAsync(long id);
|
|
}
|
|
|
|
public class ShengsiGuigeService : IShengsiGuigeService
|
|
{
|
|
private readonly IRepository<ShengsiGuige> _repo;
|
|
public ShengsiGuigeService(IRepository<ShengsiGuige> repo) => _repo = repo;
|
|
|
|
public async Task<PageResult<ShengsiGuigeDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword)
|
|
{
|
|
var all = await _repo.GetAllAsync();
|
|
var q = all.AsQueryable();
|
|
if (!string.IsNullOrWhiteSpace(keyword)) q = q.Where(x => x.Guige.Contains(keyword));
|
|
var total = q.LongCount();
|
|
var items = q.OrderBy(x => x.Sort).ThenBy(x => x.Id).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
|
|
return new PageResult<ShengsiGuigeDto> { Items = items.Select(ToDto).ToList(), Total = total, PageIndex = pageIndex, PageSize = pageSize };
|
|
}
|
|
|
|
public async Task<List<string>> GetAllGuigeAsync()
|
|
=> (await _repo.GetAllAsync()).OrderBy(x => x.Sort).Select(x => x.Guige).Distinct().ToList();
|
|
|
|
public async Task<ShengsiGuigeDto> CreateAsync(ShengsiGuigeDto dto)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(dto.Guige)) throw new ServiceException("规格不能为空");
|
|
var e = Map(new ShengsiGuige(), dto);
|
|
await _repo.AddAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return ToDto(e);
|
|
}
|
|
|
|
public async Task<ShengsiGuigeDto> UpdateAsync(long id, ShengsiGuigeDto dto)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
Map(e, dto);
|
|
await _repo.UpdateAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return ToDto(e);
|
|
}
|
|
|
|
public async Task DeleteAsync(long id)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
await _repo.DeleteAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
}
|
|
|
|
private static ShengsiGuige Map(ShengsiGuige e, ShengsiGuigeDto d)
|
|
{
|
|
e.Guige = d.Guige; e.CenterrangeLolimit = d.CenterrangeLolimit; e.CenterrangeUplimit = d.CenterrangeUplimit;
|
|
e.CenterXiandu = d.CenterXiandu; e.ValidLolimit = d.ValidLolimit; e.ValidUplimit = d.ValidUplimit;
|
|
e.XiaoyeLolimit = d.XiaoyeLolimit; e.XiaoyeUplimit = d.XiaoyeUplimit;
|
|
e.DayeLolimit = d.DayeLolimit; e.DayeUplimit = d.DayeUplimit;
|
|
e.TeyeLolimit = d.TeyeLolimit; e.TeyeUplimit = d.TeyeUplimit;
|
|
e.YexianNkLolimitLeft = d.YexianNkLolimitLeft; e.YexianNkLolimitRight = d.YexianNkLolimitRight;
|
|
e.YexianNkUplimitLeft = d.YexianNkUplimitLeft; e.YexianNkUplimitRight = d.YexianNkUplimitRight;
|
|
e.LaodongJingsaiYexianLolimit = d.LaodongJingsaiYexianLolimit; e.LaodongJingsaiYexianUplimit = d.LaodongJingsaiYexianUplimit;
|
|
e.Sort = d.Sort; e.Memo = d.Memo;
|
|
return e;
|
|
}
|
|
|
|
private static ShengsiGuigeDto ToDto(ShengsiGuige e) => new()
|
|
{
|
|
Id = e.Id, Guige = e.Guige, CenterrangeLolimit = e.CenterrangeLolimit, CenterrangeUplimit = e.CenterrangeUplimit,
|
|
CenterXiandu = e.CenterXiandu, ValidLolimit = e.ValidLolimit, ValidUplimit = e.ValidUplimit,
|
|
XiaoyeLolimit = e.XiaoyeLolimit, XiaoyeUplimit = e.XiaoyeUplimit,
|
|
DayeLolimit = e.DayeLolimit, DayeUplimit = e.DayeUplimit,
|
|
TeyeLolimit = e.TeyeLolimit, TeyeUplimit = e.TeyeUplimit,
|
|
YexianNkLolimitLeft = e.YexianNkLolimitLeft, YexianNkLolimitRight = e.YexianNkLolimitRight,
|
|
YexianNkUplimitLeft = e.YexianNkUplimitLeft, YexianNkUplimitRight = e.YexianNkUplimitRight,
|
|
LaodongJingsaiYexianLolimit = e.LaodongJingsaiYexianLolimit, LaodongJingsaiYexianUplimit = e.LaodongJingsaiYexianUplimit,
|
|
Sort = e.Sort, Memo = e.Memo
|
|
};
|
|
}
|
|
|
|
// ==================== 生丝定级指标 ====================
|
|
public interface IShengsiDingjizhibiaoService
|
|
{
|
|
Task<PageResult<ShengsiDingjizhibiaoDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword, int? standard, string guige);
|
|
Task<ShengsiDingjizhibiaoDto> CreateAsync(ShengsiDingjizhibiaoDto dto);
|
|
Task<ShengsiDingjizhibiaoDto> UpdateAsync(long id, ShengsiDingjizhibiaoDto dto);
|
|
Task DeleteAsync(long id);
|
|
}
|
|
|
|
public class ShengsiDingjizhibiaoService : IShengsiDingjizhibiaoService
|
|
{
|
|
private readonly IRepository<ShengsiDingjizhibiao> _repo;
|
|
public ShengsiDingjizhibiaoService(IRepository<ShengsiDingjizhibiao> repo) => _repo = repo;
|
|
|
|
private static string StandardName(int v) => v switch { 0 => "厂标", 1 => "国标", 2 => "个人", _ => "" };
|
|
|
|
public async Task<PageResult<ShengsiDingjizhibiaoDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword, int? standard, string guige)
|
|
{
|
|
var all = await _repo.GetAllAsync();
|
|
var q = all.AsQueryable();
|
|
if (!string.IsNullOrWhiteSpace(keyword)) q = q.Where(x => x.Grade.Contains(keyword));
|
|
if (standard.HasValue) q = q.Where(x => x.Standard == standard.Value);
|
|
if (!string.IsNullOrWhiteSpace(guige)) q = q.Where(x => x.Guige == guige);
|
|
var total = q.LongCount();
|
|
var items = q.OrderBy(x => x.Standard).ThenBy(x => x.Guige).ThenBy(x => x.GradeScore)
|
|
.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
|
|
return new PageResult<ShengsiDingjizhibiaoDto> { Items = items.Select(ToDto).ToList(), Total = total, PageIndex = pageIndex, PageSize = pageSize };
|
|
}
|
|
|
|
public async Task<ShengsiDingjizhibiaoDto> CreateAsync(ShengsiDingjizhibiaoDto dto)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(dto.Grade)) throw new ServiceException("等级不能为空");
|
|
var e = Map(new ShengsiDingjizhibiao(), dto);
|
|
await _repo.AddAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return ToDto(e);
|
|
}
|
|
|
|
public async Task<ShengsiDingjizhibiaoDto> UpdateAsync(long id, ShengsiDingjizhibiaoDto dto)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
Map(e, dto);
|
|
await _repo.UpdateAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return ToDto(e);
|
|
}
|
|
|
|
public async Task DeleteAsync(long id)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
await _repo.DeleteAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
}
|
|
|
|
private static ShengsiDingjizhibiao Map(ShengsiDingjizhibiao e, ShengsiDingjizhibiaoDto d)
|
|
{
|
|
e.Standard = d.Standard; e.Guige = d.Guige; e.Grade = d.Grade; e.GradeScore = d.GradeScore;
|
|
e.Piancha = d.Piancha; e.Dacha = d.Dacha; e.Erdu = d.Erdu; e.Sandu = d.Sandu;
|
|
e.Qingjie = d.Qingjie; e.Jiejing = d.Jiejing;
|
|
return e;
|
|
}
|
|
|
|
private static ShengsiDingjizhibiaoDto ToDto(ShengsiDingjizhibiao e) => new()
|
|
{
|
|
Id = e.Id, Standard = e.Standard, StandardName = StandardName(e.Standard), Guige = e.Guige, Grade = e.Grade,
|
|
GradeScore = e.GradeScore, Piancha = e.Piancha, Dacha = e.Dacha, Erdu = e.Erdu, Sandu = e.Sandu,
|
|
Qingjie = e.Qingjie, Jiejing = e.Jiejing
|
|
};
|
|
}
|
|
|
|
// ==================== 机组车台 ====================
|
|
public interface IJizuChetaiService
|
|
{
|
|
Task<PageResult<JizuChetaiDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword);
|
|
Task<JizuChetaiDto> GetByDepIdAndJizuAsync(long deptId, int jizu);
|
|
Task<JizuChetaiDto> CreateAsync(JizuChetaiDto dto);
|
|
Task<JizuChetaiDto> UpdateAsync(long id, JizuChetaiDto dto);
|
|
Task DeleteAsync(long id);
|
|
|
|
/// <summary>车间下拉:只取职责类型为「前缫」的部门</summary>
|
|
Task<List<DeptOptionDto>> GetQianxianDepsAsync();
|
|
}
|
|
|
|
public class JizuChetaiService : IJizuChetaiService
|
|
{
|
|
private readonly IRepository<JizuChetai> _repo;
|
|
private readonly IRepository<SysDept.Department> _deptRepo;
|
|
public JizuChetaiService(IRepository<JizuChetai> repo, IRepository<SysDept.Department> deptRepo)
|
|
{
|
|
_repo = repo; _deptRepo = deptRepo;
|
|
}
|
|
|
|
public async Task<PageResult<JizuChetaiDto>> GetPagedAsync(int pageIndex, int pageSize, string keyword)
|
|
{
|
|
var all = await _repo.GetAllAsync();
|
|
var q = all.AsQueryable();
|
|
var depts = await _deptRepo.GetAllAsync();
|
|
var deptDict = depts.ToDictionary(d => d.Id, d => d.Name);
|
|
|
|
if (!string.IsNullOrWhiteSpace(keyword))
|
|
{
|
|
var kwDeptIds = depts.Where(d => d.Name.Contains(keyword)).Select(d => d.Id).ToHashSet();
|
|
q = q.Where(x => kwDeptIds.Contains(x.DepartmentId) || x.Jizu.ToString().Contains(keyword));
|
|
}
|
|
var total = q.LongCount();
|
|
var items = q.OrderBy(x => x.DepartmentId).ThenBy(x => x.Jizu).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
|
|
return new PageResult<JizuChetaiDto>
|
|
{
|
|
Items = items.Select(x => new JizuChetaiDto
|
|
{
|
|
Id = x.Id, DepartmentId = x.DepartmentId, DepartmentName = deptDict.GetValueOrDefault(x.DepartmentId, ""),
|
|
Jizu = x.Jizu, ChetaiStart = x.ChetaiStart, ChetaiEnd = x.ChetaiEnd
|
|
}).ToList(),
|
|
Total = total, PageIndex = pageIndex, PageSize = pageSize
|
|
};
|
|
}
|
|
|
|
public async Task<JizuChetaiDto> GetByDepIdAndJizuAsync(long deptId, int jizu)
|
|
{
|
|
var e = await _repo.FirstOrDefaultAsync(x => x.DepartmentId == deptId && x.Jizu == jizu);
|
|
if (e == null) return null;
|
|
return await GetDto(e);
|
|
}
|
|
|
|
public async Task<JizuChetaiDto> CreateAsync(JizuChetaiDto dto)
|
|
{
|
|
await ValidateAsync(dto, 0);
|
|
var e = new JizuChetai { DepartmentId = dto.DepartmentId, Jizu = dto.Jizu, ChetaiStart = dto.ChetaiStart, ChetaiEnd = dto.ChetaiEnd };
|
|
await _repo.AddAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return await GetDto(e);
|
|
}
|
|
|
|
public async Task<JizuChetaiDto> UpdateAsync(long id, JizuChetaiDto dto)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
await ValidateAsync(dto, id);
|
|
e.DepartmentId = dto.DepartmentId; e.Jizu = dto.Jizu; e.ChetaiStart = dto.ChetaiStart; e.ChetaiEnd = dto.ChetaiEnd;
|
|
await _repo.UpdateAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
return await GetDto(e);
|
|
}
|
|
|
|
/// <summary>校验:车间、机组号、车台范围必填且合理,同一车间的机组不可重复</summary>
|
|
private async Task ValidateAsync(JizuChetaiDto dto, long excludeId)
|
|
{
|
|
if (dto.DepartmentId <= 0) throw new ServiceException("请选择车间");
|
|
if (dto.Jizu <= 0) throw new ServiceException("机组号必须大于 0");
|
|
if (dto.ChetaiStart <= 0) throw new ServiceException("开始车台号必须大于 0");
|
|
if (dto.ChetaiEnd < dto.ChetaiStart) throw new ServiceException("结束车台号不能小于开始车台号");
|
|
|
|
var all = await _repo.GetAllAsync();
|
|
if (all.Any(x => x.Id != excludeId && x.DepartmentId == dto.DepartmentId && x.Jizu == dto.Jizu))
|
|
throw new ServiceException("该车间的此机组已存在,请勿重复配置");
|
|
}
|
|
|
|
public async Task<List<DeptOptionDto>> GetQianxianDepsAsync()
|
|
{
|
|
var depts = await _deptRepo.GetAllAsync();
|
|
return depts
|
|
.Where(d => d.DutyType == Department_DutyType_Enum.前缫)
|
|
.OrderBy(d => d.SortOrder).ThenBy(d => d.Id)
|
|
.Select(d => new DeptOptionDto { Id = d.Id, Name = d.Name })
|
|
.ToList();
|
|
}
|
|
|
|
public async Task DeleteAsync(long id)
|
|
{
|
|
var e = await _repo.GetByIdAsync(id);
|
|
if (e == null) throw new ServiceException("记录不存在", 404);
|
|
await _repo.DeleteAsync(e);
|
|
await _repo.SaveChangesAsync();
|
|
}
|
|
|
|
private async Task<JizuChetaiDto> GetDto(JizuChetai e)
|
|
{
|
|
var dept = await _deptRepo.GetByIdAsync(e.DepartmentId);
|
|
return new JizuChetaiDto { Id = e.Id, DepartmentId = e.DepartmentId, DepartmentName = dept?.Name ?? "", Jizu = e.Jizu, ChetaiStart = e.ChetaiStart, ChetaiEnd = e.ChetaiEnd };
|
|
}
|
|
}
|