ResourceOvertimeService.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. namespace Admin.NET.Plugin.AiDOP.Production;
  2. /// <summary>
  3. /// 产线加班(ResourceOccupancyTime)
  4. /// 路由前缀:/api/Production/overtime/...
  5. /// </summary>
  6. [ApiDescriptionSettings(Order = 270, Description = "产线加班")]
  7. [Route("api/Production")]
  8. [AllowAnonymous]
  9. [NonUnify]
  10. public class ResourceOvertimeService : IDynamicApiController, ITransient
  11. {
  12. private readonly ISqlSugarClient _db;
  13. private readonly UserManager _userManager;
  14. public ResourceOvertimeService(ISqlSugarClient db, UserManager userManager)
  15. {
  16. _db = db;
  17. _userManager = userManager;
  18. }
  19. [DisplayName("产线加班列表")]
  20. [HttpGet("overtime/list")]
  21. public async Task<object> GetList([FromQuery] ResourceOvertimeListInput input)
  22. {
  23. var pars = new List<SugarParameter>();
  24. var where = "r.IsActive = 1";
  25. if (!string.IsNullOrWhiteSpace(input.Resource))
  26. {
  27. where += " AND r.Resource = @Resource";
  28. pars.Add(new SugarParameter("@Resource", input.Resource.Trim()));
  29. }
  30. if (!string.IsNullOrWhiteSpace(input.StartTimeFrom))
  31. {
  32. where += " AND r.StartTime >= @StartTimeFrom";
  33. pars.Add(new SugarParameter("@StartTimeFrom", input.StartTimeFrom.Trim()));
  34. }
  35. if (!string.IsNullOrWhiteSpace(input.EndTimeFrom))
  36. {
  37. where += " AND r.EndTime >= @EndTimeFrom";
  38. pars.Add(new SugarParameter("@EndTimeFrom", input.EndTimeFrom.Trim()));
  39. }
  40. if (!string.IsNullOrWhiteSpace(input.ResourceType))
  41. {
  42. where += " AND r.ResourceType LIKE @ResourceType";
  43. pars.Add(new SugarParameter("@ResourceType", $"%{input.ResourceType.Trim()}%"));
  44. }
  45. var orderClause = ResolveOrder(input.OrderBy, input.Sort);
  46. var offset = (input.Page - 1) * input.PageSize;
  47. var baseSql = $"""
  48. SELECT
  49. r.RecID AS Id,
  50. r.`Domain`,
  51. r.Site,
  52. r.BusinessID,
  53. r.ResourceType,
  54. r.Resource,
  55. r.StartTime,
  56. r.EndTime,
  57. r.Descr,
  58. r.IsRest,
  59. r.IsActive,
  60. r.IsConfirm,
  61. r.IsChanged,
  62. r.Ufld1,
  63. r.Ufld2,
  64. ROUND(CAST(IFNULL(r.Ufld1, 0) AS DECIMAL(20, 10)) * 60, 0) AS Time1,
  65. ROUND(CAST(IFNULL(r.Ufld2, 0) AS DECIMAL(20, 10)) * 60, 0) AS Time2,
  66. r.CreateUser,
  67. r.UpdateUser,
  68. r.CreateTime,
  69. r.UpdateTime
  70. FROM ResourceOccupancyTime r
  71. WHERE {where}
  72. """;
  73. var total = await _db.Ado.GetIntAsync($"SELECT COUNT(*) FROM ({baseSql}) AS t", pars);
  74. var list = await _db.Ado.SqlQueryAsync<ResourceOvertimeListRow>(
  75. $"SELECT * FROM ({baseSql}) AS t ORDER BY {orderClause} LIMIT {input.PageSize} OFFSET {offset}", pars);
  76. return new { total, page = input.Page, pageSize = input.PageSize, list };
  77. }
  78. [DisplayName("产线加班详情")]
  79. [HttpGet("overtime/{id:long}")]
  80. public async Task<object> GetDetail(long id)
  81. {
  82. var row = (await _db.Ado.SqlQueryAsync<ResourceOvertimeDetailRow>(
  83. """
  84. SELECT RecID AS Id, `Domain`, Site, ResourceType, Resource, StartTime, EndTime, Descr,
  85. Ufld1, Ufld2,
  86. ROUND(CAST(IFNULL(Ufld1, 0) AS DECIMAL(20, 10)) * 60, 0) AS WorkMinutes,
  87. ROUND(CAST(IFNULL(Ufld2, 0) AS DECIMAL(20, 10)) * 60, 0) AS RestMinutes
  88. FROM ResourceOccupancyTime
  89. WHERE RecID = @Id
  90. """,
  91. new List<SugarParameter> { new("@Id", id) })).FirstOrDefault()
  92. ?? throw Oops.Oh("记录不存在");
  93. return row;
  94. }
  95. [DisplayName("保存产线加班")]
  96. [HttpPost("overtime/save")]
  97. public async Task<object> Save([FromBody] ResourceOvertimeSaveInput input)
  98. {
  99. var account = Truncate(_userManager.Account ?? "system", 8);
  100. var now = DateTime.Now;
  101. var domain = Truncate(input.Domain.Trim(), 8);
  102. var site = string.IsNullOrWhiteSpace(input.Site) ? null : Truncate(input.Site.Trim(), 8);
  103. var resource = Truncate(input.Resource.Trim(), 20);
  104. var resType = string.IsNullOrWhiteSpace(input.ResourceType) ? "" : Truncate(input.ResourceType.Trim(), 20);
  105. var descr = string.IsNullOrWhiteSpace(input.Descr) ? "-" : Truncate(input.Descr.Trim(), 60);
  106. var ufld1Hours = input.WorkMinutes.HasValue ? input.WorkMinutes.Value / 60m : (decimal?)null;
  107. var ufld2Hours = input.RestMinutes.HasValue ? input.RestMinutes.Value / 60m : (decimal?)null;
  108. if (input.Id is null or 0)
  109. {
  110. await _db.Ado.ExecuteCommandAsync(
  111. """
  112. INSERT INTO ResourceOccupancyTime (
  113. `Domain`, Site, BusinessID, ResourceType, Resource, StartTime, EndTime, Descr,
  114. IsRest, IsActive, IsConfirm, IsChanged, Ufld1, Ufld2,
  115. CreateUser, CreateTime, UpdateUser, UpdateTime
  116. ) VALUES (
  117. @Domain, @Site, 0, @ResourceType, @Resource, @StartTime, @EndTime, @Descr,
  118. 0, 1, 0, 0, @Ufld1, @Ufld2,
  119. @User, @Now, @User, @Now
  120. )
  121. """,
  122. new List<SugarParameter>
  123. {
  124. new("@Domain", domain),
  125. new("@Site", (object?)site ?? DBNull.Value),
  126. new("@ResourceType", resType),
  127. new("@Resource", resource),
  128. new("@StartTime", (object?)input.StartTime ?? DBNull.Value),
  129. new("@EndTime", (object?)input.EndTime ?? DBNull.Value),
  130. new("@Descr", descr),
  131. new("@Ufld1", (object?)ufld1Hours ?? DBNull.Value),
  132. new("@Ufld2", (object?)ufld2Hours ?? DBNull.Value),
  133. new("@User", account),
  134. new("@Now", now)
  135. });
  136. var newId = await _db.Ado.GetIntAsync("SELECT LAST_INSERT_ID()");
  137. return new { id = (long)newId, message = "新增成功" };
  138. }
  139. var n = await _db.Ado.ExecuteCommandAsync(
  140. """
  141. UPDATE ResourceOccupancyTime
  142. SET `Domain` = @Domain,
  143. Site = @Site,
  144. ResourceType = @ResourceType,
  145. Resource = @Resource,
  146. StartTime = @StartTime,
  147. EndTime = @EndTime,
  148. Descr = @Descr,
  149. Ufld1 = @Ufld1,
  150. Ufld2 = @Ufld2,
  151. UpdateUser = @User,
  152. UpdateTime = @Now
  153. WHERE RecID = @Id
  154. """,
  155. new List<SugarParameter>
  156. {
  157. new("@Id", input.Id!.Value),
  158. new("@Domain", domain),
  159. new("@Site", (object?)site ?? DBNull.Value),
  160. new("@ResourceType", resType),
  161. new("@Resource", resource),
  162. new("@StartTime", (object?)input.StartTime ?? DBNull.Value),
  163. new("@EndTime", (object?)input.EndTime ?? DBNull.Value),
  164. new("@Descr", descr),
  165. new("@Ufld1", (object?)ufld1Hours ?? DBNull.Value),
  166. new("@Ufld2", (object?)ufld2Hours ?? DBNull.Value),
  167. new("@User", account),
  168. new("@Now", now)
  169. });
  170. if (n == 0)
  171. throw Oops.Oh("记录不存在或未变更");
  172. return new { id = input.Id, message = "保存成功" };
  173. }
  174. [DisplayName("删除产线加班")]
  175. [HttpPost("overtime/delete/{id:long}")]
  176. public async Task<object> Delete(long id)
  177. {
  178. var n = await _db.Ado.ExecuteCommandAsync(
  179. "UPDATE ResourceOccupancyTime SET IsActive = 0, UpdateTime = @Now WHERE RecID = @Id",
  180. new List<SugarParameter> { new("@Id", id), new("@Now", DateTime.Now) });
  181. if (n == 0)
  182. throw Oops.Oh("记录不存在");
  183. return new { message = "已删除" };
  184. }
  185. [DisplayName("生产线列表")]
  186. [HttpGet("overtime/lines")]
  187. public async Task<object> GetLines([FromQuery] string? domain)
  188. {
  189. var pars = new List<SugarParameter>();
  190. var where = "IsActive = 1";
  191. if (!string.IsNullOrWhiteSpace(domain))
  192. {
  193. where += " AND `Domain` = @Domain";
  194. pars.Add(new SugarParameter("@Domain", domain.Trim()));
  195. }
  196. var rows = await _db.Ado.SqlQueryAsync<LineKvOvertime>(
  197. $"SELECT `Line` AS Value, `Line` AS Label, `Domain` AS Extra FROM LineMaster WHERE {where} ORDER BY `Line`", pars);
  198. return new { list = rows };
  199. }
  200. private static string Truncate(string s, int maxLen) =>
  201. s.Length <= maxLen ? s : s[..maxLen];
  202. private static string ResolveOrder(string? orderBy, string? sort)
  203. {
  204. var desc = string.Equals(sort?.Trim(), "desc", StringComparison.OrdinalIgnoreCase);
  205. var dir = desc ? "DESC" : "ASC";
  206. var key = orderBy?.Trim().ToLowerInvariant();
  207. var col = key switch
  208. {
  209. "resource" => "t.Resource",
  210. "starttime" => "t.StartTime",
  211. "endtime" => "t.EndTime",
  212. "resourcetype" => "t.ResourceType",
  213. _ => "t.Id"
  214. };
  215. return $"{col} {dir}";
  216. }
  217. private sealed class ResourceOvertimeListRow
  218. {
  219. public long Id { get; set; }
  220. public string? Domain { get; set; }
  221. public string? Site { get; set; }
  222. public long BusinessID { get; set; }
  223. public string? ResourceType { get; set; }
  224. public string? Resource { get; set; }
  225. public DateTime? StartTime { get; set; }
  226. public DateTime? EndTime { get; set; }
  227. public string? Descr { get; set; }
  228. public bool IsRest { get; set; }
  229. public bool IsActive { get; set; }
  230. public bool IsConfirm { get; set; }
  231. public bool IsChanged { get; set; }
  232. public string? Ufld1 { get; set; }
  233. public string? Ufld2 { get; set; }
  234. public decimal? Time1 { get; set; }
  235. public decimal? Time2 { get; set; }
  236. public string? CreateUser { get; set; }
  237. public string? UpdateUser { get; set; }
  238. public DateTime? CreateTime { get; set; }
  239. public DateTime? UpdateTime { get; set; }
  240. }
  241. private sealed class ResourceOvertimeDetailRow
  242. {
  243. public long Id { get; set; }
  244. public string? Domain { get; set; }
  245. public string? Site { get; set; }
  246. public string? ResourceType { get; set; }
  247. public string? Resource { get; set; }
  248. public DateTime? StartTime { get; set; }
  249. public DateTime? EndTime { get; set; }
  250. public string? Descr { get; set; }
  251. public string? Ufld1 { get; set; }
  252. public string? Ufld2 { get; set; }
  253. public decimal? WorkMinutes { get; set; }
  254. public decimal? RestMinutes { get; set; }
  255. }
  256. private sealed class LineKvOvertime
  257. {
  258. public string? Value { get; set; }
  259. public string? Label { get; set; }
  260. public string? Extra { get; set; }
  261. }
  262. }