using Aliyun.OSS; 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; using Infrastructure.Attribute; using Infrastructure.Extensions; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.IdentityModel.Tokens; 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 => p.ProjectCode.Contains(parm.ProjectCode)) .AndIF(!string.IsNullOrEmpty(parm.ProjectName), p => p.ProjectName.Contains(parm.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; // 检查是否已存在相同的项目 var item1 = Context.Queryable().Any(p => p.ProjectCode == projectCode); if (!item1) { 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); } } var item2 = Context.Queryable().Any(p => p.RoutingCode == routingCode); if (!item2) { var routing = new ProcessmodelRouting { RoutingCode = routingCode, RoutingName = routingName, ProductCode = productCode, Description = $"{productName}的工艺路线", Version = "1.0", CreateTime = DateTime.Now, IsActive = "1" }; routingList.Add(routing); } var item3 = Context.Queryable().Any(p => p.ProcessCode == processCode); if (!item3) { 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 <= 15; 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(); 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); } var routing = new ProcessmodelRouting { RoutingCode = routingCode, RoutingName = routingName, ProductCode = productCode, Description = $"{productName}的工艺路线", Version = "1.0", CreateTime = DateTime.Now, IsActive = "1" }; routingList.Add(routing); 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() { // 获取模板文件路径 IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment)); string templatePath = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", "processmodel.xlsx"); //if (!System.IO.File.Exists(templatePath)) //{ // throw new Exception("模板文件不存在"); //} // 读取模板文件 IWorkbook workbook; using (var templateStream = new FileStream(templatePath, FileMode.Open, FileAccess.Read)) { workbook = new XSSFWorkbook(templateStream); } ISheet sheet = workbook.GetSheetAt(0); // 查询数据库获取数据 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); var routing = process != null ? routings.FirstOrDefault(r => r.RoutingCode == process.RoutingCode) : null; var project = routing != null ? projects.FirstOrDefault(p => p.ProductCode == routing.ProductCode) : null; if (project != null && routing != null && process != null) { 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++) { dataRow.CreateCell(col).SetCellValue(col - 10 < item.UniqueValues.Count ? item.UniqueValues[col - 10] ?? "" : ""); } } // 将工作簿写入内存流 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; } } } }