ScheduleExceptionService.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using Yitter.IdGenerator;
  2. namespace Admin.NET.Plugin.AiDOP.Production;
  3. /// <summary>
  4. /// 排产异常记录服务 🏭
  5. /// 路由前缀:/api/Production/schedule-exception/...
  6. /// </summary>
  7. [ApiDescriptionSettings(Order = 267, Description = "排产异常记录")]
  8. [Route("api/Production")]
  9. [AllowAnonymous]
  10. [NonUnify]
  11. public class ScheduleExceptionService : IDynamicApiController, ITransient
  12. {
  13. private const string C = "utf8mb4_general_ci";
  14. private readonly ISqlSugarClient _db;
  15. private readonly SqlSugarRepository<ScheduleExceptionMaster> _rep;
  16. public ScheduleExceptionService(ISqlSugarClient db, SqlSugarRepository<ScheduleExceptionMaster> rep)
  17. {
  18. _db = db;
  19. _rep = rep;
  20. }
  21. // ══════════════════════════════════════════════════════════════
  22. // 列表 GET /api/Production/schedule-exception/list
  23. // ══════════════════════════════════════════════════════════════
  24. /// <summary>排产异常分页列表(ScheduleExceptionMaster + ItemMaster.Descr1)</summary>
  25. [DisplayName("排产异常记录列表")]
  26. [HttpGet("schedule-exception/list")]
  27. public async Task<object> GetList([FromQuery] ScheduleExceptionListInput input)
  28. {
  29. var pars = new List<SugarParameter>();
  30. var inner = new List<string> { "1=1" };
  31. if (!string.IsNullOrWhiteSpace(input.OptTime))
  32. {
  33. inner.Add($"(CAST(sm.OptTime AS CHAR(50)) COLLATE {C}) LIKE @OptTimeLike");
  34. pars.Add(new SugarParameter("@OptTimeLike", $"%{input.OptTime.Trim()}%"));
  35. }
  36. if (!string.IsNullOrWhiteSpace(input.WorkOrd))
  37. {
  38. inner.Add($"(sm.WorkOrd COLLATE {C}) LIKE @WorkOrd");
  39. pars.Add(new SugarParameter("@WorkOrd", $"%{input.WorkOrd.Trim()}%"));
  40. }
  41. if (!string.IsNullOrWhiteSpace(input.ItemNum))
  42. {
  43. inner.Add($"(sm.ItemNum COLLATE {C}) = @ItemNumEq");
  44. pars.Add(new SugarParameter("@ItemNumEq", input.ItemNum.Trim()));
  45. }
  46. var baseSql = BuildListBaseSql(string.Join(" AND ", inner));
  47. var offset = (input.Page - 1) * input.PageSize;
  48. var total = await _db.Ado.GetIntAsync($"SELECT COUNT(*) FROM ({baseSql}) AS t", pars);
  49. var list = await _db.Ado.SqlQueryAsync<ScheduleExceptionListRow>(
  50. $"SELECT * FROM ({baseSql}) AS t ORDER BY t.Id DESC LIMIT {input.PageSize} OFFSET {offset}", pars);
  51. return new { total, page = input.Page, pageSize = input.PageSize, list };
  52. }
  53. private static string BuildListBaseSql(string innerWhere)
  54. {
  55. const string coll = "utf8mb4_general_ci";
  56. return $"""
  57. SELECT
  58. sm.RecID AS Id,
  59. sm.`Domain` AS Domain,
  60. sm.OptTime AS OptTime,
  61. sm.WorkOrd AS WorkOrd,
  62. sm.ItemNum AS ItemNum,
  63. im.Descr1 AS Descr1,
  64. sm.Remark AS Remark,
  65. sm.Type AS Type
  66. FROM ScheduleExceptionMaster sm
  67. LEFT JOIN ItemMaster im
  68. ON (sm.`Domain` COLLATE {coll}) = (im.`Domain` COLLATE {coll})
  69. AND (sm.ItemNum COLLATE {coll}) = (im.ItemNum COLLATE {coll})
  70. WHERE {innerWhere}
  71. """;
  72. }
  73. // ══════════════════════════════════════════════════════════════
  74. // 详情 GET /api/Production/schedule-exception/{id}
  75. // ══════════════════════════════════════════════════════════════
  76. /// <summary>排产异常详情</summary>
  77. [DisplayName("排产异常记录详情")]
  78. [HttpGet("schedule-exception/{id:long}")]
  79. public async Task<object> GetDetail(long id)
  80. {
  81. var e = await _rep.GetFirstAsync(u => u.RecID == id)
  82. ?? throw Oops.Oh("记录不存在");
  83. return new
  84. {
  85. id = e.RecID,
  86. domain = e.Domain,
  87. workOrd = e.WorkOrd,
  88. itemNum = e.ItemNum,
  89. remark = e.Remark,
  90. type = e.Type,
  91. optTime = e.OptTime,
  92. createTime = e.CreateTime
  93. };
  94. }
  95. // ══════════════════════════════════════════════════════════════
  96. // 保存 POST /api/Production/schedule-exception/save
  97. // ══════════════════════════════════════════════════════════════
  98. /// <summary>保存排产异常(新增或编辑)</summary>
  99. [DisplayName("保存排产异常记录")]
  100. [ApiDescriptionSettings(Name = "SaveScheduleException"), HttpPost("schedule-exception/save")]
  101. public async Task<object> Save([FromBody] ScheduleExceptionSaveInput input)
  102. {
  103. if (input.Id is null or 0)
  104. {
  105. var entity = new ScheduleExceptionMaster
  106. {
  107. RecID = YitIdHelper.NextId(),
  108. Domain = input.Domain.Trim(),
  109. WorkOrd = input.WorkOrd.Trim(),
  110. ItemNum = input.ItemNum.Trim(),
  111. Remark = input.Remark?.Trim(),
  112. Type = input.Type?.Trim(),
  113. OptTime = input.OptTime ?? DateTime.Now,
  114. CreateTime = input.CreateTime ?? DateTime.Now
  115. };
  116. await _rep.InsertAsync(entity);
  117. return new { id = entity.RecID, message = "新增成功" };
  118. }
  119. var exist = await _rep.GetFirstAsync(u => u.RecID == input.Id!.Value)
  120. ?? throw Oops.Oh("记录不存在");
  121. exist.Domain = input.Domain.Trim();
  122. exist.WorkOrd = input.WorkOrd.Trim();
  123. exist.ItemNum = input.ItemNum.Trim();
  124. exist.Remark = input.Remark?.Trim();
  125. exist.Type = input.Type?.Trim();
  126. if (input.OptTime.HasValue) exist.OptTime = input.OptTime;
  127. if (input.CreateTime.HasValue) exist.CreateTime = input.CreateTime;
  128. await _rep.UpdateAsync(exist);
  129. return new { id = exist.RecID, message = "编辑成功" };
  130. }
  131. // ══════════════════════════════════════════════════════════════
  132. // 删除 POST /api/Production/schedule-exception/delete/{id}
  133. // ══════════════════════════════════════════════════════════════
  134. /// <summary>删除排产异常</summary>
  135. [DisplayName("删除排产异常记录")]
  136. [HttpPost("schedule-exception/delete/{id:long}")]
  137. public async Task<object> Delete(long id)
  138. {
  139. var n = await _db.Ado.ExecuteCommandAsync(
  140. "DELETE FROM ScheduleExceptionMaster WHERE RecID = @Id",
  141. new List<SugarParameter> { new("@Id", id) });
  142. if (n == 0)
  143. throw Oops.Oh("记录不存在");
  144. return new { message = "删除成功" };
  145. }
  146. private sealed class ScheduleExceptionListRow
  147. {
  148. public long Id { get; set; }
  149. public string? Domain { get; set; }
  150. public DateTime? OptTime { get; set; }
  151. public string? WorkOrd { get; set; }
  152. public string? ItemNum { get; set; }
  153. public string? Descr1 { get; set; }
  154. public string? Remark { get; set; }
  155. public string? Type { get; set; }
  156. }
  157. }