From a5019b475f8620dba3b495da983f4db9e32f7ca8 Mon Sep 17 00:00:00 2001
From: 啊鑫 <t2856754968@163.com>
Date: 星期四, 10 七月 2025 08:18:36 +0800
Subject: [PATCH] AOI

---
 MES.Service/Modes/MesPcbTestData.cs                    |  210 +++++++
 MESApplication/Controllers/QC/PcbTestDataController.cs |  508 ++++++++++++++++++
 MES.Service/Dto/service/WholeboardGenerateDto.cs       |  234 ++++++++
 MES.Service/service/QC/PcbTestDataService.cs           |  366 +++++++++++++
 MES.Service/Dto/service/SingleBoardGenerateDto.cs      |  150 +++++
 MES.Service/Modes/MesPcbComponentData.cs               |   96 +++
 6 files changed, 1,564 insertions(+), 0 deletions(-)

diff --git a/MES.Service/Dto/service/SingleBoardGenerateDto.cs b/MES.Service/Dto/service/SingleBoardGenerateDto.cs
new file mode 100644
index 0000000..2d3494a
--- /dev/null
+++ b/MES.Service/Dto/service/SingleBoardGenerateDto.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace MES.Service.Dto.service
+{
+    /// <summary>
+    /// 鎷兼澘(鍗曟澘)鐢熸垚鏁版嵁DTO
+    /// </summary>
+    public class SingleBoardGenerateDto
+    {
+        /// <summary>
+        /// 璁惧鍚嶇О
+        /// </summary>
+        [JsonPropertyName("device_name")]
+        public string DeviceName { get; set; }
+
+        /// <summary>
+        /// 鏁存澘鏉$爜
+        /// </summary>
+        [JsonPropertyName("pcb_sn")]
+        public string PcbSn { get; set; }
+
+        /// <summary>
+        /// 杞ㄩ亾淇℃伅锛�1锛�1杞級锛�2锛�2杞級
+        /// </summary>
+        [JsonPropertyName("pcb_track_line")]
+        public int PcbTrackLine { get; set; }
+
+        /// <summary>
+        /// 鏉块潰锛圱锛岄《闈級锛圔锛屽簳闈級锛圱+B锛屾澘闈�+搴曢潰锛�
+        /// </summary>
+        [JsonPropertyName("pcb_board_side")]
+        public string PcbBoardSide { get; set; }
+
+        /// <summary>
+        /// 妫�娴嬫椂闂�
+        /// </summary>
+        [JsonPropertyName("pcb_test_time")]
+        public string PcbTestTime { get; set; }
+
+        /// <summary>
+        /// 妫�娴嬭�楁椂锛屽崟浣嶇
+        /// </summary>
+        [JsonPropertyName("pcb_cycle_time")]
+        public float PcbCycleTime { get; set; }
+
+        /// <summary>
+        /// 绋嬪簭鍚�/鏉垮紡鍚�
+        /// </summary>
+        [JsonPropertyName("pcb_project_name")]
+        public string PcbProjectName { get; set; }
+
+        /// <summary>
+        /// 鏁存澘妫�娴嬬粨鏋�
+        /// </summary>
+        [JsonPropertyName("pcb_robot_result")]
+        public string PcbRobotResult { get; set; }
+
+        /// <summary>
+        /// 鏁存澘澶嶅垽缁撴灉
+        /// </summary>
+        [JsonPropertyName("pcb_user_result")]
+        public string PcbUserResult { get; set; }
+
+        /// <summary>
+        /// 鏁存澘鏈�缁堢粨鏋�
+        /// </summary>
+        [JsonPropertyName("pcb_final_result")]
+        public string PcbFinalResult { get; set; }
+
+        /// <summary>
+        /// 缁翠慨绔欏鍒ょ敤鎴峰悕
+        /// </summary>
+        [JsonPropertyName("pcb_repair_user")]
+        public string PcbRepairUser { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_board_number")]
+        public int PcbBoardNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鎬绘暟閲�
+        /// </summary>
+        [JsonPropertyName("pcb_comp_number")]
+        public int PcbCompNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏉$爜
+        /// </summary>
+        [JsonPropertyName("board_sn")]
+        public string BoardSn { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘搴忓彿
+        /// </summary>
+        [JsonPropertyName("board_no")]
+        public string BoardNo { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘妫�娴嬬粨鏋�
+        /// </summary>
+        [JsonPropertyName("board_robot_result")]
+        public string BoardRobotResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘澶嶅垽缁撴灉
+        /// </summary>
+        [JsonPropertyName("board_user_result")]
+        public string BoardUserResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏈�缁堢粨鏋�
+        /// </summary>
+        [JsonPropertyName("board_final_result")]
+        public string BoardFinalResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢鏁伴噺
+        /// </summary>
+        [JsonPropertyName("board_comp_number")]
+        public int BoardCompNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢妫�娴婲G鎬绘暟
+        /// </summary>
+        [JsonPropertyName("board_comp_robot_ng_number")]
+        public int BoardCompRobotNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢澶嶅垽NG鎬绘暟
+        /// </summary>
+        [JsonPropertyName("board_comp_user_ng_number")]
+        public int BoardCompUserNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢璇姤鎬绘暟
+        /// </summary>
+        [JsonPropertyName("board_comp_repass_number")]
+        public int BoardCompRepassNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鍒楄〃
+        /// </summary>
+        [JsonPropertyName("comp_data")]
+        public List<ComponentDataDto> CompData { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/MES.Service/Dto/service/WholeboardGenerateDto.cs b/MES.Service/Dto/service/WholeboardGenerateDto.cs
new file mode 100644
index 0000000..66644dd
--- /dev/null
+++ b/MES.Service/Dto/service/WholeboardGenerateDto.cs
@@ -0,0 +1,234 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace MES.Service.Dto.service
+{
+    /// <summary>
+    /// 鏁存澘鐢熸垚鏁版嵁DTO
+    /// </summary>
+    public class WholeboardGenerateDto
+    {
+        /// <summary>
+        /// 璁惧鍚嶇О
+        /// </summary>
+        [JsonPropertyName("device_name")]
+        public string DeviceName { get; set; }
+
+        /// <summary>
+        /// 鏁存澘鏉$爜
+        /// </summary>
+        [JsonPropertyName("pcb_sn")]
+        public string PcbSn { get; set; }
+
+        /// <summary>
+        /// 杞ㄩ亾淇℃伅锛�1锛�1杞級锛�2锛�2杞級
+        /// </summary>
+        [JsonPropertyName("pcb_track_line")]
+        public int PcbTrackLine { get; set; }
+
+        /// <summary>
+        /// 鏉块潰锛圱锛岄《闈級锛圔锛屽簳闈級锛圱+B锛屾澘闈�+搴曢潰锛�
+        /// </summary>
+        [JsonPropertyName("pcb_board_side")]
+        public string PcbBoardSide { get; set; }
+
+        /// <summary>
+        /// 妫�娴嬫椂闂达紝鏍煎紡yyyy-mm-dd hh:mm:ss
+        /// </summary>
+        [JsonPropertyName("pcb_test_time")]
+        public string PcbTestTime { get; set; }
+
+        /// <summary>
+        /// 妫�娴嬭�楁椂锛屽崟浣嶇
+        /// </summary>
+        [JsonPropertyName("pcb_cycle_time")]
+        public float PcbCycleTime { get; set; }
+
+        /// <summary>
+        /// 绋嬪簭鍚�/鏉垮紡鍚�
+        /// </summary>
+        [JsonPropertyName("pcb_project_name")]
+        public string PcbProjectName { get; set; }
+
+        /// <summary>
+        /// 鏁存澘妫�娴嬬粨鏋�
+        /// </summary>
+        [JsonPropertyName("pcb_robot_result")]
+        public string PcbRobotResult { get; set; }
+
+        /// <summary>
+        /// 鏁存澘澶嶅垽缁撴灉
+        /// </summary>
+        [JsonPropertyName("pcb_user_result")]
+        public string PcbUserResult { get; set; }
+
+        /// <summary>
+        /// 鏁存澘鏈�缁堢粨鏋�
+        /// </summary>
+        [JsonPropertyName("pcb_final_result")]
+        public string PcbFinalResult { get; set; }
+
+        /// <summary>
+        /// 缁翠慨绔欏鍒ょ敤鎴峰悕
+        /// </summary>
+        [JsonPropertyName("pcb_repair_user")]
+        public string PcbRepairUser { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_board_number")]
+        public int PcbBoardNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘妫�娴婲G鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_board_robot_ng_number")]
+        public int PcbBoardRobotNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘澶嶅垽NG鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_board_user_ng_number")]
+        public int PcbBoardUserNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘璇姤鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_board_repass_number")]
+        public int PcbBoardRepassNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鎬绘暟閲�
+        /// </summary>
+        [JsonPropertyName("pcb_comp_number")]
+        public int PcbCompNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢妫�娴婲G鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_comp_robot_ng_number")]
+        public int PcbCompRobotNgNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢澶嶅垽NG鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_comp_user_ng_number")]
+        public int PcbCompUserNgNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢璇姤鏁伴噺
+        /// </summary>
+        [JsonPropertyName("pcb_comp_repass_number")]
+        public int PcbCompRepassNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍒楄〃
+        /// </summary>
+        [JsonPropertyName("board_data")]
+        public List<BoardDataDto> BoardData { get; set; }
+    }
+
+    /// <summary>
+    /// 鎷兼澘鏁版嵁DTO
+    /// </summary>
+    public class BoardDataDto
+    {
+        /// <summary>
+        /// 鎷兼澘鏉$爜
+        /// </summary>
+        [JsonPropertyName("board_sn")]
+        public string BoardSn { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘搴忓彿
+        /// </summary>
+        [JsonPropertyName("board_no")]
+        public string BoardNo { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘妫�娴嬬粨鏋�
+        /// </summary>
+        [JsonPropertyName("board_robot_result")]
+        public string BoardRobotResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘澶嶅垽缁撴灉
+        /// </summary>
+        [JsonPropertyName("board_user_result")]
+        public string BoardUserResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏈�缁堢粨鏋�
+        /// </summary>
+        [JsonPropertyName("board_final_result")]
+        public string BoardFinalResult { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鍒楄〃
+        /// </summary>
+        [JsonPropertyName("comp_data")]
+        public List<ComponentDataDto> CompData { get; set; }
+    }
+
+    /// <summary>
+    /// 鍣ㄤ欢鏁版嵁DTO
+    /// </summary>
+    public class ComponentDataDto
+    {
+        /// <summary>
+        /// 鍣ㄤ欢浣嶅彿
+        /// </summary>
+        [JsonPropertyName("comp_designator")]
+        public string CompDesignator { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鏂欏彿
+        /// </summary>
+        [JsonPropertyName("comp_part")]
+        public string CompPart { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢灏佽
+        /// </summary>
+        [JsonPropertyName("comp_package")]
+        public string CompPackage { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢绫诲瀷
+        /// </summary>
+        [JsonPropertyName("comp_type")]
+        public string CompType { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢妫�娴嬩笉鑹唬鐮�
+        /// </summary>
+        [JsonPropertyName("comp_robot_code")]
+        public string CompRobotCode { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢妫�娴嬬粨鏋�
+        /// </summary>
+        [JsonPropertyName("comp_robot_result")]
+        public string CompRobotResult { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢澶嶅垽涓嶈壇浠g爜
+        /// </summary>
+        [JsonPropertyName("comp_user_code")]
+        public string CompUserCode { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢澶嶅垽缁撴灉
+        /// </summary>
+        [JsonPropertyName("comp_user_result")]
+        public string CompUserResult { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鍥剧墖鍦板潃
+        /// </summary>
+        [JsonPropertyName("comp_image")]
+        public string CompImage { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/MES.Service/Modes/MesPcbComponentData.cs b/MES.Service/Modes/MesPcbComponentData.cs
new file mode 100644
index 0000000..1da9b3b
--- /dev/null
+++ b/MES.Service/Modes/MesPcbComponentData.cs
@@ -0,0 +1,96 @@
+using SqlSugar;
+using System;
+
+namespace MES.Service.Modes
+{
+    /// <summary>
+    /// PCB鍣ㄤ欢妫�娴嬫暟鎹〃
+    /// </summary>
+    [SugarTable("MES_PCB_COMPONENT_DATA")]
+    public class MesPcbComponentData
+    {
+        /// <summary>
+        /// 涓婚敭ID
+        /// </summary>
+        [SugarColumn(ColumnName = "ID", OracleSequenceName = "SEQ_PCB_COMPONENT_DATA", IsPrimaryKey = true)]
+        public decimal Id { get; set; }
+
+        /// <summary>
+        /// 妫�娴嬫暟鎹富琛↖D
+        /// </summary>
+        [SugarColumn(ColumnName = "TEST_DATA_ID")]
+        public decimal TestDataId { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢浣嶅彿
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_DESIGNATOR")]
+        public string? CompDesignator { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鏂欏彿
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_PART")]
+        public string? CompPart { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢灏佽
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_PACKAGE")]
+        public string? CompPackage { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢绫诲瀷
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_TYPE")]
+        public string? CompType { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢妫�娴嬩笉鑹唬鐮�
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_ROBOT_CODE")]
+        public string? CompRobotCode { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢妫�娴嬬粨鏋�
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_ROBOT_RESULT")]
+        public string? CompRobotResult { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢澶嶅垽涓嶈壇浠g爜
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_USER_CODE")]
+        public string? CompUserCode { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢澶嶅垽缁撴灉
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_USER_RESULT")]
+        public string? CompUserResult { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鍥剧墖鍦板潃
+        /// </summary>
+        [SugarColumn(ColumnName = "COMP_IMAGE")]
+        public string? CompImage { get; set; }
+
+        /// <summary>
+        /// 鍒涘缓鏃堕棿
+        /// </summary>
+        [SugarColumn(ColumnName = "CREATE_TIME")]
+        public DateTime? CreateTime { get; set; }
+
+        /// <summary>
+        /// 鏇存柊鏃堕棿
+        /// </summary>
+        [SugarColumn(ColumnName = "UPDATE_TIME")]
+        public DateTime? UpdateTime { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        [SugarColumn(ColumnName = "REMARKS")]
+        public string? Remarks { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/MES.Service/Modes/MesPcbTestData.cs b/MES.Service/Modes/MesPcbTestData.cs
new file mode 100644
index 0000000..1e7073d
--- /dev/null
+++ b/MES.Service/Modes/MesPcbTestData.cs
@@ -0,0 +1,210 @@
+using SqlSugar;
+using System;
+
+namespace MES.Service.Modes
+{
+    /// <summary>
+    /// PCB妫�娴嬫暟鎹〃锛堟暣鏉�/鍗曟澘缁熶竴瀛樺偍锛�
+    /// </summary>
+    [SugarTable("MES_PCB_TEST_DATA")]
+    public class MesPcbTestData
+    {
+        /// <summary>
+        /// 涓婚敭ID
+        /// </summary>
+        [SugarColumn(ColumnName = "ID", OracleSequenceName = "SEQ_PCB_TEST_DATA", IsPrimaryKey = true)]
+        public decimal Id { get; set; }
+
+        /// <summary>
+        /// 鏁版嵁绫诲瀷锛歐HOLE-鏁存澘锛孲INGLE-鍗曟澘
+        /// </summary>
+        [SugarColumn(ColumnName = "DATA_TYPE")]
+        public string DataType { get; set; }
+
+        /// <summary>
+        /// 璁惧鍚嶇О
+        /// </summary>
+        [SugarColumn(ColumnName = "DEVICE_NAME")]
+        public string? DeviceName { get; set; }
+
+        /// <summary>
+        /// 鏁存澘鏉$爜
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_SN")]
+        public string? PcbSn { get; set; }
+
+        /// <summary>
+        /// 杞ㄩ亾淇℃伅锛�1-1杞紝2-2杞級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_TRACK_LINE")]
+        public int? PcbTrackLine { get; set; }
+
+        /// <summary>
+        /// 鏉块潰锛圱-椤堕潰锛孊-搴曢潰锛孴+B-椤堕潰+搴曢潰锛�
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_BOARD_SIDE")]
+        public string? PcbBoardSide { get; set; }
+
+        /// <summary>
+        /// 妫�娴嬫椂闂�
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_TEST_TIME")]
+        public DateTime? PcbTestTime { get; set; }
+
+        /// <summary>
+        /// 妫�娴嬭�楁椂锛堢锛�
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_CYCLE_TIME")]
+        public decimal? PcbCycleTime { get; set; }
+
+        /// <summary>
+        /// 绋嬪簭鍚�/鏉垮紡鍚�
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_PROJECT_NAME")]
+        public string? PcbProjectName { get; set; }
+
+        /// <summary>
+        /// 鏁存澘妫�娴嬬粨鏋�
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_ROBOT_RESULT")]
+        public string? PcbRobotResult { get; set; }
+
+        /// <summary>
+        /// 鏁存澘澶嶅垽缁撴灉
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_USER_RESULT")]
+        public string? PcbUserResult { get; set; }
+
+        /// <summary>
+        /// 鏁存澘鏈�缁堢粨鏋�
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_FINAL_RESULT")]
+        public string? PcbFinalResult { get; set; }
+
+        /// <summary>
+        /// 缁翠慨绔欏鍒ょ敤鎴峰悕
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_REPAIR_USER")]
+        public string? PcbRepairUser { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏁伴噺锛堟暣鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_BOARD_NUMBER")]
+        public int? PcbBoardNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘妫�娴婲G鏁伴噺锛堟暣鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_BOARD_ROBOT_NG_NUMBER")]
+        public int? PcbBoardRobotNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘澶嶅垽NG鏁伴噺锛堟暣鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_BOARD_USER_NG_NUMBER")]
+        public int? PcbBoardUserNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘璇姤鏁伴噺锛堟暣鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_BOARD_REPASS_NUMBER")]
+        public int? PcbBoardRepassNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢鎬绘暟閲�
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_COMP_NUMBER")]
+        public int? PcbCompNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢妫�娴婲G鏁伴噺锛堟暣鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_COMP_ROBOT_NG_NUMBER")]
+        public int? PcbCompRobotNgNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢澶嶅垽NG鏁伴噺锛堟暣鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_COMP_USER_NG_NUMBER")]
+        public int? PcbCompUserNgNumber { get; set; }
+
+        /// <summary>
+        /// 鍣ㄤ欢璇姤鏁伴噺锛堟暣鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "PCB_COMP_REPASS_NUMBER")]
+        public int? PcbCompRepassNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏉$爜锛堝崟鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_SN")]
+        public string? BoardSn { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘搴忓彿锛堝崟鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_NO")]
+        public string? BoardNo { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘妫�娴嬬粨鏋滐紙鍗曟澘鏁版嵁浣跨敤锛�
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_ROBOT_RESULT")]
+        public string? BoardRobotResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘澶嶅垽缁撴灉锛堝崟鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_USER_RESULT")]
+        public string? BoardUserResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鏈�缁堢粨鏋滐紙鍗曟澘鏁版嵁浣跨敤锛�
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_FINAL_RESULT")]
+        public string? BoardFinalResult { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢鏁伴噺锛堝崟鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_COMP_NUMBER")]
+        public int? BoardCompNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢妫�娴婲G鎬绘暟锛堝崟鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_COMP_ROBOT_NG_NUMBER")]
+        public int? BoardCompRobotNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢澶嶅垽NG鎬绘暟锛堝崟鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_COMP_USER_NG_NUMBER")]
+        public int? BoardCompUserNgNumber { get; set; }
+
+        /// <summary>
+        /// 鎷兼澘鍣ㄤ欢璇姤鎬绘暟锛堝崟鏉挎暟鎹娇鐢級
+        /// </summary>
+        [SugarColumn(ColumnName = "BOARD_COMP_REPASS_NUMBER")]
+        public int? BoardCompRepassNumber { get; set; }
+
+        /// <summary>
+        /// 鍒涘缓鏃堕棿
+        /// </summary>
+        [SugarColumn(ColumnName = "CREATE_TIME")]
+        public DateTime? CreateTime { get; set; }
+
+        /// <summary>
+        /// 鏇存柊鏃堕棿
+        /// </summary>
+        [SugarColumn(ColumnName = "UPDATE_TIME")]
+        public DateTime? UpdateTime { get; set; }
+
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        [SugarColumn(ColumnName = "REMARKS")]
+        public string? Remarks { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/MES.Service/service/QC/PcbTestDataService.cs b/MES.Service/service/QC/PcbTestDataService.cs
new file mode 100644
index 0000000..2f70d7b
--- /dev/null
+++ b/MES.Service/service/QC/PcbTestDataService.cs
@@ -0,0 +1,366 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MES.Service.DB;
+using MES.Service.Dto.service;
+using MES.Service.Modes;
+using MES.Service.util;
+using SqlSugar;
+
+namespace MES.Service.service.QC
+{
+    /// <summary>
+    /// PCB妫�娴嬫暟鎹湇鍔�
+    /// </summary>
+    public class PcbTestDataService
+    {
+        /// <summary>
+        /// 淇濆瓨鏁存澘妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="dto">鏁存澘妫�娴嬫暟鎹瓺TO</param>
+        /// <returns>淇濆瓨缁撴灉</returns>
+        public bool SaveWholeboardData(WholeboardGenerateDto dto)
+        {
+            try
+            {
+                return SqlSugarHelper.UseTransactionWithOracle(db =>
+                {
+                    var testData = ConvertWholeboardToEntity(dto);
+                    testData.CreateTime = DateTime.Now;
+                    testData.DataType = "WHOLE";
+
+                    var testDataId = db.Insertable(testData).ExecuteReturnIdentity();
+
+                    var affectedRows = 1;
+                    if (dto.BoardData != null && dto.BoardData.Count > 0)
+                    {
+                        var componentDataList = new List<MesPcbComponentData>();
+                        foreach (var boardData in dto.BoardData)
+                        {
+                            if (boardData.CompData != null && boardData.CompData.Count > 0)
+                            {
+                                var componentData = ConvertComponentListToEntity(boardData.CompData, testDataId);
+                                componentDataList.AddRange(componentData);
+                            }
+                        }
+
+                        if (componentDataList.Count > 0)
+                        {
+                            affectedRows += db.Insertable(componentDataList).ExecuteCommand();
+                        }
+                    }
+
+                    return affectedRows;
+                }) > 0;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"淇濆瓨鏁存澘妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+            }
+        }
+
+        /// <summary>
+        /// 淇濆瓨鍗曟澘妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="dto">鍗曟澘妫�娴嬫暟鎹瓺TO</param>
+        /// <returns>淇濆瓨缁撴灉</returns>
+        public bool SaveSingleBoardData(SingleBoardGenerateDto dto)
+        {
+            try
+            {
+                return SqlSugarHelper.UseTransactionWithOracle(db =>
+                {
+                    var testData = ConvertSingleBoardToEntity(dto);
+                    testData.CreateTime = DateTime.Now;
+                    testData.DataType = "SINGLE";
+
+                    var testDataId = db.Insertable(testData).ExecuteReturnIdentity();
+
+                    var affectedRows = 1;
+                    if (dto.CompData != null && dto.CompData.Count > 0)
+                    {
+                        var componentDataList = ConvertComponentListToEntity(dto.CompData, testDataId);
+                        affectedRows += db.Insertable(componentDataList).ExecuteCommand();
+                    }
+
+                    return affectedRows;
+                }) > 0;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"淇濆瓨鍗曟澘妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁ID鑾峰彇PCB妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="id">鏁版嵁ID</param>
+        /// <returns>PCB妫�娴嬫暟鎹�</returns>
+        public MesPcbTestData GetPcbTestDataById(decimal id)
+        {
+            try
+            {
+                var db = SqlSugarHelper.GetInstance();
+                return db.Queryable<MesPcbTestData>()
+                    .Where(x => x.Id == id)
+                    .First();
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"鑾峰彇PCB妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁鏉′欢鍒嗛〉鏌ヨPCB妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="dataType">鏁版嵁绫诲瀷锛圵HOLE/SINGLE锛�</param>
+        /// <param name="deviceName">璁惧鍚嶇О</param>
+        /// <param name="pcbSn">PCB鏉$爜</param>
+        /// <param name="startTime">寮�濮嬫椂闂�</param>
+        /// <param name="endTime">缁撴潫鏃堕棿</param>
+        /// <param name="pageIndex">椤电爜</param>
+        /// <param name="pageSize">椤靛ぇ灏�</param>
+        /// <returns>鍒嗛〉鏁版嵁</returns>
+        public (List<MesPcbTestData> items, int totalCount) GetPcbTestDataPage(
+            string dataType = null,
+            string deviceName = null,
+            string pcbSn = null,
+            DateTime? startTime = null,
+            DateTime? endTime = null,
+            int pageIndex = 1,
+            int pageSize = 20)
+        {
+            try
+            {
+                var db = SqlSugarHelper.GetInstance();
+                var totalCount = 0;
+
+                var data = db.Queryable<MesPcbTestData>()
+                    .WhereIF(StringUtil.IsNotNullOrEmpty(dataType), x => x.DataType == dataType)
+                    .WhereIF(StringUtil.IsNotNullOrEmpty(deviceName), x => x.DeviceName.Contains(deviceName))
+                    .WhereIF(StringUtil.IsNotNullOrEmpty(pcbSn), x => x.PcbSn.Contains(pcbSn))
+                    .WhereIF(startTime.HasValue, x => x.PcbTestTime >= startTime.Value)
+                    .WhereIF(endTime.HasValue, x => x.PcbTestTime <= endTime.Value)
+                    .OrderBy(x => x.PcbTestTime, OrderByType.Desc)
+                    .ToPageList(pageIndex, pageSize, ref totalCount);
+
+                return (data, totalCount);
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"鏌ヨPCB妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁娴嬭瘯鏁版嵁ID鑾峰彇鍣ㄤ欢鏁版嵁
+        /// </summary>
+        /// <param name="testDataId">娴嬭瘯鏁版嵁ID</param>
+        /// <returns>鍣ㄤ欢鏁版嵁鍒楄〃</returns>
+        public List<MesPcbComponentData> GetComponentDataByTestDataId(decimal testDataId)
+        {
+            try
+            {
+                var db = SqlSugarHelper.GetInstance();
+                return db.Queryable<MesPcbComponentData>()
+                    .Where(x => x.TestDataId == testDataId)
+                    .OrderBy(x => x.CompDesignator)
+                    .ToList();
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"鑾峰彇鍣ㄤ欢鏁版嵁澶辫触: {ex.Message}", ex);
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁PCB鏉$爜鑾峰彇妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="pcbSn">PCB鏉$爜</param>
+        /// <returns>妫�娴嬫暟鎹垪琛�</returns>
+        public List<MesPcbTestData> GetPcbTestDataByPcbSn(string pcbSn)
+        {
+            try
+            {
+                var db = SqlSugarHelper.GetInstance();
+                return db.Queryable<MesPcbTestData>()
+                    .Where(x => x.PcbSn == pcbSn)
+                    .OrderBy(x => x.PcbTestTime, OrderByType.Desc)
+                    .ToList();
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"鏍规嵁PCB鏉$爜鑾峰彇妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+            }
+        }
+
+        /// <summary>
+        /// 鍒犻櫎PCB妫�娴嬫暟鎹紙绾ц仈鍒犻櫎鍣ㄤ欢鏁版嵁锛�
+        /// </summary>
+        /// <param name="id">鏁版嵁ID</param>
+        /// <returns>鍒犻櫎缁撴灉</returns>
+        public bool DeletePcbTestData(decimal id)
+        {
+            try
+            {
+                return SqlSugarHelper.UseTransactionWithOracle(db =>
+                {
+                    var affectedRows = 0;
+                    
+                    // 鍏堝垹闄ゅ櫒浠舵暟鎹�
+                    affectedRows += db.Deleteable<MesPcbComponentData>()
+                        .Where(x => x.TestDataId == id)
+                        .ExecuteCommand();
+                    
+                    // 鍐嶅垹闄や富鏁版嵁
+                    affectedRows += db.Deleteable<MesPcbTestData>()
+                        .Where(x => x.Id == id)
+                        .ExecuteCommand();
+
+                    return affectedRows;
+                }) > 0;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"鍒犻櫎PCB妫�娴嬫暟鎹け璐�: {ex.Message}", ex);
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇妫�娴嬬粺璁℃暟鎹�
+        /// </summary>
+        /// <param name="dataType">鏁版嵁绫诲瀷</param>
+        /// <param name="deviceName">璁惧鍚嶇О</param>
+        /// <param name="startTime">寮�濮嬫椂闂�</param>
+        /// <param name="endTime">缁撴潫鏃堕棿</param>
+        /// <returns>缁熻鏁版嵁</returns>
+        public dynamic GetTestStatistics(string dataType = null, string deviceName = null, 
+            DateTime? startTime = null, DateTime? endTime = null)
+        {
+            try
+            {
+                var db = SqlSugarHelper.GetInstance();
+                
+                var statistics = db.Queryable<MesPcbTestData>()
+                    .WhereIF(StringUtil.IsNotNullOrEmpty(dataType), x => x.DataType == dataType)
+                    .WhereIF(StringUtil.IsNotNullOrEmpty(deviceName), x => x.DeviceName == deviceName)
+                    .WhereIF(startTime.HasValue, x => x.PcbTestTime >= startTime.Value)
+                    .WhereIF(endTime.HasValue, x => x.PcbTestTime <= endTime.Value)
+                    .GroupBy(x => new { x.DataType, x.DeviceName })
+                    .Select(x => new
+                    {
+                        DataType = x.DataType,
+                        DeviceName = x.DeviceName,
+                        TotalCount = SqlFunc.AggregateCount(x.Id),
+                        PassCount = SqlFunc.AggregateCount(SqlFunc.IIF(x.PcbFinalResult == "PASS", x.Id, 0)),
+                        FailCount = SqlFunc.AggregateCount(SqlFunc.IIF(x.PcbFinalResult == "FAIL", x.Id, 0)),
+                        AvgCycleTime = SqlFunc.AggregateAvg(x.PcbCycleTime)
+                    })
+                    .ToList();
+
+                return statistics;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception($"鑾峰彇妫�娴嬬粺璁℃暟鎹け璐�: {ex.Message}", ex);
+            }
+        }
+
+        #region 绉佹湁鏂规硶 - DTO杞崲
+
+        /// <summary>
+        /// 灏嗘暣鏉緿TO杞崲涓哄疄浣�
+        /// </summary>
+        /// <param name="dto">鏁存澘DTO</param>
+        /// <returns>瀹炰綋瀵硅薄</returns>
+        private MesPcbTestData ConvertWholeboardToEntity(WholeboardGenerateDto dto)
+        {
+            return new MesPcbTestData
+            {
+                DeviceName = dto.DeviceName,
+                PcbSn = dto.PcbSn,
+                PcbTrackLine = dto.PcbTrackLine,
+                PcbBoardSide = dto.PcbBoardSide,
+                PcbTestTime = StringUtil.IsNotNullOrEmpty(dto.PcbTestTime) ? 
+                    DateTime.Parse(dto.PcbTestTime) : null,
+                PcbCycleTime = (decimal?)dto.PcbCycleTime,
+                PcbProjectName = dto.PcbProjectName,
+                PcbRobotResult = dto.PcbRobotResult,
+                PcbUserResult = dto.PcbUserResult,
+                PcbFinalResult = dto.PcbFinalResult,
+                PcbRepairUser = dto.PcbRepairUser,
+                PcbBoardNumber = dto.PcbBoardNumber,
+                PcbBoardRobotNgNumber = dto.PcbBoardRobotNgNumber,
+                PcbBoardUserNgNumber = dto.PcbBoardUserNgNumber,
+                PcbBoardRepassNumber = dto.PcbBoardRepassNumber,
+                PcbCompNumber = dto.PcbCompNumber,
+                PcbCompRobotNgNumber = dto.PcbCompRobotNgNumber,
+                PcbCompUserNgNumber = dto.PcbCompUserNgNumber,
+                PcbCompRepassNumber = dto.PcbCompRepassNumber
+            };
+        }
+
+        /// <summary>
+        /// 灏嗗崟鏉緿TO杞崲涓哄疄浣�
+        /// </summary>
+        /// <param name="dto">鍗曟澘DTO</param>
+        /// <returns>瀹炰綋瀵硅薄</returns>
+        private MesPcbTestData ConvertSingleBoardToEntity(SingleBoardGenerateDto dto)
+        {
+            return new MesPcbTestData
+            {
+                DeviceName = dto.DeviceName,
+                PcbSn = dto.PcbSn,
+                PcbTrackLine = dto.PcbTrackLine,
+                PcbBoardSide = dto.PcbBoardSide,
+                PcbTestTime = StringUtil.IsNotNullOrEmpty(dto.PcbTestTime) ? 
+                    DateTime.Parse(dto.PcbTestTime) : null,
+                PcbCycleTime = (decimal?)dto.PcbCycleTime,
+                PcbProjectName = dto.PcbProjectName,
+                PcbRobotResult = dto.PcbRobotResult,
+                PcbUserResult = dto.PcbUserResult,
+                PcbFinalResult = dto.PcbFinalResult,
+                PcbRepairUser = dto.PcbRepairUser,
+                PcbBoardNumber = dto.PcbBoardNumber,
+                PcbCompNumber = dto.PcbCompNumber,
+                BoardSn = dto.BoardSn,
+                BoardNo = dto.BoardNo,
+                BoardRobotResult = dto.BoardRobotResult,
+                BoardUserResult = dto.BoardUserResult,
+                BoardFinalResult = dto.BoardFinalResult,
+                BoardCompNumber = dto.BoardCompNumber,
+                BoardCompRobotNgNumber = dto.BoardCompRobotNgNumber,
+                BoardCompUserNgNumber = dto.BoardCompUserNgNumber,
+                BoardCompRepassNumber = dto.BoardCompRepassNumber
+            };
+        }
+
+        /// <summary>
+        /// 灏嗗櫒浠禗TO鍒楄〃杞崲涓哄疄浣撳垪琛�
+        /// </summary>
+        /// <param name="dtoList">鍣ㄤ欢DTO鍒楄〃</param>
+        /// <param name="testDataId">娴嬭瘯鏁版嵁ID</param>
+        /// <returns>瀹炰綋鍒楄〃</returns>
+        private List<MesPcbComponentData> ConvertComponentListToEntity(List<ComponentDataDto> dtoList, decimal testDataId)
+        {
+            return dtoList.Select(dto => new MesPcbComponentData
+            {
+                TestDataId = testDataId,
+                CompDesignator = dto.CompDesignator,
+                CompPart = dto.CompPart,
+                CompPackage = dto.CompPackage,
+                CompType = dto.CompType,
+                CompRobotCode = dto.CompRobotCode,
+                CompRobotResult = dto.CompRobotResult,
+                CompUserCode = dto.CompUserCode,
+                CompUserResult = dto.CompUserResult,
+                CompImage = dto.CompImage,
+                CreateTime = DateTime.Now
+            }).ToList();
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file
diff --git a/MESApplication/Controllers/QC/PcbTestDataController.cs b/MESApplication/Controllers/QC/PcbTestDataController.cs
new file mode 100644
index 0000000..185694b
--- /dev/null
+++ b/MESApplication/Controllers/QC/PcbTestDataController.cs
@@ -0,0 +1,508 @@
+using System;
+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>
+    /// PCB妫�娴嬫暟鎹帶鍒跺櫒
+    /// </summary>
+    [Route("api/[controller]")]
+    [ApiController]
+    public class PcbTestDataController : ControllerBase
+    {
+        private readonly MessageCenterManager _manager = new();
+        private readonly PcbTestDataService _service = new();
+        
+        private readonly string METHOD = "POST";
+        private readonly string TableName = "MES_PCB_TEST_DATA";
+        private readonly string URL = "http://localhost:10054/api/PcbTestData/";
+
+        /// <summary>
+        /// 淇濆瓨鏁存澘妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="dto">鏁存澘妫�娴嬫暟鎹瓺TO</param>
+        /// <returns>淇濆瓨缁撴灉</returns>
+        [HttpPost("SaveWholeboardData")]
+        public ResponseResult SaveWholeboardData([FromBody] WholeboardGenerateDto dto)
+        {
+            var entity = new MessageCenter();
+            entity.TableName = TableName;
+            entity.Url = URL + "SaveWholeboardData";
+            entity.Method = METHOD;
+            entity.Data = JsonConvert.SerializeObject(dto);
+            entity.Status = 1;
+            entity.CreateBy = "PL017";
+            
+            try
+            {
+                dynamic resultInfos = new ExpandoObject();
+                var result = _service.SaveWholeboardData(dto);
+                resultInfos.result = result;
+                resultInfos.message = result ? "鏁存澘妫�娴嬫暟鎹繚瀛樻垚鍔�" : "鏁存澘妫�娴嬫暟鎹繚瀛樺け璐�";
+                
+                entity.Result = result ? (short)1 : (short)0;
+                entity.DealWith = 1;
+                _manager.save(entity);
+                
+                return new ResponseResult
+                {
+                    status = result ? 0 : 1,
+                    message = result ? "OK" : "FAIL",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                entity.Result = 0;
+                entity.DealWith = 0;
+                entity.ResultData = ex.Message;
+                _manager.save(entity);
+                
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+
+        /// <summary>
+        /// 淇濆瓨鍗曟澘妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="dto">鍗曟澘妫�娴嬫暟鎹瓺TO</param>
+        /// <returns>淇濆瓨缁撴灉</returns>
+        [HttpPost("SaveSingleBoardData")]
+        public ResponseResult SaveSingleBoardData([FromBody] SingleBoardGenerateDto dto)
+        {
+            var entity = new MessageCenter();
+            entity.TableName = TableName;
+            entity.Url = URL + "SaveSingleBoardData";
+            entity.Method = METHOD;
+            entity.Data = JsonConvert.SerializeObject(dto);
+            entity.Status = 1;
+            entity.CreateBy = "PL017";
+            
+            try
+            {
+                dynamic resultInfos = new ExpandoObject();
+                var result = _service.SaveSingleBoardData(dto);
+                resultInfos.result = result;
+                resultInfos.message = result ? "鍗曟澘妫�娴嬫暟鎹繚瀛樻垚鍔�" : "鍗曟澘妫�娴嬫暟鎹繚瀛樺け璐�";
+                
+                entity.Result = result ? (short)1 : (short)0;
+                entity.DealWith = 1;
+                _manager.save(entity);
+                
+                return new ResponseResult
+                {
+                    status = result ? 0 : 1,
+                    message = result ? "OK" : "FAIL",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                entity.Result = 0;
+                entity.DealWith = 0;
+                entity.ResultData = ex.Message;
+                _manager.save(entity);
+                
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+
+        /// <summary>
+        /// 鍒嗛〉鏌ヨPCB妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="request">鏌ヨ璇锋眰</param>
+        /// <returns>鍒嗛〉鏁版嵁</returns>
+        [HttpPost("GetPage")]
+        public ResponseResult GetPage([FromBody] JObject request)
+        {
+            try
+            {
+                var dataType = request["dataType"]?.ToString();
+                var deviceName = request["deviceName"]?.ToString();
+                var pcbSn = request["pcbSn"]?.ToString();
+                var startTime = request["startTime"]?.ToString();
+                var endTime = request["endTime"]?.ToString();
+                var pageIndex = request["pageIndex"]?.ToObject<int>() ?? 1;
+                var pageSize = request["pageSize"]?.ToObject<int>() ?? 20;
+
+                DateTime? startDateTime = null;
+                DateTime? endDateTime = null;
+
+                if (StringUtil.IsNotNullOrEmpty(startTime) && DateTime.TryParse(startTime, out var start))
+                    startDateTime = start;
+
+                if (StringUtil.IsNotNullOrEmpty(endTime) && DateTime.TryParse(endTime, out var end))
+                    endDateTime = end;
+
+                var (items, totalCount) = _service.GetPcbTestDataPage(
+                    dataType, deviceName, pcbSn, 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);
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁ID鑾峰彇PCB妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="request">璇锋眰鍙傛暟</param>
+        /// <returns>PCB妫�娴嬫暟鎹�</returns>
+        [HttpPost("GetById")]
+        public ResponseResult GetById([FromBody] JObject request)
+        {
+            try
+            {
+                var id = request["id"]?.ToObject<decimal>();
+                if (!id.HasValue)
+                {
+                    return new ResponseResult
+                    {
+                        status = 1,
+                        message = "ID涓嶈兘涓虹┖",
+                        data = null
+                    };
+                }
+
+                var testData = _service.GetPcbTestDataById(id.Value);
+                var componentData = _service.GetComponentDataByTestDataId(id.Value);
+
+                dynamic resultInfos = new ExpandoObject();
+                resultInfos.testData = testData;
+                resultInfos.componentData = componentData;
+
+                return new ResponseResult
+                {
+                    status = 0,
+                    message = "OK",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+
+        /// <summary>
+        /// 鏍规嵁PCB鏉$爜鑾峰彇妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="request">璇锋眰鍙傛暟</param>
+        /// <returns>妫�娴嬫暟鎹垪琛�</returns>
+        [HttpPost("GetByPcbSn")]
+        public ResponseResult GetByPcbSn([FromBody] JObject request)
+        {
+            try
+            {
+                var pcbSn = request["pcbSn"]?.ToString();
+                if (StringUtil.IsNullOrEmpty(pcbSn))
+                {
+                    return new ResponseResult
+                    {
+                        status = 1,
+                        message = "PCB鏉$爜涓嶈兘涓虹┖",
+                        data = null
+                    };
+                }
+
+                var testDataList = _service.GetPcbTestDataByPcbSn(pcbSn);
+
+                dynamic resultInfos = new ExpandoObject();
+                resultInfos.testDataList = testDataList;
+
+                return new ResponseResult
+                {
+                    status = 0,
+                    message = "OK",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍣ㄤ欢妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="request">璇锋眰鍙傛暟</param>
+        /// <returns>鍣ㄤ欢妫�娴嬫暟鎹�</returns>
+        [HttpPost("GetComponentData")]
+        public ResponseResult GetComponentData([FromBody] JObject request)
+        {
+            try
+            {
+                var testDataId = request["testDataId"]?.ToObject<decimal>();
+                if (!testDataId.HasValue)
+                {
+                    return new ResponseResult
+                    {
+                        status = 1,
+                        message = "娴嬭瘯鏁版嵁ID涓嶈兘涓虹┖",
+                        data = null
+                    };
+                }
+
+                var componentData = _service.GetComponentDataByTestDataId(testDataId.Value);
+
+                dynamic resultInfos = new ExpandoObject();
+                resultInfos.componentData = componentData;
+
+                return new ResponseResult
+                {
+                    status = 0,
+                    message = "OK",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇妫�娴嬬粺璁℃暟鎹�
+        /// </summary>
+        /// <param name="request">璇锋眰鍙傛暟</param>
+        /// <returns>缁熻鏁版嵁</returns>
+        [HttpPost("GetStatistics")]
+        public ResponseResult GetStatistics([FromBody] JObject request)
+        {
+            try
+            {
+                var dataType = request["dataType"]?.ToString();
+                var deviceName = request["deviceName"]?.ToString();
+                var startTime = request["startTime"]?.ToString();
+                var endTime = request["endTime"]?.ToString();
+
+                DateTime? startDateTime = null;
+                DateTime? endDateTime = null;
+
+                if (StringUtil.IsNotNullOrEmpty(startTime) && DateTime.TryParse(startTime, out var start))
+                    startDateTime = start;
+
+                if (StringUtil.IsNotNullOrEmpty(endTime) && DateTime.TryParse(endTime, out var end))
+                    endDateTime = end;
+
+                var statistics = _service.GetTestStatistics(dataType, deviceName, startDateTime, endDateTime);
+
+                dynamic resultInfos = new ExpandoObject();
+                resultInfos.statistics = statistics;
+
+                return new ResponseResult
+                {
+                    status = 0,
+                    message = "OK",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+
+        /// <summary>
+        /// 鍒犻櫎PCB妫�娴嬫暟鎹�
+        /// </summary>
+        /// <param name="request">璇锋眰鍙傛暟</param>
+        /// <returns>鍒犻櫎缁撴灉</returns>
+        [HttpPost("Delete")]
+        public ResponseResult Delete([FromBody] JObject request)
+        {
+            var entity = new MessageCenter();
+            entity.TableName = TableName;
+            entity.Url = URL + "Delete";
+            entity.Method = METHOD;
+            entity.Data = JsonConvert.SerializeObject(request);
+            entity.Status = 1;
+            entity.CreateBy = "PL017";
+            
+            try
+            {
+                var id = request["id"]?.ToObject<decimal>();
+                if (!id.HasValue)
+                {
+                    entity.Result = 0;
+                    entity.DealWith = 0;
+                    entity.ResultData = "ID涓嶈兘涓虹┖";
+                    _manager.save(entity);
+                    
+                    return new ResponseResult
+                    {
+                        status = 1,
+                        message = "ID涓嶈兘涓虹┖",
+                        data = null
+                    };
+                }
+
+                var result = _service.DeletePcbTestData(id.Value);
+
+                dynamic resultInfos = new ExpandoObject();
+                resultInfos.result = result;
+                resultInfos.message = result ? "鍒犻櫎鎴愬姛" : "鍒犻櫎澶辫触";
+
+                entity.Result = result ? (short)1 : (short)0;
+                entity.DealWith = 1;
+                _manager.save(entity);
+
+                return new ResponseResult
+                {
+                    status = result ? 0 : 1,
+                    message = result ? "OK" : "FAIL",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                entity.Result = 0;
+                entity.DealWith = 0;
+                entity.ResultData = ex.Message;
+                _manager.save(entity);
+                
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+
+        /// <summary>
+        /// 缁熶竴淇濆瓨鎺ュ彛锛堣嚜鍔ㄨ瘑鍒暣鏉挎垨鍗曟澘鏁版嵁锛�
+        /// </summary>
+        /// <param name="request">璇锋眰鍙傛暟</param>
+        /// <returns>淇濆瓨缁撴灉</returns>
+        [HttpPost("SaveTestData")]
+        public ResponseResult SaveTestData([FromBody] JObject request)
+        {
+            var entity = new MessageCenter();
+            entity.TableName = TableName;
+            entity.Url = URL + "SaveTestData";
+            entity.Method = METHOD;
+            entity.Data = JsonConvert.SerializeObject(request);
+            entity.Status = 1;
+            entity.CreateBy = "PL017";
+            
+            try
+            {
+                var dataType = request["dataType"]?.ToString();
+                
+                if (StringUtil.IsNullOrEmpty(dataType))
+                {
+                    entity.Result = 0;
+                    entity.DealWith = 0;
+                    entity.ResultData = "鏁版嵁绫诲瀷涓嶈兘涓虹┖锛岃鎸囧畾WHOLE鎴朣INGLE";
+                    _manager.save(entity);
+                    
+                    return new ResponseResult
+                    {
+                        status = 1,
+                        message = "鏁版嵁绫诲瀷涓嶈兘涓虹┖锛岃鎸囧畾WHOLE鎴朣INGLE",
+                        data = null
+                    };
+                }
+
+                dynamic resultInfos = new ExpandoObject();
+                bool result = false;
+                string message = "";
+
+                switch (dataType.ToUpper())
+                {
+                    case "WHOLE":
+                        var wholeboardDto = request["data"]?.ToObject<WholeboardGenerateDto>();
+                        if (wholeboardDto == null)
+                        {
+                            entity.Result = 0;
+                            entity.DealWith = 0;
+                            entity.ResultData = "鏁存澘鏁版嵁涓嶈兘涓虹┖";
+                            _manager.save(entity);
+                            
+                            return new ResponseResult
+                            {
+                                status = 1,
+                                message = "鏁存澘鏁版嵁涓嶈兘涓虹┖",
+                                data = null
+                            };
+                        }
+                        result = _service.SaveWholeboardData(wholeboardDto);
+                        message = result ? "鏁存澘妫�娴嬫暟鎹繚瀛樻垚鍔�" : "鏁存澘妫�娴嬫暟鎹繚瀛樺け璐�";
+                        break;
+
+                    case "SINGLE":
+                        var singleBoardDto = request["data"]?.ToObject<SingleBoardGenerateDto>();
+                        if (singleBoardDto == null)
+                        {
+                            entity.Result = 0;
+                            entity.DealWith = 0;
+                            entity.ResultData = "鍗曟澘鏁版嵁涓嶈兘涓虹┖";
+                            _manager.save(entity);
+                            
+                            return new ResponseResult
+                            {
+                                status = 1,
+                                message = "鍗曟澘鏁版嵁涓嶈兘涓虹┖",
+                                data = null
+                            };
+                        }
+                        result = _service.SaveSingleBoardData(singleBoardDto);
+                        message = result ? "鍗曟澘妫�娴嬫暟鎹繚瀛樻垚鍔�" : "鍗曟澘妫�娴嬫暟鎹繚瀛樺け璐�";
+                        break;
+
+                    default:
+                        entity.Result = 0;
+                        entity.DealWith = 0;
+                        entity.ResultData = "涓嶆敮鎸佺殑鏁版嵁绫诲瀷锛岃鎸囧畾WHOLE鎴朣INGLE";
+                        _manager.save(entity);
+                        
+                        return new ResponseResult
+                        {
+                            status = 1,
+                            message = "涓嶆敮鎸佺殑鏁版嵁绫诲瀷锛岃鎸囧畾WHOLE鎴朣INGLE",
+                            data = null
+                        };
+                }
+
+                resultInfos.result = result;
+                resultInfos.message = message;
+
+                entity.Result = result ? (short)1 : (short)0;
+                entity.DealWith = 1;
+                _manager.save(entity);
+
+                return new ResponseResult
+                {
+                    status = result ? 0 : 1,
+                    message = result ? "OK" : "FAIL",
+                    data = resultInfos
+                };
+            }
+            catch (Exception ex)
+            {
+                entity.Result = 0;
+                entity.DealWith = 0;
+                entity.ResultData = ex.Message;
+                _manager.save(entity);
+                
+                return ResponseResult.ResponseError(ex);
+            }
+        }
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.3