From 45a7bf7f1f1c5da428883e7a142b33a9bc82eeea Mon Sep 17 00:00:00 2001
From: tjx <t2856754968@163.com>
Date: 星期一, 13 十月 2025 13:10:26 +0800
Subject: [PATCH] 11111
---
MESApplication/Controllers/QC/SpiAoiController.cs | 228 +++++++
MESApplication/bin/Debug/net8.0/MES.Service.pdb | 0
MESApplication/bin/Debug/net8.0/MESApplication.dll | 0
MES.Service/bin/Debug/net8.0/MES.Service.dll | 0
MESApplication/bin/Debug/net8.0/MESApplication.xml | 224 ++++--
MESApplication/bin/Debug/net8.0/MES.Service.dll | 0
MES.Service/Modes/MesSpiAoiDetail.cs | 220 +++++++
MES.Service/Modes/MesSpiAoiHeader.cs | 100 +++
MESApplication/bin/Debug/net8.0/MESApplication.pdb | 0
MES.Service/service/QC/SpiAoiService.cs | 387 ++++++++++++
MES.Service/service/QC/SPIAOI.txt | 428 +++++++++++++
MESApplication/bin/Debug/net8.0/MESApplication.deps.json | 2
MESApplication/bin/Debug/net8.0/MESApplication.exe | 0
MESApplication/bin/Debug/net8.0/MESApplication.staticwebassets.endpoints.json | 6
MES.Service/Dto/service/SpiAoiDto.cs | 260 ++++++++
MES.Service/bin/Debug/net8.0/MES.Service.pdb | 0
16 files changed, 1,759 insertions(+), 96 deletions(-)
diff --git a/MES.Service/Dto/service/SpiAoiDto.cs b/MES.Service/Dto/service/SpiAoiDto.cs
new file mode 100644
index 0000000..602a5eb
--- /dev/null
+++ b/MES.Service/Dto/service/SpiAoiDto.cs
@@ -0,0 +1,260 @@
+namespace MES.Service.Dto.service;
+
+/// <summary>
+/// SPI/AOI涓婁紶璇锋眰DTO
+/// </summary>
+public class SpiAoiUploadRequest
+{
+ /// <summary>
+ /// 涓昏〃鏁版嵁
+ /// </summary>
+ public SpiAoiHeaderDto Header { get; set; }
+
+ /// <summary>
+ /// 瀛愯〃鏁版嵁鍒楄〃
+ /// </summary>
+ public List<SpiAoiDetailDto> Details { get; set; }
+}
+
+/// <summary>
+/// SPI/AOI涓昏〃DTO
+/// </summary>
+public class SpiAoiHeaderDto
+{
+ /// <summary>
+ /// 娴嬭瘯鏃ユ湡(鏍煎紡锛歽yyy-MM-dd)
+ /// </summary>
+ public string TestDate { get; set; }
+
+ /// <summary>
+ /// 娴嬭瘯鏃堕棿(鏍煎紡锛欻H:mm:ss)
+ /// </summary>
+ public string TestTime { get; set; }
+
+ /// <summary>
+ /// 娴嬭瘯缁撴灉(濡傦細0:0:1;0銆�0;0;0:1銆丗ail绛�)
+ /// </summary>
+ public string TestResult { get; set; }
+
+ /// <summary>
+ /// 鏉块潰(T鎴朆)
+ /// </summary>
+ public string Surface { get; set; }
+
+ /// <summary>
+ /// 娴嬭瘯鐐规暟
+ /// </summary>
+ public int? TotalPoints { get; set; }
+
+ /// <summary>
+ /// 瀹為檯涓嶈壇鐐规暟
+ /// </summary>
+ public int? ActualDefects { get; set; }
+
+ /// <summary>
+ /// 璁惧鍨嬪彿
+ /// </summary>
+ public string? EquipmentModel { get; set; }
+
+ /// <summary>
+ /// 鎵规宸ュ崟
+ /// </summary>
+ public string? WorkOrder { get; set; }
+
+ /// <summary>
+ /// 鏈虹鍚�
+ /// </summary>
+ public string? ProductModel { get; set; }
+
+ /// <summary>
+ /// 鏉$爜
+ /// </summary>
+ public string BoardBarcode { get; set; }
+
+ /// <summary>
+ /// SMT缁勫埆
+ /// </summary>
+ public string? SmtGroup { get; set; }
+
+ /// <summary>
+ /// 绾垮埆
+ /// </summary>
+ public string? LineName { get; set; }
+}
+
+/// <summary>
+/// SPI/AOI瀛愯〃DTO
+/// </summary>
+public class SpiAoiDetailDto
+{
+ /// <summary>
+ /// 鏈哄櫒鍚嶇О
+ /// </summary>
+ public string? MachineName { get; set; }
+
+ /// <summary>
+ /// 鐢熶骇绾垮悕绉�
+ /// </summary>
+ public string? LineDisplayName { get; set; }
+
+ /// <summary>
+ /// 鍋忎綅鏁伴噺
+ /// </summary>
+ public int OffsetCount { get; set; }
+
+ /// <summary>
+ /// 缂轰欢鏁伴噺
+ /// </summary>
+ public int MissingCount { get; set; }
+
+ /// <summary>
+ /// 鍙嶅悜鏁伴噺
+ /// </summary>
+ public int ReverseCount { get; set; }
+
+ /// <summary>
+ /// 缈樿捣鏁伴噺
+ /// </summary>
+ public int LiftedCount { get; set; }
+
+ /// <summary>
+ /// 娴珮鏁伴噺
+ /// </summary>
+ public int FloatHighCount { get; set; }
+
+ /// <summary>
+ /// 绔嬬鏁伴噺
+ /// </summary>
+ public int TombstoneCount { get; set; }
+
+ /// <summary>
+ /// 缈昏浆鏁伴噺
+ /// </summary>
+ public int FlipCount { get; set; }
+
+ /// <summary>
+ /// 閿欎欢鏁伴噺
+ /// </summary>
+ public int WrongPartCount { get; set; }
+
+ /// <summary>
+ /// 缈樿剼鏁伴噺
+ /// </summary>
+ public int LeadLiftCount { get; set; }
+
+ /// <summary>
+ /// 铏氱剨鏁伴噺
+ /// </summary>
+ public int ColdJointCount { get; set; }
+
+ /// <summary>
+ /// 绌虹剨鏁伴噺
+ /// </summary>
+ public int NoSolderCount { get; set; }
+
+ /// <summary>
+ /// 灏戦敗鏁伴噺
+ /// </summary>
+ public int InsufficientSolderCount { get; set; }
+
+ /// <summary>
+ /// 澶氶敗鏁伴噺
+ /// </summary>
+ public int ExcessSolderCount { get; set; }
+
+ /// <summary>
+ /// 杩為敗鏁伴噺
+ /// </summary>
+ public int BridgeCount { get; set; }
+
+ /// <summary>
+ /// 婕忛摐鏁伴噺
+ /// </summary>
+ public int CopperExposureCount { get; set; }
+
+ /// <summary>
+ /// 鎷夊皷鏁伴噺
+ /// </summary>
+ public int SpikeCount { get; set; }
+
+ /// <summary>
+ /// 寮傜墿鏁伴噺
+ /// </summary>
+ public int ForeignMatterCount { get; set; }
+
+ /// <summary>
+ /// 婧㈣兌鏁伴噺
+ /// </summary>
+ public int GlueOverflowCount { get; set; }
+
+ /// <summary>
+ /// 寮曡剼鍋忎綅鏁伴噺
+ /// </summary>
+ public int PinOffsetCount { get; set; }
+
+ /// <summary>
+ /// 鎶曞叆鏉挎暟
+ /// </summary>
+ public int InputBoards { get; set; }
+
+ /// <summary>
+ /// OK鏉挎暟
+ /// </summary>
+ public int OkBoards { get; set; }
+
+ /// <summary>
+ /// 閫氳繃鏉挎暟
+ /// </summary>
+ public int PassBoards { get; set; }
+
+ /// <summary>
+ /// 鍚堟牸鐜�(%)
+ /// </summary>
+ public decimal? PassRate { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鏉挎暟
+ /// </summary>
+ public int DefectBoards { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鐜�(%)
+ /// </summary>
+ public decimal? DefectRate { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鐜�(PPM)
+ /// </summary>
+ public int? DefectPpm { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鐐规暟
+ /// </summary>
+ public int DefectPoints { get; set; }
+
+ /// <summary>
+ /// 瀹炴祴鐐规暟
+ /// </summary>
+ public int MeasuredPoints { get; set; }
+
+ /// <summary>
+ /// 寰呮祴鐐规暟
+ /// </summary>
+ public int PendingPoints { get; set; }
+}
+
+/// <summary>
+/// SPI/AOI涓婁紶鍝嶅簲DTO
+/// </summary>
+public class SpiAoiUploadResponse
+{
+ /// <summary>
+ /// 涓昏〃ID
+ /// </summary>
+ public decimal HeaderId { get; set; }
+
+ /// <summary>
+ /// 鎻掑叆鐨勫瓙琛ㄨ褰曟暟
+ /// </summary>
+ public int DetailCount { get; set; }
+}
diff --git a/MES.Service/Modes/MesSpiAoiDetail.cs b/MES.Service/Modes/MesSpiAoiDetail.cs
new file mode 100644
index 0000000..a492e4e
--- /dev/null
+++ b/MES.Service/Modes/MesSpiAoiDetail.cs
@@ -0,0 +1,220 @@
+using SqlSugar;
+
+namespace MES.Service.Modes;
+
+/// <summary>
+/// SPI/AOI 妫�娴嬫槑缁嗗疄浣擄紝璁板綍缂洪櫡鍒嗙被缁熻鍙婁骇绾挎晥鐜囨寚鏍囥��
+/// </summary>
+[SugarTable("MES_SPI_AOI_DETAIL")]
+public class MesSpiAoiDetail
+{
+ /// <summary>
+ /// 涓婚敭ID锛岀敱 Oracle 搴忓垪 SEQ_SPI_AOI_DETAIL 鐢熸垚銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "ID", IsPrimaryKey = true, OracleSequenceName = "SEQ_SPI_AOI_DETAIL")]
+ public decimal Id { get; set; }
+
+ /// <summary>
+ /// 涓昏〃 ID锛堝閿級锛屽叧鑱� <see cref="MesSpiAoiHeader" />銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "HEADER_ID")]
+ public decimal HeaderId { get; set; }
+
+ /// <summary>
+ /// 鍋忎綅鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "OFFSET_COUNT")]
+ public int OffsetCount { get; set; }
+
+ /// <summary>
+ /// 缂轰欢鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "MISSING_COUNT")]
+ public int MissingCount { get; set; }
+
+ /// <summary>
+ /// 鍙嶅悜瀹夎鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "REVERSE_COUNT")]
+ public int ReverseCount { get; set; }
+
+ /// <summary>
+ /// 缈樿捣鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "LIFTED_COUNT")]
+ public int LiftedCount { get; set; }
+
+ /// <summary>
+ /// 娴珮鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "FLOAT_HIGH_COUNT")]
+ public int FloatHighCount { get; set; }
+
+ /// <summary>
+ /// 绔嬬鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "TOMBSTONE_COUNT")]
+ public int TombstoneCount { get; set; }
+
+ /// <summary>
+ /// 缈昏浆鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "FLIP_COUNT")]
+ public int FlipCount { get; set; }
+
+ /// <summary>
+ /// 閿欎欢鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "WRONG_PART_COUNT")]
+ public int WrongPartCount { get; set; }
+
+ /// <summary>
+ /// 缈樿剼鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "LEAD_LIFT_COUNT")]
+ public int LeadLiftCount { get; set; }
+
+ /// <summary>
+ /// 铏氱剨鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "COLD_JOINT_COUNT")]
+ public int ColdJointCount { get; set; }
+
+ /// <summary>
+ /// 绌虹剨鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "NO_SOLDER_COUNT")]
+ public int NoSolderCount { get; set; }
+
+ /// <summary>
+ /// 灏戦敗鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "INSUFFICIENT_SOLDER_COUNT")]
+ public int InsufficientSolderCount { get; set; }
+
+ /// <summary>
+ /// 澶氶敗鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "EXCESS_SOLDER_COUNT")]
+ public int ExcessSolderCount { get; set; }
+
+ /// <summary>
+ /// 杩為敗鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "BRIDGE_COUNT")]
+ public int BridgeCount { get; set; }
+
+ /// <summary>
+ /// 婕忛摐鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "COPPER_EXPOSURE_COUNT")]
+ public int CopperExposureCount { get; set; }
+
+ /// <summary>
+ /// 鎷夊皷鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "SPIKE_COUNT")]
+ public int SpikeCount { get; set; }
+
+ /// <summary>
+ /// 寮傜墿娈嬬暀鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "FOREIGN_MATTER_COUNT")]
+ public int ForeignMatterCount { get; set; }
+
+ /// <summary>
+ /// 婧㈣兌鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "GLUE_OVERFLOW_COUNT")]
+ public int GlueOverflowCount { get; set; }
+
+ /// <summary>
+ /// 寮曡剼鍋忎綅鏁伴噺銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "PIN_OFFSET_COUNT")]
+ public int PinOffsetCount { get; set; }
+
+ /// <summary>
+ /// 浜х嚎鏄剧ず鍚嶇О銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "LINE_DISPLAY_NAME")]
+ public string? LineDisplayName { get; set; }
+
+ /// <summary>
+ /// 妫�娴嬫満鍙板悕绉般��
+ /// </summary>
+ [SugarColumn(ColumnName = "MACHINE_NAME")]
+ public string? MachineName { get; set; }
+
+ /// <summary>
+ /// 鎶曞叆鏉挎暟閲忋��
+ /// </summary>
+ [SugarColumn(ColumnName = "INPUT_BOARDS")]
+ public int InputBoards { get; set; }
+
+ /// <summary>
+ /// OK 鏉挎暟閲忋��
+ /// </summary>
+ [SugarColumn(ColumnName = "OK_BOARDS")]
+ public int OkBoards { get; set; }
+
+ /// <summary>
+ /// 閫氳繃鏉挎暟閲忋��
+ /// </summary>
+ [SugarColumn(ColumnName = "PASS_BOARDS")]
+ public int PassBoards { get; set; }
+
+ /// <summary>
+ /// 鍚堟牸鐜囷紙鍗曚綅锛�%锛夈��
+ /// </summary>
+ [SugarColumn(ColumnName = "PASS_RATE")]
+ public decimal? PassRate { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鏉挎暟閲忋��
+ /// </summary>
+ [SugarColumn(ColumnName = "DEFECT_BOARDS")]
+ public int DefectBoards { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鐜囷紙鍗曚綅锛�%锛夈��
+ /// </summary>
+ [SugarColumn(ColumnName = "DEFECT_RATE")]
+ public decimal? DefectRate { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鏁帮紙鍗曚綅锛歅PM锛夈��
+ /// </summary>
+ [SugarColumn(ColumnName = "DEFECT_PPM")]
+ public int? DefectPpm { get; set; }
+
+ /// <summary>
+ /// 涓嶈壇鐐规暟銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "DEFECT_POINTS")]
+ public int DefectPoints { get; set; }
+
+ /// <summary>
+ /// 瀹炴祴鐐规暟銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "MEASURED_POINTS")]
+ public int MeasuredPoints { get; set; }
+
+ /// <summary>
+ /// 寰呮祴鐐规暟銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "PENDING_POINTS")]
+ public int PendingPoints { get; set; }
+
+ /// <summary>
+ /// 鍒涘缓鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴炽��
+ /// </summary>
+ [SugarColumn(ColumnName = "CREATED_AT")]
+ public DateTime CreatedAt { get; set; }
+
+ /// <summary>
+ /// 鏇存柊鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴炽��
+ /// </summary>
+ [SugarColumn(ColumnName = "UPDATED_AT")]
+ public DateTime UpdatedAt { get; set; }
+}
diff --git a/MES.Service/Modes/MesSpiAoiHeader.cs b/MES.Service/Modes/MesSpiAoiHeader.cs
new file mode 100644
index 0000000..3b00ce9
--- /dev/null
+++ b/MES.Service/Modes/MesSpiAoiHeader.cs
@@ -0,0 +1,100 @@
+using SqlSugar;
+
+namespace MES.Service.Modes;
+
+/// <summary>
+/// SPI/AOI 妫�娴嬩富琛ㄥ疄浣擄紝鐢ㄤ簬淇濆瓨鍗曞潡 PCB 鐨勬壒娆℃娴嬫瑙堟暟鎹��
+/// </summary>
+[SugarTable("MES_SPI_AOI_HEADER")]
+public class MesSpiAoiHeader
+{
+ /// <summary>
+ /// 涓婚敭ID锛岀敱 Oracle 搴忓垪 SEQ_SPI_AOI_HEADER 鐢熸垚銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "ID", IsPrimaryKey = true, OracleSequenceName = "SEQ_SPI_AOI_HEADER")]
+ public decimal Id { get; set; }
+
+ /// <summary>
+ /// 娴嬭瘯鏃ユ湡锛堣澶囦笂浼犵殑骞存湀鏃ワ級銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "TEST_DATE")]
+ public DateTime TestDate { get; set; }
+
+ /// <summary>
+ /// 娴嬭瘯鏃堕棿锛圚H:mm:ss 鏍煎紡锛屼繚鎸佸師濮嬪�硷級銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "TEST_TIME")]
+ public string TestTime { get; set; } = string.Empty;
+
+ /// <summary>
+ /// 娴嬭瘯缁撴灉鍘熷瀛楃涓诧紝渚嬪 0:0:1;0銆�0;0;0:1銆丗ail銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "TEST_RESULT")]
+ public string TestResult { get; set; } = string.Empty;
+
+ /// <summary>
+ /// 妫�娴嬮潰锛圱 = Top 椤堕潰锛孊 = Bottom 搴曢潰锛夈��
+ /// </summary>
+ [SugarColumn(ColumnName = "SURFACE")]
+ public string Surface { get; set; } = string.Empty;
+
+ /// <summary>
+ /// 璁″垝妫�娴嬬偣鏁般��
+ /// </summary>
+ [SugarColumn(ColumnName = "TOTAL_POINTS")]
+ public int? TotalPoints { get; set; }
+
+ /// <summary>
+ /// 瀹為檯涓嶈壇鐐规暟銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "ACTUAL_DEFECTS")]
+ public int? ActualDefects { get; set; }
+
+ /// <summary>
+ /// 璁惧鍨嬪彿銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "EQUIPMENT_MODEL")]
+ public string? EquipmentModel { get; set; }
+
+ /// <summary>
+ /// 瀵瑰簲鐢熶骇宸ュ崟鎴栨壒娆″彿銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "WORK_ORDER")]
+ public string? WorkOrder { get; set; }
+
+ /// <summary>
+ /// 鏈虹鍚嶇О銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "PRODUCT_MODEL")]
+ public string? ProductModel { get; set; }
+
+ /// <summary>
+ /// 鏉夸欢鏉$爜锛堝敮涓�绾︽潫锛夈��
+ /// </summary>
+ [SugarColumn(ColumnName = "BOARD_BARCODE")]
+ public string BoardBarcode { get; set; } = string.Empty;
+
+ /// <summary>
+ /// SMT 缁勫埆銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "SMT_GROUP")]
+ public string? SmtGroup { get; set; }
+
+ /// <summary>
+ /// 绾垮埆鍚嶇О銆�
+ /// </summary>
+ [SugarColumn(ColumnName = "LINE_NAME")]
+ public string? LineName { get; set; }
+
+ /// <summary>
+ /// 鍒涘缓鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴炽��
+ /// </summary>
+ [SugarColumn(ColumnName = "CREATED_AT")]
+ public DateTime CreatedAt { get; set; }
+
+ /// <summary>
+ /// 鏇存柊鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴炽��
+ /// </summary>
+ [SugarColumn(ColumnName = "UPDATED_AT")]
+ public DateTime UpdatedAt { get; set; }
+}
diff --git a/MES.Service/bin/Debug/net8.0/MES.Service.dll b/MES.Service/bin/Debug/net8.0/MES.Service.dll
index ace4808..54d04c6 100644
--- a/MES.Service/bin/Debug/net8.0/MES.Service.dll
+++ b/MES.Service/bin/Debug/net8.0/MES.Service.dll
Binary files differ
diff --git a/MES.Service/bin/Debug/net8.0/MES.Service.pdb b/MES.Service/bin/Debug/net8.0/MES.Service.pdb
index 1ebf67e..1c43e59 100644
--- a/MES.Service/bin/Debug/net8.0/MES.Service.pdb
+++ b/MES.Service/bin/Debug/net8.0/MES.Service.pdb
Binary files differ
diff --git a/MES.Service/service/QC/SPIAOI.txt b/MES.Service/service/QC/SPIAOI.txt
new file mode 100644
index 0000000..4513b32
--- /dev/null
+++ b/MES.Service/service/QC/SPIAOI.txt
@@ -0,0 +1,428 @@
+锘夸富琛ㄥ瓧娈�
+娴嬭瘯鏃堕棿(骞淬�佹湀銆佹棩),娴嬭瘯鏃堕棿(鏃躲�佸垎銆佺),娴嬭瘯缁撴灉(鍥哄畾涓轰笁绉�:0:0:1;0:娴嬭瘯涓篛K,0;0;0:1:娴嬭瘯涓篎ail,T闈�(鍒員op(涓�)闈�/Bottom(涓�)闈�),娴嬭瘯鐐规暟,瀹為檯涓嶈壇,璁惧鍨嬪彿,鎵规宸ュ崟,鏈虹鍚�,鏉$爜,SMT缁勫埆,绾垮埆
+
+瀛愯〃瀛楁
+鍋忎綅,缂轰欢,鍙嶅悜,缈樿捣,娴珮,绔嬬,缈昏浆,閿欎欢,缈樿剼,铏氱剨,绌虹剨,灏戦敗,澶氶敗,杩為敗,婕忛摐,鎷夊皷,寮傜墿,婧㈣兌,寮曡剼鍋忎綅,鐢熶骇绾垮悕绉�,鏈哄櫒鍚嶇О,鎶曞叆鏉挎暟,OK鏉挎暟,閫氳繃鏉挎暟,鍚堟牸鐜�,涓嶈壇鏉挎暟,涓嶈壇鐜�,涓嶈壇鐜�(PPM),涓嶈壇鐐规暟,瀹炴祴鐐规暟,寰呮祴鐐规暟
+
+鎵ц鐩爣
+- 灏� `MES.Service/service/QC/SPIAOI.txt`:1-7 涓殑 SPI/AOI 妫�娴嬪瓧娈佃浆鍖栦负涓�涓彲璋冪敤鐨� REST API锛屽苟琛ュ厖鏁版嵁搴撳缓琛ㄤ笌鎸佷箙鍖栭�昏緫銆�
+- 鐩爣瑕嗙洊璇锋眰濂戠害銆佹暟鎹牎楠屻�佷富浠庤〃寤烘ā銆佸瓨鍌ㄨ繃绋�/鏈嶅姟淇濆瓨娴佺▼浠ュ強寮傚父涓庢棩蹇楀鐞嗐��
+
+鏁版嵁缁撴瀯鎷嗚В
+- `涓昏〃瀛楁` 鈫� 璁板綍鍗曟 SPI/AOI 妫�娴嬬殑澶翠俊鎭�傚缓璁瓧娈�/绫诲瀷锛�
+ 娴嬭瘯鏃ユ湡(`TestDate`/DATE)銆佹祴璇曟椂闂�(`TestTime`/VARCHAR2(8 CHAR))銆佹祴璇曠粨鏋�(`TestResult`/VARCHAR2(12 CHAR)锛屽�煎煙锛歚0:0:1;0`銆乣0;0;0:1`銆乣Fail`)銆侀潰鍒�(`Surface`/CHAR(1)锛屽�煎煙 `T`/`B`)銆佹祴璇曠偣鏁�(`TotalPoints`/NUMBER(6))銆佸疄闄呬笉鑹偣鏁�(`ActualDefects`/NUMBER(6))銆佽澶囧瀷鍙�(`EquipmentModel`/VARCHAR2(64 CHAR))銆佹壒娆″伐鍗�(`WorkOrder`/VARCHAR2(64 CHAR))銆佹満绉嶅悕(`ProductModel`/VARCHAR2(64 CHAR))銆佹潯鐮�(`BoardBarcode`/VARCHAR2(128 CHAR))銆丼MT 缁勫埆(`SmtGroup`/VARCHAR2(32 CHAR))銆佺嚎鍒�(`LineName`/VARCHAR2(32 CHAR))銆�
+- `瀛愯〃瀛楁` 鈫� 璁板綍鍗曟妫�娴嬬殑缂洪櫡缁熻銆傚缓璁瓧娈�/绫诲瀷锛�
+ 鍋忎綅(`OffsetCount`/NUMBER(6))銆佺己浠�(`MissingCount`/NUMBER(6))銆佸弽鍚�(`ReverseCount`/NUMBER(6))銆佺繕璧�(`LiftedCount`/NUMBER(6))銆佹诞楂�(`FloatHighCount`/NUMBER(6))銆佺珛纰�(`TombstoneCount`/NUMBER(6))銆佺炕杞�(`FlipCount`/NUMBER(6))銆侀敊浠�(`WrongPartCount`/NUMBER(6))銆佺繕鑴�(`LeadLiftCount`/NUMBER(6))銆佽櫄鐒�(`ColdJointCount`/NUMBER(6))銆佺┖鐒�(`NoSolderCount`/NUMBER(6))銆佸皯閿�(`InsufficientSolderCount`/NUMBER(6))銆佸閿�(`ExcessSolderCount`/NUMBER(6))銆佽繛閿�(`BridgeCount`/NUMBER(6))銆佹紡閾�(`CopperExposureCount`/NUMBER(6))銆佹媺灏�(`SpikeCount`/NUMBER(6))銆佸紓鐗�(`ForeignMatterCount`/NUMBER(6))銆佹孩鑳�(`GlueOverflowCount`/NUMBER(6))銆佸紩鑴氬亸浣�(`PinOffsetCount`/NUMBER(6))銆佺敓浜х嚎鍚嶇О(`LineDisplayName`/VARCHAR2(64 CHAR))銆佹満鍣ㄥ悕绉�(`MachineName`/VARCHAR2(64 CHAR))銆佹姇鍏ユ澘鏁�(`InputBoards`/NUMBER(6))銆丱K鏉挎暟(`OkBoards`/NUMBER(6))銆侀�氳繃鏉挎暟(`PassBoards`/NUMBER(6))銆佸悎鏍肩巼(`PassRate`/NUMBER(5,2))銆佷笉鑹澘鏁�(`DefectBoards`/NUMBER(6))銆佷笉鑹巼(`DefectRate`/NUMBER(5,2))銆佷笉鑹巼PPM(`DefectPpm`/NUMBER(9))銆佷笉鑹偣鏁�(`DefectPoints`/NUMBER(6))銆佸疄娴嬬偣鏁�(`MeasuredPoints`/NUMBER(6))銆佸緟娴嬬偣鏁�(`PendingPoints`/NUMBER(6))銆傛墍鏈夆�滅巼鈥濆瓧娈典互鐧惧垎姣斿瓨鍌紝鍏ュ簱鍓嶈浆涓烘暟鍊煎瀷銆�
+
+鏁版嵁搴撹璁�
+- 鐩爣搴撲负 Oracle 11g锛�11.2锛夛紝鏈」鐩娇鐢� `SqlSugar` 骞堕�氳繃 `[SugarColumn(OracleSequenceName = "...")]` 鑷姩鍙栧彿锛屽洜姝ゅ彧闇�澹版槑涓婚敭鍜屽簭鍒楋紝鏃犻渶瑙﹀彂鍣ㄣ�傜ず渚� DDL锛�
+```
+-- 涓昏〃锛氳褰曟瘡鍧楃數璺澘鐨� SPI/AOI 鎵规妫�娴嬫憳瑕佹暟鎹�
+-- SPI/AOI 涓昏〃锛岃褰曞崟鏉挎壒娆℃娴嬫憳瑕�
+CREATE TABLE MES_SPI_AOI_HEADER (
+ ID NUMBER(19) NOT NULL,
+ TEST_DATE DATE NOT NULL,
+ TEST_TIME VARCHAR2(8 CHAR) NOT NULL,
+ TEST_RESULT VARCHAR2(12 CHAR) NOT NULL,
+ SURFACE CHAR(1) NOT NULL CHECK (SURFACE IN ('T','B')),
+ TOTAL_POINTS NUMBER(6),
+ ACTUAL_DEFECTS NUMBER(6),
+ EQUIPMENT_MODEL VARCHAR2(64 CHAR),
+ WORK_ORDER VARCHAR2(64 CHAR),
+ PRODUCT_MODEL VARCHAR2(64 CHAR),
+ BOARD_BARCODE VARCHAR2(128 CHAR) NOT NULL,
+ SMT_GROUP VARCHAR2(32 CHAR),
+ LINE_NAME VARCHAR2(32 CHAR),
+ CREATED_AT TIMESTAMP DEFAULT SYSTIMESTAMP,
+ UPDATED_AT TIMESTAMP DEFAULT SYSTIMESTAMP
+);
+ALTER TABLE MES_SPI_AOI_HEADER
+ ADD CONSTRAINT PK_SPI_AOI_HEADER PRIMARY KEY (ID);
+CREATE UNIQUE INDEX IDX_SPI_AOI_BARCODE ON MES_SPI_AOI_HEADER (BOARD_BARCODE);
+
+COMMENT ON TABLE MES_SPI_AOI_HEADER IS 'SPI/AOI 涓昏〃锛岃褰曞崟鏉挎娴嬫憳瑕佹暟鎹�';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.ID IS '涓婚敭ID锛岀敱搴忓垪 SEQ_SPI_AOI_HEADER 鐢熸垚';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.TEST_DATE IS '娴嬭瘯鏃ユ湡锛屾部鐢ㄨ澶囦笂浼犵殑骞存湀鏃�';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.TEST_TIME IS '娴嬭瘯鏃堕棿锛屾部鐢ㄨ澶囦笂浼犵殑 HH:mm:ss';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.TEST_RESULT IS '娴嬭瘯缁撴灉鍘熷瀛楃涓诧紝渚嬪 0:0:1;0銆�0;0;0:1銆丗ail';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.SURFACE IS '妫�娴嬮潰锛孴=Top 椤堕潰锛孊=Bottom 搴曢潰';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.TOTAL_POINTS IS '璁″垝妫�娴嬬偣鏁�';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.ACTUAL_DEFECTS IS '瀹為檯涓嶈壇鐐规暟';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.EQUIPMENT_MODEL IS '璁惧鍨嬪彿';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.WORK_ORDER IS '瀵瑰簲宸ュ崟鎴栨壒娆″彿';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.PRODUCT_MODEL IS '鏈虹鍚嶇О';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.BOARD_BARCODE IS '鏉夸欢鏉$爜锛屾暣鍗曞敮涓�';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.SMT_GROUP IS 'SMT 缁勫埆';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.LINE_NAME IS '绾垮埆鍚嶇О';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.CREATED_AT IS '鍒涘缓鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴�';
+COMMENT ON COLUMN MES_SPI_AOI_HEADER.UPDATED_AT IS '鏇存柊鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴�';
+
+CREATE SEQUENCE SEQ_SPI_AOI_HEADER START WITH 1 INCREMENT BY 1 NOCACHE;
+
+-- SPI/AOI 鏄庣粏琛紝鎷嗗垎缂洪櫡缁熻涓庝骇鑳芥寚鏍�
+CREATE TABLE MES_SPI_AOI_DETAIL (
+ ID NUMBER(19) NOT NULL,
+ HEADER_ID NUMBER(19) NOT NULL,
+ OFFSET_COUNT NUMBER(6) DEFAULT 0,
+ MISSING_COUNT NUMBER(6) DEFAULT 0,
+ REVERSE_COUNT NUMBER(6) DEFAULT 0,
+ LIFTED_COUNT NUMBER(6) DEFAULT 0,
+ FLOAT_HIGH_COUNT NUMBER(6) DEFAULT 0,
+ TOMBSTONE_COUNT NUMBER(6) DEFAULT 0,
+ FLIP_COUNT NUMBER(6) DEFAULT 0,
+ WRONG_PART_COUNT NUMBER(6) DEFAULT 0,
+ LEAD_LIFT_COUNT NUMBER(6) DEFAULT 0,
+ COLD_JOINT_COUNT NUMBER(6) DEFAULT 0,
+ NO_SOLDER_COUNT NUMBER(6) DEFAULT 0,
+ INSUFFICIENT_SOLDER_COUNT NUMBER(6) DEFAULT 0,
+ EXCESS_SOLDER_COUNT NUMBER(6) DEFAULT 0,
+ BRIDGE_COUNT NUMBER(6) DEFAULT 0,
+ COPPER_EXPOSURE_COUNT NUMBER(6) DEFAULT 0,
+ SPIKE_COUNT NUMBER(6) DEFAULT 0,
+ FOREIGN_MATTER_COUNT NUMBER(6) DEFAULT 0,
+ GLUE_OVERFLOW_COUNT NUMBER(6) DEFAULT 0,
+ PIN_OFFSET_COUNT NUMBER(6) DEFAULT 0,
+ LINE_DISPLAY_NAME VARCHAR2(64 CHAR),
+ MACHINE_NAME VARCHAR2(64 CHAR),
+ INPUT_BOARDS NUMBER(6) DEFAULT 0,
+ OK_BOARDS NUMBER(6) DEFAULT 0,
+ PASS_BOARDS NUMBER(6) DEFAULT 0,
+ PASS_RATE NUMBER(5,2),
+ DEFECT_BOARDS NUMBER(6) DEFAULT 0,
+ DEFECT_RATE NUMBER(5,2),
+ DEFECT_PPM NUMBER(9),
+ DEFECT_POINTS NUMBER(6) DEFAULT 0,
+ MEASURED_POINTS NUMBER(6) DEFAULT 0,
+ PENDING_POINTS NUMBER(6) DEFAULT 0,
+ CREATED_AT TIMESTAMP DEFAULT SYSTIMESTAMP,
+ UPDATED_AT TIMESTAMP DEFAULT SYSTIMESTAMP
+);
+ALTER TABLE MES_SPI_AOI_DETAIL
+ ADD CONSTRAINT PK_SPI_AOI_DETAIL PRIMARY KEY (ID);
+ALTER TABLE MES_SPI_AOI_DETAIL
+ ADD CONSTRAINT FK_SPI_AOI_DETAIL_HEADER FOREIGN KEY (HEADER_ID)
+ REFERENCES MES_SPI_AOI_HEADER(ID);
+
+CREATE INDEX IDX_SPI_AOI_DETAIL_HEADER ON MES_SPI_AOI_DETAIL (HEADER_ID);
+
+COMMENT ON TABLE MES_SPI_AOI_DETAIL IS 'SPI/AOI 鏄庣粏琛紝璁板綍缂洪櫡鍒嗙被缁熻涓庝骇绾挎晥鐜囨暟鎹�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.ID IS '涓婚敭ID锛岀敱搴忓垪 SEQ_SPI_AOI_DETAIL 鐢熸垚';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.HEADER_ID IS '涓昏〃澶栭敭锛屾寚鍚� MES_SPI_AOI_HEADER.ID';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.OFFSET_COUNT IS '鍋忎綅鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.MISSING_COUNT IS '缂轰欢鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.REVERSE_COUNT IS '鍙嶅悜瀹夎鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.LIFTED_COUNT IS '缈樿捣鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.FLOAT_HIGH_COUNT IS '娴珮鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.TOMBSTONE_COUNT IS '绔嬬鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.FLIP_COUNT IS '缈昏浆鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.WRONG_PART_COUNT IS '閿欎欢鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.LEAD_LIFT_COUNT IS '缈樿剼鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.COLD_JOINT_COUNT IS '铏氱剨鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.NO_SOLDER_COUNT IS '绌虹剨鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.INSUFFICIENT_SOLDER_COUNT IS '灏戦敗鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.EXCESS_SOLDER_COUNT IS '澶氶敗鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.BRIDGE_COUNT IS '杩為敗鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.COPPER_EXPOSURE_COUNT IS '婕忛摐鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.SPIKE_COUNT IS '鎷夊皷鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.FOREIGN_MATTER_COUNT IS '寮傜墿娈嬬暀鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.GLUE_OVERFLOW_COUNT IS '婧㈣兌鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.PIN_OFFSET_COUNT IS '寮曡剼鍋忎綅鏁伴噺';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.LINE_DISPLAY_NAME IS '浜х嚎鏄剧ず鍚嶇О';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.MACHINE_NAME IS '妫�娴嬫満鍙板悕绉�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.INPUT_BOARDS IS '鎶曞叆鏉挎暟閲�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.OK_BOARDS IS 'OK 鏉挎暟閲�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.PASS_BOARDS IS '閫氳繃鏉挎暟閲�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.PASS_RATE IS '鍚堟牸鐜囷紙%锛�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.DEFECT_BOARDS IS '涓嶈壇鏉挎暟閲�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.DEFECT_RATE IS '涓嶈壇鐜囷紙%锛�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.DEFECT_PPM IS '涓嶈壇鏁帮紙PPM锛�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.DEFECT_POINTS IS '涓嶈壇鐐规暟';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.MEASURED_POINTS IS '瀹炴祴鐐规暟';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.PENDING_POINTS IS '寰呮祴鐐规暟';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.CREATED_AT IS '鍒涘缓鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴�';
+COMMENT ON COLUMN MES_SPI_AOI_DETAIL.UPDATED_AT IS '鏇存柊鏃堕棿锛岄粯璁ゅ啓鍏ユ暟鎹簱鏃堕棿鎴�';
+
+CREATE SEQUENCE SEQ_SPI_AOI_DETAIL START WITH 1 INCREMENT BY 1 NOCACHE;
+
+娴嬭瘯缁撴灉璇存槑
+- `TestResult` 瀛楁鐩存帴鎺ユ敹鍘熷瀛楃涓诧紝涓嶅仛鏋氫妇鏍¢獙
+- 甯歌鍊煎弬鑰冿細
+ - "0:0:1;0" (閫氬父琛ㄧず娴嬭瘯閫氳繃)
+ - "0;0;0:1" (閫氬父琛ㄧず娴嬭瘯澶辫触)
+ - "Fail" (閫氬父琛ㄧず娴嬭瘯寮傚父)
+- 鏁版嵁搴撳瓨鍌ㄥ師濮嬪�硷紝鐢变笟鍔″眰鏍规嵁闇�瑕佽В鏋�
+
+鎺ュ彛璁捐
+- URL锛歚POST /api/QC/SpiAoi/Upload`锛堜綅浜� `MESApplication.Controllers.QC` 鍛藉悕绌洪棿锛屾部鐢� `ResponseResult` 杩斿洖鏍煎紡锛夈��
+- 璇锋眰浣撶粨鏋勶細
+```
+{
+ "header": {
+ "testDate": "2025-10-10",
+ "testTime": "14:33:21",
+ "testResult": "0;0;0:1",
+ "surface": "T",
+ "totalPoints": 500,
+ "actualDefects": 3,
+ "equipmentModel": "SPI-9000",
+ "workOrder": "WO20251010-01",
+ "productModel": "MODEL-ABC",
+ "boardBarcode": "BC123456789",
+ "smtGroup": "A1",
+ "lineName": "SMT-01"
+ },
+ "details": [
+ {
+ "machineName": "AOI-01",
+ "lineDisplayName": "SMT-01",
+ "offsetCount": 1,
+ "missingCount": 0,
+ "reverseCount": 0,
+ "liftedCount": 0,
+ "floatHighCount": 0,
+ "tombstoneCount": 0,
+ "flipCount": 0,
+ "wrongPartCount": 0,
+ "leadLiftCount": 0,
+ "coldJointCount": 0,
+ "noSolderCount": 0,
+ "insufficientSolderCount": 1,
+ "excessSolderCount": 0,
+ "bridgeCount": 1,
+ "copperExposureCount": 0,
+ "spikeCount": 0,
+ "foreignMatterCount": 0,
+ "glueOverflowCount": 0,
+ "pinOffsetCount": 0,
+ "inputBoards": 120,
+ "okBoards": 117,
+ "passBoards": 117,
+ "passRate": 97.5,
+ "defectBoards": 3,
+ "defectRate": 2.5,
+ "defectPpm": 25000,
+ "defectPoints": 3,
+ "measuredPoints": 500,
+ "pendingPoints": 0
+ }
+ ]
+}
+```
+- 鍝嶅簲绀轰緥锛�
+```
+{
+ "status": 0,
+ "message": "OK",
+ "data": { "headerId": 12345 }
+}
+```
+
+涓氬姟澶勭悊娴佺▼
+- 鍏ュ彛鎺у埗鍣ㄨ礋璐fā鍨嬬粦瀹氫笌鍩烘湰鏍¢獙锛�
+ - 蹇呭~瀛楁锛歵estDate銆乼estTime銆乼estResult銆乥oardBarcode銆乻urface
+ - 鏋氫妇鍚堟硶鎬э細surface 蹇呴』涓� "T" 鎴� "B"
+ - testResult锛氫笉鍋氭灇涓炬牎楠岋紝鐩存帴鎺ユ敹鍘熷瀛楃涓�
+ - 鏁板�奸潪璐燂細鎵�鏈夎鏁板瓧娈靛繀椤� >= 0
+ - **details 涓嶈兘涓虹┖鎴� null**
+- 灏嗚姹傚鎵樼粰 `SpiAoiService`锛堜綅浜� `MES.Service.service.QC`锛夛紝璇ユ湇鍔′娇鐢� `SqlSugarClient` 鍚姩浜嬪姟锛�
+ 1. **鏉$爜鍞竴鎬ф娴�**锛氳嫢 `BOARD_BARCODE` 宸插瓨鍦紝鐩存帴杩斿洖閿欒 `status=1, message="鏉$爜宸插瓨鍦紝涓嶅厑璁搁噸澶嶄笂浼�"`锛堜繚鎸佸敮涓�绱㈠紩绾︽潫锛夈��
+ 2. 鎻掑叆澶磋〃璁板綍锛岃繑鍥� `HEADER_ID`锛堝疄浣撻�氳繃 `[SugarColumn(IsPrimaryKey = true, OracleSequenceName = "SEQ_SPI_AOI_HEADER")]` 鑷姩鑾峰彇搴忓垪鍊硷級銆�
+ 3. 閬嶅巻 `details`锛屼负姣忔潯濉厖 `HEADER_ID` 骞舵彃鍏ュ瓙琛ㄣ��
+ 4. **琛嶇敓瀛楁鏍¢獙**锛堣褰曟棩蹇椾絾涓嶉樆鏂級锛�
+ - `passBoards <= inputBoards`
+ - `defectBoards = inputBoards - passBoards`
+ - `passRate` 涓庤绠楀�� `(passBoards / inputBoards * 100)` 鐨勫亸宸湪 卤1.0 浠ュ唴
+ - 鑻ユ牎楠屽け璐ワ紝璁板綍璀﹀憡鏃ュ織浣嗕笉鍥炴粴浜嬪姟
+ 5. 鎻愪氦浜嬪姟锛涘紓甯稿垯鍥炴粴骞惰褰曟棩蹇椼��
+- 鎴愬姛鍚庤繑鍥� `headerId`锛涘け璐ヨ繑鍥� `status=1` 涓庨敊璇俊鎭��
+
+楠岃瘉涓庨敊璇鐞�
+- **杈撳叆鏍¢獙澶辫触**锛氳繑鍥� `status=1`锛宍message` 鎸囨槑瀛楁鍙婂師鍥狅紙濡傦細"boardBarcode 涓嶈兘涓虹┖"銆�"surface 蹇呴』涓� T 鎴� B"锛夈��
+- **鏉$爜閲嶅**锛氳繑鍥� `status=1, message="鏉$爜 {boardBarcode} 宸插瓨鍦紝涓嶅厑璁搁噸澶嶄笂浼�"`銆�
+- **details 涓虹┖**锛氳繑鍥� `status=1, message="details 涓嶈兘涓虹┖"`銆�
+- **鏁版嵁搴撳紓甯�**锛氭崟鑾� `SqlSugar`/Oracle 寮傚父锛岃褰曞埌鐜版湁鏃ュ織锛堝 `LogUtil`锛夛紝鍚屾椂鍐欏叆娑堟伅涓績锛堣嫢闇� ERP 鍚屾锛夋垨鑷畾涔夐敊璇槦鍒椼��
+
+瀹炰綋瀹氫箟绀轰緥
+```csharp
+[SugarTable("MES_SPI_AOI_HEADER")]
+public class SpiAoiHeader
+{
+ [SugarColumn(ColumnName = "ID", IsPrimaryKey = true, OracleSequenceName = "SEQ_SPI_AOI_HEADER")]
+ public long Id { get; set; }
+
+ [SugarColumn(ColumnName = "TEST_DATE")]
+ public DateTime TestDate { get; set; }
+
+ [SugarColumn(ColumnName = "TEST_TIME")]
+ public string TestTime { get; set; }
+
+ [SugarColumn(ColumnName = "TEST_RESULT")]
+ public string TestResult { get; set; }
+
+ [SugarColumn(ColumnName = "SURFACE")]
+ public string Surface { get; set; }
+
+ [SugarColumn(ColumnName = "TOTAL_POINTS")]
+ public int? TotalPoints { get; set; }
+
+ [SugarColumn(ColumnName = "ACTUAL_DEFECTS")]
+ public int? ActualDefects { get; set; }
+
+ [SugarColumn(ColumnName = "EQUIPMENT_MODEL")]
+ public string EquipmentModel { get; set; }
+
+ [SugarColumn(ColumnName = "WORK_ORDER")]
+ public string WorkOrder { get; set; }
+
+ [SugarColumn(ColumnName = "PRODUCT_MODEL")]
+ public string ProductModel { get; set; }
+
+ [SugarColumn(ColumnName = "BOARD_BARCODE")]
+ public string BoardBarcode { get; set; }
+
+ [SugarColumn(ColumnName = "SMT_GROUP")]
+ public string SmtGroup { get; set; }
+
+ [SugarColumn(ColumnName = "LINE_NAME")]
+ public string LineName { get; set; }
+
+ [SugarColumn(ColumnName = "CREATED_AT")]
+ public DateTime CreatedAt { get; set; }
+
+ [SugarColumn(ColumnName = "UPDATED_AT")]
+ public DateTime UpdatedAt { get; set; }
+}
+
+[SugarTable("MES_SPI_AOI_DETAIL")]
+public class SpiAoiDetail
+{
+ [SugarColumn(ColumnName = "ID", IsPrimaryKey = true, OracleSequenceName = "SEQ_SPI_AOI_DETAIL")]
+ public long Id { get; set; }
+
+ [SugarColumn(ColumnName = "HEADER_ID")]
+ public long HeaderId { get; set; }
+
+ [SugarColumn(ColumnName = "OFFSET_COUNT")]
+ public int OffsetCount { get; set; }
+
+ [SugarColumn(ColumnName = "MISSING_COUNT")]
+ public int MissingCount { get; set; }
+
+ [SugarColumn(ColumnName = "REVERSE_COUNT")]
+ public int ReverseCount { get; set; }
+
+ [SugarColumn(ColumnName = "LIFTED_COUNT")]
+ public int LiftedCount { get; set; }
+
+ [SugarColumn(ColumnName = "FLOAT_HIGH_COUNT")]
+ public int FloatHighCount { get; set; }
+
+ [SugarColumn(ColumnName = "TOMBSTONE_COUNT")]
+ public int TombstoneCount { get; set; }
+
+ [SugarColumn(ColumnName = "FLIP_COUNT")]
+ public int FlipCount { get; set; }
+
+ [SugarColumn(ColumnName = "WRONG_PART_COUNT")]
+ public int WrongPartCount { get; set; }
+
+ [SugarColumn(ColumnName = "LEAD_LIFT_COUNT")]
+ public int LeadLiftCount { get; set; }
+
+ [SugarColumn(ColumnName = "COLD_JOINT_COUNT")]
+ public int ColdJointCount { get; set; }
+
+ [SugarColumn(ColumnName = "NO_SOLDER_COUNT")]
+ public int NoSolderCount { get; set; }
+
+ [SugarColumn(ColumnName = "INSUFFICIENT_SOLDER_COUNT")]
+ public int InsufficientSolderCount { get; set; }
+
+ [SugarColumn(ColumnName = "EXCESS_SOLDER_COUNT")]
+ public int ExcessSolderCount { get; set; }
+
+ [SugarColumn(ColumnName = "BRIDGE_COUNT")]
+ public int BridgeCount { get; set; }
+
+ [SugarColumn(ColumnName = "COPPER_EXPOSURE_COUNT")]
+ public int CopperExposureCount { get; set; }
+
+ [SugarColumn(ColumnName = "SPIKE_COUNT")]
+ public int SpikeCount { get; set; }
+
+ [SugarColumn(ColumnName = "FOREIGN_MATTER_COUNT")]
+ public int ForeignMatterCount { get; set; }
+
+ [SugarColumn(ColumnName = "GLUE_OVERFLOW_COUNT")]
+ public int GlueOverflowCount { get; set; }
+
+ [SugarColumn(ColumnName = "PIN_OFFSET_COUNT")]
+ public int PinOffsetCount { get; set; }
+
+ [SugarColumn(ColumnName = "LINE_DISPLAY_NAME")]
+ public string LineDisplayName { get; set; }
+
+ [SugarColumn(ColumnName = "MACHINE_NAME")]
+ public string MachineName { get; set; }
+
+ [SugarColumn(ColumnName = "INPUT_BOARDS")]
+ public int InputBoards { get; set; }
+
+ [SugarColumn(ColumnName = "OK_BOARDS")]
+ public int OkBoards { get; set; }
+
+ [SugarColumn(ColumnName = "PASS_BOARDS")]
+ public int PassBoards { get; set; }
+
+ [SugarColumn(ColumnName = "PASS_RATE")]
+ public decimal? PassRate { get; set; }
+
+ [SugarColumn(ColumnName = "DEFECT_BOARDS")]
+ public int DefectBoards { get; set; }
+
+ [SugarColumn(ColumnName = "DEFECT_RATE")]
+ public decimal? DefectRate { get; set; }
+
+ [SugarColumn(ColumnName = "DEFECT_PPM")]
+ public int? DefectPpm { get; set; }
+
+ [SugarColumn(ColumnName = "DEFECT_POINTS")]
+ public int DefectPoints { get; set; }
+
+ [SugarColumn(ColumnName = "MEASURED_POINTS")]
+ public int MeasuredPoints { get; set; }
+
+ [SugarColumn(ColumnName = "PENDING_POINTS")]
+ public int PendingPoints { get; set; }
+
+ [SugarColumn(ColumnName = "CREATED_AT")]
+ public DateTime CreatedAt { get; set; }
+
+ [SugarColumn(ColumnName = "UPDATED_AT")]
+ public DateTime UpdatedAt { get; set; }
+}
+```
+
+瀹炵幇姝ラ寤鸿
+1. **鍒涘缓鏁版嵁搴撹〃**锛氭墽琛屼笂杩� DDL锛屽垱寤� `MES_SPI_AOI_HEADER`銆乣MES_SPI_AOI_DETAIL` 琛ㄥ強搴忓垪銆�
+2. **瀹氫箟瀹炰綋妯″瀷**锛氬湪 `MES.Service.Modes` 涓嬪垱寤� `SpiAoiHeader.cs` 鍜� `SpiAoiDetail.cs`锛堝弬鑰冧笂杩板疄浣撳畾涔夌ず渚嬶級銆�
+3. **鍒涘缓 DTO**锛�
+ - `SpiAoiHeaderDto.cs`锛堢敤浜庤姹備綋 header 閮ㄥ垎锛�
+ - `SpiAoiDetailDto.cs`锛堢敤浜庤姹備綋 details 鏁扮粍鍏冪礌锛�
+ - `SpiAoiUploadRequest.cs`锛堝寘鍚� Header 鍜� Details 鍒楄〃锛�
+ - `SpiAoiUploadResponse.cs`锛堝寘鍚� headerId锛�
+4. **瀹炵幇鏈嶅姟灞�**锛�
+ - 鍦� `MES.Service.service.QC` 涓嬪垱寤� `SpiAoiService.cs`
+ - 瀹炵幇鏉$爜鍞竴鎬ф鏌ャ�佷簨鍔℃彃鍏ャ�佹暟鎹牎楠岀瓑涓氬姟閫昏緫
+5. **瀹炵幇鎺у埗鍣�**锛�
+ - 鍦� `MESApplication.Controllers.QC` 涓嬪垱寤� `SpiAoiController.cs`
+ - 娣诲姞 `[HttpPost("Upload")]` 鏂规硶锛岃皟鐢ㄦ湇鍔″眰骞惰繑鍥� `ResponseResult`
+6. **娣诲姞鍗曞厓娴嬭瘯**锛堝彲閫夛級锛氶獙璇佹垚鍔熸彃鍏ャ�侀潪娉曟灇涓俱�佹潯鐮侀噸澶嶃�乨etails 涓虹┖銆佷簨鍔″洖婊氱瓑鍦烘櫙銆�
+
+娉ㄦ剰浜嬮」
+- 鎵�鏈夊瓧绗︿覆瀛楁闇�妫�鏌ラ暱搴︽槸鍚﹁秴杩囨暟鎹簱瀹氫箟锛堝 `BOARD_BARCODE` 鏈�澶� 128 瀛楃锛夈��
+- `TestDate` 鍜� `TestTime` 鍒嗗紑瀛樺偍锛屽墠绔渶鍒嗗埆浼犲叆鏃ユ湡鍜屾椂闂村瓧绗︿覆銆�
+- `TestResult` 涓嶅仛鏋氫妇鏍¢獙锛屾帴鏀朵换鎰忓瓧绗︿覆鍊硷紙鏈�澶� 12 瀛楃锛夛紝鍘熸牱瀛樺偍鍒版暟鎹簱銆�
+- 瀵逛簬 `CREATED_AT` 鍜� `UPDATED_AT`锛屽缓璁湪浠g爜涓樉寮忚祴鍊� `DateTime.Now`锛岃�岄潪渚濊禆鏁版嵁搴撻粯璁ゅ�笺��
+- Oracle 11g 闇�纭繚 SqlSugar 鐗堟湰鍏煎锛堟帹鑽� 5.x 鎴栨洿楂樼増鏈級銆�
+- 鏉$爜鍞竴绱㈠紩 `IDX_SPI_AOI_BARCODE` 浼氳嚜鍔ㄩ樆姝㈤噸澶嶆彃鍏ワ紝浣嗗缓璁湪浠g爜涓彁鍓嶆鏌ュ苟杩斿洖鍙嬪ソ閿欒淇℃伅銆�
diff --git a/MES.Service/service/QC/SpiAoiService.cs b/MES.Service/service/QC/SpiAoiService.cs
new file mode 100644
index 0000000..7a2aad8
--- /dev/null
+++ b/MES.Service/service/QC/SpiAoiService.cs
@@ -0,0 +1,387 @@
+using MES.Service.DB;
+using MES.Service.Dto.service;
+using MES.Service.Modes;
+using MES.Service.util;
+
+namespace MES.Service.service.QC;
+
+/// <summary>
+/// SPI/AOI妫�娴嬫暟鎹湇鍔�
+/// </summary>
+public class SpiAoiService
+{
+ /// <summary>
+ /// 涓婁紶SPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="request">涓婁紶璇锋眰DTO</param>
+ /// <returns>涓婁紶鍝嶅簲DTO</returns>
+ public SpiAoiUploadResponse UploadSpiAoiData(SpiAoiUploadRequest request)
+ {
+ // 1. 鍩烘湰鏍¢獙
+ ValidateRequest(request);
+
+ try
+ {
+ SpiAoiUploadResponse response = null;
+
+ SqlSugarHelper.UseTransactionWithOracle(db =>
+ {
+ // 2. 妫�鏌ユ潯鐮佹槸鍚﹀凡瀛樺湪
+ var existingHeader = db.Queryable<MesSpiAoiHeader>()
+ .Where(x => x.BoardBarcode == request.Header.BoardBarcode)
+ .First();
+
+ if (existingHeader != null)
+ {
+ throw new Exception($"鏉$爜 {request.Header.BoardBarcode} 宸插瓨鍦紝涓嶅厑璁搁噸澶嶄笂浼�");
+ }
+
+ // 3. 杞崲骞舵彃鍏ヤ富琛ㄦ暟鎹�
+ var header = ConvertHeaderDtoToEntity(request.Header);
+ header.CreatedAt = DateTime.Now;
+ header.UpdatedAt = DateTime.Now;
+
+ var headerId = db.Insertable(header).ExecuteReturnIdentity();
+
+ // 4. 杞崲骞舵彃鍏ュ瓙琛ㄦ暟鎹�
+ var detailCount = 0;
+ if (request.Details != null && request.Details.Count > 0)
+ {
+ var details = ConvertDetailDtoListToEntity(request.Details, headerId);
+
+ // 鏁版嵁鏍¢獙(璁板綍璀﹀憡浣嗕笉闃绘柇)
+ ValidateDetailData(request.Details);
+
+ detailCount = db.Insertable(details).ExecuteCommand();
+ }
+
+ response = new SpiAoiUploadResponse
+ {
+ HeaderId = headerId,
+ DetailCount = detailCount
+ };
+
+ return 1; // 杩斿洖鍙楀奖鍝嶇殑琛屾暟渚涗簨鍔″垽鏂�
+ });
+
+ if (response == null)
+ {
+ throw new Exception("涓婁紶澶辫触");
+ }
+
+ return response;
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"涓婁紶SPI/AOI妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+ }
+ }
+
+ /// <summary>
+ /// 鏍规嵁鏉$爜鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="boardBarcode">鏉$爜</param>
+ /// <returns>妫�娴嬫暟鎹�(涓昏〃+瀛愯〃)</returns>
+ public (MesSpiAoiHeader header, List<MesSpiAoiDetail> details) GetByBarcode(string boardBarcode)
+ {
+ try
+ {
+ var db = SqlSugarHelper.GetInstance();
+
+ var header = db.Queryable<MesSpiAoiHeader>()
+ .Where(x => x.BoardBarcode == boardBarcode)
+ .First();
+
+ if (header == null)
+ {
+ return (null, null);
+ }
+
+ var details = db.Queryable<MesSpiAoiDetail>()
+ .Where(x => x.HeaderId == header.Id)
+ .ToList();
+
+ return (header, details);
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"鏌ヨSPI/AOI妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+ }
+ }
+
+ /// <summary>
+ /// 鏍规嵁ID鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="headerId">涓昏〃ID</param>
+ /// <returns>妫�娴嬫暟鎹�(涓昏〃+瀛愯〃)</returns>
+ public (MesSpiAoiHeader header, List<MesSpiAoiDetail> details) GetById(decimal headerId)
+ {
+ try
+ {
+ var db = SqlSugarHelper.GetInstance();
+
+ var header = db.Queryable<MesSpiAoiHeader>()
+ .Where(x => x.Id == headerId)
+ .First();
+
+ if (header == null)
+ {
+ return (null, null);
+ }
+
+ var details = db.Queryable<MesSpiAoiDetail>()
+ .Where(x => x.HeaderId == headerId)
+ .ToList();
+
+ return (header, details);
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"鏌ヨSPI/AOI妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+ }
+ }
+
+ /// <summary>
+ /// 鍒嗛〉鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="boardBarcode">鏉$爜(鍙��)</param>
+ /// <param name="workOrder">宸ュ崟(鍙��)</param>
+ /// <param name="surface">鏉块潰(鍙��)</param>
+ /// <param name="startDate">寮�濮嬫棩鏈�(鍙��)</param>
+ /// <param name="endDate">缁撴潫鏃ユ湡(鍙��)</param>
+ /// <param name="pageIndex">椤电爜</param>
+ /// <param name="pageSize">椤靛ぇ灏�</param>
+ /// <returns>鍒嗛〉鏁版嵁</returns>
+ public (List<MesSpiAoiHeader> items, int totalCount) GetPage(
+ string boardBarcode = null,
+ string workOrder = null,
+ string surface = null,
+ DateTime? startDate = null,
+ DateTime? endDate = null,
+ int pageIndex = 1,
+ int pageSize = 20)
+ {
+ try
+ {
+ var db = SqlSugarHelper.GetInstance();
+ var totalCount = 0;
+
+ var data = db.Queryable<MesSpiAoiHeader>()
+ .WhereIF(StringUtil.IsNotNullOrEmpty(boardBarcode),
+ x => x.BoardBarcode.Contains(boardBarcode))
+ .WhereIF(StringUtil.IsNotNullOrEmpty(workOrder),
+ x => x.WorkOrder.Contains(workOrder))
+ .WhereIF(StringUtil.IsNotNullOrEmpty(surface),
+ x => x.Surface == surface)
+ .WhereIF(startDate.HasValue,
+ x => x.TestDate >= startDate.Value)
+ .WhereIF(endDate.HasValue,
+ x => x.TestDate <= endDate.Value)
+ .OrderBy(x => x.CreatedAt, SqlSugar.OrderByType.Desc)
+ .ToPageList(pageIndex, pageSize, ref totalCount);
+
+ return (data, totalCount);
+ }
+ catch (Exception ex)
+ {
+ throw new Exception($"鍒嗛〉鏌ヨSPI/AOI妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+ }
+ }
+
+ #region 绉佹湁鏂规硶
+
+ /// <summary>
+ /// 鏍¢獙璇锋眰鍙傛暟
+ /// </summary>
+ /// <param name="request">璇锋眰DTO</param>
+ private void ValidateRequest(SpiAoiUploadRequest request)
+ {
+ if (request == null)
+ {
+ throw new Exception("璇锋眰鍙傛暟涓嶈兘涓虹┖");
+ }
+
+ if (request.Header == null)
+ {
+ throw new Exception("header 涓嶈兘涓虹┖");
+ }
+
+ if (request.Details == null || request.Details.Count == 0)
+ {
+ throw new Exception("details 涓嶈兘涓虹┖");
+ }
+
+ // 鏍¢獙蹇呭~瀛楁
+ if (StringUtil.IsNullOrEmpty(request.Header.TestDate))
+ {
+ throw new Exception("testDate 涓嶈兘涓虹┖");
+ }
+
+ if (StringUtil.IsNullOrEmpty(request.Header.TestTime))
+ {
+ throw new Exception("testTime 涓嶈兘涓虹┖");
+ }
+
+ if (StringUtil.IsNullOrEmpty(request.Header.TestResult))
+ {
+ throw new Exception("testResult 涓嶈兘涓虹┖");
+ }
+
+ if (StringUtil.IsNullOrEmpty(request.Header.BoardBarcode))
+ {
+ throw new Exception("boardBarcode 涓嶈兘涓虹┖");
+ }
+
+ if (StringUtil.IsNullOrEmpty(request.Header.Surface))
+ {
+ throw new Exception("surface 涓嶈兘涓虹┖");
+ }
+
+ // 鏍¢獙鏋氫妇鍊�
+ if (request.Header.Surface != "T" && request.Header.Surface != "B")
+ {
+ throw new Exception("surface 蹇呴』涓� T 鎴� B");
+ }
+
+ // 鏍¢獙瀛楃涓查暱搴�
+ if (request.Header.BoardBarcode.Length > 128)
+ {
+ throw new Exception("boardBarcode 闀垮害涓嶈兘瓒呰繃 128 瀛楃");
+ }
+
+ if (request.Header.TestResult.Length > 12)
+ {
+ throw new Exception("testResult 闀垮害涓嶈兘瓒呰繃 12 瀛楃");
+ }
+
+ // 鏍¢獙鏁板�奸潪璐�
+ foreach (var detail in request.Details)
+ {
+ if (detail.OffsetCount < 0 || detail.MissingCount < 0 ||
+ detail.ReverseCount < 0 || detail.LiftedCount < 0 ||
+ detail.FloatHighCount < 0 || detail.TombstoneCount < 0 ||
+ detail.FlipCount < 0 || detail.WrongPartCount < 0 ||
+ detail.LeadLiftCount < 0 || detail.ColdJointCount < 0 ||
+ detail.NoSolderCount < 0 || detail.InsufficientSolderCount < 0 ||
+ detail.ExcessSolderCount < 0 || detail.BridgeCount < 0 ||
+ detail.CopperExposureCount < 0 || detail.SpikeCount < 0 ||
+ detail.ForeignMatterCount < 0 || detail.GlueOverflowCount < 0 ||
+ detail.PinOffsetCount < 0 || detail.InputBoards < 0 ||
+ detail.OkBoards < 0 || detail.PassBoards < 0 ||
+ detail.DefectBoards < 0 || detail.DefectPoints < 0 ||
+ detail.MeasuredPoints < 0 || detail.PendingPoints < 0)
+ {
+ throw new Exception("鎵�鏈夎鏁板瓧娈靛繀椤� >= 0");
+ }
+ }
+ }
+
+ /// <summary>
+ /// 鏍¢獙瀛愯〃鏁版嵁(璁板綍璀﹀憡浣嗕笉闃绘柇)
+ /// </summary>
+ /// <param name="details">瀛愯〃DTO鍒楄〃</param>
+ private void ValidateDetailData(List<SpiAoiDetailDto> details)
+ {
+ foreach (var detail in details)
+ {
+ // 鏍¢獙 passBoards <= inputBoards
+ if (detail.PassBoards > detail.InputBoards)
+ {
+ Console.WriteLine($"[璀﹀憡] passBoards({detail.PassBoards}) 澶т簬 inputBoards({detail.InputBoards})");
+ }
+
+ // 鏍¢獙 defectBoards = inputBoards - passBoards
+ var expectedDefectBoards = detail.InputBoards - detail.PassBoards;
+ if (Math.Abs(detail.DefectBoards - expectedDefectBoards) > 0)
+ {
+ Console.WriteLine($"[璀﹀憡] defectBoards({detail.DefectBoards}) 涓庤绠楀��({expectedDefectBoards})涓嶄竴鑷�");
+ }
+
+ // 鏍¢獙 passRate 鍋忓樊鍦� 卤1.0 浠ュ唴
+ if (detail.InputBoards > 0 && detail.PassRate.HasValue)
+ {
+ var expectedPassRate = (decimal)detail.PassBoards / detail.InputBoards * 100;
+ var deviation = Math.Abs(detail.PassRate.Value - expectedPassRate);
+ if (deviation > 1.0m)
+ {
+ Console.WriteLine($"[璀﹀憡] passRate({detail.PassRate}) 涓庤绠楀��({expectedPassRate:F2})鍋忓樊瓒呰繃1.0");
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// 灏嗕富琛―TO杞崲涓哄疄浣�
+ /// </summary>
+ /// <param name="dto">涓昏〃DTO</param>
+ /// <returns>涓昏〃瀹炰綋</returns>
+ private MesSpiAoiHeader ConvertHeaderDtoToEntity(SpiAoiHeaderDto dto)
+ {
+ return new MesSpiAoiHeader
+ {
+ TestDate = DateTime.Parse(dto.TestDate),
+ TestTime = dto.TestTime,
+ TestResult = dto.TestResult,
+ Surface = dto.Surface,
+ TotalPoints = dto.TotalPoints,
+ ActualDefects = dto.ActualDefects,
+ EquipmentModel = dto.EquipmentModel,
+ WorkOrder = dto.WorkOrder,
+ ProductModel = dto.ProductModel,
+ BoardBarcode = dto.BoardBarcode,
+ SmtGroup = dto.SmtGroup,
+ LineName = dto.LineName
+ };
+ }
+
+ /// <summary>
+ /// 灏嗗瓙琛―TO鍒楄〃杞崲涓哄疄浣撳垪琛�
+ /// </summary>
+ /// <param name="dtoList">瀛愯〃DTO鍒楄〃</param>
+ /// <param name="headerId">涓昏〃ID</param>
+ /// <returns>瀛愯〃瀹炰綋鍒楄〃</returns>
+ private List<MesSpiAoiDetail> ConvertDetailDtoListToEntity(
+ List<SpiAoiDetailDto> dtoList, decimal headerId)
+ {
+ var now = DateTime.Now;
+ return dtoList.Select(dto => new MesSpiAoiDetail
+ {
+ HeaderId = headerId,
+ OffsetCount = dto.OffsetCount,
+ MissingCount = dto.MissingCount,
+ ReverseCount = dto.ReverseCount,
+ LiftedCount = dto.LiftedCount,
+ FloatHighCount = dto.FloatHighCount,
+ TombstoneCount = dto.TombstoneCount,
+ FlipCount = dto.FlipCount,
+ WrongPartCount = dto.WrongPartCount,
+ LeadLiftCount = dto.LeadLiftCount,
+ ColdJointCount = dto.ColdJointCount,
+ NoSolderCount = dto.NoSolderCount,
+ InsufficientSolderCount = dto.InsufficientSolderCount,
+ ExcessSolderCount = dto.ExcessSolderCount,
+ BridgeCount = dto.BridgeCount,
+ CopperExposureCount = dto.CopperExposureCount,
+ SpikeCount = dto.SpikeCount,
+ ForeignMatterCount = dto.ForeignMatterCount,
+ GlueOverflowCount = dto.GlueOverflowCount,
+ PinOffsetCount = dto.PinOffsetCount,
+ LineDisplayName = dto.LineDisplayName,
+ MachineName = dto.MachineName,
+ InputBoards = dto.InputBoards,
+ OkBoards = dto.OkBoards,
+ PassBoards = dto.PassBoards,
+ PassRate = dto.PassRate,
+ DefectBoards = dto.DefectBoards,
+ DefectRate = dto.DefectRate,
+ DefectPpm = dto.DefectPpm,
+ DefectPoints = dto.DefectPoints,
+ MeasuredPoints = dto.MeasuredPoints,
+ PendingPoints = dto.PendingPoints,
+ CreatedAt = now,
+ UpdatedAt = now
+ }).ToList();
+ }
+
+ #endregion
+}
diff --git a/MESApplication/Controllers/QC/SpiAoiController.cs b/MESApplication/Controllers/QC/SpiAoiController.cs
new file mode 100644
index 0000000..1339d59
--- /dev/null
+++ b/MESApplication/Controllers/QC/SpiAoiController.cs
@@ -0,0 +1,228 @@
+using System.Dynamic;
+using MES.Service.Dto.service;
+using MES.Service.Modes;
+using MES.Service.service;
+using MES.Service.service.QC;
+using MES.Service.util;
+using Microsoft.AspNetCore.Mvc;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace MESApplication.Controllers.QC;
+
+/// <summary>
+/// SPI/AOI妫�娴嬫暟鎹帶鍒跺櫒
+/// </summary>
+[Route("api/[controller]")]
+[ApiController]
+public class SpiAoiController : ControllerBase
+{
+ private readonly MessageCenterManager _manager = new();
+ private readonly SpiAoiService _service = new();
+
+ private readonly string METHOD = "POST";
+ private readonly string TableName = "MES_SPI_AOI_HEADER";
+ private readonly string URL = "http://localhost:10054/api/QC/SpiAoi/";
+
+ /// <summary>
+ /// 涓婁紶SPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="request">涓婁紶璇锋眰</param>
+ /// <returns>涓婁紶缁撴灉</returns>
+ [HttpPost("Upload")]
+ public ResponseResult Upload([FromBody] SpiAoiUploadRequest request)
+ {
+ var entity = new MessageCenter();
+ entity.TableName = TableName;
+ entity.Url = URL + "Upload";
+ entity.Method = METHOD;
+ entity.Data = JsonConvert.SerializeObject(request);
+ entity.Status = 1;
+ entity.CreateBy = "SPI_AOI_SYSTEM";
+
+ try
+ {
+ var response = _service.UploadSpiAoiData(request);
+
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.headerId = response.HeaderId;
+ resultInfos.detailCount = response.DetailCount;
+ resultInfos.message = "SPI/AOI妫�娴嬫暟鎹笂浼犳垚鍔�";
+
+ entity.Result = 1;
+ entity.DealWith = 1;
+ entity.ResultData = JsonConvert.SerializeObject(response);
+ _manager.save(entity);
+
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos
+ };
+ }
+ catch (Exception ex)
+ {
+ entity.Result = 0;
+ entity.DealWith = 0;
+ entity.ResultData = ex.Message;
+ _manager.save(entity);
+
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+
+ /// <summary>
+ /// 鏍规嵁鏉$爜鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="request">璇锋眰鍙傛暟</param>
+ /// <returns>妫�娴嬫暟鎹�</returns>
+ [HttpPost("GetByBarcode")]
+ public ResponseResult GetByBarcode([FromBody] JObject request)
+ {
+ try
+ {
+ var boardBarcode = request["boardBarcode"]?.ToString();
+ if (StringUtil.IsNullOrEmpty(boardBarcode))
+ {
+ return new ResponseResult
+ {
+ status = 1,
+ message = "boardBarcode 涓嶈兘涓虹┖",
+ data = null
+ };
+ }
+
+ var (header, details) = _service.GetByBarcode(boardBarcode);
+
+ if (header == null)
+ {
+ return new ResponseResult
+ {
+ status = 1,
+ message = $"鏈壘鍒版潯鐮� {boardBarcode} 鐨勬娴嬫暟鎹�",
+ data = null
+ };
+ }
+
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.header = header;
+ resultInfos.details = details;
+
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos
+ };
+ }
+ catch (Exception ex)
+ {
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+
+ /// <summary>
+ /// 鏍规嵁ID鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="request">璇锋眰鍙傛暟</param>
+ /// <returns>妫�娴嬫暟鎹�</returns>
+ [HttpPost("GetById")]
+ public ResponseResult GetById([FromBody] JObject request)
+ {
+ try
+ {
+ var headerId = request["headerId"]?.ToObject<decimal>();
+ if (!headerId.HasValue)
+ {
+ return new ResponseResult
+ {
+ status = 1,
+ message = "headerId 涓嶈兘涓虹┖",
+ data = null
+ };
+ }
+
+ var (header, details) = _service.GetById(headerId.Value);
+
+ if (header == null)
+ {
+ return new ResponseResult
+ {
+ status = 1,
+ message = $"鏈壘鍒癐D {headerId} 鐨勬娴嬫暟鎹�",
+ data = null
+ };
+ }
+
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.header = header;
+ resultInfos.details = details;
+
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos
+ };
+ }
+ catch (Exception ex)
+ {
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+
+ /// <summary>
+ /// 鍒嗛〉鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ /// </summary>
+ /// <param name="request">鏌ヨ璇锋眰</param>
+ /// <returns>鍒嗛〉鏁版嵁</returns>
+ [HttpPost("GetPage")]
+ public ResponseResult GetPage([FromBody] JObject request)
+ {
+ try
+ {
+ var boardBarcode = request["boardBarcode"]?.ToString();
+ var workOrder = request["workOrder"]?.ToString();
+ var surface = request["surface"]?.ToString();
+ var startDate = request["startDate"]?.ToString();
+ var endDate = request["endDate"]?.ToString();
+ var pageIndex = request["pageIndex"]?.ToObject<int>() ?? 1;
+ var pageSize = request["pageSize"]?.ToObject<int>() ?? 20;
+
+ DateTime? startDateTime = null;
+ DateTime? endDateTime = null;
+
+ if (StringUtil.IsNotNullOrEmpty(startDate) &&
+ DateTime.TryParse(startDate, out var start))
+ {
+ startDateTime = start;
+ }
+
+ if (StringUtil.IsNotNullOrEmpty(endDate) &&
+ DateTime.TryParse(endDate, out var end))
+ {
+ endDateTime = end;
+ }
+
+ var (items, totalCount) = _service.GetPage(
+ boardBarcode, workOrder, surface, startDateTime, endDateTime,
+ pageIndex, pageSize);
+
+ dynamic resultInfos = new ExpandoObject();
+ resultInfos.items = items;
+
+ return new ResponseResult
+ {
+ status = 0,
+ message = "OK",
+ data = resultInfos,
+ TotalCount = totalCount
+ };
+ }
+ catch (Exception ex)
+ {
+ return ResponseResult.ResponseError(ex);
+ }
+ }
+}
diff --git a/MESApplication/bin/Debug/net8.0/MES.Service.dll b/MESApplication/bin/Debug/net8.0/MES.Service.dll
index ace4808..54d04c6 100644
--- a/MESApplication/bin/Debug/net8.0/MES.Service.dll
+++ b/MESApplication/bin/Debug/net8.0/MES.Service.dll
Binary files differ
diff --git a/MESApplication/bin/Debug/net8.0/MES.Service.pdb b/MESApplication/bin/Debug/net8.0/MES.Service.pdb
index 1ebf67e..1c43e59 100644
--- a/MESApplication/bin/Debug/net8.0/MES.Service.pdb
+++ b/MESApplication/bin/Debug/net8.0/MES.Service.pdb
Binary files differ
diff --git a/MESApplication/bin/Debug/net8.0/MESApplication.deps.json b/MESApplication/bin/Debug/net8.0/MESApplication.deps.json
index 95a84e5..523a7cc 100644
--- a/MESApplication/bin/Debug/net8.0/MESApplication.deps.json
+++ b/MESApplication/bin/Debug/net8.0/MESApplication.deps.json
@@ -1413,7 +1413,7 @@
},
"runtime": {
"MES.Service.dll": {
- "assemblyVersion": "1.0.0",
+ "assemblyVersion": "1.0.0.0",
"fileVersion": "1.0.0.0"
}
}
diff --git a/MESApplication/bin/Debug/net8.0/MESApplication.dll b/MESApplication/bin/Debug/net8.0/MESApplication.dll
index 3b9ad49..2d93d6a 100644
--- a/MESApplication/bin/Debug/net8.0/MESApplication.dll
+++ b/MESApplication/bin/Debug/net8.0/MESApplication.dll
Binary files differ
diff --git a/MESApplication/bin/Debug/net8.0/MESApplication.exe b/MESApplication/bin/Debug/net8.0/MESApplication.exe
index 3a126b4..c50ced5 100644
--- a/MESApplication/bin/Debug/net8.0/MESApplication.exe
+++ b/MESApplication/bin/Debug/net8.0/MESApplication.exe
Binary files differ
diff --git a/MESApplication/bin/Debug/net8.0/MESApplication.pdb b/MESApplication/bin/Debug/net8.0/MESApplication.pdb
index d9bfecb..facc967 100644
--- a/MESApplication/bin/Debug/net8.0/MESApplication.pdb
+++ b/MESApplication/bin/Debug/net8.0/MESApplication.pdb
Binary files differ
diff --git a/MESApplication/bin/Debug/net8.0/MESApplication.staticwebassets.endpoints.json b/MESApplication/bin/Debug/net8.0/MESApplication.staticwebassets.endpoints.json
index 2b6c535..5576e88 100644
--- a/MESApplication/bin/Debug/net8.0/MESApplication.staticwebassets.endpoints.json
+++ b/MESApplication/bin/Debug/net8.0/MESApplication.staticwebassets.endpoints.json
@@ -1,5 +1 @@
-{
- "Version": 1,
- "ManifestType": "Build",
- "Endpoints": []
-}
\ No newline at end of file
+{"Version":1,"ManifestType":"Build","Endpoints":[]}
\ No newline at end of file
diff --git a/MESApplication/bin/Debug/net8.0/MESApplication.xml b/MESApplication/bin/Debug/net8.0/MESApplication.xml
index 3fecfd7..868abcb 100644
--- a/MESApplication/bin/Debug/net8.0/MESApplication.xml
+++ b/MESApplication/bin/Debug/net8.0/MESApplication.xml
@@ -752,111 +752,126 @@
</member>
<member name="M:MESApplication.Controllers.OrganizeController.GetList">
<summary>
- 鑾峰彇鎵�鏈�
+ 鑾峰彇鎵�鏈�
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.OrganizeController.GetById(System.Int32)">
<summary>
- 鏍规嵁涓婚敭鑾峰彇
+ 鏍规嵁涓婚敭鑾峰彇
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.OrganizeController.DeleteByIds(System.Object[])">
<summary>
- 鏍规嵁涓婚敭鍒犻櫎
+ 鏍规嵁涓婚敭鍒犻櫎
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.OrganizeController.Add(MES.Service.Modes.Organize)">
<summary>
- 娣诲姞
+ 娣诲姞
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.OrganizeController.InsertReturnIdentity(MES.Service.Modes.Organize)">
<summary>
- 娣诲姞杩斿洖鑷
+ 娣诲姞杩斿洖鑷
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.OrganizeController.Update(MES.Service.Modes.Organize)">
<summary>
- 淇敼
+ 淇敼
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeController.GetList">
<summary>
- 鑾峰彇鎵�鏈�
+ 鑾峰彇鎵�鏈�
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeController.GetById(System.Int32)">
<summary>
- 鏍规嵁涓婚敭鑾峰彇
+ 鏍规嵁涓婚敭鑾峰彇
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeController.DeleteByIds(System.Object[])">
<summary>
- 鏍规嵁涓婚敭鍒犻櫎
+ 鏍规嵁涓婚敭鍒犻櫎
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeController.Add(MES.Service.Modes.SalesDeliveryNotice)">
<summary>
- 娣诲姞
+ 娣诲姞
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeController.InsertReturnIdentity(MES.Service.Modes.SalesDeliveryNotice)">
<summary>
- 娣诲姞杩斿洖鑷
+ 娣诲姞杩斿洖鑷
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeController.Update(MES.Service.Modes.SalesDeliveryNotice)">
<summary>
- 淇敼
+ 淇敼
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeDetailController.GetList">
<summary>
- 鑾峰彇鎵�鏈�
+ 鑾峰彇鎵�鏈�
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeDetailController.GetById(System.Int32)">
<summary>
- 鏍规嵁涓婚敭鑾峰彇
+ 鏍规嵁涓婚敭鑾峰彇
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeDetailController.DeleteByIds(System.Object[])">
<summary>
- 鏍规嵁涓婚敭鍒犻櫎
+ 鏍规嵁涓婚敭鍒犻櫎
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeDetailController.Add(MES.Service.Modes.SalesDeliveryNoticeDetail)">
<summary>
- 娣诲姞
+ 娣诲姞
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeDetailController.InsertReturnIdentity(MES.Service.Modes.SalesDeliveryNoticeDetail)">
<summary>
- 娣诲姞杩斿洖鑷
+ 娣诲姞杩斿洖鑷
</summary>
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.SalesDeliveryNoticeDetailController.Update(MES.Service.Modes.SalesDeliveryNoticeDetail)">
<summary>
- 淇敼
+ 淇敼
</summary>
<returns></returns>
+ </member>
+ <member name="T:MESApplication.Controllers.FBSDB.FbsDbController">
+ <summary>
+ 璋冩嫧
+ </summary>
+ </member>
+ <member name="M:MESApplication.Controllers.FBSDB.FbsDbController.Save(MES.Service.Dto.webApi.FbsDb.ErpDb)">
+ <summary>
+ 鏂板
+ </summary>
+ </member>
+ <member name="M:MESApplication.Controllers.FBSDB.FbsDbController.SaveList(System.Collections.Generic.List{MES.Service.Dto.webApi.FbsDb.ErpDb})">
+ <summary>
+ 鏂板鎵归噺
+ </summary>
</member>
<member name="M:MESApplication.Controllers.QC.MesLineUserController.GetList">
<summary>
@@ -893,6 +908,107 @@
淇敼
</summary>
<returns></returns>
+ </member>
+ <member name="T:MESApplication.Controllers.QC.PcbTestDataController">
+ <summary>
+ PCB妫�娴嬫暟鎹帶鍒跺櫒
+ </summary>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.SaveWholeboardData(MES.Service.Dto.service.WholeboardGenerateDto)">
+ <summary>
+ 淇濆瓨鏁存澘妫�娴嬫暟鎹�
+ </summary>
+ <param name="dto">鏁存澘妫�娴嬫暟鎹瓺TO</param>
+ <returns>淇濆瓨缁撴灉</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.SaveSingleBoardData(MES.Service.Dto.service.SingleBoardGenerateDto)">
+ <summary>
+ 淇濆瓨鍗曟澘妫�娴嬫暟鎹�
+ </summary>
+ <param name="dto">鍗曟澘妫�娴嬫暟鎹瓺TO</param>
+ <returns>淇濆瓨缁撴灉</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.GetPage(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鍒嗛〉鏌ヨPCB妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">鏌ヨ璇锋眰</param>
+ <returns>鍒嗛〉鏁版嵁</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.GetById(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鏍规嵁ID鑾峰彇PCB妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>PCB妫�娴嬫暟鎹�</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.GetByPcbSn(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鏍规嵁PCB鏉$爜鑾峰彇妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>妫�娴嬫暟鎹垪琛�</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.GetComponentData(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鑾峰彇鍣ㄤ欢妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>鍣ㄤ欢妫�娴嬫暟鎹�</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.GetStatistics(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鑾峰彇妫�娴嬬粺璁℃暟鎹�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>缁熻鏁版嵁</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.Delete(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鍒犻櫎PCB妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>鍒犻櫎缁撴灉</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.PcbTestDataController.SaveTestData(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 缁熶竴淇濆瓨鎺ュ彛锛堣嚜鍔ㄨ瘑鍒暣鏉挎垨鍗曟澘鏁版嵁锛�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>淇濆瓨缁撴灉</returns>
+ </member>
+ <member name="T:MESApplication.Controllers.QC.SpiAoiController">
+ <summary>
+ SPI/AOI妫�娴嬫暟鎹帶鍒跺櫒
+ </summary>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.SpiAoiController.Upload(MES.Service.Dto.service.SpiAoiUploadRequest)">
+ <summary>
+ 涓婁紶SPI/AOI妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">涓婁紶璇锋眰</param>
+ <returns>涓婁紶缁撴灉</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.SpiAoiController.GetByBarcode(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鏍规嵁鏉$爜鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>妫�娴嬫暟鎹�</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.SpiAoiController.GetById(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鏍规嵁ID鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">璇锋眰鍙傛暟</param>
+ <returns>妫�娴嬫暟鎹�</returns>
+ </member>
+ <member name="M:MESApplication.Controllers.QC.SpiAoiController.GetPage(Newtonsoft.Json.Linq.JObject)">
+ <summary>
+ 鍒嗛〉鏌ヨSPI/AOI妫�娴嬫暟鎹�
+ </summary>
+ <param name="request">鏌ヨ璇锋眰</param>
+ <returns>鍒嗛〉鏁版嵁</returns>
</member>
<member name="M:MESApplication.Controllers.QC.XJController.getDaa001(Newtonsoft.Json.Linq.JObject)">
<summary>
@@ -1152,78 +1268,6 @@
<returns></returns>
</member>
<member name="M:MESApplication.Controllers.Warehouse.MesInvItemInCItemsController.Update(MES.Service.Modes.MesInvItemInCItems)">
- <summary>
- 淇敼
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesCDetailsController.GetList">
- <summary>
- 鑾峰彇鎵�鏈�
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesCDetailsController.GetById(System.Int32)">
- <summary>
- 鏍规嵁涓婚敭鑾峰彇
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesCDetailsController.DeleteByIds(System.Object[])">
- <summary>
- 鏍规嵁涓婚敭鍒犻櫎
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesCDetailsController.Add(MES.Service.Modes.MesInvItemMovesCDetails)">
- <summary>
- 娣诲姞
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesCDetailsController.InsertReturnIdentity(MES.Service.Modes.MesInvItemMovesCDetails)">
- <summary>
- 娣诲姞杩斿洖鑷
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesCDetailsController.Update(MES.Service.Modes.MesInvItemMovesCDetails)">
- <summary>
- 淇敼
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesController.GetList">
- <summary>
- 鑾峰彇鎵�鏈�
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesController.GetById(System.Int32)">
- <summary>
- 鏍规嵁涓婚敭鑾峰彇
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesController.DeleteByIds(System.Object[])">
- <summary>
- 鏍规嵁涓婚敭鍒犻櫎
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesController.Add(MES.Service.Modes.MesInvItemMoves)">
- <summary>
- 娣诲姞
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesController.InsertReturnIdentity(MES.Service.Modes.MesInvItemMoves)">
- <summary>
- 娣诲姞杩斿洖鑷
- </summary>
- <returns></returns>
- </member>
- <member name="M:MESApplication.Controllers.Warehouse.MesInvItemMovesController.Update(MES.Service.Modes.MesInvItemMoves)">
<summary>
淇敼
</summary>
--
Gitblit v1.9.3