Просмотр исходного кода

fix(s8): wire exception list types into dashboards

YY968XX 4 месяцев назад
Родитель
Сommit
5845a2c68d

+ 1 - 1
Web/package.json

@@ -1,7 +1,7 @@
 {
 	"name": "admin.net",
 	"type": "module",
-	"version": "2.4.181",
+	"version": "2.4.182",
 	"packageManager": "pnpm@10.32.1",
 	"lastBuildTime": "2026.03.15",
 	"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",

+ 4 - 0
Web/src/views/aidop/s8/api/s8MonitoringApi.ts

@@ -34,6 +34,7 @@ export type S8Period =
 	| 'today'
 	| 'this_week'
 	| 'this_month'
+	| 'this_quarter'
 	| 'last_24h'
 	| 'last_7d'
 	| 'last_30d';
@@ -88,6 +89,7 @@ export interface S8DeliveryTrendDay {
 	orderDueDateDelay: number;
 	productDesignDelay: number;
 	deliveryDelayWarning: number;
+	shipmentAbnormal: number;
 	total: number;
 }
 
@@ -112,6 +114,7 @@ export interface S8ProductionTrendDay {
 	materialFault: number;
 	qualityFault: number;
 	bodyProductionDelay: number;
+	productionWorkOrderCompletionDelay: number;
 	total: number;
 }
 
@@ -135,6 +138,7 @@ export interface S8SupplyTrendDay {
 	purchaseExecutionDelay: number;
 	materialStockAbnormal: number;
 	inventoryTurnoverAbnormal: number;
+	purchaseDeliveryAbnormal: number;
 	total: number;
 }
 

+ 2 - 3
Web/src/views/aidop/s8/monitoring/S8MonitoringDeliveryPage.vue

@@ -360,10 +360,9 @@ function anomalyToneClass(closeRate: number | null | undefined) {
 }
 
 // ─── 工具(趋势标题)──────────────────────────────────────────────────────
-const PERIOD_LABEL: Record<string, string> = { today: '本日', this_week: '本周', this_month: '本月', last_24h: '过去24h', last_7d: '过去7天', last_30d: '过去30天' };
+const PERIOD_LABEL: Record<string, string> = { today: '本日', this_week: '本周', this_month: '本月', this_quarter: '本季度', last_24h: '过去24h', last_7d: '过去7天', last_30d: '过去30天' };
 function trendTitle(domain: string) {
-	const label = PERIOD_LABEL[period.value ?? ''] ?? '本月';
-	return `${label}${domain}异常趋势`;
+	return `${domain}异常趋势`;
 }
 
 // ─── 数据加载 ──────────────────────────────────────────────────────────────

+ 2 - 3
Web/src/views/aidop/s8/monitoring/S8MonitoringProductionPage.vue

@@ -356,10 +356,9 @@ function anomalyToneClass(closeRate: number | null | undefined) {
 }
 
 // ─── 工具(趋势标题)──────────────────────────────────────────────────────
-const PERIOD_LABEL: Record<string, string> = { today: '本日', this_week: '本周', this_month: '本月', last_24h: '过去24h', last_7d: '过去7天', last_30d: '过去30天' };
+const PERIOD_LABEL: Record<string, string> = { today: '本日', this_week: '本周', this_month: '本月', this_quarter: '本季度', last_24h: '过去24h', last_7d: '过去7天', last_30d: '过去30天' };
 function trendTitle(domain: string) {
-	const label = PERIOD_LABEL[period.value ?? ''] ?? '本月';
-	return `${label}${domain}异常趋势`;
+	return `${domain}异常趋势`;
 }
 
 // ─── 数据加载 ──────────────────────────────────────────────────────────────

+ 2 - 3
Web/src/views/aidop/s8/monitoring/S8MonitoringSupplyPage.vue

@@ -376,10 +376,9 @@ function anomalyToneClass(closeRate: number | null | undefined) {
 }
 
 // ─── 工具(趋势标题)──────────────────────────────────────────────────────
-const PERIOD_LABEL: Record<string, string> = { today: '本日', this_week: '本周', this_month: '本月', last_24h: '过去24h', last_7d: '过去7天', last_30d: '过去30天' };
+const PERIOD_LABEL: Record<string, string> = { today: '本日', this_week: '本周', this_month: '本月', this_quarter: '本季度', last_24h: '过去24h', last_7d: '过去7天', last_30d: '过去30天' };
 function trendTitle(domain: string) {
-	const label = PERIOD_LABEL[period.value ?? ''] ?? '本月';
-	return `${label}${domain}异常趋势`;
+	return `${domain}异常趋势`;
 }
 
 // ─── 数据加载 ──────────────────────────────────────────────────────────────

+ 2 - 1
Web/src/views/aidop/s8/monitoring/components/S8DeliveryTrendChart.vue

@@ -43,7 +43,7 @@ const props = defineProps<{
 	title?: string;
 }>();
 
-const title = computed(() => props.title ?? '本月交付异常趋势');
+const title = computed(() => props.title ?? '交付异常趋势');
 
 const chartRef = ref();
 
@@ -68,6 +68,7 @@ const SERIES_META = [
 	{ key: 'orderDueDateDelay', name: '订单交期延期', color: '#7bd0ff' },
 	{ key: 'productDesignDelay', name: '产品设计延期', color: '#a78bfa' },
 	{ key: 'deliveryDelayWarning', name: '总装发货延期', color: '#ffc107' },
+	{ key: 'shipmentAbnormal', name: '发运异常', color: '#fb7185' },
 ] as const;
 
 const chartOption = computed(() => {

+ 1 - 0
Web/src/views/aidop/s8/monitoring/components/S8PeriodFilter.vue

@@ -21,6 +21,7 @@ const OPTIONS = [
 	{ value: 'today' as S8Period, label: '本日' },
 	{ value: 'this_week' as S8Period, label: '本周' },
 	{ value: 'this_month' as S8Period, label: '本月' },
+	{ value: 'this_quarter' as S8Period, label: '本季度' },
 	{ value: 'last_24h' as S8Period, label: '过去24h' },
 	{ value: 'last_7d' as S8Period, label: '过去7天' },
 	{ value: 'last_30d' as S8Period, label: '过去30天' },

+ 6 - 5
Web/src/views/aidop/s8/monitoring/components/S8ProductionTrendChart.vue

@@ -44,7 +44,7 @@ const props = defineProps<{
 	title?: string;
 }>();
 
-const title = computed(() => props.title ?? '本月生产异常趋势');
+const title = computed(() => props.title ?? '生产异常趋势');
 
 const chartRef = ref();
 
@@ -66,10 +66,11 @@ const todayText = computed(() => String(summary.value?.todayValue ?? 0));
 
 // S8-PRODUCTION-PAGE-TYPE-TITLE-AND-TREND-ALIGN-1:series 扩为 4 类(含本体生产延期)。
 const SERIES_META = [
-	{ key: 'equipmentFault',      name: '设备异常',     color: '#ffc107' },
-	{ key: 'materialFault',       name: '物料异常',     color: '#7bd0ff' },
-	{ key: 'qualityFault',        name: '质量异常',     color: '#ff9d6c' },
-	{ key: 'bodyProductionDelay', name: '本体生产延期', color: '#a78bfa' },
+	{ key: 'equipmentFault',                     name: '设备异常',     color: '#ffc107' },
+	{ key: 'materialFault',                      name: '物料异常',     color: '#7bd0ff' },
+	{ key: 'qualityFault',                       name: '质量异常',     color: '#ff9d6c' },
+	{ key: 'bodyProductionDelay',                name: '本体生产延期', color: '#a78bfa' },
+	{ key: 'productionWorkOrderCompletionDelay', name: '工单完工延期', color: '#fb7185' },
 ] as const;
 
 const chartOption = computed(() => {

+ 2 - 1
Web/src/views/aidop/s8/monitoring/components/S8SupplyTrendChart.vue

@@ -44,7 +44,7 @@ const props = defineProps<{
 	title?: string;
 }>();
 
-const title = computed(() => props.title ?? '本月供应异常趋势');
+const title = computed(() => props.title ?? '供应异常趋势');
 
 const chartRef = ref();
 
@@ -77,6 +77,7 @@ const ALL_SERIES_META = [
 	{ key: 'purchaseExecutionDelay',       name: '采购执行延期',       color: '#a78bfa' },
 	{ key: 'materialStockAbnormal',        name: '物料库存异常',       color: '#60a5fa' },
 	{ key: 'inventoryTurnoverAbnormal',    name: '库存周转异常',       color: '#facc15' },
+	{ key: 'purchaseDeliveryAbnormal',     name: '采购到货异常',       color: '#fb7185' },
 ] as const;
 
 type SeriesMeta = typeof ALL_SERIES_META[number];

+ 1 - 1
Web/src/views/aidop/s8/monitoring/useS8PeriodFilter.ts

@@ -2,7 +2,7 @@ import { shallowRef } from 'vue';
 import type { S8Period } from '../api/s8MonitoringApi';
 
 export function useS8PeriodFilter() {
-	const period = shallowRef<S8Period | undefined>('this_month');
+	const period = shallowRef<S8Period | undefined>('this_quarter');
 	const setPeriod = (next: S8Period) => { period.value = next; };
 	return { period, setPeriod };
 }

+ 3 - 3
server/Admin.NET.Web.Entry/Admin.NET.Web.Entry.csproj

@@ -11,9 +11,9 @@
     <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
     <Copyright>Admin.NET</Copyright>
     <Description>Admin.NET 通用权限开发平台</Description>
-    <AssemblyVersion>1.0.155</AssemblyVersion>
-    <FileVersion>1.0.155</FileVersion>
-    <Version>1.0.155</Version>
+    <AssemblyVersion>1.0.156</AssemblyVersion>
+    <FileVersion>1.0.156</FileVersion>
+    <Version>1.0.156</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 6 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Dto/S8/AdoS8Dtos.cs

@@ -375,6 +375,8 @@ public class AdoS8DeliveryTrendDayDto
     public int ProductDesignDelay { get; set; }
     /// <summary>总装发货延期(DELIVERY_DELAY_WARNING)当日计数</summary>
     public int DeliveryDelayWarning { get; set; }
+    /// <summary>发运异常(SHIPMENT_ABNORMAL)当日计数</summary>
+    public int ShipmentAbnormal { get; set; }
     public int Total { get; set; }
 }
 
@@ -404,6 +406,8 @@ public class AdoS8ProductionTrendDayDto
     public int QualityFault { get; set; }
     /// <summary>本体生产延期(BODY_PRODUCTION_DELAY_WARNING)当日计数</summary>
     public int BodyProductionDelay { get; set; }
+    /// <summary>工单完工延期(PRODUCTION_WORK_ORDER_COMPLETION_DELAY)当日计数</summary>
+    public int ProductionWorkOrderCompletionDelay { get; set; }
     public int Total { get; set; }
 }
 
@@ -433,6 +437,8 @@ public class AdoS8SupplyTrendDayDto
     public int MaterialStockAbnormal { get; set; }
     /// <summary>库存周转异常(INVENTORY_TURNOVER_ABNORMAL)当日计数</summary>
     public int InventoryTurnoverAbnormal { get; set; }
+    /// <summary>采购到货异常(PURCHASE_DELIVERY_ABNORMAL)当日计数</summary>
+    public int PurchaseDeliveryAbnormal { get; set; }
     public int Total { get; set; }
 }
 

+ 17 - 8
server/Plugins/Admin.NET.Plugin.AiDOP/Infrastructure/S8/S8PeriodHelper.cs

@@ -7,7 +7,7 @@ public static class S8PeriodHelper
 {
     /// <summary>
     /// 将 period 字符串解析为半开区间 [from, to)。
-    /// 支持 today / this_week / this_month(大小写容错)。
+    /// 支持 today / this_week / this_month / this_quarter(大小写容错)。
     /// 非法或空值返回 (null, null),调用方保持全量行为。
     /// </summary>
     public static (DateTime? from, DateTime? to) Resolve(string? period)
@@ -17,13 +17,14 @@ public static class S8PeriodHelper
         var today = DateTime.Today;
         return period.Trim().ToLowerInvariant() switch
         {
-            "today"      => (today, today.AddDays(1)),
-            "this_week"  => ResolveThisWeek(today),
-            "this_month" => (new DateTime(today.Year, today.Month, 1), new DateTime(today.Year, today.Month, 1).AddMonths(1)),
-            "last_24h"   => (DateTime.Now.AddHours(-24), DateTime.Now),
-            "last_7d"    => (today.AddDays(-6), today.AddDays(1)),
-            "last_30d"   => (today.AddDays(-29), today.AddDays(1)),
-            _            => (null, null),
+            "today"        => (today, today.AddDays(1)),
+            "this_week"    => ResolveThisWeek(today),
+            "this_month"   => (new DateTime(today.Year, today.Month, 1), new DateTime(today.Year, today.Month, 1).AddMonths(1)),
+            "this_quarter" => ResolveThisQuarter(today),
+            "last_24h"     => (DateTime.Now.AddHours(-24), DateTime.Now),
+            "last_7d"      => (today.AddDays(-6), today.AddDays(1)),
+            "last_30d"     => (today.AddDays(-29), today.AddDays(1)),
+            _              => (null, null),
         };
     }
 
@@ -34,4 +35,12 @@ public static class S8PeriodHelper
         var monday = today.AddDays(-offset);
         return (monday, monday.AddDays(7));
     }
+
+    private static (DateTime? from, DateTime? to) ResolveThisQuarter(DateTime today)
+    {
+        // 季度起始月:1 / 4 / 7 / 10
+        var quarterStartMonth = ((today.Month - 1) / 3) * 3 + 1;
+        var start = new DateTime(today.Year, quarterStartMonth, 1);
+        return (start, start.AddMonths(3));
+    }
 }

+ 26 - 16
server/Plugins/Admin.NET.Plugin.AiDOP/Service/S8/S8MonitoringService.cs

@@ -406,7 +406,7 @@ public class S8MonitoringService : ITransient
         }
 
         var deliveryModules = new[] { "S1", "S7" };
-        var deliveryTypes = new[] { "ORDER_DUE_DATE_DELAY", "PRODUCT_DESIGN_DELAY", "DELIVERY_DELAY_WARNING" };
+        var deliveryTypes = new[] { "ORDER_DUE_DATE_DELAY", "PRODUCT_DESIGN_DELAY", "DELIVERY_DELAY_WARNING", "SHIPMENT_ABNORMAL" };
 
         var rows = await _rep.AsQueryable()
             .Where(e => e.TenantId == tenantId && e.FactoryId == factoryId && !e.IsDeleted)
@@ -428,6 +428,7 @@ public class S8MonitoringService : ITransient
             var orderDueDateDelay    = bucket.Count(r => r.ExceptionTypeCode == "ORDER_DUE_DATE_DELAY");
             var productDesignDelay   = bucket.Count(r => r.ExceptionTypeCode == "PRODUCT_DESIGN_DELAY");
             var deliveryDelayWarning = bucket.Count(r => r.ExceptionTypeCode == "DELIVERY_DELAY_WARNING");
+            var shipmentAbnormal     = bucket.Count(r => r.ExceptionTypeCode == "SHIPMENT_ABNORMAL");
             dayList.Add(new AdoS8DeliveryTrendDayDto
             {
                 Date                 = d.ToString("MM/dd"),
@@ -435,7 +436,8 @@ public class S8MonitoringService : ITransient
                 OrderDueDateDelay    = orderDueDateDelay,
                 ProductDesignDelay   = productDesignDelay,
                 DeliveryDelayWarning = deliveryDelayWarning,
-                Total                = orderDueDateDelay + productDesignDelay + deliveryDelayWarning,
+                ShipmentAbnormal     = shipmentAbnormal,
+                Total                = orderDueDateDelay + productDesignDelay + deliveryDelayWarning + shipmentAbnormal,
             });
         }
 
@@ -489,7 +491,7 @@ public class S8MonitoringService : ITransient
         var prodTypes = new[]
         {
             "EQUIP_FAULT", "MFG_MATERIAL_ABNORMAL", "MFG_QUALITY_ABNORMAL",
-            "BODY_PRODUCTION_DELAY_WARNING"
+            "BODY_PRODUCTION_DELAY_WARNING", "PRODUCTION_WORK_ORDER_COMPLETION_DELAY"
         };
 
         var rows = await _rep.AsQueryable()
@@ -511,15 +513,17 @@ public class S8MonitoringService : ITransient
             var mf  = bucket.Count(r => r.ExceptionTypeCode == "MFG_MATERIAL_ABNORMAL");
             var qf  = bucket.Count(r => r.ExceptionTypeCode == "MFG_QUALITY_ABNORMAL");
             var bpd = bucket.Count(r => r.ExceptionTypeCode == "BODY_PRODUCTION_DELAY_WARNING");
+            var pwo = bucket.Count(r => r.ExceptionTypeCode == "PRODUCTION_WORK_ORDER_COMPLETION_DELAY");
             dayList.Add(new AdoS8ProductionTrendDayDto
             {
-                Date                = d.ToString("MM/dd"),
-                RawDate             = d.ToString("yyyy-MM-dd"),
-                EquipmentFault      = ef,
-                MaterialFault       = mf,
-                QualityFault        = qf,
-                BodyProductionDelay = bpd,
-                Total               = ef + mf + qf + bpd,
+                Date                                = d.ToString("MM/dd"),
+                RawDate                             = d.ToString("yyyy-MM-dd"),
+                EquipmentFault                      = ef,
+                MaterialFault                       = mf,
+                QualityFault                        = qf,
+                BodyProductionDelay                 = bpd,
+                ProductionWorkOrderCompletionDelay  = pwo,
+                Total                               = ef + mf + qf + bpd + pwo,
             });
         }
 
@@ -578,7 +582,8 @@ public class S8MonitoringService : ITransient
             "SUPPLIER_ETA_ISSUE", "SUPPLIER_SHIP_ISSUE", "SUPPLIER_DELIVERY_DELAY_WARNING",
             "WAREHOUSE_RECEIPT_ABNORMAL", "IQC_ISSUE", "WH_PUTAWAY_ISSUE",
             "WORK_ORDER_KITTING_ABNORMAL", "WORK_ORDER_ISSUE_ABNORMAL",
-            "PURCHASE_EXECUTION_DELAY", "MATERIAL_STOCK_ABNORMAL", "INVENTORY_TURNOVER_ABNORMAL"
+            "PURCHASE_EXECUTION_DELAY", "MATERIAL_STOCK_ABNORMAL", "INVENTORY_TURNOVER_ABNORMAL",
+            "PURCHASE_DELIVERY_ABNORMAL"
         };
 
         var rows = await _rep.AsQueryable()
@@ -607,6 +612,7 @@ public class S8MonitoringService : ITransient
             var ped   = bucket.Count(r => r.ExceptionTypeCode == "PURCHASE_EXECUTION_DELAY");
             var msa   = bucket.Count(r => r.ExceptionTypeCode == "MATERIAL_STOCK_ABNORMAL");
             var ita   = bucket.Count(r => r.ExceptionTypeCode == "INVENTORY_TURNOVER_ABNORMAL");
+            var pda   = bucket.Count(r => r.ExceptionTypeCode == "PURCHASE_DELIVERY_ABNORMAL");
             dayList.Add(new AdoS8SupplyTrendDayDto
             {
                 Date                          = d.ToString("MM/dd"),
@@ -622,7 +628,8 @@ public class S8MonitoringService : ITransient
                 PurchaseExecutionDelay        = ped,
                 MaterialStockAbnormal         = msa,
                 InventoryTurnoverAbnormal     = ita,
-                Total                         = sEta + sShip + sDdw + whR + iqc + whP + woK + woI + ped + msa + ita,
+                PurchaseDeliveryAbnormal      = pda,
+                Total                         = sEta + sShip + sDdw + whR + iqc + whP + woK + woI + ped + msa + ita + pda,
             });
         }
 
@@ -667,15 +674,17 @@ public class S8MonitoringService : ITransient
                 ("order-due-date-delay",    "订单交期延期", "ORDER_DUE_DATE_DELAY"),
                 ("product-design-delay",    "产品设计延期", "PRODUCT_DESIGN_DELAY"),
                 ("delivery-delay-warning",  "总装发货延期", "DELIVERY_DELAY_WARNING"),
+                ("shipment-abnormal",       "发运异常",     "SHIPMENT_ABNORMAL"),
             },
             "PRODUCTION" => new (string, string, string)[]
             {
-                ("equipment-fault",                "设备异常",         "EQUIP_FAULT"),
-                ("material-fault",                 "物料异常",         "MFG_MATERIAL_ABNORMAL"),
-                ("quality-fault",                  "质量异常",         "MFG_QUALITY_ABNORMAL"),
+                ("equipment-fault",                          "设备异常",         "EQUIP_FAULT"),
+                ("material-fault",                           "物料异常",         "MFG_MATERIAL_ABNORMAL"),
+                ("quality-fault",                            "质量异常",         "MFG_QUALITY_ABNORMAL"),
                 // S8-PRODUCTION-PAGE-TYPE-TITLE-AND-TREND-ALIGN-1:大屏显示「本体生产延期」(去预警),
                 // typeCode 保持 BODY_PRODUCTION_DELAY_WARNING,不改 ado_s8_exception_type.type_name。
-                ("body-production-delay-warning",  "本体生产延期",     "BODY_PRODUCTION_DELAY_WARNING"),
+                ("body-production-delay-warning",            "本体生产延期",     "BODY_PRODUCTION_DELAY_WARNING"),
+                ("production-work-order-completion-delay",   "工单完工延期",     "PRODUCTION_WORK_ORDER_COMPLETION_DELAY"),
             },
             "SUPPLY" => new (string, string, string)[]
             {
@@ -693,6 +702,7 @@ public class S8MonitoringService : ITransient
                 ("purchase-execution-delay",       "采购执行延期",         "PURCHASE_EXECUTION_DELAY"),
                 ("material-stock-abnormal",        "物料库存异常",         "MATERIAL_STOCK_ABNORMAL"),
                 ("inventory-turnover-abnormal",    "库存周转异常",         "INVENTORY_TURNOVER_ABNORMAL"),
+                ("purchase-delivery-abnormal",     "采购到货异常",         "PURCHASE_DELIVERY_ABNORMAL"),
             },
             _ => Array.Empty<(string, string, string)>(),
         };