CLAUDE.md
@@ -24,10 +24,12 @@ ### Database Layer - Uses **SqlSugar ORM** for data access with Oracle database - Connection string configured in `appsettings.json` - Two database contexts available: - `DbContext<T>` (MES.Service/DB/DbContext.cs:10) - Generic repository pattern - `SqlSugarHelper` (MES.Service/DB/SqlSugarHelper.cs:6) - Oracle-specific helper with transaction support - Connection string configured in `appsettings.json` and loaded via `AppsettingsUtility.Settings.DataBaseConn` - Three database access patterns available: - `Repository<T>` (MES.Service/DB/Repository.cs:6) - Base class for all Manager classes, extends SqlSugar's SimpleClient with Oracle configuration and transaction support via `UseTransaction()` method - `DbContext<T>` (MES.Service/DB/DbContext.cs:10) - Generic repository pattern for SqlServer (legacy, not actively used) - `SqlSugarHelper` (MES.Service/DB/SqlSugarHelper.cs:6) - Static Oracle helper with `GetInstance()` and `UseTransactionWithOracle()` methods - **IMPORTANT**: Most services inherit from `Repository<T>`, which provides pre-configured Oracle connection and built-in transaction management ### Service Layer Structure - **BasicData**: Core business entities (customers, items, suppliers, etc.) @@ -38,11 +40,13 @@ - `webApi/`: External API DTOs for ERP integration ### API Layer - ASP.NET Core Web API with Swagger documentation - Controllers organized by domain (BasicData, QC, Warehouse) - Newtonsoft.Json for serialization with camelCase naming - ASP.NET Core Web API with Swagger documentation (available in Development mode) - Controllers organized by domain (BasicData, QC, Warehouse, FBSDB) - Newtonsoft.Json for serialization with camelCase naming (configured in Startup.cs:46) - CORS enabled for cross-origin requests - Custom ActionFilter for request/response handling - Custom ActionFilter (MESApplication/Filter/ActionFilter.cs) for global request/response logging - All endpoints use `[HttpPost]` by convention, even for read operations - Route pattern: `api/[controller]/[action]` ## Common Development Commands @@ -89,19 +93,54 @@ ## Important Patterns ### Repository Pattern Most business logic follows the Manager pattern: - Managers in `MES.Service/service/` handle business operations - Controllers in `MESApplication/Controllers/` handle HTTP requests - Models in `MES.Service/Modes/` represent database entities All business logic follows the Manager pattern with inheritance-based repository access: - **Managers** in `MES.Service/service/` inherit from `Repository<T>` and handle business operations - Example: `MesCustomerManager : Repository<MesCustomer>` (47 Manager classes total) - Managers use `UseTransaction(db => {...})` for transactional operations - Directly access SqlSugar methods via inherited SimpleClient functionality - **Controllers** in `MESApplication/Controllers/` handle HTTP requests and instantiate Manager classes - Controllers manually create Manager instances (e.g., `new MesCustomerManager()`) - Use `ResponseResult` utility class for standardized API responses - Controllers wrap Manager calls in try-catch blocks and log to MessageCenter - **Models** in `MES.Service/Modes/` represent database entities with SqlSugar attributes ### Service Registration Services are manually instantiated rather than using dependency injection containers. When adding new services, follow the existing pattern in the respective Manager classes. ### Service Registration and Response Format Services are manually instantiated rather than using dependency injection containers: - Controllers directly instantiate Managers: `private readonly MesCustomerManager m = new();` - Startup.cs configures `AppSettings` from appsettings.json into static `AppsettingsUtility.Settings` - No DI container for business logic - all service creation is explicit All API endpoints return `ResponseResult` (MES.Service/util/ResponseResult.cs:7) with structure: ```csharp { status: 0, // 0 = success, 1 = failure message: "OK", // error message or "OK" data: object, // response payload wrapped in ExpandoObject TotalCount: 0 // optional pagination count } ``` ### Error Handling - ActionFilter handles global request/response processing - SQL logging enabled via SqlSugar AOP for debugging - Console output for SQL query debugging - `ActionFilter` (MESApplication/Filter/ActionFilter.cs:13) handles global request/response processing - Logs all requests with headers and body parameters - Logs all responses with execution time - Catches exceptions and logs via `ErrorLog.Write()` - SQL logging enabled via SqlSugar AOP for debugging (prints to Console) - All Controller methods catch exceptions and return `ResponseResult.ResponseError(ex)` - ERP integration operations logged to `MessageCenter` table with status tracking ## API Documentation API documentation is available in the `MESApplication/Docs/` folder: - `Spi_API.md` - SPI (Solder Paste Inspection) API documentation - `Aoi_API.md` - AOI (Automated Optical Inspection) API documentation ## Testing No test projects are currently configured in this solution. When adding tests, create separate test projects following .NET testing conventions. No test projects are currently configured in this solution. When adding tests, create separate test projects following .NET testing conventions. ## Key Utilities - `AppsettingsUtility` (MES.Service/util/AppsettingsUtility.cs:6) - Loads configuration into static `Settings` property - `ResponseResult` (MES.Service/util/ResponseResult.cs:7) - Standardized API response wrapper - `ErrorLog` - Custom error logging utility used by ActionFilter MES.Service/Dto/service/SpiAoiDto.cs
@@ -16,7 +16,7 @@ public string TestTime { get; set; } /// <summary> /// 娴嬭瘯缁撴灉(濡傦細0:0:1;0銆?;0;0:1銆丗ail绛? /// 测试结果(固定为三种:0:0:1;0:测试为OK,0;0;0:1:测试为Fail /// </summary> public string TestResult { get; set; } @@ -46,7 +46,7 @@ public string? WorkOrder { get; set; } /// <summary> /// 鏈虹鍚? /// 机种 /// </summary> public string? ProductModel { get; set; } @@ -77,7 +77,7 @@ public string? MachineName { get; set; } /// <summary> /// 鐢熶骇绾垮悕绉? /// 生产线名 /// </summary> public string? LineDisplayName { get; set; } @@ -85,101 +85,52 @@ /// Legacy header identifier (optional). /// </summary> public decimal? HeaderId { get; set; } /// <summary> /// 偏位数量 /// </summary> public int OffsetCount { get; set; } /// <summary> /// 缺件数量 /// 面积超出数量 /// </summary> public int MissingCount { get; set; } public int AreaOverflowCount { get; set; } /// <summary> /// 反向数量 /// 面积不足数量 /// </summary> public int ReverseCount { get; set; } public int AreaUnderflowCount { get; set; } /// <summary> /// 翘起数量 /// 高度超出数量 /// </summary> public int LiftedCount { get; set; } public int ExceedingHeightCount { get; set; } /// <summary> /// 浮高数量 /// 高度不足数量 /// </summary> public int FloatHighCount { get; set; } public int InsufficientHeightCount { get; set; } /// <summary> /// 立碑数量 /// X偏移数量 /// </summary> public int TombstoneCount { get; set; } public int XDeviationCount { get; set; } /// <summary> /// 翻转数量 /// Y偏移数量 /// </summary> public int FlipCount { get; set; } public int YDeviationCount { get; set; } /// <summary> /// 错件数量 /// 塌陷数量 /// </summary> public int WrongPartCount { get; set; } public int CollapseCount { get; set; } /// <summary> /// 翘脚数量 /// 拉尖数量(焊锡拉尖) /// </summary> public int LeadLiftCount { get; set; } public int SolderPullTipCount { 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; } public int AbnormalityCount { get; set; } /// <summary> /// 投入板数 /// </summary> @@ -196,7 +147,7 @@ public int PassBoards { get; set; } /// <summary> /// 鍚堟牸鐜?%) /// 合格 /// </summary> public decimal? PassRate { get; set; } @@ -206,12 +157,12 @@ public int DefectBoards { get; set; } /// <summary> /// 涓嶈壇鐜?%) /// 不良 /// </summary> public decimal? DefectRate { get; set; } /// <summary> /// 涓嶈壇鐜?PPM) /// 不良 /// </summary> public int? DefectPpm { get; set; } MES.Service/MES.Service.csproj
@@ -11,8 +11,4 @@ <PackageReference Include="SqlSugarCore" Version="5.1.4.158" /> </ItemGroup> <ItemGroup> <Folder Include="DB\Scripts\" /> </ItemGroup> </Project> MES.Service/Modes/MesSpiAoiDetail.cs
@@ -21,118 +21,58 @@ public decimal HeaderId { get; set; } /// <summary> /// 偏位数量。 /// 面积超出数量。 /// </summary> [SugarColumn(ColumnName = "OFFSET_COUNT")] public int OffsetCount { get; set; } [SugarColumn(ColumnName = "AREA_OVERFLOW_COUNT")] public int AreaOverflowCount { get; set; } /// <summary> /// 缺件数量。 /// 面积不足数量。 /// </summary> [SugarColumn(ColumnName = "MISSING_COUNT")] public int MissingCount { get; set; } [SugarColumn(ColumnName = "AREA_UNDERFLOW_COUNT")] public int AreaUnderflowCount { get; set; } /// <summary> /// 反向安装数量。 /// 高度超出数量。 /// </summary> [SugarColumn(ColumnName = "REVERSE_COUNT")] public int ReverseCount { get; set; } [SugarColumn(ColumnName = "EXCEEDING_HEIGHT_COUNT")] public int ExceedingHeightCount { get; set; } /// <summary> /// 翘起数量。 /// 高度不足数量。 /// </summary> [SugarColumn(ColumnName = "LIFTED_COUNT")] public int LiftedCount { get; set; } [SugarColumn(ColumnName = "INSUFFICIENT_HEIGHT_COUNT")] public int InsufficientHeightCount { get; set; } /// <summary> /// 浮高数量。 /// X偏移数量。 /// </summary> [SugarColumn(ColumnName = "FLOAT_HIGH_COUNT")] public int FloatHighCount { get; set; } [SugarColumn(ColumnName = "X_DEVIATION_COUNT")] public int XDeviationCount { get; set; } /// <summary> /// 立碑数量。 /// Y偏移数量。 /// </summary> [SugarColumn(ColumnName = "TOMBSTONE_COUNT")] public int TombstoneCount { get; set; } [SugarColumn(ColumnName = "Y_DEVIATION_COUNT")] public int YDeviationCount { get; set; } /// <summary> /// 翻转数量。 /// 塌陷数量。 /// </summary> [SugarColumn(ColumnName = "FLIP_COUNT")] public int FlipCount { get; set; } [SugarColumn(ColumnName = "COLLAPSE_COUNT")] public int CollapseCount { get; set; } /// <summary> /// 错件数量。 /// 拉尖数量(焊锡拉尖)。 /// </summary> [SugarColumn(ColumnName = "WRONG_PART_COUNT")] public int WrongPartCount { get; set; } [SugarColumn(ColumnName = "SOLDER_PULL_TIP_COUNT")] public int SolderPullTipCount { 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; } [SugarColumn(ColumnName = "ABNORMALITY_COUNT")] public int AbnormalityCount { get; set; } /// <summary> /// 产线显示名称。 MES.Service/bin/Debug/net8.0/MES.Service.dllBinary files differ
MES.Service/bin/Debug/net8.0/MES.Service.pdbBinary files differ
MES.Service/bin/Release/net8.0/MES.Service.dllBinary files differ
MES.Service/bin/Release/net8.0/MES.Service.pdbBinary files differ
MES.Service/service/QC/SpiAoiService.cs
@@ -443,25 +443,15 @@ return new MesSpiAoiDetail { HeaderId = dto.HeaderId ?? 0, 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, AreaOverflowCount = dto.AreaOverflowCount, AreaUnderflowCount = dto.AreaUnderflowCount, ExceedingHeightCount = dto.ExceedingHeightCount, InsufficientHeightCount = dto.InsufficientHeightCount, XDeviationCount = dto.XDeviationCount, YDeviationCount = dto.YDeviationCount, CollapseCount = dto.CollapseCount, SolderPullTipCount = dto.SolderPullTipCount, AbnormalityCount = dto.AbnormalityCount, LineDisplayName = dto.LineDisplayName, MachineName = dto.MachineName, InputBoards = dto.InputBoards, MESApplication/bin/Debug/net8.0/MES.Service.dllBinary files differ
MESApplication/bin/Debug/net8.0/MES.Service.pdbBinary files differ
MESApplication/bin/Debug/net8.0/MESApplication.dllBinary files differ
MESApplication/bin/Debug/net8.0/MESApplication.exeBinary files differ
MESApplication/bin/Debug/net8.0/MESApplication.pdbBinary files differ
MESApplication/bin/Debug/net8.0/MESApplication.xml
@@ -982,12 +982,33 @@ SPI/AOI检测数据控制器 </summary> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.Upload(MES.Service.Dto.service.SpiAoiUploadRequest)"> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadAoiHeader(MES.Service.Dto.service.SpiAoiHeaderDto)"> <summary> 上传SPI/AOI检测数据 Upload AOI header data. </summary> <param name="request">上传请求</param> <returns>上传结果</returns> <param name="header">AOI header payload.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadAoiHeaderBatch(System.Collections.Generic.List{MES.Service.Dto.service.SpiAoiHeaderDto})"> <summary> Batch upload AOI header data. </summary> <param name="headers">AOI header payload collection.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadSpiDetails(MES.Service.Dto.service.SpiAoiDetailDto)"> <summary> Upload SPI detail data. </summary> <param name="request">SPI detail payload.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadSpiDetailsBatch(System.Collections.Generic.List{MES.Service.Dto.service.SpiAoiDetailDto})"> <summary> Batch upload SPI detail data. </summary> <param name="requests">SPI detail payload collection.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.GetByBarcode(Newtonsoft.Json.Linq.JObject)"> <summary> MESApplication/bin/Release/net8.0/MES.Service.dllBinary files differ
MESApplication/bin/Release/net8.0/MES.Service.pdbBinary files differ
MESApplication/bin/Release/net8.0/MESApplication.dllBinary files differ
MESApplication/bin/Release/net8.0/MESApplication.exeBinary files differ
MESApplication/bin/Release/net8.0/MESApplication.pdbBinary files differ
MESApplication/bin/Release/net8.0/MESApplication.xml
@@ -977,6 +977,60 @@ <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.UploadAoiHeader(MES.Service.Dto.service.SpiAoiHeaderDto)"> <summary> Upload AOI header data. </summary> <param name="header">AOI header payload.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadAoiHeaderBatch(System.Collections.Generic.List{MES.Service.Dto.service.SpiAoiHeaderDto})"> <summary> Batch upload AOI header data. </summary> <param name="headers">AOI header payload collection.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadSpiDetails(MES.Service.Dto.service.SpiAoiDetailDto)"> <summary> Upload SPI detail data. </summary> <param name="request">SPI detail payload.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadSpiDetailsBatch(System.Collections.Generic.List{MES.Service.Dto.service.SpiAoiDetailDto})"> <summary> Batch upload SPI detail data. </summary> <param name="requests">SPI detail payload collection.</param> <returns>Upload result.</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> 获取工单 MESApplication/bin/Release/net8.0/publish/MES.Service.dllBinary files differ
MESApplication/bin/Release/net8.0/publish/MES.Service.pdbBinary files differ
MESApplication/bin/Release/net8.0/publish/MESApplication.deps.json
@@ -1161,7 +1161,7 @@ }, "runtime": { "MES.Service.dll": { "assemblyVersion": "1.0.0", "assemblyVersion": "1.0.0.0", "fileVersion": "1.0.0.0" } } MESApplication/bin/Release/net8.0/publish/MESApplication.dllBinary files differ
MESApplication/bin/Release/net8.0/publish/MESApplication.exeBinary files differ
MESApplication/bin/Release/net8.0/publish/MESApplication.pdbBinary files differ
MESApplication/bin/Release/net8.0/publish/MESApplication.staticwebassets.endpoints.json
@@ -1,5 +1 @@ { "Version": 1, "ManifestType": "Publish", "Endpoints": [] } {"Version":1,"ManifestType":"Publish","Endpoints":[]} MESApplication/bin/Release/net8.0/publish/MESApplication.xml
@@ -977,6 +977,60 @@ <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.UploadAoiHeader(MES.Service.Dto.service.SpiAoiHeaderDto)"> <summary> Upload AOI header data. </summary> <param name="header">AOI header payload.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadAoiHeaderBatch(System.Collections.Generic.List{MES.Service.Dto.service.SpiAoiHeaderDto})"> <summary> Batch upload AOI header data. </summary> <param name="headers">AOI header payload collection.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadSpiDetails(MES.Service.Dto.service.SpiAoiDetailDto)"> <summary> Upload SPI detail data. </summary> <param name="request">SPI detail payload.</param> <returns>Upload result.</returns> </member> <member name="M:MESApplication.Controllers.QC.SpiAoiController.UploadSpiDetailsBatch(System.Collections.Generic.List{MES.Service.Dto.service.SpiAoiDetailDto})"> <summary> Batch upload SPI detail data. </summary> <param name="requests">SPI detail payload collection.</param> <returns>Upload result.</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> 获取工单 MESApplication/bin/Release/net8.0/publish/web.config
@@ -8,5 +8,4 @@ <aspNetCore processPath="dotnet" arguments=".\MESApplication.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" /> </system.webServer> </location> </configuration> <!--ProjectGuid: C0B360C5-E8CC-4BC3-AAA5-3F03A2D6C0AA--> </configuration>