From 8a055d170492a9ef7a8d4ce745a1d69615c28887 Mon Sep 17 00:00:00 2001 From: Carl Date: Tue, 6 Jan 2026 17:26:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=BA=E5=85=A5=E5=BA=93=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MmMaterialController.cs | 60 +++++++++++++++- .../wwwroot/ImportTemplate/material.xlsx | Bin 0 -> 4363 bytes .../MES/Material/Dto/ImportResultDto.cs | 21 ++++++ DOAN.Model/MES/Material/Dto/MmMaterialDto.cs | 2 + .../Material/IService/IMmMaterialService.cs | 5 +- .../MES/Material/MmMaterialService.cs | 66 +++++++++++++----- 6 files changed, 134 insertions(+), 20 deletions(-) create mode 100644 DOAN.Admin.WebApi/wwwroot/ImportTemplate/material.xlsx create mode 100644 DOAN.Model/MES/Material/Dto/ImportResultDto.cs diff --git a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmMaterialController.cs b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmMaterialController.cs index 613b241..9ed67b3 100644 --- a/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmMaterialController.cs +++ b/DOAN.Admin.WebApi/Controllers/MES/Material/productionMaterial/MmMaterialController.cs @@ -1,11 +1,15 @@ using DOAN.Admin.WebApi.Filters; +using DOAN.Model; using DOAN.Model.BZFM; using DOAN.Model.BZFM.Dto; using DOAN.Model.System; +using DOAN.Model.System.Dto; using DOAN.Service.BZFM; using DOAN.Service.BZFM.IBZFMService; using Microsoft.AspNetCore.Mvc; using MiniExcelLibs; +using System.Linq; +using System.Collections.Generic; //创建时间:2025-12-25 namespace DOAN.Admin.WebApi.Controllers.BZFM @@ -123,13 +127,65 @@ namespace DOAN.Admin.WebApi.Controllers.BZFM [ActionPermissionFilter(Permission = "mmmaterial:import")] public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile) { - List material = new(); + List material = new(); using (var stream = formFile.OpenReadStream()) { - material = stream.Query(startCell: "A2").ToList(); + material = stream.Query(startCell: "A2").ToList(); } return SUCCESS(_MmMaterialService.Importmaterial(material)); } + + /// + /// 下载物料导入模板 + /// + /// + [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, "material"); + return ExportExcel(result.Item2, result.Item1); + } + + /// + /// 用户导出 + /// + /// + /// + [HttpGet("export")] + [Log(Title = "物料清单导出", BusinessType = BusinessType.EXPORT)] + [ActionPermissionFilter(Permission = "mmmaterial:export")] + public IActionResult MaterialExport([FromQuery] MmMaterialQueryDto material) + { + var list = _MmMaterialService.SelectMaterialList(material, new PagerInfo(1, 10000)); + + var data = (list?.Result ?? new List()); + + // Build list of dictionaries to control column titles and format dates + var exportList = data.Select(x => new Dictionary + { + ["物料编码"] = x.MaterialCode, + ["物料名称"] = x.MaterialName, + ["规格"] = x.Specification, + ["物料分类编码"] = x.CategoryCode, + ["物料分类名称"] = x.CategoryName, + ["计量单位"] = x.Unit, + ["物料类型"] = x.Type, + ["供应商编码"] = x.SupplierCode, + ["供应商名称"] = x.SupplierName, + ["安全库存"] = x.SafetyStock, + ["状态"] = x.Status, + ["创建时间"] = x.CreatedTime.HasValue ? x.CreatedTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : string.Empty, + ["更新时间"] = x.UpdatedTime.HasValue ? x.UpdatedTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : string.Empty, + ["描述"] = x.Description + }).ToList(); + + var result = ExportExcelMini(exportList, "material", "物料清单"); + return ExportExcel(result.Item2, result.Item1); + } } } \ No newline at end of file diff --git a/DOAN.Admin.WebApi/wwwroot/ImportTemplate/material.xlsx b/DOAN.Admin.WebApi/wwwroot/ImportTemplate/material.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..d878635e85d616c4a5bb23428dafb28ca4c43107 GIT binary patch literal 4363 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 literal 0 HcmV?d00001 diff --git a/DOAN.Model/MES/Material/Dto/ImportResultDto.cs b/DOAN.Model/MES/Material/Dto/ImportResultDto.cs new file mode 100644 index 0000000..98cd291 --- /dev/null +++ b/DOAN.Model/MES/Material/Dto/ImportResultDto.cs @@ -0,0 +1,21 @@ +namespace DOAN.Model.BZFM.Dto +{ + public class ImportErrorDto + { + public string MaterialCode { get; set; } + public string Message { get; set; } + } + + public class ImportResultDto + { + public string Message { get; set; } + public int Inserted { get; set; } + public int Updated { get; set; } + public int ErrorCount { get; set; } + public int IgnoredCount { get; set; } + public int Deleted { get; set; } + public int Total { get; set; } + public List Errors { get; set; } = new List(); + public List Ignored { get; set; } = new List(); + } +} diff --git a/DOAN.Model/MES/Material/Dto/MmMaterialDto.cs b/DOAN.Model/MES/Material/Dto/MmMaterialDto.cs index ee6b5bc..b0eecbf 100644 --- a/DOAN.Model/MES/Material/Dto/MmMaterialDto.cs +++ b/DOAN.Model/MES/Material/Dto/MmMaterialDto.cs @@ -17,6 +17,8 @@ namespace DOAN.Model.BZFM.Dto public string Type { get; set; } public string Status { get; set; } public DateTime? CreatedTime { get; set; } + + public int Id { get; set; } } ///

diff --git a/DOAN.Service/MES/Material/IService/IMmMaterialService.cs b/DOAN.Service/MES/Material/IService/IMmMaterialService.cs index df9524a..d39104c 100644 --- a/DOAN.Service/MES/Material/IService/IMmMaterialService.cs +++ b/DOAN.Service/MES/Material/IService/IMmMaterialService.cs @@ -1,6 +1,7 @@ using DOAN.Model.BZFM; using DOAN.Model.BZFM.Dto; using DOAN.Model.System; +using DOAN.Model.System.Dto; namespace DOAN.Service.BZFM.IBZFMService { @@ -26,7 +27,9 @@ namespace DOAN.Service.BZFM.IBZFMService /// /// /// - (string, object, object) Importmaterial(List material); + ImportResultDto Importmaterial(List material); + + public PagedInfo SelectMaterialList(MmMaterialQueryDto material, PagerInfo pager); } } diff --git a/DOAN.Service/MES/Material/MmMaterialService.cs b/DOAN.Service/MES/Material/MmMaterialService.cs index db27ffb..3f0fbc0 100644 --- a/DOAN.Service/MES/Material/MmMaterialService.cs +++ b/DOAN.Service/MES/Material/MmMaterialService.cs @@ -2,6 +2,7 @@ using DOAN.Common; using DOAN.Model.BZFM; using DOAN.Model.BZFM.Dto; using DOAN.Model.System; +using DOAN.Model.System.Dto; using DOAN.Repository; using DOAN.Service.BZFM.IBZFMService; using Infrastructure; @@ -118,14 +119,27 @@ namespace DOAN.Service.BZFM /// /// /// - public (string, object, object) Importmaterial(List material) + public ImportResultDto Importmaterial(List material) { + // normalize and set defaults, do not overwrite provided values material.ForEach(x => { - x.CreatedTime = DateTime.Now; - x.Status = "启用"; - x.MaterialCode = ""; - x.MaterialName = "E10ADC3949BA59ABBE56E057F20F883E"; + if (x.CreatedTime == null) + { + x.CreatedTime = DateTime.Now; + } + if (string.IsNullOrWhiteSpace(x.Status)) + { + x.Status = "启用"; + } + if (!string.IsNullOrWhiteSpace(x.MaterialCode)) + { + x.MaterialCode = x.MaterialCode.Trim(); + } + if (!string.IsNullOrWhiteSpace(x.MaterialName)) + { + x.MaterialName = x.MaterialName.Trim(); + } //x.Remark = x.Remark.IsEmpty() ? "数据导入" : x.Remark; }); var x = Context.Storageable(material) @@ -137,27 +151,45 @@ namespace DOAN.Service.BZFM .ToStorage(); var result = x.AsInsertable.ExecuteCommand();//插入可插入部分; - string msg = string.Format(" 插入{0} 更新{1} 错误数据{2} 不计算数据{3} 删除数据{4} 总共{5}", - x.InsertList.Count, - x.UpdateList.Count, - x.ErrorList.Count, - x.IgnoreList.Count, - x.DeleteList.Count, - x.TotalList.Count); + var importResult = new ImportResultDto + { + 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(msg); + Console.WriteLine(importResult); - //输出错误信息 + // 收集错误与忽略信息 foreach (var item in x.ErrorList) { - Console.WriteLine("MaterialCode为" + item.Item.MaterialCode + " : " + item.StorageMessage); + importResult.Errors.Add(new ImportErrorDto { MaterialCode = item.Item.MaterialCode, Message = item.StorageMessage }); } foreach (var item in x.IgnoreList) { - Console.WriteLine("MaterialCode为" + item.Item.MaterialCode + " : " + item.StorageMessage); + importResult.Ignored.Add(new ImportErrorDto { MaterialCode = item.Item.MaterialCode, Message = item.StorageMessage }); } - return (msg, x.ErrorList, x.IgnoreList); + return importResult; + } + + /// + /// 导出物料表列表 + /// + /// + public PagedInfo SelectMaterialList(MmMaterialQueryDto material, PagerInfo pager) + { + // Use the same predicate builder as GetList to support consistent filtering + var predicate = QueryExp(material); + + var query = Queryable() + .Where(predicate.ToExpression()); + + return query.ToPage(pager); } } } \ No newline at end of file