RequirementExamineDetailService.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. namespace Admin.NET.Plugin.AiDOP.Order;
  2. /// <summary>
  3. /// 需求明细核验(资源检查运算明细,只读查询)
  4. /// 路由前缀:/api/Order/examine-detail/...
  5. /// </summary>
  6. [ApiDescriptionSettings(Order = 255, Description = "需求明细核验")]
  7. [Route("api/Order")]
  8. [AllowAnonymous]
  9. [NonUnify]
  10. public class RequirementExamineDetailService : IDynamicApiController, ITransient
  11. {
  12. private readonly ISqlSugarClient _db;
  13. private readonly UserManager _userManager;
  14. public RequirementExamineDetailService(ISqlSugarClient db, UserManager userManager)
  15. {
  16. _db = db;
  17. _userManager = userManager;
  18. }
  19. /// <summary>
  20. /// 分页查询需求明细核验(扁平行;前端组树)
  21. /// </summary>
  22. [DisplayName("需求明细分页列表")]
  23. [HttpGet("examine-detail/list")]
  24. public async Task<object> PageRequirementExamineDetail([FromQuery] RequirementExamineDetailListInput input)
  25. {
  26. var tenantId = _userManager.TenantId;
  27. var pars = new List<SugarParameter> { new("@TenantId", tenantId) };
  28. var where = new List<string> { "bce.is_use = 1", "ber.tenant_id = @TenantId" };
  29. if (!string.IsNullOrWhiteSpace(input.BillNo))
  30. {
  31. where.Add("sen.bill_no LIKE @BillNo");
  32. pars.Add(new SugarParameter("@BillNo", $"%{input.BillNo.Trim()}%"));
  33. }
  34. if (!string.IsNullOrWhiteSpace(input.MorderNo))
  35. {
  36. where.Add("ber.morder_no LIKE @MorderNo");
  37. pars.Add(new SugarParameter("@MorderNo", $"%{input.MorderNo.Trim()}%"));
  38. }
  39. if (!string.IsNullOrWhiteSpace(input.ItemNumber))
  40. {
  41. where.Add("bce.item_number = @ItemNumber");
  42. pars.Add(new SugarParameter("@ItemNumber", input.ItemNumber.Trim()));
  43. }
  44. var whereSql = string.Join(" AND ", where);
  45. var orderExpr = ResolveOrderClause(input.OrderBy, input.Sort);
  46. var baseSql = $"""
  47. SELECT
  48. bce.id AS RowId,
  49. CASE
  50. WHEN bce.num = 1 THEN NULL
  51. ELSE (
  52. SELECT MIN(x.id)
  53. FROM b_bom_child_examine x
  54. WHERE x.examine_id = bce.examine_id AND x.num = 1 AND x.is_use = 1
  55. )
  56. END AS ParentRowId,
  57. CAST(bce.num AS CHAR) AS Num,
  58. bce.item_number AS ItemNumber,
  59. bce.item_name AS ItemName,
  60. bce.bom_number AS BomNumber,
  61. bce.model AS Model,
  62. DATE_FORMAT(bce.kitting_time, '%Y-%m-%d') AS KittingTime,
  63. CASE WHEN bce.type = 1 THEN '替代件' ELSE '标准件' END AS Type,
  64. CASE bce.erp_cls
  65. WHEN 0 THEN '配置类'
  66. WHEN 1 THEN '自制'
  67. WHEN 2 THEN '委外加工'
  68. WHEN 3 THEN '外购'
  69. WHEN 4 THEN '虚拟件'
  70. END AS ErpClsName,
  71. CAST(bce.qty AS DECIMAL(18,4)) AS Qty,
  72. CAST(IFNULL(bce.wastage, 0) AS DECIMAL(18,4)) AS Wastage,
  73. CAST(bce.needCount AS DECIMAL(18,4)) AS NeedCount,
  74. CAST(bce.sqty AS DECIMAL(18,4)) AS Sqty,
  75. CAST(bce.use_qty AS DECIMAL(18,4)) AS UseQty,
  76. CAST(bce.self_lack_qty AS DECIMAL(18,4)) AS SelfLackQty,
  77. CAST(bce.lack_qty AS DECIMAL(18,4)) AS LackQty,
  78. CAST(bce.mo_qty AS DECIMAL(18,4)) AS MoQty,
  79. CAST(IF(bce.make_qty = 0 AND bce.erp_cls = 1, bce.lack_qty, bce.make_qty) AS DECIMAL(18,4)) AS MakeQty,
  80. CAST(bce.purchase_qty AS DECIMAL(18,4)) AS PurchaseQty,
  81. CAST(bce.purchase_occupy_qty AS DECIMAL(18,4)) AS PurchaseOccupyQty,
  82. DATE_FORMAT(bce.satisfy_time, '%Y-%m-%d') AS SatisfyTime,
  83. CASE WHEN bce.haveicsubs = 1 THEN '是' ELSE '否' END AS HaveIcSubs,
  84. bce.substitute_code AS SubstituteCode,
  85. sen.bill_no AS BillNo,
  86. ber.morder_no AS MorderNo,
  87. ber.create_time AS CreateTime
  88. FROM b_examine_result ber
  89. INNER JOIN b_bom_child_examine bce ON ber.Id = bce.examine_id
  90. LEFT JOIN crm_seorderentry sen ON ber.sentry_id = sen.id
  91. WHERE {whereSql}
  92. """;
  93. var countSql = $"SELECT COUNT(*) FROM ({baseSql}) AS t";
  94. var total = await _db.Ado.GetIntAsync(countSql, pars);
  95. var offset = (input.Page - 1) * input.PageSize;
  96. var dataSql = $"""
  97. SELECT * FROM ({baseSql}) AS t
  98. ORDER BY {orderExpr}
  99. LIMIT {input.PageSize} OFFSET {offset}
  100. """;
  101. var list = await _db.Ado.SqlQueryAsync<RequirementExamineDetailRow>(dataSql, pars);
  102. // 分页内重算序号(与当前页一致)
  103. var snoStart = offset + 1;
  104. for (var i = 0; i < list.Count; i++)
  105. list[i].Sno = snoStart + i;
  106. return new
  107. {
  108. total,
  109. page = input.Page,
  110. pageSize = input.PageSize,
  111. list
  112. };
  113. }
  114. private static string ResolveOrderClause(string? orderBy, string? sort)
  115. {
  116. var desc = string.Equals(sort?.Trim(), "desc", StringComparison.OrdinalIgnoreCase);
  117. var dir = desc ? "DESC" : "ASC";
  118. var key = orderBy?.Trim();
  119. var col = key?.ToLowerInvariant() switch
  120. {
  121. "sno" => "t.RowId",
  122. "rowid" => "t.RowId",
  123. "billno" => "t.BillNo",
  124. "morderno" => "t.MorderNo",
  125. "itemnumber" => "t.ItemNumber",
  126. "kittingtime" => "t.KittingTime",
  127. _ => "t.RowId"
  128. };
  129. return $"{col} {dir}, t.RowId ASC";
  130. }
  131. }