using Admin.NET.Plugin.AiDOP.Dto.S0.Manufacturing; using Admin.NET.Plugin.AiDOP.Dto.S0.Sales; using Admin.NET.Plugin.AiDOP.Entity.S0.Manufacturing; using Admin.NET.Plugin.AiDOP.Infrastructure; namespace Admin.NET.Plugin.AiDOP.Controllers.S0.Manufacturing; [ApiController] [Route("api/s0/manufacturing/line-posts")] [AllowAnonymous] [NonUnify] public class AdoS0MfgLinePostsController : ControllerBase { private readonly SqlSugarRepository _postRep; private readonly SqlSugarRepository _skillRep; private readonly SqlSugarRepository _personSkillRep; private readonly SqlSugarRepository _lineMasterRep; public AdoS0MfgLinePostsController( SqlSugarRepository postRep, SqlSugarRepository skillRep, SqlSugarRepository personSkillRep, SqlSugarRepository lineMasterRep) { _postRep = postRep; _skillRep = skillRep; _personSkillRep = personSkillRep; _lineMasterRep = lineMasterRep; } [HttpGet] public async Task GetPagedAsync([FromQuery] AdoS0LineSkillMasterQueryDto q) { var page = q.Page; var pageSize = q.PageSize; (page, pageSize) = PagingGuard.Normalize(page, pageSize); var domain = q.Domain.Trim(); var query = _postRep.AsQueryable() .Where(x => x.Domain == domain) .WhereIF(!string.IsNullOrWhiteSpace(q.Keyword), x => x.ProdLine.Contains(q.Keyword!) || x.JOBNo.Contains(q.Keyword!) || (x.JOBDescr != null && x.JOBDescr.Contains(q.Keyword!))); var total = await query.CountAsync(); var list = await query .OrderByDescending(x => x.UpdateTime ?? x.CreateTime) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(); // 补展示字段:ProdLine + Describe var lineCodes = list.Select(x => x.ProdLine).Distinct().ToList(); var lineMap = await _lineMasterRep.AsQueryable() .Where(lm => lm.Domain == domain && lineCodes.Contains(lm.Line)) .ToListAsync(); var describeByLine = lineMap.ToDictionary(x => x.Line, x => x.Describe ?? string.Empty); var shaped = list.Select(x => new { id = x.Id, domain = x.Domain, prodLine = x.ProdLine, prodLineDisplay = $"{x.ProdLine} { (describeByLine.TryGetValue(x.ProdLine, out var d) ? d : string.Empty) }".Trim(), jobNo = x.JOBNo, jobDescr = x.JOBDescr, createUser = x.CreateUser, createTime = x.CreateTime, updateUser = x.UpdateUser, updateTime = x.UpdateTime }).ToList(); return Ok(new { total, page, pageSize, list = shaped }); } [HttpGet("{id:long}")] public async Task GetDetailAsync(long id) { var header = await _postRep.GetByIdAsync(id); if (header == null) return NotFound(); var skills = await _skillRep.AsQueryable() .Where(x => x.LineSkillMasterId == id) .OrderBy(x => x.Id) .ToListAsync(); return Ok(new { header, linePostSkills = skills }); } [HttpPost] public async Task CreateAsync([FromBody] AdoS0LineSkillMasterUpsertDto dto) { var fkErr = await ValidatePersonSkillsAsync(dto); if (fkErr != null) return BadRequest(new { message = fkErr }); var db = _postRep.Context; await db.Ado.BeginTranAsync(); try { var now = DateTime.Now; var post = new AdoS0LineSkillMaster { Domain = dto.Domain.Trim(), ProdLine = dto.ProdLine.Trim(), JOBNo = dto.JOBNo.Trim(), JOBDescr = dto.JOBDescr, CreateUser = dto.CreateUser ?? dto.UpdateUser, CreateTime = dto.CreateTime ?? dto.UpdateTime ?? now, UpdateUser = dto.UpdateUser, UpdateTime = dto.UpdateTime }; post = await _postRep.AsInsertable(post).ExecuteReturnEntityAsync(); foreach (var s in dto.Skills) { var row = MapSkill(post.Id, s); await _skillRep.AsInsertable(row).ExecuteCommandAsync(); } await db.Ado.CommitTranAsync(); return await GetDetailAsync(post.Id); } catch { await db.Ado.RollbackTranAsync(); throw; } } [HttpPut("{id:long}")] public async Task UpdateAsync(long id, [FromBody] AdoS0LineSkillMasterUpsertDto dto) { var header = await _postRep.GetByIdAsync(id); if (header == null) return NotFound(); var fkErr = await ValidatePersonSkillsAsync(dto); if (fkErr != null) return BadRequest(new { message = fkErr }); var db = _postRep.Context; await db.Ado.BeginTranAsync(); try { header.Domain = dto.Domain.Trim(); header.ProdLine = dto.ProdLine.Trim(); header.JOBNo = dto.JOBNo.Trim(); header.JOBDescr = dto.JOBDescr; header.UpdateUser = dto.UpdateUser; header.UpdateTime = dto.UpdateTime ?? DateTime.Now; await _postRep.AsUpdateable(header).ExecuteCommandAsync(); await _skillRep.AsDeleteable().Where(x => x.LineSkillMasterId == id).ExecuteCommandAsync(); foreach (var s in dto.Skills) { var row = MapSkill(id, s); await _skillRep.AsInsertable(row).ExecuteCommandAsync(); } await db.Ado.CommitTranAsync(); return await GetDetailAsync(id); } catch { await db.Ado.RollbackTranAsync(); throw; } } [HttpDelete("{id:long}")] public async Task DeleteAsync(long id) { var header = await _postRep.GetByIdAsync(id); if (header == null) return NotFound(); var db = _postRep.Context; await db.Ado.BeginTranAsync(); try { await _skillRep.AsDeleteable().Where(x => x.LineSkillMasterId == id).ExecuteCommandAsync(); await _postRep.DeleteAsync(header); await db.Ado.CommitTranAsync(); return Ok(new { message = "删除成功" }); } catch { await db.Ado.RollbackTranAsync(); throw; } } private async Task ValidatePersonSkillsAsync(AdoS0LineSkillMasterUpsertDto dto) { if (dto.Skills == null || dto.Skills.Count == 0) return null; var ids = dto.Skills.Select(s => s.PersonSkillId).Distinct().ToList(); var cnt = await _personSkillRep.AsQueryable() .Where(p => ids.Contains(p.Id)) .CountAsync(); return cnt == ids.Count ? null : "存在无效的人员技能主数据引用"; } private static AdoS0LineSkillDetail MapSkill(long lineSkillMasterId, AdoS0LineSkillDetailUpsertDto s) { return new AdoS0LineSkillDetail { LineSkillMasterId = lineSkillMasterId, PersonSkillId = s.PersonSkillId, RequiredLevel = s.RequiredLevel, Remark = s.Remark, EffectiveDate = s.EffectiveDate, IsEnabled = s.IsEnabled, CreateTime = DateTime.Now }; } }