| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- namespace Admin.NET.Plugin.AiDOP.SmartOps;
- public enum SmartDiagnosisEvidenceDomain
- {
- Delivery,
- Supply,
- Manufacturing,
- Quality,
- Exception
- }
- public sealed record SmartDiagnosisEvidenceFilterColumn(string QueryKey, string SqlColumn);
- public sealed record SmartDiagnosisEvidenceSource(
- string Key,
- SmartDiagnosisEvidenceDomain Domain,
- IReadOnlyList<string> Modules,
- string ObjectType,
- string DrillPath,
- string CountSql,
- string ItemSql,
- IReadOnlyList<SmartDiagnosisEvidenceFilterColumn> Filters);
- public static class SmartDiagnosisEvidenceRegistry
- {
- public const int DefaultLimit = 20;
- public const int MaxLimit = 50;
- private static readonly SmartDiagnosisEvidenceSource[] Sources =
- {
- new(
- "order_schedule",
- SmartDiagnosisEvidenceDomain.Manufacturing,
- new[] { "S1", "S2", "S6" },
- "work_order",
- "/aidop/s2/work-order-scheduling",
- """
- SELECT COUNT(*) FROM dwd_order_schedule_trans
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(work_order,'')<>''
- """,
- """
- SELECT work_order AS ObjectCode,
- CONCAT(IFNULL(sales_order_no,''),' / ',IFNULL(work_order,''),' / ',IFNULL(item_code,'')) AS Title,
- GREATEST(IFNULL(qty_ordered,0)-IFNULL(qty_completed,0),0) AS Contribution,
- CASE
- WHEN IFNULL(schedule_satisfaction_flag,1)=0 OR (due_date IS NOT NULL AND due_date<CURDATE()) THEN 'red'
- WHEN IFNULL(wip_qty,0)>0 THEN 'yellow'
- ELSE 'green'
- END AS Status,
- COALESCE(due_date, stat_date) AS OccurredAt
- FROM dwd_order_schedule_trans
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(work_order,'')<>''
- ORDER BY Contribution DESC, OccurredAt
- LIMIT @limit
- """,
- new[]
- {
- new SmartDiagnosisEvidenceFilterColumn("workOrder", "work_order"),
- new SmartDiagnosisEvidenceFilterColumn("orderNo", "sales_order_no"),
- new SmartDiagnosisEvidenceFilterColumn("material", "item_code"),
- new SmartDiagnosisEvidenceFilterColumn("productionLine", "prod_line"),
- }),
- new(
- "supplier_delivery",
- SmartDiagnosisEvidenceDomain.Supply,
- new[] { "S3", "S4" },
- "purchase_order",
- "/aidop/s4/purchase-execution",
- """
- SELECT COUNT(*) FROM dwd_supplier_delivery
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(po_no,'')<>''
- """,
- """
- SELECT po_no AS ObjectCode,
- CONCAT(IFNULL(supplier_name,supplier_code),' / ',IFNULL(item_code,''),' / ',IFNULL(po_no,'')) AS Title,
- GREATEST(IFNULL(remaining_qty,0),0) AS Contribution,
- CASE
- WHEN UPPER(IFNULL(risk_level,'')) IN ('HIGH','RED')
- OR UPPER(IFNULL(delivery_status,'')) IN ('OVERDUE','DELAYED','LATE') THEN 'red'
- WHEN IFNULL(remaining_qty,0)>0 THEN 'yellow'
- ELSE 'green'
- END AS Status,
- COALESCE(due_date, stat_date) AS OccurredAt
- FROM dwd_supplier_delivery
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(po_no,'')<>''
- ORDER BY Contribution DESC, OccurredAt
- LIMIT @limit
- """,
- new[]
- {
- new SmartDiagnosisEvidenceFilterColumn("poNo", "po_no"),
- new SmartDiagnosisEvidenceFilterColumn("supplier", "supplier_code"),
- new SmartDiagnosisEvidenceFilterColumn("material", "item_code"),
- }),
- new(
- "material_readiness",
- SmartDiagnosisEvidenceDomain.Supply,
- new[] { "S3" },
- "work_order",
- "/aidop/s3/material-readiness",
- """
- SELECT COUNT(*) FROM dwd_material_readiness
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(shortage_qty,0)>0
- """,
- """
- SELECT work_order AS ObjectCode,
- CONCAT('缺料 ',IFNULL(work_order,''),' / ',IFNULL(supplier_code,'')) AS Title,
- IFNULL(shortage_qty,0) AS Contribution,
- 'red' AS Status,
- stat_date AS OccurredAt
- FROM dwd_material_readiness
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(shortage_qty,0)>0
- ORDER BY Contribution DESC, OccurredAt
- LIMIT @limit
- """,
- new[]
- {
- new SmartDiagnosisEvidenceFilterColumn("workOrder", "work_order"),
- new SmartDiagnosisEvidenceFilterColumn("supplier", "supplier_code"),
- }),
- new(
- "s6_report",
- SmartDiagnosisEvidenceDomain.Manufacturing,
- new[] { "S6" },
- "work_order",
- "/aidop/s6/report-work",
- """
- SELECT COUNT(*) FROM mdp_std_s6_report
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(work_order_no,'')<>''
- """,
- """
- SELECT work_order_no AS ObjectCode,
- CONCAT('报工 ',IFNULL(work_order_no,'')) AS Title,
- IFNULL(report_qty,0) AS Contribution,
- 'yellow' AS Status,
- report_date AS OccurredAt
- FROM mdp_std_s6_report
- WHERE tenant_id=@tenantId
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- AND IFNULL(work_order_no,'')<>''
- ORDER BY Contribution DESC, OccurredAt
- LIMIT @limit
- """,
- new[]
- {
- new SmartDiagnosisEvidenceFilterColumn("workOrder", "work_order_no"),
- }),
- new(
- "iqc_bill",
- SmartDiagnosisEvidenceDomain.Quality,
- new[] { "S5" },
- "inspection_bill",
- "/aidop/s5/iqc",
- """
- SELECT COUNT(*) FROM qms_qcp_inspbill
- WHERE tenant_id=@tenantId AND IFNULL(FBILLNO,'')<>''
- """,
- """
- SELECT FBILLNO AS ObjectCode,
- CONCAT('IQC ',IFNULL(FBILLNO,''),' / ',IFNULL(FBILLSTATUS,'')) AS Title,
- 1 AS Contribution,
- CASE WHEN UPPER(IFNULL(FBILLSTATUS,'')) IN ('NG','REJECT','UNQUALIFIED') THEN 'red' ELSE 'yellow' END AS Status,
- NULL AS OccurredAt
- FROM qms_qcp_inspbill
- WHERE tenant_id=@tenantId AND IFNULL(FBILLNO,'')<>''
- ORDER BY id DESC
- LIMIT @limit
- """,
- Array.Empty<SmartDiagnosisEvidenceFilterColumn>()),
- new(
- "fqc_result",
- SmartDiagnosisEvidenceDomain.Quality,
- new[] { "S7" },
- "inspection_bill",
- "/aidop/s7/fqc",
- """
- SELECT COUNT(*) FROM mdp_std_fqc_result
- WHERE tenant_id=@tenantId AND IFNULL(bill_no,'')<>''
- """,
- """
- SELECT bill_no AS ObjectCode,
- CONCAT('FQC ',IFNULL(bill_no,''),' / ',IFNULL(material_code,'')) AS Title,
- GREATEST(IFNULL(unqualified_qty,0),0) AS Contribution,
- CASE WHEN IFNULL(unqualified_qty,0)>0 OR UPPER(IFNULL(judgment,'')) IN ('NG','FAIL','UNQUALIFIED') THEN 'red' ELSE 'green' END AS Status,
- inspect_time AS OccurredAt
- FROM mdp_std_fqc_result
- WHERE tenant_id=@tenantId AND IFNULL(bill_no,'')<>''
- ORDER BY Contribution DESC, OccurredAt
- LIMIT @limit
- """,
- new[]
- {
- new SmartDiagnosisEvidenceFilterColumn("material", "material_code"),
- new SmartDiagnosisEvidenceFilterColumn("workOrder", "sap_work_order_no"),
- }),
- new(
- "s8_exception",
- SmartDiagnosisEvidenceDomain.Exception,
- new[] { "S8" },
- "s8_exception",
- "/aidop/s8/exceptions",
- """
- SELECT COUNT(*) FROM ado_s8_exception
- WHERE tenant_id=@tenantId AND IFNULL(is_deleted,0)=0
- AND IFNULL(exception_code,'')<>''
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- """,
- """
- SELECT exception_code AS ObjectCode,
- CONCAT(IFNULL(exception_code,''),' / ',IFNULL(title,'')) AS Title,
- GREATEST(IFNULL(priority_score,0),0) AS Contribution,
- CASE
- WHEN UPPER(IFNULL(status,'')) IN ('CLOSED','CANCELLED','CANCELED') THEN 'green'
- WHEN UPPER(IFNULL(severity,'')) IN ('SERIOUS','CRITICAL','HIGH') THEN 'red'
- ELSE 'yellow'
- END AS Status,
- created_at AS OccurredAt
- FROM ado_s8_exception
- WHERE tenant_id=@tenantId AND IFNULL(is_deleted,0)=0
- AND IFNULL(exception_code,'')<>''
- AND (factory_id IS NULL OR factory_id=0 OR factory_id=1 OR factory_id=@factoryId)
- AND (factory_id IS NULL OR factory_id<>@tenantId)
- ORDER BY Contribution DESC, OccurredAt
- LIMIT @limit
- """,
- new[]
- {
- new SmartDiagnosisEvidenceFilterColumn("orderNo", "related_object_code"),
- }),
- };
- public static IReadOnlyList<SmartDiagnosisEvidenceSource> All => Sources;
- public static IReadOnlyList<SmartDiagnosisEvidenceSource> Resolve(string moduleCode)
- {
- var mc = (moduleCode ?? "").Trim().ToUpperInvariant();
- if (mc == "S9")
- return Sources.Where(x => x.Key != "s8_exception").ToList();
- return Sources.Where(x => x.Modules.Contains(mc, StringComparer.OrdinalIgnoreCase)).ToList();
- }
- public static SmartDiagnosisEvidenceSource? Get(string key) =>
- Sources.FirstOrDefault(x => string.Equals(x.Key, key, StringComparison.OrdinalIgnoreCase));
- }
- public sealed class SmartDiagnosisEvidenceItem
- {
- public string ObjectType { get; set; } = "";
- public string ObjectCode { get; set; } = "";
- public string Title { get; set; } = "";
- public decimal? Contribution { get; set; }
- public string ContributionUnit { get; set; } = "";
- public string Status { get; set; } = "green";
- public string? OccurredAt { get; set; }
- public string? DrillPath { get; set; }
- }
- public sealed class SmartDiagnosisEvidenceResult
- {
- public string Scope { get; set; } = "no_data";
- public string? AsOf { get; set; }
- public string Domain { get; set; } = "";
- public int Total { get; set; }
- public int Returned { get; set; }
- public bool Truncated { get; set; }
- public List<string> Sources { get; set; } = new();
- public List<SmartDiagnosisEvidenceItem> Items { get; set; } = new();
- }
- internal sealed class SmartDiagnosisEvidenceSqlRow
- {
- public string? ObjectCode { get; set; }
- public string? Title { get; set; }
- public decimal? Contribution { get; set; }
- public string? Status { get; set; }
- public DateTime? OccurredAt { get; set; }
- }
|