HolidayMasterService.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. namespace Admin.NET.Plugin.AiDOP.Production;
  2. /// <summary>
  3. /// 产线节假日(HolidayMaster)
  4. /// 路由前缀:/api/Production/holiday/...
  5. ///
  6. /// 【租户安全边界】租户一律经 <see cref="AidopTenantScope.ResolveOrThrow"/> 从认证后 JWT 解析,
  7. /// 无有效租户即拒绝,不读前端 tenantId、无默认回退(原实现:类级 <c>[AllowAnonymous]</c> + 宽松解析,
  8. /// 未认证方可携带 <c>?tenantId=&lt;任意租户&gt;</c> 读写该租户数据)。
  9. /// </summary>
  10. [ApiDescriptionSettings(Order = 269, Description = "产线节假日")]
  11. [Route("api/Production")]
  12. [NonUnify]
  13. public class HolidayMasterService : IDynamicApiController, ITransient
  14. {
  15. private readonly ISqlSugarClient _db;
  16. private readonly UserManager _userManager;
  17. public HolidayMasterService(ISqlSugarClient db, UserManager userManager)
  18. {
  19. _db = db;
  20. _userManager = userManager;
  21. }
  22. [DisplayName("产线节假日列表")]
  23. [HttpGet("holiday/list")]
  24. public async Task<object> GetList([FromQuery] HolidayMasterListInput input)
  25. {
  26. var tenantId = AidopTenantScope.ResolveOrThrow(_userManager);
  27. var pars = new List<SugarParameter> { new("@TenantId", tenantId) };
  28. var where = "h.IsActive = 1 AND h.tenant_id = @TenantId";
  29. if (!string.IsNullOrWhiteSpace(input.HolidayType))
  30. {
  31. where += " AND h.Ufld1 = @Ufld1";
  32. pars.Add(new SugarParameter("@Ufld1", input.HolidayType.Trim()));
  33. }
  34. var orderClause = ResolveOrder(input.OrderBy, input.Sort);
  35. var offset = (input.Page - 1) * input.PageSize;
  36. var baseSql = $"""
  37. SELECT
  38. h.Dated AS Dated,
  39. h.Ufld1 AS Ufld1,
  40. h.Holiday AS Holiday,
  41. h.RecID AS Id,
  42. h.`Domain` AS Domain,
  43. h.Site AS Site
  44. FROM HolidayMaster h
  45. WHERE {where}
  46. """;
  47. var total = await _db.Ado.GetIntAsync($"SELECT COUNT(*) FROM ({baseSql}) AS t", pars);
  48. var list = await _db.Ado.SqlQueryAsync<HolidayListRow>(
  49. $"SELECT * FROM ({baseSql}) AS t ORDER BY {orderClause} LIMIT {input.PageSize} OFFSET {offset}", pars);
  50. return new { total, page = input.Page, pageSize = input.PageSize, list };
  51. }
  52. [DisplayName("产线节假日详情")]
  53. [HttpGet("holiday/{id:long}")]
  54. public async Task<object> GetDetail(long id)
  55. {
  56. var tenantId = AidopTenantScope.ResolveOrThrow(_userManager);
  57. var row = (await _db.Ado.SqlQueryAsync<HolidayDetailRow>(
  58. """
  59. SELECT RecID AS Id, Holiday, Dated, Ufld1, `Domain`, Site
  60. FROM HolidayMaster
  61. WHERE RecID = @Id AND tenant_id = @TenantId
  62. """,
  63. new List<SugarParameter> { new("@Id", id), new("@TenantId", tenantId) })).FirstOrDefault()
  64. ?? throw Oops.Oh("记录不存在");
  65. return row;
  66. }
  67. [DisplayName("保存产线节假日")]
  68. [HttpPost("holiday/save")]
  69. public async Task<object> Save([FromBody] HolidayMasterSaveInput input)
  70. {
  71. var tenantId = AidopTenantScope.ResolveOrThrow(_userManager);
  72. var account = Truncate8(_userManager.Account ?? "system");
  73. var now = DateTime.Now;
  74. var holiday = Truncate(input.Holiday.Trim(), 8);
  75. var ufld1 = Truncate(input.Ufld1.Trim(), 8);
  76. var domain = Truncate(input.Domain.Trim(), 8);
  77. var site = Truncate(input.Site.Trim(), 4);
  78. var dated = input.Dated ?? throw Oops.Oh("日期不能为空");
  79. // 同一日期重复校验(编辑时排除自身)
  80. var dupWhere = "DATE(Dated) = DATE(@Dated) AND IsActive = 1 AND tenant_id = @TenantId";
  81. var dupPars = new List<SugarParameter>
  82. {
  83. new("@Dated", dated),
  84. new("@TenantId", tenantId)
  85. };
  86. if (input.Id is not null and not 0)
  87. {
  88. dupWhere += " AND RecID <> @ExcludeId";
  89. dupPars.Add(new SugarParameter("@ExcludeId", input.Id.Value));
  90. }
  91. var dupCount = await _db.Ado.GetIntAsync(
  92. $"SELECT COUNT(*) FROM HolidayMaster WHERE {dupWhere}", dupPars);
  93. if (dupCount > 0)
  94. throw Oops.Oh("该日期已配置节假日");
  95. if (input.Id is null or 0)
  96. {
  97. await _db.Ado.ExecuteCommandAsync(
  98. """
  99. INSERT INTO HolidayMaster (
  100. Holiday, Dated, Ufld1, `Domain`, Site,
  101. BusinessID, IsActive, IsConfirm, IsChanged,
  102. CreateUser, CreateTime, UpdateUser, UpdateTime, tenant_id
  103. ) VALUES (
  104. @Holiday, @Dated, @Ufld1, @Domain, @Site,
  105. 0, 1, 0, 0,
  106. @User, @Now, @User, @Now, @TenantId
  107. )
  108. """,
  109. new List<SugarParameter>
  110. {
  111. new("@Holiday", holiday),
  112. new("@Dated", dated),
  113. new("@Ufld1", ufld1),
  114. new("@Domain", domain),
  115. new("@Site", site),
  116. new("@User", account),
  117. new("@Now", now),
  118. new("@TenantId", tenantId)
  119. });
  120. var newId = await _db.Ado.GetIntAsync("SELECT LAST_INSERT_ID()");
  121. return new { id = (long)newId, message = "新增成功" };
  122. }
  123. var n = await _db.Ado.ExecuteCommandAsync(
  124. """
  125. UPDATE HolidayMaster
  126. SET Holiday = @Holiday,
  127. Dated = @Dated,
  128. Ufld1 = @Ufld1,
  129. `Domain` = @Domain,
  130. Site = @Site,
  131. UpdateUser = @User,
  132. UpdateTime = @Now
  133. WHERE RecID = @Id AND tenant_id = @TenantId
  134. """,
  135. new List<SugarParameter>
  136. {
  137. new("@Id", input.Id!.Value),
  138. new("@Holiday", holiday),
  139. new("@Dated", dated),
  140. new("@Ufld1", ufld1),
  141. new("@Domain", domain),
  142. new("@Site", site),
  143. new("@User", account),
  144. new("@Now", now),
  145. new("@TenantId", tenantId)
  146. });
  147. if (n == 0)
  148. throw Oops.Oh("记录不存在或未变更");
  149. return new { id = input.Id, message = "保存成功" };
  150. }
  151. [DisplayName("删除产线节假日")]
  152. [HttpPost("holiday/delete/{id:long}")]
  153. public async Task<object> Delete(long id)
  154. {
  155. var tenantId = AidopTenantScope.ResolveOrThrow(_userManager);
  156. var n = await _db.Ado.ExecuteCommandAsync(
  157. "UPDATE HolidayMaster SET IsActive = 0, UpdateTime = @Now WHERE RecID = @Id AND tenant_id = @TenantId",
  158. new List<SugarParameter> { new("@Id", id), new("@Now", DateTime.Now), new("@TenantId", tenantId) });
  159. if (n == 0)
  160. throw Oops.Oh("记录不存在");
  161. return new { message = "已删除" };
  162. }
  163. private static string Truncate(string s, int maxLen) =>
  164. s.Length <= maxLen ? s : s[..maxLen];
  165. private static string Truncate8(string s) => Truncate(s, 8);
  166. private static string ResolveOrder(string? orderBy, string? sort)
  167. {
  168. var desc = string.Equals(sort?.Trim(), "desc", StringComparison.OrdinalIgnoreCase);
  169. var dir = desc ? "DESC" : "ASC";
  170. var key = orderBy?.Trim().ToLowerInvariant();
  171. var col = key switch
  172. {
  173. "holiday" => "t.Holiday",
  174. "dated" => "t.Dated",
  175. "ufld1" => "t.Ufld1",
  176. _ => "t.Dated"
  177. };
  178. return $"{col} {dir}, t.Id";
  179. }
  180. private sealed class HolidayListRow
  181. {
  182. public DateTime? Dated { get; set; }
  183. public string? Ufld1 { get; set; }
  184. public string? Holiday { get; set; }
  185. public long Id { get; set; }
  186. public string? Domain { get; set; }
  187. public string? Site { get; set; }
  188. }
  189. private sealed class HolidayDetailRow
  190. {
  191. public long Id { get; set; }
  192. public string? Holiday { get; set; }
  193. public DateTime? Dated { get; set; }
  194. public string? Ufld1 { get; set; }
  195. public string? Domain { get; set; }
  196. public string? Site { get; set; }
  197. }
  198. }