WorkOrderDispatchService.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. namespace Admin.NET.Plugin.AiDOP.WorkOrder;
  2. /// <summary>
  3. /// 工单下达服务 🏭
  4. /// 路由前缀:/api/WorkOrder/dispatch/...
  5. /// </summary>
  6. [ApiDescriptionSettings(Order = 260, Description = "工单下达")]
  7. [Route("api/WorkOrder")]
  8. [AllowAnonymous]
  9. [NonUnify]
  10. public class WorkOrderDispatchService : IDynamicApiController, ITransient
  11. {
  12. private readonly ISqlSugarClient _db;
  13. private readonly UserManager _userManager;
  14. public WorkOrderDispatchService(ISqlSugarClient db, UserManager userManager)
  15. {
  16. _db = db;
  17. _userManager = userManager;
  18. }
  19. // ══════════════════════════════════════════════════════════════
  20. // 列表 GET /api/WorkOrder/dispatch/list
  21. // ══════════════════════════════════════════════════════════════
  22. /// <summary>获取工单下达分页列表 🏭</summary>
  23. [DisplayName("获取工单下达列表")]
  24. [HttpGet("dispatch/list")]
  25. public async Task<object> GetDispatchList([FromQuery] WorkOrderDispatchListInput input)
  26. {
  27. var pars = new List<SugarParameter>();
  28. var conditions = new List<string> { "a.Status = 'p'" };
  29. if (!string.IsNullOrWhiteSpace(input.WorkOrd))
  30. {
  31. conditions.Add("a.WorkOrd LIKE @WorkOrd");
  32. pars.Add(new SugarParameter("@WorkOrd", $"%{input.WorkOrd.Trim()}%"));
  33. }
  34. if (!string.IsNullOrWhiteSpace(input.ItemNum))
  35. {
  36. conditions.Add("a.ItemNum LIKE @ItemNum");
  37. pars.Add(new SugarParameter("@ItemNum", $"%{input.ItemNum.Trim()}%"));
  38. }
  39. if (!string.IsNullOrWhiteSpace(input.Descr))
  40. {
  41. conditions.Add("b.Descr LIKE @Descr");
  42. pars.Add(new SugarParameter("@Descr", $"%{input.Descr.Trim()}%"));
  43. }
  44. if (!string.IsNullOrWhiteSpace(input.OrdDateFrom))
  45. {
  46. conditions.Add("a.OrdDate >= @OrdDateFrom");
  47. pars.Add(new SugarParameter("@OrdDateFrom", input.OrdDateFrom.Trim()));
  48. }
  49. var whereClause = "WHERE " + string.Join(" AND ", conditions);
  50. var baseSql = $"""
  51. SELECT
  52. a.RecID AS Id,
  53. a.Domain,
  54. a.WorkOrd,
  55. a.Priority,
  56. a.ItemNum,
  57. b.Descr,
  58. b.Descr1,
  59. a.QtyOrded,
  60. m.MaterialSituation,
  61. a.OrdDate,
  62. a.DueDate,
  63. LOWER(a.Status) AS Status,
  64. a.LotSerial,
  65. IFNULL(nm.Nbr,'') AS PrevNbr,
  66. IFNULL(nm1.Nbr,'') AS Nbr,
  67. CONCAT(IFNULL(b.ItemNum,''), IFNULL(b.Descr,''), IFNULL(b.Descr1,'')) AS Wl
  68. FROM WorkOrdMaster a
  69. LEFT JOIN ItemMaster b ON a.ItemNum = b.ItemNum
  70. LEFT JOIN mes_morder m ON a.WorkOrd = m.morder_no AND a.Domain = m.factory_id
  71. LEFT JOIN NbrMaster nm
  72. ON a.Domain = nm.Domain AND a.WorkOrd = nm.WorkOrd
  73. AND nm.Type = 'SM' AND nm.TransType = 'PrevProcess'
  74. LEFT JOIN NbrMaster nm1
  75. ON a.Domain = nm1.Domain AND a.WorkOrd = nm1.WorkOrd
  76. AND nm1.Type = 'SM' AND nm1.TransType = ''
  77. {whereClause}
  78. """;
  79. var offset = (input.Page - 1) * input.PageSize;
  80. var total = await _db.Ado.GetIntAsync(
  81. $"SELECT COUNT(*) FROM ({baseSql}) AS t", pars);
  82. var list = await _db.Ado.SqlQueryAsync<WorkOrderDispatchRow>(
  83. $"SELECT * FROM ({baseSql}) AS t ORDER BY t.Id DESC LIMIT {input.PageSize} OFFSET {offset}",
  84. pars);
  85. return new { total, page = input.Page, pageSize = input.PageSize, list };
  86. }
  87. // ══════════════════════════════════════════════════════════════
  88. // 工单下达 POST /api/WorkOrder/dispatch/release
  89. // ══════════════════════════════════════════════════════════════
  90. /// <summary>工单下达(更新开工日期、生产批号,状态改为 r)🏭</summary>
  91. [DisplayName("工单下达")]
  92. [ApiDescriptionSettings(Name = "ReleaseWorkOrder"), HttpPost("dispatch/release")]
  93. public async Task<object> ReleaseWorkOrder([FromBody] WorkOrderReleaseInput input)
  94. {
  95. // 参照 SysJobService.UpdateJobDetail:先查再改
  96. var pars = new List<SugarParameter>
  97. {
  98. new SugarParameter("@WorkOrd", input.WorkOrd),
  99. new SugarParameter("@Domain", input.Domain)
  100. };
  101. var exists = await _db.Ado.GetIntAsync(
  102. "SELECT COUNT(*) FROM WorkOrdMaster WHERE WorkOrd = @WorkOrd AND Domain = @Domain AND Status = 'p'",
  103. pars);
  104. if (exists == 0)
  105. throw Oops.Oh("工单不存在或状态不为初始(p),无法下达");
  106. var ordDate = string.IsNullOrWhiteSpace(input.OrdDate)
  107. ? (DateTime?)null
  108. : DateTime.Parse(input.OrdDate);
  109. var releaseDate = DateTime.Now;
  110. var account = _userManager.Account ?? "system";
  111. var updatePars = new List<SugarParameter>
  112. {
  113. new SugarParameter("@Status", "r"),
  114. new SugarParameter("@OrdDate", ordDate),
  115. new SugarParameter("@LotSerial", input.LotSerial ?? (object)DBNull.Value),
  116. new SugarParameter("@ReleaseDate", releaseDate),
  117. new SugarParameter("@UpdateUser", account),
  118. new SugarParameter("@UpdateTime", releaseDate),
  119. new SugarParameter("@WorkOrd", input.WorkOrd),
  120. new SugarParameter("@Domain", input.Domain)
  121. };
  122. await _db.Ado.ExecuteCommandAsync(
  123. """
  124. UPDATE WorkOrdMaster
  125. SET Status = @Status,
  126. OrdDate = @OrdDate,
  127. LotSerial = @LotSerial,
  128. ReleaseDate = @ReleaseDate,
  129. UpdateUser = @UpdateUser,
  130. UpdateTime = @UpdateTime
  131. WHERE WorkOrd = @WorkOrd AND Domain = @Domain
  132. """,
  133. updatePars);
  134. return new { message = "工单下达成功" };
  135. }
  136. // ──────────────── 内部查询结果映射类 ────────────────
  137. private sealed class WorkOrderDispatchRow
  138. {
  139. public int Id { get; set; }
  140. public string? Domain { get; set; }
  141. public string? WorkOrd { get; set; }
  142. public string? Priority { get; set; }
  143. public string? ItemNum { get; set; }
  144. public string? Descr { get; set; }
  145. public string? Descr1 { get; set; }
  146. public decimal? QtyOrded { get; set; }
  147. public string? MaterialSituation { get; set; }
  148. public DateTime? OrdDate { get; set; }
  149. public DateTime? DueDate { get; set; }
  150. public string? Status { get; set; }
  151. public string? LotSerial { get; set; }
  152. public string? PrevNbr { get; set; }
  153. public string? Nbr { get; set; }
  154. public string? Wl { get; set; }
  155. }
  156. }