ProductionIssueService.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. using Admin.NET.Plugin.AiDOP.MaterialWarehouse.Dto;
  2. namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse;
  3. /// <summary>
  4. /// S5 生产领料单 只读 list 服务。
  5. ///
  6. /// 数据源:DOP 数据中台标准层 mdp_std_production_issue(头级)。
  7. /// 由 ProductionIssueMdpSyncService 从 aidopdev.NbrMaster Type='SM' 同步标准化而来。
  8. ///
  9. /// 本服务仅 SELECT:无新增/编辑/删除/发料确认/库存事务/状态流转/明细。
  10. /// 领料单为头级列表(一单一行),不 JOIN 明细,无重复。
  11. /// </summary>
  12. [ApiDescriptionSettings(Order = 305, Description = "生产领料单")]
  13. [Route("api/ProductionIssue")]
  14. [AllowAnonymous]
  15. [NonUnify]
  16. public class ProductionIssueService : IDynamicApiController, ITransient
  17. {
  18. private readonly ISqlSugarClient _db;
  19. public ProductionIssueService(ISqlSugarClient db)
  20. {
  21. _db = db;
  22. }
  23. /// <summary>
  24. /// 生产领料单列表(只读分页查询)。
  25. /// </summary>
  26. [DisplayName("生产领料单列表")]
  27. [HttpGet("list")]
  28. public async Task<object> GetList([FromQuery] ProductionIssueListInput input)
  29. {
  30. var page = input.Page <= 0 ? 1 : input.Page;
  31. var pageSize = input.PageSize <= 0 ? 10 : input.PageSize;
  32. var offset = (page - 1) * pageSize;
  33. var where = new List<string> { "1=1" };
  34. var pars = new List<SugarParameter>();
  35. if (input.TenantId is > 0)
  36. {
  37. where.Add("m.tenant_id = @TenantId");
  38. pars.Add(new SugarParameter("@TenantId", input.TenantId));
  39. }
  40. if (!string.IsNullOrWhiteSpace(input.Nbr))
  41. {
  42. where.Add("m.nbr LIKE @Nbr");
  43. pars.Add(new SugarParameter("@Nbr", $"%{input.Nbr.Trim()}%"));
  44. }
  45. if (!string.IsNullOrWhiteSpace(input.WorkOrd))
  46. {
  47. where.Add("m.work_ord LIKE @WorkOrd");
  48. pars.Add(new SugarParameter("@WorkOrd", $"%{input.WorkOrd.Trim()}%"));
  49. }
  50. if (!string.IsNullOrWhiteSpace(input.Status))
  51. {
  52. where.Add("m.status = @Status");
  53. pars.Add(new SugarParameter("@Status", input.Status.Trim()));
  54. }
  55. if (!string.IsNullOrWhiteSpace(input.ProdLine))
  56. {
  57. where.Add("m.prod_line LIKE @ProdLine");
  58. pars.Add(new SugarParameter("@ProdLine", $"%{input.ProdLine.Trim()}%"));
  59. }
  60. if (!string.IsNullOrWhiteSpace(input.DateFrom))
  61. {
  62. where.Add("m.issue_date >= @DateFrom");
  63. pars.Add(new SugarParameter("@DateFrom", $"{input.DateFrom.Trim()} 00:00:00"));
  64. }
  65. if (!string.IsNullOrWhiteSpace(input.DateTo))
  66. {
  67. where.Add("m.issue_date <= @DateTo");
  68. pars.Add(new SugarParameter("@DateTo", $"{input.DateTo.Trim()} 23:59:59"));
  69. }
  70. var whereSql = string.Join(" AND ", where);
  71. var total = await _db.Ado.GetIntAsync(
  72. $"SELECT COUNT(1) FROM mdp_std_production_issue m WHERE {whereSql}", pars);
  73. var list = await _db.Ado.SqlQueryAsync<ProductionIssueListRow>(
  74. $"""
  75. SELECT
  76. m.id AS Id,
  77. m.nbr AS Nbr,
  78. m.issue_date AS IssueDate,
  79. m.status_desc AS StatusDesc,
  80. m.work_ord AS WorkOrd,
  81. m.department_desc AS DepartmentDesc,
  82. m.prod_line AS ProdLine,
  83. m.qty_ord AS QtyOrd,
  84. m.issue_user AS IssueUser,
  85. m.remark AS Remark,
  86. m.create_user AS CreateUser,
  87. m.source_create_time AS CreateTime
  88. FROM mdp_std_production_issue m
  89. WHERE {whereSql}
  90. ORDER BY {BuildOrderBy(input.OrderBy, input.OrderDir)}
  91. LIMIT {pageSize} OFFSET {offset}
  92. """,
  93. pars);
  94. return new { total, page, pageSize, list };
  95. }
  96. /// <summary>
  97. /// 排序白名单:仅允许按已展示列排序,杜绝 SQL 注入;非法字段回落默认。
  98. /// </summary>
  99. private static string BuildOrderBy(string? orderBy, string? orderDir)
  100. {
  101. var column = orderBy switch
  102. {
  103. "nbr" => "m.nbr",
  104. "issueDate" => "m.issue_date",
  105. "status" => "m.status",
  106. "workOrd" => "m.work_ord",
  107. "prodLine" => "m.prod_line",
  108. "createTime" => "m.source_create_time",
  109. _ => "m.issue_date",
  110. };
  111. var direction = string.Equals(orderDir, "asc", StringComparison.OrdinalIgnoreCase) ? "ASC" : "DESC";
  112. return $"{column} {direction}, m.id DESC";
  113. }
  114. }