AdoS0MfgLinePostsController.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using Admin.NET.Plugin.AiDOP.Dto.S0.Manufacturing;
  2. using Admin.NET.Plugin.AiDOP.Dto.S0.Sales;
  3. using Admin.NET.Plugin.AiDOP.Entity.S0.Manufacturing;
  4. using Admin.NET.Plugin.AiDOP.Infrastructure;
  5. namespace Admin.NET.Plugin.AiDOP.Controllers.S0.Manufacturing;
  6. [ApiController]
  7. [Route("api/s0/manufacturing/line-posts")]
  8. [NonUnify]
  9. public class AdoS0MfgLinePostsController : ControllerBase
  10. {
  11. private readonly SqlSugarRepository<AdoS0LineSkillMaster> _postRep;
  12. private readonly SqlSugarRepository<AdoS0LineSkillDetail> _skillRep;
  13. private readonly SqlSugarRepository<AdoS0MfgPersonSkill> _personSkillRep;
  14. private readonly SqlSugarRepository<AdoS0LineMaster> _lineMasterRep;
  15. public AdoS0MfgLinePostsController(
  16. SqlSugarRepository<AdoS0LineSkillMaster> postRep,
  17. SqlSugarRepository<AdoS0LineSkillDetail> skillRep,
  18. SqlSugarRepository<AdoS0MfgPersonSkill> personSkillRep,
  19. SqlSugarRepository<AdoS0LineMaster> lineMasterRep)
  20. {
  21. _postRep = postRep;
  22. _skillRep = skillRep;
  23. _personSkillRep = personSkillRep;
  24. _lineMasterRep = lineMasterRep;
  25. }
  26. [HttpGet]
  27. public async Task<IActionResult> GetPagedAsync([FromQuery] AdoS0LineSkillMasterQueryDto q)
  28. {
  29. if (!AdoS0TenantScope.TryResolveRequired(out var tenantId, out var tenantError)) return tenantError!;
  30. var page = q.Page;
  31. var pageSize = q.PageSize;
  32. (page, pageSize) = PagingGuard.Normalize(page, pageSize);
  33. var domain = q.Domain?.Trim();
  34. var query = _postRep.ScopedTo(tenantId)
  35. .WhereIF(!string.IsNullOrWhiteSpace(domain), x => x.Domain == domain)
  36. .WhereIF(!string.IsNullOrWhiteSpace(q.Keyword),
  37. x => x.ProdLine.Contains(q.Keyword!) || x.JOBNo.Contains(q.Keyword!) || (x.JOBDescr != null && x.JOBDescr.Contains(q.Keyword!)));
  38. var total = await query.CountAsync();
  39. var list = await query
  40. .OrderByDescending(x => x.UpdateTime ?? x.CreateTime)
  41. .Skip((page - 1) * pageSize)
  42. .Take(pageSize)
  43. .ToListAsync();
  44. // 补展示字段:按 (Domain, ProdLine) 元组反查 LineMaster.Describe,避免跨域错配
  45. var domains = list.Select(x => x.Domain).Distinct().ToList();
  46. var lineCodes = list.Select(x => x.ProdLine).Distinct().ToList();
  47. var lineMap = await _lineMasterRep.ScopedTo(tenantId)
  48. .Where(lm => domains.Contains(lm.Domain) && lineCodes.Contains(lm.Line))
  49. .Select(lm => new { lm.Domain, lm.Line, lm.Describe })
  50. .ToListAsync();
  51. var describeByKey = lineMap
  52. .GroupBy(x => (x.Domain, x.Line))
  53. .ToDictionary(g => g.Key, g => g.First().Describe ?? string.Empty);
  54. var shaped = list.Select(x => new
  55. {
  56. id = x.Id,
  57. domain = x.Domain,
  58. prodLine = x.ProdLine,
  59. prodLineDisplay = $"{x.ProdLine} {(describeByKey.TryGetValue((x.Domain, x.ProdLine), out var d) ? d : string.Empty)}".Trim(),
  60. jobNo = x.JOBNo,
  61. jobDescr = x.JOBDescr,
  62. site = x.Site,
  63. orderby = x.Orderby,
  64. wType = x.WType,
  65. runCrew = x.RunCrew,
  66. createUser = x.CreateUser,
  67. createTime = x.CreateTime,
  68. updateUser = x.UpdateUser,
  69. updateTime = x.UpdateTime
  70. }).ToList();
  71. return Ok(new { total, page, pageSize, list = shaped });
  72. }
  73. [HttpGet("{id:long}")]
  74. public async Task<IActionResult> GetDetailAsync(long id)
  75. {
  76. if (!AdoS0TenantScope.TryResolveRequired(out var tenantId, out var tenantError)) return tenantError!;
  77. var header = await _postRep.ByIdScopedAsync(id, tenantId);
  78. if (header == null) return NotFound();
  79. var skills = await _skillRep.ScopedTo(tenantId)
  80. .Where(x => x.LineSkillMasterId == id)
  81. .OrderBy(x => x.Id)
  82. .ToListAsync();
  83. return Ok(new { header, linePostSkills = skills });
  84. }
  85. [HttpPost]
  86. public async Task<IActionResult> CreateAsync([FromBody] AdoS0LineSkillMasterUpsertDto dto)
  87. {
  88. if (!AdoS0TenantScope.TryResolveRequired(out var tenantId, out var tenantError)) return tenantError!;
  89. var fkErr = await ValidatePersonSkillsAsync(dto, tenantId);
  90. if (fkErr != null) return BadRequest(new { message = fkErr });
  91. var db = _postRep.Context;
  92. await db.Ado.BeginTranAsync();
  93. try
  94. {
  95. var now = DateTime.Now;
  96. var post = new AdoS0LineSkillMaster
  97. {
  98. TenantId = tenantId,
  99. Domain = dto.Domain.Trim(),
  100. ProdLine = dto.ProdLine.Trim(),
  101. JOBNo = dto.JOBNo.Trim(),
  102. JOBDescr = dto.JOBDescr,
  103. Site = dto.Site,
  104. Orderby = dto.Orderby,
  105. WType = dto.WType,
  106. RunCrew = dto.RunCrew,
  107. CreateUser = dto.CreateUser ?? dto.UpdateUser,
  108. CreateTime = dto.CreateTime ?? dto.UpdateTime ?? now,
  109. UpdateUser = dto.UpdateUser,
  110. UpdateTime = dto.UpdateTime
  111. };
  112. post = await _postRep.AsInsertable(post).ExecuteReturnEntityAsync();
  113. foreach (var s in dto.Skills)
  114. {
  115. var row = MapSkill(post.Id, s, tenantId);
  116. await _skillRep.AsInsertable(row).ExecuteCommandAsync();
  117. }
  118. await db.Ado.CommitTranAsync();
  119. return await GetDetailAsync(post.Id);
  120. }
  121. catch
  122. {
  123. await db.Ado.RollbackTranAsync();
  124. throw;
  125. }
  126. }
  127. [HttpPut("{id:long}")]
  128. public async Task<IActionResult> UpdateAsync(long id, [FromBody] AdoS0LineSkillMasterUpsertDto dto)
  129. {
  130. if (!AdoS0TenantScope.TryResolveRequired(out var tenantId, out var tenantError)) return tenantError!;
  131. var header = await _postRep.ByIdScopedAsync(id, tenantId);
  132. if (header == null) return NotFound();
  133. var fkErr = await ValidatePersonSkillsAsync(dto, tenantId);
  134. if (fkErr != null) return BadRequest(new { message = fkErr });
  135. var db = _postRep.Context;
  136. await db.Ado.BeginTranAsync();
  137. try
  138. {
  139. header.Domain = dto.Domain.Trim();
  140. header.ProdLine = dto.ProdLine.Trim();
  141. header.JOBNo = dto.JOBNo.Trim();
  142. header.JOBDescr = dto.JOBDescr;
  143. header.Site = dto.Site;
  144. header.Orderby = dto.Orderby;
  145. header.WType = dto.WType;
  146. header.RunCrew = dto.RunCrew;
  147. header.UpdateUser = dto.UpdateUser;
  148. header.UpdateTime = dto.UpdateTime ?? DateTime.Now;
  149. await _postRep.AsUpdateable(header).ExecuteCommandAsync();
  150. await _skillRep.AsDeleteable().Where(x => x.LineSkillMasterId == id).ExecuteCommandAsync();
  151. foreach (var s in dto.Skills)
  152. {
  153. var row = MapSkill(id, s, tenantId);
  154. await _skillRep.AsInsertable(row).ExecuteCommandAsync();
  155. }
  156. await db.Ado.CommitTranAsync();
  157. return await GetDetailAsync(id);
  158. }
  159. catch
  160. {
  161. await db.Ado.RollbackTranAsync();
  162. throw;
  163. }
  164. }
  165. [HttpDelete("{id:long}")]
  166. public async Task<IActionResult> DeleteAsync(long id)
  167. {
  168. if (!AdoS0TenantScope.TryResolveRequired(out var tenantId, out var tenantError)) return tenantError!;
  169. var header = await _postRep.ByIdScopedAsync(id, tenantId);
  170. if (header == null) return NotFound();
  171. var db = _postRep.Context;
  172. await db.Ado.BeginTranAsync();
  173. try
  174. {
  175. await _skillRep.AsDeleteable().Where(x => x.LineSkillMasterId == id).ExecuteCommandAsync();
  176. await _postRep.DeleteAsync(header);
  177. await db.Ado.CommitTranAsync();
  178. return Ok(new { message = "删除成功" });
  179. }
  180. catch
  181. {
  182. await db.Ado.RollbackTranAsync();
  183. throw;
  184. }
  185. }
  186. private async Task<string?> ValidatePersonSkillsAsync(AdoS0LineSkillMasterUpsertDto dto, long tenantId)
  187. {
  188. if (dto.Skills == null || dto.Skills.Count == 0)
  189. return null;
  190. var ids = dto.Skills.Select(s => s.PersonSkillId).Distinct().ToList();
  191. var cnt = await _personSkillRep.ScopedTo(tenantId)
  192. .Where(p => ids.Contains(p.Id))
  193. .CountAsync();
  194. return cnt == ids.Count ? null : "存在无效的人员技能主数据引用";
  195. }
  196. private static AdoS0LineSkillDetail MapSkill(long lineSkillMasterId, AdoS0LineSkillDetailUpsertDto s, long tenantId)
  197. {
  198. return new AdoS0LineSkillDetail
  199. {
  200. TenantId = tenantId,
  201. LineSkillMasterId = lineSkillMasterId,
  202. PersonSkillId = s.PersonSkillId,
  203. RequiredLevel = s.RequiredLevel,
  204. Remark = s.Remark,
  205. EffectiveDate = s.EffectiveDate,
  206. IsEnabled = s.IsEnabled,
  207. CreateTime = DateTime.Now
  208. };
  209. }
  210. }