diff --git a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs index 251ec29..2c56970 100644 --- a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs +++ b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmInventoryController.cs @@ -1,8 +1,10 @@ -using Microsoft.AspNetCore.Mvc; -using DOAN.Model.BZFM.Dto; -using DOAN.Model.BZFM; -using DOAN.Service.BZFM.IBZFMService; using DOAN.Admin.WebApi.Filters; +using DOAN.Model; +using DOAN.Model.BZFM; +using DOAN.Model.BZFM.Dto; +using DOAN.Service.BZFM; +using DOAN.Service.BZFM.IBZFMService; +using Microsoft.AspNetCore.Mvc; //创建时间:2025-12-24 namespace DOAN.Admin.WebApi.Controllers.BZFM @@ -190,5 +192,57 @@ namespace DOAN.Admin.WebApi.Controllers.BZFM } + /// + /// 导入 + /// + /// 使用IFromFile必须使用name属性否则获取不到文件 + /// + [HttpPost("importData")] + [Log(Title = "库存管理导入", BusinessType = BusinessType.IMPORT, IsSaveRequestData = false, IsSaveResponseData = true)] + [ActionPermissionFilter(Permission = "mminventory:import")] + public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile) + { + //return SUCCESS(_MmMaterialService.Importmaterial(material)); + if (formFile == null) + { + return SUCCESS(null); + } + ImportResultDto response = _MmInventoryService.ImportInventory(formFile, HttpContext.GetName()); + + return SUCCESS(response); + } + + /// + /// 下载库存导入模板 + /// + /// + [HttpGet("importTemplate")] + [Log(Title = "库存模板", BusinessType = BusinessType.EXPORT)] + [AllowAnonymous] + public IActionResult ImportTemplateExcel() + { + // create an empty sample list of export DTO to generate header row + var sample = new List(); + var result = DownloadImportTemplate(sample, "inventory"); + return ExportExcel(result.Item2, result.Item1); + } + + /// + /// 库存导出 + /// + /// + /// + [HttpGet("export")] + [Log(Title = "物料清单导出", BusinessType = BusinessType.EXPORT)] + [ActionPermissionFilter(Permission = "mminventory:export")] + public IActionResult MaterialExport([FromQuery] MmInventoryQueryDto inventory) + { + var list = _MmInventoryService.SelectInventoryList(inventory, new PagerInfo(1, 10000)); + + var data = (list?.Result ?? new List()); + + var result = ExportExcelMini(data, "inventory", "库存管理"); + return ExportExcel(result.Item2, result.Item1); + } } } \ No newline at end of file diff --git a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmRecordInboundController.cs b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmRecordInboundController.cs index 0378a29..8c10d57 100644 --- a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmRecordInboundController.cs +++ b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmRecordInboundController.cs @@ -1,8 +1,10 @@ -using Microsoft.AspNetCore.Mvc; -using DOAN.Model.BZFM.Dto; -using DOAN.Model.BZFM; -using DOAN.Service.BZFM.IBZFMService; using DOAN.Admin.WebApi.Filters; +using DOAN.Model; +using DOAN.Model.BZFM; +using DOAN.Model.BZFM.Dto; +using DOAN.Service.BZFM; +using DOAN.Service.BZFM.IBZFMService; +using Microsoft.AspNetCore.Mvc; //创建时间:2025-12-25 namespace DOAN.Admin.WebApi.Controllers.BZFM @@ -98,5 +100,57 @@ namespace DOAN.Admin.WebApi.Controllers.BZFM return ToResponse(_MmRecordInboundService.Delete(idArr)); } + /// + /// 导入 + /// + /// 使用IFromFile必须使用name属性否则获取不到文件 + /// + [HttpPost("importData")] + [Log(Title = "入库记录导入", BusinessType = BusinessType.IMPORT, IsSaveRequestData = false, IsSaveResponseData = true)] + [ActionPermissionFilter(Permission = "mmrecordinbound:import")] + public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile) + { + if (formFile == null) + { + return SUCCESS(null); + } + ImportResultDto response = _MmRecordInboundService.ImportRecordinbound(formFile, HttpContext.GetName()); + + return SUCCESS(response); + } + + /// + /// 下载入库记录导入模板 + /// + /// + [HttpGet("importTemplate")] + [Log(Title = "入库记录模板", BusinessType = BusinessType.EXPORT)] + [AllowAnonymous] + public IActionResult ImportTemplateExcel() + { + // create an empty sample list of export DTO to generate header row + var sample = new List(); + var result = DownloadImportTemplate(sample, "recordinbound"); + return ExportExcel(result.Item2, result.Item1); + } + + /// + /// 入库记录导出 + /// + /// + /// + [HttpGet("export")] + [Log(Title = "入库记录导出", BusinessType = BusinessType.EXPORT)] + [ActionPermissionFilter(Permission = "mmrecordinbound:export")] + public IActionResult MaterialExport([FromQuery] MmRecordInboundQueryDto recordinbound) + { + var list = _MmRecordInboundService.SelectRecordinboundList(recordinbound, new PagerInfo(1, 10000)); + + var data = (list?.Result ?? new List()); + + var result = ExportExcelMini(data, "recordinbound", "入库记录"); + return ExportExcel(result.Item2, result.Item1); + } + } } \ No newline at end of file diff --git a/DOAN.Admin.WebApi/wwwroot/ImportTemplate/inventory.xlsx b/DOAN.Admin.WebApi/wwwroot/ImportTemplate/inventory.xlsx new file mode 100644 index 0000000..9babe2c Binary files /dev/null and b/DOAN.Admin.WebApi/wwwroot/ImportTemplate/inventory.xlsx differ diff --git a/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs b/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs index eba259d..bb61eef 100644 --- a/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs +++ b/DOAN.Model/MES/Material/Dto/MmInventoryDto.cs @@ -54,4 +54,47 @@ namespace DOAN.Model.BZFM.Dto } + + // + /// 库存管理导入导出 + /// + [SugarTable("mm_inventory", "库存管理")] + public class MmInventoryExcelDto + { + [ExcelColumn(Name = "id")] + [SugarColumn(IsIdentity = true, IsPrimaryKey = true)] + public int Id { get; set; } + + [ExcelColumn(Name = "物料编码")] + [SugarColumn(ColumnName = "material_code")] + public string MaterialCode { get; set; } + + [ExcelColumn(Name = "批次号")] + [SugarColumn(ColumnName = "batch_no")] + public string BatchNo { get; set; } + + [ExcelColumn(Name = "当前库存量")] + [SugarColumn(ColumnName = "current_qty")] + public decimal CurrentQty { get; set; } + + [ExcelColumn(Name = "仓库编码")] + [SugarColumn(ColumnName = "warehouse_code")] + public string WarehouseCode { get; set; } + + [ExcelColumn(Name = "仓库名称")] + [SugarColumn(ColumnName = "warehouse_name")] + public string WarehouseName { get; set; } + + [ExcelColumn(Name = "库位编码")] + [SugarColumn(ColumnName = "location_code")] + public string LocationCode { get; set; } + + [ExcelColumn(Name = "库位名称")] + [SugarColumn(ColumnName = "location_name")] + public string LocationName { get; set; } + + [ExcelColumn(Name = "创建时间")] + [SugarColumn(ColumnName = "created_time")] + public DateTime? CreatedTime { get; set; } + } } \ No newline at end of file diff --git a/DOAN.Model/MES/Material/Dto/MmRecordInboundDto.cs b/DOAN.Model/MES/Material/Dto/MmRecordInboundDto.cs index 0ceefcb..84328ff 100644 --- a/DOAN.Model/MES/Material/Dto/MmRecordInboundDto.cs +++ b/DOAN.Model/MES/Material/Dto/MmRecordInboundDto.cs @@ -103,5 +103,72 @@ namespace DOAN.Model.BZFM.Dto public string TransactionTypeLabel { get; set; } // 1-蓝单正向 2-红单逆向 public int ReceiptType { get; set; } = 1; -} + } + + // + /// 入库记录导入导出 + /// + [SugarTable("mm_recordinbound", "入库记录")] + public class MmRecordinboundExcelDto + { + [ExcelColumn(Name = "id")] + [SugarColumn(IsIdentity = true, IsPrimaryKey = true)] + public int Id { get; set; } + + [ExcelColumn(Name = "入库单号")] + [SugarColumn(ColumnName = "Inbound_no")] + public string InboundNo { get; set; } + + [ExcelColumn(Name = "物料编码")] + [SugarColumn(ColumnName = "material_code")] + public string MaterialCode { get; set; } + + [ExcelColumn(Name = "物料名称")] + [SugarColumn(ColumnName = "material_name")] + public string MaterialName { get; set; } + + [ExcelColumn(Name = "批次号")] + [SugarColumn(ColumnName = "batch_no")] + public string BatchNo { get; set; } + + [ExcelColumn(Name = "入库数量")] + [SugarColumn(ColumnName = "quantity")] + public decimal Quantity { get; set; } + + [ExcelColumn(Name = "入库类型")] + [SugarColumn(ColumnName = "transaction_Type")] + public string TransactionType { get; set; } + + [ExcelColumn(Name = "操作员")] + [SugarColumn(ColumnName = "operator")] + public string Operator { get; set; } + + [ExcelColumn(Name = "仓库编码")] + [SugarColumn(ColumnName = "warehouse_code")] + public string WarehouseCode { get; set; } + + [ExcelColumn(Name = "仓库名称")] + [SugarColumn(ColumnName = "warehouse_name")] + public string WarehouseName { get; set; } + + [ExcelColumn(Name = "库位编码")] + [SugarColumn(ColumnName = "location_code")] + public string LocationCode { get; set; } + + [ExcelColumn(Name = "库位名称")] + [SugarColumn(ColumnName = "location_name")] + public string LocationName { get; set; } + + [ExcelColumn(Name = "供应商编码")] + [SugarColumn(ColumnName = "supplier_Code")] + public string SupplierCode { get; set; } + + [ExcelColumn(Name = "供应商名称")] + [SugarColumn(ColumnName = "supplier_Name")] + public string SupplierName { get; set; } + + [ExcelColumn(Name = "创建时间")] + [SugarColumn(ColumnName = "created_time")] + public DateTime? CreatedTime { get; set; } + } } \ No newline at end of file diff --git a/DOAN.Service/MES/Material/IService/IMmInventoryService.cs b/DOAN.Service/MES/Material/IService/IMmInventoryService.cs index 918efe0..fcb34fe 100644 --- a/DOAN.Service/MES/Material/IService/IMmInventoryService.cs +++ b/DOAN.Service/MES/Material/IService/IMmInventoryService.cs @@ -1,5 +1,6 @@ -using DOAN.Model.BZFM.Dto; using DOAN.Model.BZFM; +using DOAN.Model.BZFM.Dto; +using Microsoft.AspNetCore.Http; namespace DOAN.Service.BZFM.IBZFMService { @@ -39,7 +40,14 @@ namespace DOAN.Service.BZFM.IBZFMService /// string CreateOutboundReceipt(OutboundReceiptDto parm); + /// + /// 导入 + /// + /// + /// + ImportResultDto ImportInventory(IFormFile formFile, string username); + public PagedInfo SelectInventoryList(MmInventoryQueryDto inventory, PagerInfo pager); } } diff --git a/DOAN.Service/MES/Material/IService/IMmRecordInboundService.cs b/DOAN.Service/MES/Material/IService/IMmRecordInboundService.cs index 33584ca..86389db 100644 --- a/DOAN.Service/MES/Material/IService/IMmRecordInboundService.cs +++ b/DOAN.Service/MES/Material/IService/IMmRecordInboundService.cs @@ -1,5 +1,6 @@ -using DOAN.Model.BZFM.Dto; using DOAN.Model.BZFM; +using DOAN.Model.BZFM.Dto; +using Microsoft.AspNetCore.Http; namespace DOAN.Service.BZFM.IBZFMService { @@ -16,6 +17,13 @@ namespace DOAN.Service.BZFM.IBZFMService MmRecordInbound AddMmRecordInbound(MmRecordInbound parm); int UpdateMmRecordInbound(MmRecordInbound parm); + /// + /// 导入 + /// + /// + /// + ImportResultDto ImportRecordinbound(IFormFile formFile, string username); + public PagedInfo SelectRecordinboundList(MmRecordInboundQueryDto recordinbound, PagerInfo pager); } } diff --git a/DOAN.Service/MES/Material/MmInventoryService.cs b/DOAN.Service/MES/Material/MmInventoryService.cs index 3435ddf..1181448 100644 --- a/DOAN.Service/MES/Material/MmInventoryService.cs +++ b/DOAN.Service/MES/Material/MmInventoryService.cs @@ -5,6 +5,10 @@ using DOAN.Repository; using DOAN.Service.BZFM.IBZFMService; using Infrastructure.Attribute; using Infrastructure.Extensions; +using Microsoft.AspNetCore.Http; +using Microsoft.IdentityModel.Tokens; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; namespace DOAN.Service.BZFM { @@ -421,5 +425,218 @@ namespace DOAN.Service.BZFM return baseNo + "001"; } } + + /// + /// 导入数据 + /// + /// + /// + public ImportResultDto ImportInventory(IFormFile formFile, string username) + { + string message = "导入成功"; + List inventoryList = new(); + using (var stream = formFile.OpenReadStream()) + { + try + { + IWorkbook workbook = new XSSFWorkbook(stream); + ISheet sheet = workbook.GetSheetAt(0); + + #region 读取excel + + // 遍历每一行 + for (int row = 1; row <= sheet.LastRowNum; row++) + { + IRow currentRow = sheet.GetRow(row); + if (currentRow != null) // 确保行不为空 + { + MmInventoryExcelDto inventory = new MmInventoryExcelDto(); + + //00 ID + NPOI.SS.UserModel.ICell currentCell_00 = currentRow.GetCell(0); + inventory.Id = (int)currentCell_00?.NumericCellValue; + + //02物料编码 + NPOI.SS.UserModel.ICell currentCell_01 = currentRow.GetCell(1); + inventory.MaterialCode = currentCell_01?.ToString(); + if ( + currentCell_01 == null + || string.IsNullOrEmpty(inventory.MaterialCode) + ) + { + message = $"物料编码不可为空,第{row + 1}行"; + break; + } + + //03批次号 + NPOI.SS.UserModel.ICell currentCell_02 = currentRow.GetCell(2); + inventory.BatchNo = currentCell_02?.ToString() ?? string.Empty; + + //04当前库存量 + NPOI.SS.UserModel.ICell currentCell_03 = currentRow.GetCell(3); + string currentQtyStr = currentCell_03?.ToString(); + + if (currentCell_03 == null || string.IsNullOrWhiteSpace(currentQtyStr)) + { + message = $"当前库存量不可为空,第{row + 1}行"; + break; + } + + // 尝试转换为decimal + if (!decimal.TryParse(currentQtyStr, out decimal currentQty)) + { + message = $"当前库存量格式错误(必须是数字),第{row + 1}行"; + break; + } + + // 验证数值范围(可根据业务需求调整) + //if (currentQty < 0) + //{ + // message = $"当前库存量不能为负数,第{row + 1}行"; + // break; + //} + inventory.CurrentQty = currentQty; + + //05 仓库编码 + NPOI.SS.UserModel.ICell currentCell_04 = currentRow.GetCell(4); + inventory.WarehouseCode = currentCell_04?.ToString(); + if ( + currentCell_04 == null + || string.IsNullOrEmpty(inventory.WarehouseCode) + ) + { + message = $"仓库编码不可为空,第{row + 1}行"; + break; + } + + //06 仓库名称 + NPOI.SS.UserModel.ICell currentCell_05 = currentRow.GetCell(5); + inventory.WarehouseName = currentCell_05?.ToString(); + if ( + currentCell_05 == null + || string.IsNullOrEmpty(inventory.WarehouseName) + ) + { + message = $"仓库名称不可为空,第{row + 1}行"; + break; + } + + //07 库位编码 + NPOI.SS.UserModel.ICell currentCell_06 = currentRow.GetCell(6); + inventory.LocationCode = currentCell_06?.ToString(); + if ( + currentCell_06 == null + || string.IsNullOrEmpty(inventory.LocationCode) + ) + { + message = $"仓库编码不可为空,第{row + 1}行"; + break; + } + + //08 库位名称 + NPOI.SS.UserModel.ICell currentCell_07 = currentRow.GetCell(7); + inventory.LocationName = currentCell_07?.ToString(); + if ( + currentCell_07 == null + || string.IsNullOrEmpty(inventory.LocationName) + ) + { + message = $"库位名称不可为空,第{row + 1}行"; + break; + } + + //09 创建时间 + NPOI.SS.UserModel.ICell currentCell_08 = currentRow.GetCell(8); + inventory.CreatedTime = currentCell_08?.DateCellValue ?? DateTime.Now; + + inventoryList.Add(inventory); + } + } + + #endregion + } + catch (Exception ex) + { + return null; + } + + + } + // TODO 3.调用SplitInsert方法实现导入操作,注意主键列的配置(建议优化为,ID相同则修改,不同则新增) + + var x = Context + .Storageable(inventoryList) + //.SplitInsert(it => !it.Any()) + //.WhereColumns(it => it.Id) //如果不是主键可以这样实现(多字段it=>new{it.x1,it.x2}) + .ToStorage(); + var result = x.AsInsertable.ExecuteCommand(); + var result2 = x.AsUpdateable.IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand(); //插入可插入部分; + + var importResult = new ImportResultDto + { + Message = message, + Inserted = x.InsertList.Count, + Updated = x.UpdateList.Count, + ErrorCount = x.ErrorList.Count, + IgnoredCount = x.IgnoreList.Count, + Deleted = x.DeleteList.Count, + Total = x.TotalList.Count, + }; + //输出统计 + Console.WriteLine(importResult); + // 4.收集错误与忽略信息,返回导入结果ImportResultDto 提示,需要修改IServer相关返回格式 + foreach (var item in x.ErrorList) + { + importResult.Errors.Add( + new ImportErrorDto + { + MaterialCode = item.Item.MaterialCode, + Message = item.StorageMessage, + } + ); + } + foreach (var item in x.IgnoreList) + { + importResult.Ignored.Add( + new ImportErrorDto + { + MaterialCode = item.Item.MaterialCode, + Message = item.StorageMessage, + } + ); + } + + return importResult; + } + + /// + /// 导出物料表列表 + /// + /// + public PagedInfo SelectInventoryList( + MmInventoryQueryDto inventory, + PagerInfo pager + ) + { + // Use the same predicate builder as GetList to support consistent filtering + var predicate = QueryExp(inventory); + + var query = Queryable() + .Where(predicate.ToExpression()) + .Select(it => new MmInventoryExcelDto + { + Id = it.Id, + MaterialCode = it.MaterialCode, + BatchNo = it.BatchNo, + CurrentQty = it.CurrentQty, + WarehouseCode = it.WarehouseCode, + WarehouseName = it.WarehouseName, + LocationCode = it.LocationCode, + LocationName = it.LocationName, + CreatedTime = it.CreatedTime, + }); + + return query.ToPage(pager); + } } } diff --git a/DOAN.Service/MES/Material/MmRecordInboundService.cs b/DOAN.Service/MES/Material/MmRecordInboundService.cs index 6043ac5..f62d39b 100644 --- a/DOAN.Service/MES/Material/MmRecordInboundService.cs +++ b/DOAN.Service/MES/Material/MmRecordInboundService.cs @@ -5,7 +5,10 @@ using DOAN.Service.BZFM.IBZFMService; using Infrastructure.Attribute; using Infrastructure.Converter; using Infrastructure.Extensions; +using Microsoft.AspNetCore.Http; using Microsoft.IdentityModel.Tokens; +using NPOI.SS.UserModel; +using NPOI.XSSF.UserModel; namespace DOAN.Service.BZFM { @@ -99,5 +102,259 @@ namespace DOAN.Service.BZFM return predicate; } + + /// + /// 导入数据 + /// + /// + /// + public ImportResultDto ImportRecordinbound(IFormFile formFile, string username) + { + string message = "导入成功"; + List recordinboundList = new(); + using (var stream = formFile.OpenReadStream()) + { + try + { + IWorkbook workbook = new XSSFWorkbook(stream); + ISheet sheet = workbook.GetSheetAt(0); + + #region 读取excel + + // 遍历每一行 + for (int row = 1; row <= sheet.LastRowNum; row++) + { + IRow currentRow = sheet.GetRow(row); + if (currentRow != null) // 确保行不为空 + { + MmRecordinboundExcelDto recordinbound = new MmRecordinboundExcelDto(); + + //00 ID + NPOI.SS.UserModel.ICell currentCell_00 = currentRow.GetCell(0); + recordinbound.Id = (int)currentCell_00?.NumericCellValue; + + //01 创建时间 + NPOI.SS.UserModel.ICell currentCell_01 = currentRow.GetCell(1); + recordinbound.CreatedTime = currentCell_01?.DateCellValue ?? DateTime.Now; + + //02 入库单号 + NPOI.SS.UserModel.ICell currentCell_02 = currentRow.GetCell(2); + recordinbound.InboundNo = currentCell_02?.ToString(); + if ( + currentCell_02 == null + || string.IsNullOrEmpty(recordinbound.InboundNo) + ) + { + message = $"入库单号不可为空,第{row + 1}行"; + break; + } + + //03 物料编码 + NPOI.SS.UserModel.ICell currentCell_03 = currentRow.GetCell(3); + recordinbound.MaterialCode = currentCell_03?.ToString(); + if ( + currentCell_03 == null + || string.IsNullOrEmpty(recordinbound.MaterialCode) + ) + { + message = $"物料编码不可为空,第{row + 1}行"; + break; + } + + //04 物料名称 + NPOI.SS.UserModel.ICell currentCell_04 = currentRow.GetCell(4); + recordinbound.MaterialName = currentCell_04?.ToString(); + if ( + currentCell_04 == null + || string.IsNullOrEmpty(recordinbound.MaterialName) + ) + { + message = $"物料名称不可为空,第{row + 1}行"; + break; + } + + //05 库位编码 + NPOI.SS.UserModel.ICell currentCell_05 = currentRow.GetCell(5); + recordinbound.LocationCode = currentCell_05?.ToString(); + if ( + currentCell_05 == null + || string.IsNullOrEmpty(recordinbound.LocationCode) + ) + { + message = $"库位编码不可为空,第{row + 1}行"; + break; + } + + //06 库位名称 + NPOI.SS.UserModel.ICell currentCell_06 = currentRow.GetCell(6); + recordinbound.LocationName = currentCell_06?.ToString(); + if ( + currentCell_06 == null + || string.IsNullOrEmpty(recordinbound.LocationName) + ) + { + message = $"库位名称不可为空,第{row + 1}行"; + break; + } + + //07 入库数量 + NPOI.SS.UserModel.ICell currentCell_07 = currentRow.GetCell(7); + string QuantityStr = currentCell_07?.ToString(); + + if (currentCell_07 == null || string.IsNullOrWhiteSpace(QuantityStr)) + { + message = $"入库数量不可为空,第{row + 1}行"; + break; + } + + // 尝试转换为decimal + if (!decimal.TryParse(QuantityStr, out decimal Quantity)) + { + message = $"入库数量格式错误(必须是数字),第{row + 1}行"; + break; + } + + //验证数值范围(可根据业务需求调整) + if (Quantity < 0) + { + message = $"入库数量不能为负数,第{row + 1}行"; + break; + } + recordinbound.Quantity = Quantity; + + //08 入库类型 + NPOI.SS.UserModel.ICell currentCell_08 = currentRow.GetCell(8); + recordinbound.TransactionType = currentCell_08?.ToString(); + if ( + currentCell_08 == null + || string.IsNullOrEmpty(recordinbound.TransactionType) + ) + { + message = $"入库类型不可为空,第{row + 1}行"; + break; + } + + //09 仓库编码 + NPOI.SS.UserModel.ICell currentCell_09 = currentRow.GetCell(9); + recordinbound.WarehouseCode = currentCell_09?.ToString(); + if ( + currentCell_09 == null + || string.IsNullOrEmpty(recordinbound.WarehouseCode) + ) + { + message = $"仓库编码不可为空,第{row + 1}行"; + break; + } + + //10 批次号 + NPOI.SS.UserModel.ICell currentCell_10 = currentRow.GetCell(10); + recordinbound.BatchNo = currentCell_10?.ToString() ?? string.Empty; + + //11 操作员 + NPOI.SS.UserModel.ICell currentCell_11 = currentRow.GetCell(11); + recordinbound.Operator = currentCell_11?.ToString() ?? string.Empty; + + //12 供应商编码 + NPOI.SS.UserModel.ICell currentCell_12 = currentRow.GetCell(12); + recordinbound.SupplierCode = currentCell_12?.ToString() ?? string.Empty; + + //13 供应商名称 + NPOI.SS.UserModel.ICell currentCell_13 = currentRow.GetCell(13); + recordinbound.SupplierName = currentCell_13?.ToString() ?? string.Empty; + + recordinboundList.Add(recordinbound); + } + } + + #endregion + } + catch (Exception ex) + { + return null; + } + + + } + // TODO 3.调用SplitInsert方法实现导入操作,注意主键列的配置(建议优化为,ID相同则修改,不同则新增) + + var x = Context + .Storageable(recordinboundList) + //.SplitInsert(it => !it.Any()) + //.WhereColumns(it => it.Id) //如果不是主键可以这样实现(多字段it=>new{it.x1,it.x2}) + .ToStorage(); + var result = x.AsInsertable.ExecuteCommand(); + var result2 = x.AsUpdateable.IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand(); //插入可插入部分; + + var importResult = new ImportResultDto + { + Message = message, + Inserted = x.InsertList.Count, + Updated = x.UpdateList.Count, + ErrorCount = x.ErrorList.Count, + IgnoredCount = x.IgnoreList.Count, + Deleted = x.DeleteList.Count, + Total = x.TotalList.Count, + }; + //输出统计 + Console.WriteLine(importResult); + // 4.收集错误与忽略信息,返回导入结果ImportResultDto 提示,需要修改IServer相关返回格式 + foreach (var item in x.ErrorList) + { + importResult.Errors.Add( + new ImportErrorDto + { + MaterialCode = item.Item.MaterialCode, + Message = item.StorageMessage, + } + ); + } + foreach (var item in x.IgnoreList) + { + importResult.Ignored.Add( + new ImportErrorDto + { + MaterialCode = item.Item.MaterialCode, + Message = item.StorageMessage, + } + ); + } + + return importResult; + } + + /// + /// 导出入库记录列表 + /// + /// + public PagedInfo SelectRecordinboundList( + MmRecordInboundQueryDto recordinbound, + PagerInfo pager + ) + { + // Use the same predicate builder as GetList to support consistent filtering + var predicate = QueryExp(recordinbound); + + var query = Queryable() + .Where(predicate.ToExpression()) + .Select(it => new MmRecordinboundExcelDto + { + Id = it.Id, + CreatedTime = it.CreatedTime, + InboundNo = it.InboundNo, + MaterialCode = it.MaterialCode, + MaterialName = it.MaterialName, + LocationCode = it.LocationCode, + LocationName = it.LocationName, + Quantity = it.Quantity, + TransactionType = it.TransactionType, + WarehouseCode = it.WarehouseCode, + BatchNo = it.BatchNo, + Operator = it.Operator, + SupplierCode = it.SupplierCode, + SupplierName = it.SupplierName, + }); + + return query.ToPage(pager); + } } } \ No newline at end of file