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