560 lines
26 KiB
C#
560 lines
26 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 产品项目表Service业务层处理
|
||
/// </summary>
|
||
[AppService(ServiceType = typeof(IProcessmodelProjectService), ServiceLifetime = LifeTime.Transient)]
|
||
public class ProcessmodelProjectService : BaseService<ProcessmodelProject>, IProcessmodelProjectService
|
||
{
|
||
// 静态变量,标记是否已执行过删除旧数据
|
||
private static bool _hasDeletedOldData = false;
|
||
|
||
/// <summary>
|
||
/// 查询产品项目表列表
|
||
/// </summary>
|
||
/// <param name="parm"></param>
|
||
/// <returns></returns>
|
||
public PagedInfo<ProcessmodelProjectDto> GetList(ProcessmodelProjectQueryDto parm)
|
||
{
|
||
var predicate = Expressionable.Create<ProcessmodelProject>()
|
||
.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<ProcessmodelProject, ProcessmodelProjectDto>(parm);
|
||
|
||
return response;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取详情
|
||
/// </summary>
|
||
/// <param name="Id"></param>
|
||
/// <returns></returns>
|
||
public ProcessmodelProject GetInfo(long Id)
|
||
{
|
||
var response = Queryable()
|
||
.Where(x => x.Id == Id)
|
||
.First();
|
||
|
||
return response;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加产品项目表
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <returns></returns>
|
||
public ProcessmodelProject AddProcessmodelProject(ProcessmodelProject model)
|
||
{
|
||
return Context.Insertable(model).ExecuteReturnEntity();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 修改产品项目表
|
||
/// </summary>
|
||
/// <param name="model"></param>
|
||
/// <returns></returns>
|
||
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增导入Excel
|
||
/// </summary>
|
||
/// <param name="formFile"></param>
|
||
/// <param name="username"></param>
|
||
/// <returns></returns>
|
||
public int AddImportExcel(IFormFile formFile, string username)
|
||
{
|
||
_hasDeletedOldData = false;
|
||
int insertCount = 0;
|
||
using (var stream = formFile.OpenReadStream())
|
||
{
|
||
try
|
||
{
|
||
List<ProcessmodelProject> projectList = new List<ProcessmodelProject>();
|
||
List<ProcessmodelRouting> routingList = new List<ProcessmodelRouting>();
|
||
List<ProcessmodelProcess> processList = new List<ProcessmodelProcess>();
|
||
List<ProcessmodelWorkStep> stepList = new List<ProcessmodelWorkStep>();
|
||
|
||
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<ProcessmodelProject>().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<ProcessmodelRouting>().Any(p => p.RoutingCode == routingCode);
|
||
if (!item2)
|
||
{
|
||
// 检查是否已存在相同的工艺路线
|
||
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);
|
||
}
|
||
}
|
||
|
||
var item3 = Context.Queryable<ProcessmodelProcess>().Any(p => p.ProcessCode == processCode);
|
||
if (!item3)
|
||
{
|
||
// 检查是否已存在相同的工序
|
||
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 保留堆栈
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 覆盖导入Excel
|
||
/// </summary>
|
||
/// <param name="formFile"></param>
|
||
/// <param name="username"></param>
|
||
/// <returns></returns>
|
||
public int CoverImportExcel(IFormFile formFile, string username)
|
||
{
|
||
_hasDeletedOldData = false;
|
||
int insertCount = 0;
|
||
using (var stream = formFile.OpenReadStream())
|
||
{
|
||
try
|
||
{
|
||
List<ProcessmodelProject> projectList = new List<ProcessmodelProject>();
|
||
List<ProcessmodelRouting> routingList = new List<ProcessmodelRouting>();
|
||
List<ProcessmodelProcess> processList = new List<ProcessmodelProcess>();
|
||
List<ProcessmodelWorkStep> stepList = new List<ProcessmodelWorkStep>();
|
||
|
||
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<ProcessmodelWorkStep>().ExecuteCommand();
|
||
Context.Deleteable<ProcessmodelProcess>().ExecuteCommand();
|
||
Context.Deleteable<ProcessmodelRouting>().ExecuteCommand();
|
||
Context.Deleteable<ProcessmodelProject>().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);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导出
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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<ProcessmodelProject>().ToList();
|
||
var routings = Context.Queryable<ProcessmodelRouting>().ToList();
|
||
var processes = Context.Queryable<ProcessmodelProcess>().ToList();
|
||
var workSteps = Context.Queryable<ProcessmodelWorkStep>().ToList();
|
||
|
||
// 构建导出数据
|
||
var exportData = new List<dynamic>();
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
} |