ReportWorkMdpSyncService.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. using System.Text.Json;
  2. using Admin.NET.Plugin.AiDOP.DataPlatform;
  3. using Admin.NET.Plugin.AiDOP.DataPlatform.Executors;
  4. using Admin.NET.Plugin.AiDOP.Infrastructure;
  5. namespace Admin.NET.Plugin.AiDOP.Manufacturing;
  6. /// <summary>
  7. /// S6 报工双模式入站:执行器 → mdp_stg_s6_report → mdp_std_s6_report。
  8. /// 源优先 T8 <c>Cj_Bg_Head_Rep</c>(实体 S6_REPORT);API 对偶 S6_REPORT_API。
  9. /// </summary>
  10. public class ReportWorkMdpSyncService : ITransient
  11. {
  12. private const string InboundEntityCode = "S6_REPORT";
  13. /// <summary>T8 报工源无 tenant_id;须经 <see cref="AidopSourceTenantMap"/> 解析。</summary>
  14. private const string SourceZtid = "pbxfxp";
  15. private readonly ISqlSugarClient _db;
  16. private readonly MdpSourcePullDispatcher _pullDispatcher;
  17. public ReportWorkMdpSyncService(ISqlSugarClient db, MdpSourcePullDispatcher pullDispatcher)
  18. {
  19. _db = db;
  20. _pullDispatcher = pullDispatcher;
  21. }
  22. public async Task<ReportWorkInboundResult> RunInboundAsync(
  23. long tenantId = 0,
  24. bool fullRefresh = false,
  25. string? entityCode = null,
  26. CancellationToken cancellationToken = default)
  27. {
  28. cancellationToken.ThrowIfCancellationRequested();
  29. await EnsureTablesAsync();
  30. // T8 源表无 tenant_id 列;显式 tenantId≤0 时经账套映射解析真实租户。
  31. var resolvedTenantId = AidopSourceTenantMap.ResolveTenantId(SourceZtid, tenantId);
  32. var code = string.IsNullOrWhiteSpace(entityCode) ? InboundEntityCode : entityCode.Trim();
  33. var now = DateTime.Now;
  34. var pullCtx = new MdpPullContext
  35. {
  36. TenantId = resolvedTenantId,
  37. FullRefresh = fullRefresh,
  38. TaskCode = "S6_REPORT_INBOUND",
  39. BatchId = $"S6_RPT_IN_{now:yyyyMMddHHmmss}"
  40. };
  41. var pull = await _pullDispatcher.PullByEntityCodeAsync(code, pullCtx, cancellationToken);
  42. var transformBatch = $"{pullCtx.BatchId}_STD";
  43. var stdRows = await TransformStandardAsync(resolvedTenantId, transformBatch, now);
  44. return new ReportWorkInboundResult
  45. {
  46. PullBatchId = pullCtx.BatchId,
  47. RowsPulled = pull.RowsWritten,
  48. RowsWrittenStg = pull.RowsWritten,
  49. TransformBatchId = transformBatch,
  50. StandardRows = stdRows
  51. };
  52. }
  53. private async Task<int> TransformStandardAsync(long tenantId, string batchId, DateTime now)
  54. {
  55. // 将 PENDING stg 投影到 std(JSON 字段兼容大小写)
  56. var sTenant = MdpJsonSql.TenantFromStg("s", "@tid");
  57. var sql = $"""
  58. INSERT INTO mdp_std_s6_report
  59. (tenant_id, factory_id, source_system, work_order_no, report_date, report_qty, ztid,
  60. source_row_id, source_biz_key, sync_batch_id, sync_time)
  61. SELECT
  62. {sTenant},
  63. 1,
  64. IFNULL(NULLIF(s.source_system,''), 'T8'),
  65. IFNULL(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.noid')), 'null'),
  66. IFNULL(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.NOID')), 'null'), s.source_biz_key)),
  67. COALESCE(
  68. STR_TO_DATE(NULLIF(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.kgdate')), 'null'), ''), '%Y-%m-%d %H:%i:%s'),
  69. STR_TO_DATE(NULLIF(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.KGDATE')), 'null'), ''), '%Y-%m-%d %H:%i:%s'),
  70. NULL),
  71. CAST(NULLIF(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.sl')), 'null'), '') AS DECIMAL(18,6)),
  72. NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.ztid')), 'null'),
  73. IFNULL(NULLIF(s.source_row_id,''), s.source_biz_key),
  74. s.source_biz_key,
  75. @batch,
  76. @now
  77. FROM mdp_stg_s6_report s
  78. WHERE s.process_status = 'PENDING'
  79. AND s.source_biz_key IS NOT NULL
  80. AND s.source_biz_key <> ''
  81. AND {MdpJsonSql.TenantGuard(sTenant)}
  82. ON DUPLICATE KEY UPDATE
  83. work_order_no = VALUES(work_order_no),
  84. report_date = VALUES(report_date),
  85. report_qty = VALUES(report_qty),
  86. ztid = VALUES(ztid),
  87. source_row_id = VALUES(source_row_id),
  88. sync_batch_id = VALUES(sync_batch_id),
  89. sync_time = VALUES(sync_time),
  90. update_time = CURRENT_TIMESTAMP
  91. """;
  92. var affected = await _db.Ado.ExecuteCommandAsync(sql,
  93. new SugarParameter("@tid", tenantId),
  94. new SugarParameter("@batch", batchId),
  95. new SugarParameter("@now", now));
  96. await _db.Ado.ExecuteCommandAsync(
  97. tenantId > 0
  98. ? "UPDATE mdp_stg_s6_report SET process_status='DONE', update_time=NOW() WHERE process_status='PENDING' AND tenant_id = @tid"
  99. : "UPDATE mdp_stg_s6_report SET process_status='DONE', update_time=NOW() WHERE process_status='PENDING'",
  100. tenantId > 0 ? new SugarParameter("@tid", tenantId) : null!);
  101. return affected;
  102. }
  103. private async Task EnsureTablesAsync()
  104. {
  105. await _db.Ado.ExecuteCommandAsync("""
  106. CREATE TABLE IF NOT EXISTS mdp_stg_s6_report (
  107. id bigint NOT NULL AUTO_INCREMENT,
  108. tenant_id bigint NOT NULL DEFAULT 0,
  109. source_system varchar(50) DEFAULT NULL,
  110. source_table varchar(200) DEFAULT NULL,
  111. source_row_id varchar(200) DEFAULT NULL,
  112. source_biz_key varchar(300) DEFAULT NULL,
  113. raw_data json DEFAULT NULL,
  114. sync_batch_id varchar(100) DEFAULT NULL,
  115. create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  116. sync_time datetime DEFAULT CURRENT_TIMESTAMP,
  117. process_status varchar(20) NOT NULL DEFAULT 'PENDING',
  118. process_message varchar(500) DEFAULT NULL,
  119. update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  120. PRIMARY KEY (id),
  121. UNIQUE KEY uk_source_key (source_system, source_table, source_biz_key)
  122. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  123. """);
  124. await _db.Ado.ExecuteCommandAsync("""
  125. CREATE TABLE IF NOT EXISTS mdp_std_s6_report (
  126. id bigint NOT NULL AUTO_INCREMENT,
  127. tenant_id bigint NOT NULL DEFAULT 0,
  128. factory_id bigint DEFAULT 1,
  129. source_system varchar(50) NOT NULL DEFAULT 'T8',
  130. work_order_no varchar(100) NOT NULL,
  131. report_date datetime DEFAULT NULL,
  132. report_qty decimal(18,6) DEFAULT NULL,
  133. ztid varchar(50) DEFAULT NULL,
  134. source_row_id varchar(100) NOT NULL,
  135. source_biz_key varchar(200) NOT NULL,
  136. sync_batch_id varchar(100) NOT NULL,
  137. sync_time datetime NOT NULL,
  138. update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  139. PRIMARY KEY (id),
  140. UNIQUE KEY uk_mdp_std_s6_report (tenant_id, source_system, source_biz_key)
  141. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  142. """);
  143. }
  144. }
  145. public class ReportWorkInboundResult
  146. {
  147. public string PullBatchId { get; set; } = string.Empty;
  148. public int RowsPulled { get; set; }
  149. public int RowsWrittenStg { get; set; }
  150. public string TransformBatchId { get; set; } = string.Empty;
  151. public int StandardRows { get; set; }
  152. }