ReportWorkMdpSyncService.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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 sql = $"""
  57. INSERT INTO mdp_std_s6_report
  58. (tenant_id, factory_id, source_system, work_order_no, report_date, report_qty, ztid,
  59. source_row_id, source_biz_key, sync_batch_id, sync_time)
  60. SELECT
  61. {MdpJsonSql.TenantFromStg("s", "@tid")},
  62. 1,
  63. IFNULL(NULLIF(s.source_system,''), 'T8'),
  64. IFNULL(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.noid')), 'null'),
  65. IFNULL(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.NOID')), 'null'), s.source_biz_key)),
  66. COALESCE(
  67. STR_TO_DATE(NULLIF(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.kgdate')), 'null'), ''), '%Y-%m-%d %H:%i:%s'),
  68. STR_TO_DATE(NULLIF(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.KGDATE')), 'null'), ''), '%Y-%m-%d %H:%i:%s'),
  69. NULL),
  70. CAST(NULLIF(NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.sl')), 'null'), '') AS DECIMAL(18,6)),
  71. NULLIF(JSON_UNQUOTE(JSON_EXTRACT(s.raw_data, '$.ztid')), 'null'),
  72. IFNULL(NULLIF(s.source_row_id,''), s.source_biz_key),
  73. s.source_biz_key,
  74. @batch,
  75. @now
  76. FROM mdp_stg_s6_report s
  77. WHERE s.process_status = 'PENDING'
  78. AND s.source_biz_key IS NOT NULL
  79. AND s.source_biz_key <> ''
  80. ON DUPLICATE KEY UPDATE
  81. work_order_no = VALUES(work_order_no),
  82. report_date = VALUES(report_date),
  83. report_qty = VALUES(report_qty),
  84. ztid = VALUES(ztid),
  85. source_row_id = VALUES(source_row_id),
  86. sync_batch_id = VALUES(sync_batch_id),
  87. sync_time = VALUES(sync_time),
  88. update_time = CURRENT_TIMESTAMP
  89. """;
  90. var affected = await _db.Ado.ExecuteCommandAsync(sql,
  91. new SugarParameter("@tid", tenantId),
  92. new SugarParameter("@batch", batchId),
  93. new SugarParameter("@now", now));
  94. await _db.Ado.ExecuteCommandAsync(
  95. tenantId > 0
  96. ? "UPDATE mdp_stg_s6_report SET process_status='DONE', update_time=NOW() WHERE process_status='PENDING' AND tenant_id = @tid"
  97. : "UPDATE mdp_stg_s6_report SET process_status='DONE', update_time=NOW() WHERE process_status='PENDING'",
  98. tenantId > 0 ? new SugarParameter("@tid", tenantId) : null!);
  99. return affected;
  100. }
  101. private async Task EnsureTablesAsync()
  102. {
  103. await _db.Ado.ExecuteCommandAsync("""
  104. CREATE TABLE IF NOT EXISTS mdp_stg_s6_report (
  105. id bigint NOT NULL AUTO_INCREMENT,
  106. tenant_id bigint NOT NULL DEFAULT 0,
  107. source_system varchar(50) DEFAULT NULL,
  108. source_table varchar(200) DEFAULT NULL,
  109. source_row_id varchar(200) DEFAULT NULL,
  110. source_biz_key varchar(300) DEFAULT NULL,
  111. raw_data json DEFAULT NULL,
  112. sync_batch_id varchar(100) DEFAULT NULL,
  113. create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  114. sync_time datetime DEFAULT CURRENT_TIMESTAMP,
  115. process_status varchar(20) NOT NULL DEFAULT 'PENDING',
  116. process_message varchar(500) DEFAULT NULL,
  117. update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  118. PRIMARY KEY (id),
  119. UNIQUE KEY uk_source_key (source_system, source_table, source_biz_key)
  120. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  121. """);
  122. await _db.Ado.ExecuteCommandAsync("""
  123. CREATE TABLE IF NOT EXISTS mdp_std_s6_report (
  124. id bigint NOT NULL AUTO_INCREMENT,
  125. tenant_id bigint NOT NULL DEFAULT 0,
  126. factory_id bigint DEFAULT 1,
  127. source_system varchar(50) NOT NULL DEFAULT 'T8',
  128. work_order_no varchar(100) NOT NULL,
  129. report_date datetime DEFAULT NULL,
  130. report_qty decimal(18,6) DEFAULT NULL,
  131. ztid varchar(50) DEFAULT NULL,
  132. source_row_id varchar(100) NOT NULL,
  133. source_biz_key varchar(200) NOT NULL,
  134. sync_batch_id varchar(100) NOT NULL,
  135. sync_time datetime NOT NULL,
  136. update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  137. PRIMARY KEY (id),
  138. UNIQUE KEY uk_mdp_std_s6_report (tenant_id, source_system, source_biz_key)
  139. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  140. """);
  141. }
  142. }
  143. public class ReportWorkInboundResult
  144. {
  145. public string PullBatchId { get; set; } = string.Empty;
  146. public int RowsPulled { get; set; }
  147. public int RowsWrittenStg { get; set; }
  148. public string TransformBatchId { get; set; } = string.Empty;
  149. public int StandardRows { get; set; }
  150. }