MoldToolReferenceChecker.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. namespace Admin.NET.Plugin.AiDOP.Manufacturing;
  2. /// <summary>
  3. /// S6 模工具台账(MoldToolList)删除前的下游引用检查(FUNC-S6-004)。
  4. ///
  5. /// 刻意**不复用** Infrastructure/AdoS0ReferenceChecker:那是 S0 共享基础设施,
  6. /// 改它需抢提交锁且会把 S6 逻辑混入 S0 模块边界(CLAUDE.md 第九节)。
  7. ///
  8. /// 引用口径一律「租户内 + 按业务编码 MoldTypeCode 匹配」,与两张下游表的实际存储一致
  9. /// (下游存的是编码字符串,不是 MoldToolList.id)。
  10. ///
  11. /// 覆盖范围(2026-09-01 实测):
  12. /// MUST ProdLineDetail.MoldTypeCode —— S0 线边物料/产线物料在用,活跃写入路径,
  13. /// 同租户命中 896 行(另有 369 行历史孤儿,非本批修复范围)
  14. /// SHOULD ScheduleResultOpMaster.MoldTypeCode —— 排产结果;当前生成逻辑未写该列(命中 0),
  15. /// 但 ExecutableDailyPlanService 已按该列做筛选消费,
  16. /// 属已声明且已被消费的引用位,一并纳入以免将来漏检
  17. /// 不纳入:LineMaterial.MoldTypeCode —— 空表、无任何 controller/service 读写路径,仅 CodeFirst 注册
  18. ///
  19. /// 只读:本类只做 SELECT,不修改、不清空、不级联删除任何下游数据。
  20. /// </summary>
  21. public sealed class MoldToolReferenceChecker : ITransient
  22. {
  23. private readonly ISqlSugarClient _db;
  24. public MoldToolReferenceChecker(ISqlSugarClient db)
  25. {
  26. _db = db;
  27. }
  28. /// <summary>
  29. /// 租户内检查该模具类型编码是否被下游引用。命中返回(条数, 中文表述),未命中返回 null。
  30. /// </summary>
  31. public async Task<(int Count, string Table)?> ReferencesAsync(long tenantId, string? moldTypeCode)
  32. {
  33. if (string.IsNullOrWhiteSpace(moldTypeCode)) return null;
  34. var code = moldTypeCode.Trim();
  35. var prodLine = await CountAsync(
  36. "SELECT COUNT(1) FROM ProdLineDetail WHERE tenant_id = @TenantId AND MoldTypeCode = @Code",
  37. tenantId, code);
  38. if (prodLine > 0) return (prodLine, "线边物料/产线物料配置 (ProdLineDetail.MoldTypeCode)");
  39. var schedule = await CountAsync(
  40. "SELECT COUNT(1) FROM ScheduleResultOpMaster WHERE tenant_id = @TenantId AND MoldTypeCode = @Code",
  41. tenantId, code);
  42. if (schedule > 0) return (schedule, "排产结果工序 (ScheduleResultOpMaster.MoldTypeCode)");
  43. return null;
  44. }
  45. private Task<int> CountAsync(string sql, long tenantId, string code)
  46. => _db.Ado.GetIntAsync(sql, new List<SugarParameter>
  47. {
  48. new("@TenantId", tenantId),
  49. new("@Code", code)
  50. });
  51. }