IncomingInspectionApplicationService.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using Admin.NET.Plugin.AiDOP.MaterialWarehouse.Dto;
  2. namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse;
  3. /// <summary>
  4. /// S5 来料检验申请列表 服务(只读)。
  5. ///
  6. /// 数据源:主库 aidopdev 表 qms_qcp_inspecapplyn(贴源 QMS 申请主表)。
  7. /// 一期降级方案②:仅查询/展示表内可直接真实渲染的字段
  8. /// FBILLNO 单据编号 / FBILLTYPE 单据类型(原值) / FAPPLYTIME 申请时间 / FCOMMENT 备注。
  9. /// 不查询 FORGID / FBIZTYPE / FAPPLYUSER —— 名称解析源(bos_org / qcbd_biztype / bos_user)
  10. /// 当前不在 aidopdev,不做脑补 join、不显示裸 ID。
  11. ///
  12. /// 租户/工厂:qms_qcp_inspecapplyn 无 tenant_id / domain / factory 列(贴源表本身不带租户维度),
  13. /// 故本接口在表结构层面无可用租户过滤列,不新增前端 factory 选择,亦不脑补租户列。
  14. ///
  15. /// 本接口只读:仅 SELECT,无新增/编辑/删除/任务拆分/状态回写。
  16. /// </summary>
  17. [ApiDescriptionSettings(Order = 305, Description = "来料检验申请")]
  18. [Route("api/IncomingInspection")]
  19. [AllowAnonymous]
  20. [NonUnify]
  21. public class IncomingInspectionApplicationService : IDynamicApiController, ITransient
  22. {
  23. private readonly ISqlSugarClient _db;
  24. public IncomingInspectionApplicationService(ISqlSugarClient db)
  25. {
  26. _db = db;
  27. }
  28. /// <summary>
  29. /// 来料检验申请列表(只读分页查询)。
  30. /// </summary>
  31. [DisplayName("来料检验申请列表")]
  32. [HttpGet("application/list")]
  33. public async Task<object> GetList([FromQuery] IncomingInspectionApplicationListInput input)
  34. {
  35. var page = input.Page <= 0 ? 1 : input.Page;
  36. var pageSize = input.PageSize <= 0 ? 10 : input.PageSize;
  37. var offset = (page - 1) * pageSize;
  38. var where = new List<string> { "1=1" };
  39. var pars = new List<SugarParameter>();
  40. if (!string.IsNullOrWhiteSpace(input.BillNo))
  41. {
  42. where.Add("m.FBILLNO LIKE @BillNo");
  43. pars.Add(new SugarParameter("@BillNo", $"%{input.BillNo.Trim()}%"));
  44. }
  45. if (!string.IsNullOrWhiteSpace(input.ApplyTimeStart))
  46. {
  47. where.Add("m.FAPPLYTIME >= @ApplyTimeStart");
  48. pars.Add(new SugarParameter("@ApplyTimeStart", $"{input.ApplyTimeStart.Trim()} 00:00:00"));
  49. }
  50. if (!string.IsNullOrWhiteSpace(input.ApplyTimeEnd))
  51. {
  52. where.Add("m.FAPPLYTIME <= @ApplyTimeEnd");
  53. pars.Add(new SugarParameter("@ApplyTimeEnd", $"{input.ApplyTimeEnd.Trim()} 23:59:59"));
  54. }
  55. var whereSql = string.Join(" AND ", where);
  56. var total = await _db.Ado.GetIntAsync(
  57. $"SELECT COUNT(1) FROM qms_qcp_inspecapplyn m WHERE {whereSql}", pars);
  58. var list = await _db.Ado.SqlQueryAsync<IncomingInspectionApplicationListRow>(
  59. $"""
  60. SELECT
  61. m.id AS Id,
  62. m.FBILLNO AS FBillNo,
  63. m.FBILLTYPE AS FBillType,
  64. m.FAPPLYTIME AS FApplyTime,
  65. m.FCOMMENT AS FComment
  66. FROM qms_qcp_inspecapplyn m
  67. WHERE {whereSql}
  68. ORDER BY {BuildOrderBy(input.SortField, input.SortOrder)}
  69. LIMIT {pageSize} OFFSET {offset}
  70. """,
  71. pars);
  72. return new { total, page, pageSize, list };
  73. }
  74. /// <summary>
  75. /// 排序白名单:仅允许按已展示列排序,杜绝 SQL 注入。
  76. /// </summary>
  77. private static string BuildOrderBy(string? sortField, string? sortOrder)
  78. {
  79. var column = sortField switch
  80. {
  81. "fBillNo" => "m.FBILLNO",
  82. "fApplyTime" => "m.FAPPLYTIME",
  83. _ => "m.FAPPLYTIME",
  84. };
  85. var direction = string.Equals(sortOrder, "asc", StringComparison.OrdinalIgnoreCase) ? "ASC" : "DESC";
  86. return $"{column} {direction}, m.id DESC";
  87. }
  88. }