Files
yanpeng200212 1f1b184411 新增工资/仓储/生产日报等模块,移除旧考勤模块
- 新增 PayRoll(工资)、Wms(仓储)、Prod(车速/缫丝/考勤/丝片检测/丝片台账/纤检日报/质量日报) 模块
- 新增对应 Domain 实体、Application DTO/Service、Api Controller 与前端页面
- 移除旧 Attendance 考勤模块(Controller/Service/Entity/DTO 及 5 个前端页面),由 Prod/Kaoqin 取代
- 调整路由、仪表盘、Lsjl 流丝记录实体与服务
- 更新业务种子数据与 DbSeeder
- 补充工作进度文档 14-27
2026-10-27 09:09:57 +08:00

189 lines
7.9 KiB
C#

using F9WebAiTest.Application.Common;
using F9WebAiTest.Application.Dtos.Prod;
using F9WebAiTest.Domain.Common;
using F9WebAiTest.Domain.Entities.Base;
using F9WebAiTest.Domain.Entities.Prod;
using SysDept = F9WebAiTest.Domain.Entities.SYS.Departments;
namespace F9WebAiTest.Application.Services.Prod;
/// <summary>丝片检查:按「日期 + 车间 + 工艺庄口 + 规格」记录前缫/后缫疵点片数</summary>
public interface ISpjcService
{
Task<PageResult<SpjcListItemDto>> GetPagedAsync(int pageIndex, int pageSize, DateTime? date, long? deptId, string like);
Task<SpjcSaveDto> GetForEditAsync(long id);
Task<long> SaveAsync(SpjcSaveDto dto);
Task DeleteAsync(long id);
}
public class SpjcService : ISpjcService
{
private readonly IRepository<Spjc> _spjcRepo;
private readonly IRepository<SysDept.Department> _deptRepo;
private readonly IRepository<CraftZhuangKou> _zkRepo;
public SpjcService(
IRepository<Spjc> spjcRepo,
IRepository<SysDept.Department> deptRepo,
IRepository<CraftZhuangKou> zkRepo)
{
_spjcRepo = spjcRepo;
_deptRepo = deptRepo;
_zkRepo = zkRepo;
}
public async Task<PageResult<SpjcListItemDto>> GetPagedAsync(int pageIndex, int pageSize, DateTime? date, long? deptId, string like)
{
var all = await _spjcRepo.GetAllAsync();
var q = all.AsQueryable();
if (date.HasValue) q = q.Where(x => x.Date.Date == date.Value.Date);
if (deptId.HasValue) q = q.Where(x => x.DeptId == deptId.Value);
var depts = await _deptRepo.GetAllAsync();
var deptDict = depts.ToDictionary(d => d.Id, d => d.Name);
var zks = await _zkRepo.GetAllAsync();
var zkDict = zks.ToDictionary(z => z.Id, z => z.ZhuangKouName);
if (!string.IsNullOrWhiteSpace(like))
{
var kwDeptIds = depts.Where(d => d.Name.Contains(like)).Select(d => d.Id).ToHashSet();
var kwZkIds = zks.Where(z => z.ZhuangKouName.Contains(like)).Select(z => z.Id).ToHashSet();
q = q.Where(x => kwDeptIds.Contains(x.DeptId) || kwZkIds.Contains(x.GyzkId) || x.Guige.Contains(like));
}
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<SpjcListItemDto>
{
Items = items.Select(x => ToListDto(x, deptDict, zkDict)).ToList(),
Total = total, PageIndex = pageIndex, PageSize = pageSize
};
}
public async Task<SpjcSaveDto> GetForEditAsync(long id)
{
var e = await _spjcRepo.GetByIdAsync(id);
if (e == null) throw new ServiceException("丝片检查不存在或已删除", 404);
var dept = await _deptRepo.GetByIdAsync(e.DeptId);
var zk = await _zkRepo.GetByIdAsync(e.GyzkId);
return new SpjcSaveDto
{
Id = e.Id,
Date = e.Date,
DeptId = e.DeptId,
DeptName = dept?.Name ?? "",
GyzkId = e.GyzkId,
GyzkName = zk?.ZhuangKouName ?? "",
Guige = e.Guige,
Pianshu = e.Pianshu,
PianshuXuegong = e.PianshuXuegong,
QsJiahua = e.QsJiahua, QsYouwu = e.QsYouwu, QsHeidian = e.QsHeidian,
QsShangsi = e.QsShangsi, QsYetiao = e.QsYetiao, QsXiaosipian = e.QsXiaosipian, QsQita = e.QsQita,
HsYouwu = e.HsYouwu, HsShangsi = e.HsShangsi, HsShuangsi = e.HsShuangsi, HsZhisi = e.HsZhisi,
HsZhantiao = e.HsZhantiao, HsYingjiao = e.HsYingjiao, HsGuojiao = e.HsGuojiao,
HsShouchu = e.HsShouchu, HsWuran = e.HsWuran, HsLiansi = e.HsLiansi, HsWdmt = e.HsWdmt,
HsMaoluan = e.HsMaoluan, HsQita = e.HsQita,
Memo = e.Memo
};
}
public async Task<long> SaveAsync(SpjcSaveDto dto)
{
if (dto.DeptId == 0) throw new ServiceException("请选择车间");
if (dto.GyzkId == 0) throw new ServiceException("请选择工艺庄口");
if (string.IsNullOrWhiteSpace(dto.Guige)) throw new ServiceException("请选择规格");
var date = dto.Date.Date;
var guige = dto.Guige.Trim();
Spjc e;
if (dto.Id > 0)
{
e = await _spjcRepo.GetByIdAsync(dto.Id);
if (e == null) throw new ServiceException("丝片检查不存在或已删除", 404);
var dup = await _spjcRepo.FirstOrDefaultAsync(x => x.Id != dto.Id && x.Date.Date == date
&& x.DeptId == dto.DeptId && x.GyzkId == dto.GyzkId
&& x.Guige == guige);
if (dup != null) throw new ServiceException("已存在相同的丝片检查!");
}
else
{
var exists = await _spjcRepo.AnyAsync(x => x.Date.Date == date && x.DeptId == dto.DeptId
&& x.GyzkId == dto.GyzkId && x.Guige == guige);
if (exists) throw new ServiceException("已存在相同的丝片检查!");
e = new Spjc();
await _spjcRepo.AddAsync(e);
}
e.Date = date;
e.DeptId = dto.DeptId;
e.GyzkId = dto.GyzkId;
e.Guige = guige;
e.Pianshu = dto.Pianshu;
e.PianshuXuegong = dto.PianshuXuegong;
e.QsJiahua = dto.QsJiahua;
e.QsYouwu = dto.QsYouwu;
e.QsHeidian = dto.QsHeidian;
e.QsShangsi = dto.QsShangsi;
e.QsYetiao = dto.QsYetiao;
e.QsXiaosipian = dto.QsXiaosipian;
e.QsQita = dto.QsQita;
e.HsYouwu = dto.HsYouwu;
e.HsShangsi = dto.HsShangsi;
e.HsShuangsi = dto.HsShuangsi;
e.HsZhisi = dto.HsZhisi;
e.HsZhantiao = dto.HsZhantiao;
e.HsYingjiao = dto.HsYingjiao;
e.HsGuojiao = dto.HsGuojiao;
e.HsShouchu = dto.HsShouchu;
e.HsWuran = dto.HsWuran;
e.HsLiansi = dto.HsLiansi;
e.HsWdmt = dto.HsWdmt;
e.HsMaoluan = dto.HsMaoluan;
e.HsQita = dto.HsQita;
e.Memo = dto.Memo ?? "";
// 合计由服务端重算(与 F9 的 Qs_heji / Hs_heji 一致)
e.QsHeji = e.QsJiahua + e.QsYouwu + e.QsHeidian + e.QsShangsi + e.QsYetiao + e.QsXiaosipian + e.QsQita;
e.HsHeji = e.HsYouwu + e.HsShangsi + e.HsShuangsi + e.HsZhisi + e.HsZhantiao + e.HsYingjiao
+ e.HsGuojiao + e.HsShouchu + e.HsWuran + e.HsLiansi + e.HsWdmt + e.HsMaoluan + e.HsQita;
await _spjcRepo.UpdateAsync(e);
return e.Id;
}
public async Task DeleteAsync(long id)
{
var e = await _spjcRepo.GetByIdAsync(id);
if (e == null) throw new ServiceException("丝片检查不存在或已删除", 404);
// 业务键带唯一索引,物理删除避免「删除后重建」撞索引(与煮茧日报同一策略)
await _spjcRepo.HardDeleteAsync(e);
}
private static SpjcListItemDto ToListDto(Spjc x, Dictionary<long, string> deptDict, Dictionary<long, string> zkDict) => new()
{
Id = x.Id,
Date = x.Date,
DeptId = x.DeptId,
DeptName = deptDict.GetValueOrDefault(x.DeptId, ""),
GyzkId = x.GyzkId,
GyzkName = zkDict.GetValueOrDefault(x.GyzkId, ""),
Guige = x.Guige,
Pianshu = x.Pianshu,
PianshuXuegong = x.PianshuXuegong,
QsJiahua = x.QsJiahua, QsYouwu = x.QsYouwu, QsHeidian = x.QsHeidian,
QsShangsi = x.QsShangsi, QsYetiao = x.QsYetiao, QsXiaosipian = x.QsXiaosipian,
QsQita = x.QsQita, QsHeji = x.QsHeji,
HsYouwu = x.HsYouwu, HsShangsi = x.HsShangsi, HsShuangsi = x.HsShuangsi, HsZhisi = x.HsZhisi,
HsZhantiao = x.HsZhantiao, HsYingjiao = x.HsYingjiao, HsGuojiao = x.HsGuojiao,
HsShouchu = x.HsShouchu, HsWuran = x.HsWuran, HsLiansi = x.HsLiansi, HsWdmt = x.HsWdmt,
HsMaoluan = x.HsMaoluan, HsQita = x.HsQita, HsHeji = x.HsHeji,
Memo = x.Memo
};
}