using DOAN.Model; using DOAN.Model.Business; using DOAN.Model.Dto; using DOAN.Model.MES.process; using DOAN.Repository; using DOAN.Service.Business.IBusinessService; using Infrastructure.Attribute; using Infrastructure.Extensions; using Microsoft.AspNetCore.Http; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using SqlSugar; using System; using System.Linq; namespace DOAN.Service.Business { /// /// 产品项目表Service业务层处理 /// [AppService(ServiceType = typeof(IProcessmodelProjectService), ServiceLifetime = LifeTime.Transient)] public class ProcessmodelProjectService : BaseService, IProcessmodelProjectService { // 静态变量,标记是否已执行过删除旧数据 private static bool _hasDeletedOldData = false; /// /// 查询产品项目表列表 /// /// /// public PagedInfo GetList(ProcessmodelProjectQueryDto parm) { var predicate = Expressionable.Create() .AndIF(!string.IsNullOrEmpty(parm.ProjectCode), p => parm.ProjectCode.Contains(p.ProjectCode)) .AndIF(!string.IsNullOrEmpty(parm.ProjectName), p => parm.ProjectName.Contains(p.ProjectName)); var response = Queryable() .Where(predicate.ToExpression()) .ToPage(parm); return response; } /// /// 获取详情 /// /// /// public ProcessmodelProject GetInfo(long Id) { var response = Queryable() .Where(x => x.Id == Id) .First(); return response; } /// /// 添加产品项目表 /// /// /// public ProcessmodelProject AddProcessmodelProject(ProcessmodelProject model) { return Context.Insertable(model).ExecuteReturnEntity(); } /// /// 修改产品项目表 /// /// /// public int UpdateProcessmodelProject(ProcessmodelProject model) { //var response = Update(w => w.Id == model.Id, it => new ProcessmodelProject() //{ // ProjectCode = model.ProjectCode, // ProjectName = model.ProjectName, // ProductCode = model.ProductCode, // ProductName = model.ProductName, // CreatedBy = model.CreatedBy, // CreatedTime = model.CreatedTime, // UpdatedBy = model.UpdatedBy, // UpdatedTime = model.UpdatedTime, //}); //return response; return Update(model, true); } /// /// 新增导入Excel /// /// /// /// public int AddImportExcel(IFormFile formFile, string username) { _hasDeletedOldData = false; int insertCount = 0; using (var stream = formFile.OpenReadStream()) { try { List projectList = new List(); List routingList = new List(); List processList = new List(); List stepList = new List(); IWorkbook workbook = new XSSFWorkbook(stream); ISheet sheet = workbook.GetSheet("Sheet1"); // 从第二行开始读取 for (int i = 1; i <= sheet.LastRowNum; i++) { IRow row = sheet.GetRow(i); if (row == null) continue; // 读取基础数据 string projectCode = GetCellStringValue(row.GetCell(0)); // A列:项目号 string projectName = GetCellStringValue(row.GetCell(1)); // B列:项目名称 string productCode = GetCellStringValue(row.GetCell(2)); // C列:零件号 string productName = GetCellStringValue(row.GetCell(3)); // D列:零件名称 string routingCode = GetCellStringValue(row.GetCell(4)); // E列:工艺路线号 string routingName = GetCellStringValue(row.GetCell(5)); // F列:工艺路线名称 string processCode = GetCellStringValue(row.GetCell(6)); // G列:工序号 string processName = GetCellStringValue(row.GetCell(7)); // H列:工序名称 string stepCode = GetCellStringValue(row.GetCell(8)); // I列:工步号 string stepName = GetCellStringValue(row.GetCell(9)); // J列:工步名称 // 跳过空行 if (string.IsNullOrEmpty(projectCode) && string.IsNullOrEmpty(productCode) && string.IsNullOrEmpty(routingCode) && string.IsNullOrEmpty(stepCode)) continue; // 检查是否已存在相同的项目 if (!projectList.Any(p => p.ProjectCode == projectCode)) { var project = new ProcessmodelProject { ProjectCode = projectCode, ProjectName = projectName, ProductCode = productCode, ProductName = productName, CreatedBy = username, CreatedTime = DateTime.Now, }; projectList.Add(project); } // 检查是否已存在相同的工艺路线 if (!routingList.Any(r => r.RoutingCode == routingCode)) { var routing = new ProcessmodelRouting { RoutingCode = routingCode, RoutingName = routingName, ProductCode = productCode, Description = $"{productName}的工艺路线", Version = "1.0", CreateTime = DateTime.Now, IsActive = "1" }; routingList.Add(routing); } // 检查是否已存在相同的工序 if (!processList.Any(p => p.ProcessCode == processCode)) { var process = new ProcessmodelProcess { ProcessCode = processCode, ProcessName = processName, RoutingCode = routingCode, //PorcessSeq = processSeq, WorkCenter = "", // 可根据需要设置默认值 StandardTime = 0, // 可根据需要设置默认值 Description = $"{processName}工序", CreateTime = DateTime.Now, IsActive = "1" }; processList.Add(process); } // 处理工步和唯一键(K列到O列) for (int col = 10; col <= 14; col++) // K列到O列 { string uniqueValue = GetCellStringValue(row.GetCell(col)); if (!string.IsNullOrEmpty(uniqueValue)) { if (!stepList.Any(p => p.StepCode == stepCode)) { var workStep = new ProcessmodelWorkStep { StepCode = stepCode, StepName = stepName, ProcessCode = processCode, Description = $"{stepName}工步", IsActive = "1", UniqueValue = uniqueValue, CreateTime = DateTime.Now, CreateBy = username, Remark = $"导入自项目:{projectCode}, 产品:{productCode}" }; stepList.Add(workStep); } } } } Context.Ado.BeginTran(); try { // 批量插入数据(按依赖顺序) // 1. 先插入项目表 if (projectList.Count != 0) { Context.Insertable(projectList).ExecuteCommand(); insertCount += projectList.Count; } // 2. 插入工艺路线表 if (routingList.Count != 0) { Context.Insertable(routingList).ExecuteCommand(); insertCount += routingList.Count; } // 3. 插入工序表 if (processList.Count != 0) { Context.Insertable(processList).ExecuteCommand(); insertCount += processList.Count; } // 4. 最后插入工步表 if (stepList.Count != 0) { Context.Insertable(stepList).ExecuteCommand(); insertCount += stepList.Count; } Context.Ado.CommitTran(); // 成功提交 } catch { Context.Ado.RollbackTran(); // 失败回滚 throw; } return insertCount; } catch (Exception ex) { // 建议记录日志,而不是直接抛出 // Log.Error(ex, "导入Excel失败"); throw; // 不要 throw ex,直接 throw 保留堆栈 } } } /// /// 覆盖导入Excel /// /// /// /// public int CoverImportExcel(IFormFile formFile, string username) { _hasDeletedOldData = false; int insertCount = 0; using (var stream = formFile.OpenReadStream()) { try { List projectList = new List(); List routingList = new List(); List processList = new List(); List stepList = new List(); IWorkbook workbook = new XSSFWorkbook(stream); ISheet sheet = workbook.GetSheet("Sheet1"); // 从第二行开始读取 for (int i = 1; i <= sheet.LastRowNum; i++) { IRow row = sheet.GetRow(i); if (row == null) continue; // 读取基础数据 string projectCode = GetCellStringValue(row.GetCell(0)); // A列:项目号 string projectName = GetCellStringValue(row.GetCell(1)); // B列:项目名称 string productCode = GetCellStringValue(row.GetCell(2)); // C列:零件号 string productName = GetCellStringValue(row.GetCell(3)); // D列:零件名称 string routingCode = GetCellStringValue(row.GetCell(4)); // E列:工艺路线号 string routingName = GetCellStringValue(row.GetCell(5)); // F列:工艺路线名称 string processCode = GetCellStringValue(row.GetCell(6)); // G列:工序号 string processName = GetCellStringValue(row.GetCell(7)); // H列:工序名称 string stepCode = GetCellStringValue(row.GetCell(8)); // I列:工步号 string stepName = GetCellStringValue(row.GetCell(9)); // J列:工步名称 // 跳过空行 if (string.IsNullOrEmpty(projectCode) && string.IsNullOrEmpty(productCode) && string.IsNullOrEmpty(routingCode) && string.IsNullOrEmpty(stepCode)) continue; // 检查是否已存在相同的项目 if (!projectList.Any(p => p.ProjectCode == projectCode)) { var project = new ProcessmodelProject { ProjectCode = projectCode, ProjectName = projectName, ProductCode = productCode, ProductName = productName, CreatedBy = username, CreatedTime = DateTime.Now, }; projectList.Add(project); } // 检查是否已存在相同的工艺路线 if (!routingList.Any(r => r.RoutingCode == routingCode)) { var routing = new ProcessmodelRouting { RoutingCode = routingCode, RoutingName = routingName, ProductCode = productCode, Description = $"{productName}的工艺路线", Version = "1.0", CreateTime = DateTime.Now, IsActive = "1" }; routingList.Add(routing); } // 检查是否已存在相同的工序 if (!processList.Any(p => p.ProcessCode == processCode)) { var process = new ProcessmodelProcess { ProcessCode = processCode, ProcessName = processName, RoutingCode = routingCode, //PorcessSeq = processSeq, WorkCenter = "", // 可根据需要设置默认值 StandardTime = 0, // 可根据需要设置默认值 Description = $"{processName}工序", CreateTime = DateTime.Now, IsActive = "1" }; processList.Add(process); } // 处理工步和唯一键(K列到O列) for (int col = 10; col <= 14; col++) // K列到O列 { string uniqueValue = GetCellStringValue(row.GetCell(col)); if (!string.IsNullOrEmpty(uniqueValue)) { var workStep = new ProcessmodelWorkStep { StepCode = stepCode, StepName = stepName, ProcessCode = processCode, Description = $"{stepName}工步", IsActive = "1", UniqueValue = uniqueValue, CreateTime = DateTime.Now, CreateBy = username, Remark = $"导入自项目:{projectCode}, 产品:{productCode}" }; stepList.Add(workStep); } } } Context.Ado.BeginTran(); // 开启事务:使用 SqlSugar 的 UsingTran 方法(自动管理事务生命周期) try { // 1. 删除旧数据(子表→父表,避免外键约束) Context.Deleteable().ExecuteCommand(); Context.Deleteable().ExecuteCommand(); Context.Deleteable().ExecuteCommand(); Context.Deleteable().ExecuteCommand(); // 2. 插入新数据(父表→子表,保证外键关联有效) if (projectList != null && projectList.Count != 0) { Context.Insertable(projectList).ExecuteCommand(); insertCount += projectList.Count; } if (routingList != null && routingList.Count != 0) { Context.Insertable(routingList).ExecuteCommand(); insertCount += routingList.Count; } if (processList != null && processList.Count != 0) { Context.Insertable(processList).ExecuteCommand(); insertCount += processList.Count; } if (stepList != null && stepList.Count != 0) { Context.Insertable(stepList).ExecuteCommand(); insertCount += stepList.Count; } Context.Ado.CommitTran(); // 成功提交 } catch { Context.Ado.RollbackTran(); // 失败回滚 throw; } return insertCount; } catch (Exception ex) { // 记录日志 throw new Exception($"导入Excel失败: {ex.Message}", ex); } } } /// /// 导出 /// /// public (byte[] fileBytes, string fileName) ExportProjectExcel() { // 创建工作簿 IWorkbook workbook = new XSSFWorkbook(); ISheet sheet = workbook.CreateSheet("Sheet1"); // 创建表头行 IRow headerRow = sheet.CreateRow(0); headerRow.CreateCell(0).SetCellValue("项目号"); headerRow.CreateCell(1).SetCellValue("项目名称"); headerRow.CreateCell(2).SetCellValue("零件号"); headerRow.CreateCell(3).SetCellValue("零件名称"); headerRow.CreateCell(4).SetCellValue("工艺路线号"); headerRow.CreateCell(5).SetCellValue("工艺路线名称"); headerRow.CreateCell(6).SetCellValue("工序号"); headerRow.CreateCell(7).SetCellValue("工序名称"); headerRow.CreateCell(8).SetCellValue("工步号"); headerRow.CreateCell(9).SetCellValue("工步名称"); headerRow.CreateCell(10).SetCellValue("唯一键"); headerRow.CreateCell(11).SetCellValue("唯一键"); headerRow.CreateCell(12).SetCellValue("唯一键"); headerRow.CreateCell(13).SetCellValue("唯一键"); headerRow.CreateCell(14).SetCellValue("唯一键"); headerRow.CreateCell(15).SetCellValue("唯一键"); // 查询数据库获取数据 var projects = Context.Queryable().ToList(); var routings = Context.Queryable().ToList(); var processes = Context.Queryable().ToList(); var workSteps = Context.Queryable().ToList(); // 构建导出数据 var exportData = new List(); // 遍历工步表,然后关联其他表 foreach (var step in workSteps) { // 找到对应的工序 var process = processes.FirstOrDefault(p => p.ProcessCode == step.ProcessCode); if (process == null) continue; // 找到对应的工艺路线 var routing = routings.FirstOrDefault(r => r.RoutingCode == process.RoutingCode); if (routing == null) continue; // 找到对应的项目 var project = projects.FirstOrDefault(p => p.ProductCode == routing.ProductCode); if (project == null) continue; exportData.Add(new { Project = project, Routing = routing, Process = process, Step = step }); } // 按工步代码和工序代码分组,因为同一工序下的工步代码可能相同,但不同工序的工步代码可能相同 var groupedData = exportData .GroupBy(x => new { x.Step.StepCode, x.Process.ProcessCode }) .Select(g => new { Project = g.First().Project, Routing = g.First().Routing, Process = g.First().Process, StepCode = g.Key.StepCode, StepName = g.First().Step.StepName, UniqueValues = g.Select(x => x.Step.UniqueValue).Distinct().ToList() }) .ToList(); int rowIndex = 1; foreach (var item in groupedData) { IRow dataRow = sheet.CreateRow(rowIndex++); // 填充基础数据 dataRow.CreateCell(0).SetCellValue(item.Project.ProjectCode ?? ""); dataRow.CreateCell(1).SetCellValue(item.Project.ProjectName ?? ""); dataRow.CreateCell(2).SetCellValue(item.Project.ProductCode ?? ""); dataRow.CreateCell(3).SetCellValue(item.Project.ProductName ?? ""); dataRow.CreateCell(4).SetCellValue(item.Routing.RoutingCode ?? ""); dataRow.CreateCell(5).SetCellValue(item.Routing.RoutingName ?? ""); dataRow.CreateCell(6).SetCellValue(item.Process.ProcessCode ?? ""); dataRow.CreateCell(7).SetCellValue(item.Process.ProcessName ?? ""); dataRow.CreateCell(8).SetCellValue(item.StepCode ?? ""); dataRow.CreateCell(9).SetCellValue(item.StepName ?? ""); // 处理统一编号数据 for (int col = 10; col <= 15; col++) { if (col - 10 < item.UniqueValues.Count) { dataRow.CreateCell(col).SetCellValue(item.UniqueValues[col - 10] ?? ""); } else { dataRow.CreateCell(col).SetCellValue(""); } } } // 自动调整列宽 for (int i = 0; i < 16; i++) { sheet.AutoSizeColumn(i); } // 将工作簿写入内存流 using (MemoryStream ms = new MemoryStream()) { workbook.Write(ms); return (ms.ToArray(), "产品项目模板_导出.xlsx"); } } // 辅助方法:获取单元格字符串值 private string GetCellStringValue(ICell cell) { if (cell == null) return string.Empty; switch (cell.CellType) { case CellType.String: return cell.StringCellValue?.Trim(); case CellType.Numeric: return cell.NumericCellValue.ToString(); case CellType.Boolean: return cell.BooleanCellValue.ToString(); case CellType.Formula: try { return cell.StringCellValue?.Trim(); } catch { return cell.NumericCellValue.ToString(); } default: return string.Empty; } } } }